Skip to content

Commit 4c64831

Browse files
Merge pull request #172 from KeystoneHQ/feat/support_signCip8Data
Feat/support sign cip8 data
2 parents 0d51084 + cd79856 commit 4c64831

File tree

4 files changed

+262
-0
lines changed

4 files changed

+262
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import {
2+
CryptoKeypath,
3+
extend,
4+
DataItem,
5+
PathComponent,
6+
RegistryItem,
7+
DataItemMap,
8+
} from "@keystonehq/bc-ur-registry";
9+
import { ExtendedRegistryTypes } from "./RegistryType";
10+
import * as uuid from "uuid";
11+
12+
const { decodeToDataItem, RegistryTypes } = extend;
13+
14+
enum Keys {
15+
requestId = 1,
16+
signData,
17+
derivationPath,
18+
origin,
19+
signType,
20+
xpub,
21+
hashPayload,
22+
addressBench32,
23+
addressFieldType,
24+
}
25+
export enum MessageAddressFieldType {
26+
ADDRESS = "ADDRESS",
27+
KEY_HASH = "KEY_HASH",
28+
}
29+
30+
type signRequestProps = {
31+
requestId?: Buffer;
32+
signData: Buffer;
33+
xpub: Buffer;
34+
derivationPath: CryptoKeypath;
35+
origin?: string;
36+
hashPayload: boolean;
37+
addressBench32?: string;
38+
addressFieldType: MessageAddressFieldType;
39+
};
40+
41+
export interface Cip8SignDataContext {
42+
requestId?: Buffer;
43+
messageHex: string;
44+
signingPath: string;
45+
xfp: string;
46+
originWallet?: string;
47+
addressFieldType: MessageAddressFieldType;
48+
}
49+
50+
export class CardanoSignCip8DataRequest extends RegistryItem {
51+
private requestId?: Buffer;
52+
private signData: Buffer;
53+
private derivationPath: CryptoKeypath;
54+
private origin?: string;
55+
private xpub: Buffer;
56+
private hashPayload: boolean;
57+
private addressBench32?: string;
58+
private addressFieldType: MessageAddressFieldType;
59+
getRegistryType = () => ExtendedRegistryTypes.CARDANO_SIGN_CIP8_DATA_REQUEST;
60+
61+
constructor(args: signRequestProps) {
62+
super();
63+
this.requestId = args.requestId;
64+
this.signData = args.signData;
65+
this.derivationPath = args.derivationPath;
66+
this.origin = args.origin;
67+
this.xpub = args.xpub;
68+
this.hashPayload = args.hashPayload;
69+
this.addressBench32 = args.addressBench32;
70+
this.addressFieldType = args.addressFieldType;
71+
}
72+
73+
public getRequestId = () => this.requestId;
74+
public getSignData = () => this.signData;
75+
public getDerivationPath = () => this.derivationPath.getPath();
76+
public getOrigin = () => this.origin;
77+
public getXpub = () => this.xpub;
78+
public getHashPayload = () => this.hashPayload;
79+
public getAddressBench32 = () => this.addressBench32;
80+
public getAddressFieldType = () => this.addressFieldType;
81+
public toDataItem = () => {
82+
const map: DataItemMap = {};
83+
if (this.requestId) {
84+
map[Keys.requestId] = new DataItem(
85+
this.requestId,
86+
RegistryTypes.UUID.getTag()
87+
);
88+
}
89+
90+
if (this.origin) {
91+
map[Keys.origin] = this.origin;
92+
}
93+
94+
map[Keys.signData] = this.signData;
95+
96+
const keyPath = this.derivationPath.toDataItem();
97+
keyPath.setTag(this.derivationPath.getRegistryType().getTag());
98+
map[Keys.derivationPath] = keyPath;
99+
map[Keys.xpub] = this.xpub;
100+
map[Keys.hashPayload] = this.hashPayload;
101+
if (this.addressBench32) {
102+
map[Keys.addressBench32] = this.addressBench32;
103+
}
104+
map[Keys.addressFieldType] = this.addressFieldType;
105+
return new DataItem(map);
106+
};
107+
108+
public static fromDataItem = (dataItem: DataItem) => {
109+
const map = dataItem.getData();
110+
const signData = map[Keys.signData];
111+
const derivationPath = CryptoKeypath.fromDataItem(map[Keys.derivationPath]);
112+
const requestId = map[Keys.requestId]
113+
? map[Keys.requestId].getData()
114+
: undefined;
115+
const origin = map[Keys.origin] ? map[Keys.origin] : undefined;
116+
const xpub = map[Keys.xpub];
117+
const hashPayload = map[Keys.hashPayload];
118+
const addressBench32 = map[Keys.addressBench32]
119+
? map[Keys.addressBench32]
120+
: undefined;
121+
const addressFieldType = map[Keys.addressFieldType];
122+
return new CardanoSignCip8DataRequest({
123+
requestId,
124+
signData,
125+
derivationPath,
126+
origin,
127+
xpub,
128+
hashPayload,
129+
addressBench32,
130+
addressFieldType,
131+
});
132+
};
133+
134+
public static fromCBOR = (_cborPayload: Buffer) => {
135+
const dataItem = decodeToDataItem(_cborPayload);
136+
return CardanoSignCip8DataRequest.fromDataItem(dataItem);
137+
};
138+
139+
public static constructCardanoSignCip8DataRequest(
140+
signData: string,
141+
hdPath: string,
142+
xfp: string,
143+
xpub: string,
144+
hashPayload: boolean,
145+
addressFieldType: MessageAddressFieldType,
146+
addressBench32?: string,
147+
uuidString?: string,
148+
origin?: string
149+
) {
150+
const paths = hdPath.replace(/[m|M]\//, "").split("/");
151+
const hdpathObject = new CryptoKeypath(
152+
paths.map((path) => {
153+
const index = parseInt(path.replace("'", ""));
154+
let isHardened = false;
155+
if (path.endsWith("'")) {
156+
isHardened = true;
157+
}
158+
return new PathComponent({ index, hardened: isHardened });
159+
}),
160+
Buffer.from(xfp, "hex")
161+
);
162+
return new CardanoSignCip8DataRequest({
163+
requestId: uuidString
164+
? Buffer.from(uuid.parse(uuidString) as Uint8Array)
165+
: undefined,
166+
signData: Buffer.from(signData, "hex"),
167+
derivationPath: hdpathObject,
168+
origin: origin || undefined,
169+
xpub: Buffer.from(xpub, "hex"),
170+
hashPayload: hashPayload,
171+
addressBench32: addressBench32 || undefined,
172+
addressFieldType: addressFieldType as MessageAddressFieldType,
173+
});
174+
}
175+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import {
2+
extend,
3+
DataItem,
4+
RegistryItem,
5+
DataItemMap,
6+
} from "@keystonehq/bc-ur-registry";
7+
import { ExtendedRegistryTypes } from "./RegistryType";
8+
9+
const { RegistryTypes, decodeToDataItem } = extend;
10+
11+
enum Keys {
12+
requestId = 1,
13+
signature,
14+
publicKey,
15+
addressField,
16+
}
17+
18+
export class CardanoSignCip8DataSignature extends RegistryItem {
19+
private requestId?: Buffer;
20+
private signature: Buffer;
21+
private publicKey: Buffer;
22+
private addressField: Buffer;
23+
getRegistryType = () => ExtendedRegistryTypes.CARDANO_SIGNATURE;
24+
25+
constructor(
26+
signature: Buffer,
27+
publicKey: Buffer,
28+
addressField: Buffer,
29+
requestId?: Buffer
30+
) {
31+
super();
32+
this.signature = signature;
33+
this.publicKey = publicKey;
34+
this.requestId = requestId;
35+
this.addressField = addressField;
36+
}
37+
38+
public getRequestId = () => this.requestId;
39+
public getSignature = () => this.signature;
40+
public getPublicKey = () => this.publicKey;
41+
public getAddressField = () => this.addressField;
42+
public toDataItem = () => {
43+
const map: DataItemMap = {};
44+
if (this.requestId) {
45+
map[Keys.requestId] = new DataItem(
46+
this.requestId,
47+
RegistryTypes.UUID.getTag()
48+
);
49+
}
50+
map[Keys.signature] = this.getSignature();
51+
map[Keys.publicKey] = this.getPublicKey();
52+
map[Keys.addressField] = this.getAddressField();
53+
return new DataItem(map);
54+
};
55+
56+
public static fromDataItem = (dataItem: DataItem) => {
57+
const map = dataItem.getData();
58+
const signature = map[Keys.signature];
59+
const publicKey = map[Keys.publicKey];
60+
const requestId = map[Keys.requestId]
61+
? map[Keys.requestId].getData()
62+
: undefined;
63+
const addressField = map[Keys.addressField];
64+
return new CardanoSignCip8DataSignature(
65+
signature,
66+
publicKey,
67+
addressField,
68+
requestId
69+
);
70+
};
71+
72+
public static fromCBOR = (_cborPayload: Buffer) => {
73+
const dataItem = decodeToDataItem(_cborPayload);
74+
return CardanoSignCip8DataSignature.fromDataItem(dataItem);
75+
};
76+
}

packages/ur-registry-cardano/src/RegistryType.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,12 @@ export const ExtendedRegistryTypes = {
2222
2208
2323
),
2424
CARDANO_DELEGATION: new RegistryType("cardano-delegation", 2209),
25+
CARDANO_SIGN_CIP8_DATA_REQUEST: new RegistryType(
26+
"cardano-sign-cip8-data-request",
27+
2210
28+
),
29+
CARDANO_SIGN_CIP8_DATA_SIGNATURE: new RegistryType(
30+
"cardano-sign-cip8-data-signature",
31+
2211
32+
),
2533
};

packages/ur-registry-cardano/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ export {
2020
CardanoCatalystRawDelegationsProps,
2121
} from "./CardanoCatalystRequest";
2222
export { CardanoCatalystSignature } from "./CardanoCatalystSignature";
23+
export { CardanoSignCip8DataRequest } from "./CardanoSignMessageCip8DataRequest";
24+
export { CardanoSignCip8DataSignature } from "./CardanoSignMessageCip8DataSignature";
25+
export { MessageAddressFieldType } from "./CardanoSignMessageCip8DataRequest";

0 commit comments

Comments
 (0)