@astrox/identity-ledgerhq 0.0.24 → 0.0.27

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,24 @@
1
+ import { HttpAgentRequest, PublicKey, Signature, SignIdentity } from '@astrox/agent';
2
+ /**
3
+ * A Hardware Ledger Internet Computer Agent identity.
4
+ */
5
+ export declare class LedgerIdentity extends SignIdentity {
6
+ private readonly _app;
7
+ readonly derivePath: string;
8
+ private readonly _publicKey;
9
+ private readonly _address;
10
+ /**
11
+ * Create a LedgerIdentity using the Web USB transport.
12
+ * @param derivePath The derivation path.
13
+ */
14
+ static create(derivePath?: string): Promise<LedgerIdentity>;
15
+ private constructor();
16
+ /**
17
+ * Required by Ledger.com that the user should be able to press a Button in UI
18
+ * and verify the address/pubkey are the same as on the device screen.
19
+ */
20
+ showAddressAndPubKeyOnDevice(): Promise<void>;
21
+ getPublicKey(): PublicKey;
22
+ sign(blob: ArrayBuffer): Promise<Signature>;
23
+ transformRequest(request: HttpAgentRequest): Promise<unknown>;
24
+ }
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __rest = (this && this.__rest) || function (s, e) {
22
+ var t = {};
23
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
24
+ t[p] = s[p];
25
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
26
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
27
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
28
+ t[p[i]] = s[p[i]];
29
+ }
30
+ return t;
31
+ };
32
+ var __importDefault = (this && this.__importDefault) || function (mod) {
33
+ return (mod && mod.__esModule) ? mod : { "default": mod };
34
+ };
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.LedgerIdentity = void 0;
37
+ const agent_1 = require("@astrox/agent");
38
+ const principal_1 = require("@astrox/principal");
39
+ const ledger_dfinity_1 = __importDefault(require("@zondax/ledger-dfinity"));
40
+ const buffer_1 = require("buffer/");
41
+ const secp256k1_1 = require("./secp256k1");
42
+ /**
43
+ * Convert the HttpAgentRequest body into cbor which can be signed by the Ledger Hardware Wallet.
44
+ * @param request - body of the HttpAgentRequest
45
+ */
46
+ function _prepareCborForLedger(request) {
47
+ return agent_1.Cbor.encode({ content: request });
48
+ }
49
+ /**
50
+ * A Hardware Ledger Internet Computer Agent identity.
51
+ */
52
+ class LedgerIdentity extends agent_1.SignIdentity {
53
+ constructor(_app, derivePath, _publicKey, _address) {
54
+ super();
55
+ this._app = _app;
56
+ this.derivePath = derivePath;
57
+ this._publicKey = _publicKey;
58
+ this._address = _address;
59
+ }
60
+ /**
61
+ * Create a LedgerIdentity using the Web USB transport.
62
+ * @param derivePath The derivation path.
63
+ */
64
+ static async create(derivePath = `m/44'/223'/0'/0/0`) {
65
+ const TransportClass = (await Promise.resolve().then(() => __importStar(require('@ledgerhq/hw-transport-webhid')))).default;
66
+ const transport = await TransportClass.create();
67
+ const app = new ledger_dfinity_1.default(transport);
68
+ const resp = await app.getAddressAndPubKey(derivePath);
69
+ // This type doesn't have the right fields in it, so we have to manually type it.
70
+ const principal = resp.principalText;
71
+ const publicKey = secp256k1_1.Secp256k1PublicKey.fromRaw(resp.publicKey);
72
+ const address = resp.address;
73
+ if (principal !== principal_1.Principal.selfAuthenticating(new Uint8Array(publicKey.toDer())).toText()) {
74
+ throw new Error('Principal returned by device does not match public key.');
75
+ }
76
+ return new this(app, derivePath, publicKey, address.buffer);
77
+ }
78
+ /**
79
+ * Required by Ledger.com that the user should be able to press a Button in UI
80
+ * and verify the address/pubkey are the same as on the device screen.
81
+ */
82
+ async showAddressAndPubKeyOnDevice() {
83
+ await this._app.showAddressAndPubKey(this.derivePath);
84
+ }
85
+ getPublicKey() {
86
+ return this._publicKey;
87
+ }
88
+ async sign(blob) {
89
+ // Force an `as any` because the types are compatible but TypeScript cannot figure it out.
90
+ const resp = await this._app.sign(this.derivePath, buffer_1.Buffer.from(blob));
91
+ const signatureRS = resp.signatureRS;
92
+ if (!signatureRS) {
93
+ throw new Error(`A ledger error happened during signature:\n` +
94
+ `Code: ${resp.returnCode}\n` +
95
+ `Message: ${JSON.stringify(resp.errorMessage)}\n`);
96
+ }
97
+ if ((signatureRS === null || signatureRS === void 0 ? void 0 : signatureRS.byteLength) !== 64) {
98
+ throw new Error(`Signature must be 64 bytes long (is ${signatureRS.length})`);
99
+ }
100
+ return signatureRS.buffer;
101
+ }
102
+ async transformRequest(request) {
103
+ const { body } = request, fields = __rest(request, ["body"]);
104
+ const signature = await this.sign(_prepareCborForLedger(body));
105
+ return Object.assign(Object.assign({}, fields), { body: {
106
+ content: body,
107
+ sender_pubkey: this._publicKey.toDer(),
108
+ sender_sig: signature,
109
+ } });
110
+ }
111
+ }
112
+ exports.LedgerIdentity = LedgerIdentity;
113
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../../src/identity/ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { DerEncodedPublicKey, PublicKey } from '@astrox/agent';
2
+ export declare class Secp256k1PublicKey implements PublicKey {
3
+ static fromRaw(rawKey: ArrayBuffer): Secp256k1PublicKey;
4
+ static fromDer(derKey: DerEncodedPublicKey): Secp256k1PublicKey;
5
+ private static RAW_KEY_LENGTH;
6
+ private static DER_PREFIX;
7
+ static derEncode(publicKey: ArrayBuffer): DerEncodedPublicKey;
8
+ static derDecode(key: DerEncodedPublicKey): ArrayBuffer;
9
+ private readonly rawKey;
10
+ private readonly derKey;
11
+ private constructor();
12
+ toDer(): DerEncodedPublicKey;
13
+ toRaw(): ArrayBuffer;
14
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Secp256k1PublicKey = void 0;
4
+ function equals(b1, b2) {
5
+ if (b1.byteLength !== b2.byteLength) {
6
+ return false;
7
+ }
8
+ const u1 = new Uint8Array(b1);
9
+ const u2 = new Uint8Array(b2);
10
+ for (let i = 0; i < u1.length; i++) {
11
+ if (u1[i] !== u2[i]) {
12
+ return false;
13
+ }
14
+ }
15
+ return true;
16
+ }
17
+ // This implementation is adjusted from the Ed25519PublicKey.
18
+ // The RAW_KEY_LENGTH and DER_PREFIX are modified accordingly
19
+ class Secp256k1PublicKey {
20
+ // `fromRaw` and `fromDer` should be used for instantiation, not this constructor.
21
+ constructor(key) {
22
+ this.rawKey = key;
23
+ this.derKey = Secp256k1PublicKey.derEncode(key);
24
+ }
25
+ static fromRaw(rawKey) {
26
+ return new Secp256k1PublicKey(rawKey);
27
+ }
28
+ static fromDer(derKey) {
29
+ return new Secp256k1PublicKey(this.derDecode(derKey));
30
+ }
31
+ static derEncode(publicKey) {
32
+ if (publicKey.byteLength !== Secp256k1PublicKey.RAW_KEY_LENGTH) {
33
+ const bl = publicKey.byteLength;
34
+ throw new TypeError(`secp256k1 public key must be ${Secp256k1PublicKey.RAW_KEY_LENGTH} bytes long (is ${bl})`);
35
+ }
36
+ const derPublicKey = Uint8Array.from([
37
+ ...Secp256k1PublicKey.DER_PREFIX,
38
+ ...new Uint8Array(publicKey),
39
+ ]);
40
+ return derPublicKey.buffer;
41
+ }
42
+ static derDecode(key) {
43
+ const expectedLength = Secp256k1PublicKey.DER_PREFIX.length + Secp256k1PublicKey.RAW_KEY_LENGTH;
44
+ if (key.byteLength !== expectedLength) {
45
+ const bl = key.byteLength;
46
+ throw new TypeError(`secp256k1 DER-encoded public key must be ${expectedLength} bytes long (is ${bl})`);
47
+ }
48
+ const rawKey = key.slice(0, Secp256k1PublicKey.DER_PREFIX.length);
49
+ if (!equals(this.derEncode(rawKey), key)) {
50
+ throw new TypeError('secp256k1 DER-encoded public key is invalid. A valid secp256k1 DER-encoded public key ' +
51
+ `must have the following prefix: ${Secp256k1PublicKey.DER_PREFIX}`);
52
+ }
53
+ return rawKey;
54
+ }
55
+ toDer() {
56
+ return this.derKey;
57
+ }
58
+ toRaw() {
59
+ return this.rawKey;
60
+ }
61
+ }
62
+ exports.Secp256k1PublicKey = Secp256k1PublicKey;
63
+ // The length of secp256k1 public keys is always 65 bytes.
64
+ Secp256k1PublicKey.RAW_KEY_LENGTH = 65;
65
+ // Adding this prefix to a raw public key is sufficient to DER-encode it.
66
+ // prettier-ignore
67
+ Secp256k1PublicKey.DER_PREFIX = Uint8Array.from([
68
+ 0x30, 0x56,
69
+ 0x30, 0x10,
70
+ 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
71
+ 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x0a,
72
+ 0x03, 0x42,
73
+ 0x00, // no padding
74
+ ]);
75
+ //# sourceMappingURL=secp256k1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secp256k1.js","sourceRoot":"","sources":["../../../src/identity/secp256k1.ts"],"names":[],"mappings":";;;AAEA,SAAS,MAAM,CAAC,EAAe,EAAE,EAAe;IAC9C,IAAI,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,UAAU,EAAE;QACnC,OAAO,KAAK,CAAC;KACd;IAED,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QAClC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE;YACnB,OAAO,KAAK,CAAC;SACd;KACF;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6DAA6D;AAC7D,6DAA6D;AAC7D,MAAa,kBAAkB;IA8D7B,kFAAkF;IAClF,YAAoB,GAAgB;QAClC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAClD,CAAC;IAjEM,MAAM,CAAC,OAAO,CAAC,MAAmB;QACvC,OAAO,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAEM,MAAM,CAAC,OAAO,CAAC,MAA2B;QAC/C,OAAO,IAAI,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;IAgBM,MAAM,CAAC,SAAS,CAAC,SAAsB;QAC5C,IAAI,SAAS,CAAC,UAAU,KAAK,kBAAkB,CAAC,cAAc,EAAE;YAC9D,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC;YAChC,MAAM,IAAI,SAAS,CACjB,gCAAgC,kBAAkB,CAAC,cAAc,mBAAmB,EAAE,GAAG,CAC1F,CAAC;SACH;QAED,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC;YACnC,GAAG,kBAAkB,CAAC,UAAU;YAChC,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC;SAC7B,CAAC,CAAC;QAEH,OAAO,YAAY,CAAC,MAA6B,CAAC;IACpD,CAAC;IAEM,MAAM,CAAC,SAAS,CAAC,GAAwB;QAC9C,MAAM,cAAc,GAAG,kBAAkB,CAAC,UAAU,CAAC,MAAM,GAAG,kBAAkB,CAAC,cAAc,CAAC;QAChG,IAAI,GAAG,CAAC,UAAU,KAAK,cAAc,EAAE;YACrC,MAAM,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC;YAC1B,MAAM,IAAI,SAAS,CACjB,4CAA4C,cAAc,mBAAmB,EAAE,GAAG,CACnF,CAAC;SACH;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,EAAE;YACxC,MAAM,IAAI,SAAS,CACjB,wFAAwF;gBACtF,mCAAmC,kBAAkB,CAAC,UAAU,EAAE,CACrE,CAAC;SACH;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAWM,KAAK;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAEM,KAAK;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;;AA1EH,gDA2EC;AAlEC,0DAA0D;AAC3C,iCAAc,GAAG,EAAE,CAAC;AAEnC,yEAAyE;AACzE,kBAAkB;AACH,6BAAU,GAAG,UAAU,CAAC,IAAI,CAAC;IAC1C,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IACpD,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;IACxC,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,aAAa;CACpB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './identity/ledger';
2
+ export * from './identity/secp256k1';
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ __exportStar(require("./identity/ledger"), exports);
14
+ __exportStar(require("./identity/secp256k1"), exports);
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAkC;AAClC,uDAAqC"}
@@ -0,0 +1,24 @@
1
+ import { HttpAgentRequest, PublicKey, Signature, SignIdentity } from '@astrox/agent';
2
+ /**
3
+ * A Hardware Ledger Internet Computer Agent identity.
4
+ */
5
+ export declare class LedgerIdentity extends SignIdentity {
6
+ private readonly _app;
7
+ readonly derivePath: string;
8
+ private readonly _publicKey;
9
+ private readonly _address;
10
+ /**
11
+ * Create a LedgerIdentity using the Web USB transport.
12
+ * @param derivePath The derivation path.
13
+ */
14
+ static create(derivePath?: string): Promise<LedgerIdentity>;
15
+ private constructor();
16
+ /**
17
+ * Required by Ledger.com that the user should be able to press a Button in UI
18
+ * and verify the address/pubkey are the same as on the device screen.
19
+ */
20
+ showAddressAndPubKeyOnDevice(): Promise<void>;
21
+ getPublicKey(): PublicKey;
22
+ sign(blob: ArrayBuffer): Promise<Signature>;
23
+ transformRequest(request: HttpAgentRequest): Promise<unknown>;
24
+ }
@@ -0,0 +1,87 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { Cbor, SignIdentity, } from '@astrox/agent';
13
+ import { Principal } from '@astrox/principal';
14
+ import DfinityApp from '@zondax/ledger-dfinity';
15
+ import { Buffer } from 'buffer/';
16
+ import { Secp256k1PublicKey } from './secp256k1';
17
+ /**
18
+ * Convert the HttpAgentRequest body into cbor which can be signed by the Ledger Hardware Wallet.
19
+ * @param request - body of the HttpAgentRequest
20
+ */
21
+ function _prepareCborForLedger(request) {
22
+ return Cbor.encode({ content: request });
23
+ }
24
+ /**
25
+ * A Hardware Ledger Internet Computer Agent identity.
26
+ */
27
+ export class LedgerIdentity extends SignIdentity {
28
+ constructor(_app, derivePath, _publicKey, _address) {
29
+ super();
30
+ this._app = _app;
31
+ this.derivePath = derivePath;
32
+ this._publicKey = _publicKey;
33
+ this._address = _address;
34
+ }
35
+ /**
36
+ * Create a LedgerIdentity using the Web USB transport.
37
+ * @param derivePath The derivation path.
38
+ */
39
+ static async create(derivePath = `m/44'/223'/0'/0/0`) {
40
+ const TransportClass = (await import('@ledgerhq/hw-transport-webhid')).default;
41
+ const transport = await TransportClass.create();
42
+ const app = new DfinityApp(transport);
43
+ const resp = await app.getAddressAndPubKey(derivePath);
44
+ // This type doesn't have the right fields in it, so we have to manually type it.
45
+ const principal = resp.principalText;
46
+ const publicKey = Secp256k1PublicKey.fromRaw(resp.publicKey);
47
+ const address = resp.address;
48
+ if (principal !== Principal.selfAuthenticating(new Uint8Array(publicKey.toDer())).toText()) {
49
+ throw new Error('Principal returned by device does not match public key.');
50
+ }
51
+ return new this(app, derivePath, publicKey, address.buffer);
52
+ }
53
+ /**
54
+ * Required by Ledger.com that the user should be able to press a Button in UI
55
+ * and verify the address/pubkey are the same as on the device screen.
56
+ */
57
+ async showAddressAndPubKeyOnDevice() {
58
+ await this._app.showAddressAndPubKey(this.derivePath);
59
+ }
60
+ getPublicKey() {
61
+ return this._publicKey;
62
+ }
63
+ async sign(blob) {
64
+ // Force an `as any` because the types are compatible but TypeScript cannot figure it out.
65
+ const resp = await this._app.sign(this.derivePath, Buffer.from(blob));
66
+ const signatureRS = resp.signatureRS;
67
+ if (!signatureRS) {
68
+ throw new Error(`A ledger error happened during signature:\n` +
69
+ `Code: ${resp.returnCode}\n` +
70
+ `Message: ${JSON.stringify(resp.errorMessage)}\n`);
71
+ }
72
+ if ((signatureRS === null || signatureRS === void 0 ? void 0 : signatureRS.byteLength) !== 64) {
73
+ throw new Error(`Signature must be 64 bytes long (is ${signatureRS.length})`);
74
+ }
75
+ return signatureRS.buffer;
76
+ }
77
+ async transformRequest(request) {
78
+ const { body } = request, fields = __rest(request, ["body"]);
79
+ const signature = await this.sign(_prepareCborForLedger(body));
80
+ return Object.assign(Object.assign({}, fields), { body: {
81
+ content: body,
82
+ sender_pubkey: this._publicKey.toDer(),
83
+ sender_sig: signature,
84
+ } });
85
+ }
86
+ }
87
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../../src/identity/ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { DerEncodedPublicKey, PublicKey } from '@astrox/agent';
2
+ export declare class Secp256k1PublicKey implements PublicKey {
3
+ static fromRaw(rawKey: ArrayBuffer): Secp256k1PublicKey;
4
+ static fromDer(derKey: DerEncodedPublicKey): Secp256k1PublicKey;
5
+ private static RAW_KEY_LENGTH;
6
+ private static DER_PREFIX;
7
+ static derEncode(publicKey: ArrayBuffer): DerEncodedPublicKey;
8
+ static derDecode(key: DerEncodedPublicKey): ArrayBuffer;
9
+ private readonly rawKey;
10
+ private readonly derKey;
11
+ private constructor();
12
+ toDer(): DerEncodedPublicKey;
13
+ toRaw(): ArrayBuffer;
14
+ }
@@ -0,0 +1,71 @@
1
+ function equals(b1, b2) {
2
+ if (b1.byteLength !== b2.byteLength) {
3
+ return false;
4
+ }
5
+ const u1 = new Uint8Array(b1);
6
+ const u2 = new Uint8Array(b2);
7
+ for (let i = 0; i < u1.length; i++) {
8
+ if (u1[i] !== u2[i]) {
9
+ return false;
10
+ }
11
+ }
12
+ return true;
13
+ }
14
+ // This implementation is adjusted from the Ed25519PublicKey.
15
+ // The RAW_KEY_LENGTH and DER_PREFIX are modified accordingly
16
+ export class Secp256k1PublicKey {
17
+ // `fromRaw` and `fromDer` should be used for instantiation, not this constructor.
18
+ constructor(key) {
19
+ this.rawKey = key;
20
+ this.derKey = Secp256k1PublicKey.derEncode(key);
21
+ }
22
+ static fromRaw(rawKey) {
23
+ return new Secp256k1PublicKey(rawKey);
24
+ }
25
+ static fromDer(derKey) {
26
+ return new Secp256k1PublicKey(this.derDecode(derKey));
27
+ }
28
+ static derEncode(publicKey) {
29
+ if (publicKey.byteLength !== Secp256k1PublicKey.RAW_KEY_LENGTH) {
30
+ const bl = publicKey.byteLength;
31
+ throw new TypeError(`secp256k1 public key must be ${Secp256k1PublicKey.RAW_KEY_LENGTH} bytes long (is ${bl})`);
32
+ }
33
+ const derPublicKey = Uint8Array.from([
34
+ ...Secp256k1PublicKey.DER_PREFIX,
35
+ ...new Uint8Array(publicKey),
36
+ ]);
37
+ return derPublicKey.buffer;
38
+ }
39
+ static derDecode(key) {
40
+ const expectedLength = Secp256k1PublicKey.DER_PREFIX.length + Secp256k1PublicKey.RAW_KEY_LENGTH;
41
+ if (key.byteLength !== expectedLength) {
42
+ const bl = key.byteLength;
43
+ throw new TypeError(`secp256k1 DER-encoded public key must be ${expectedLength} bytes long (is ${bl})`);
44
+ }
45
+ const rawKey = key.slice(0, Secp256k1PublicKey.DER_PREFIX.length);
46
+ if (!equals(this.derEncode(rawKey), key)) {
47
+ throw new TypeError('secp256k1 DER-encoded public key is invalid. A valid secp256k1 DER-encoded public key ' +
48
+ `must have the following prefix: ${Secp256k1PublicKey.DER_PREFIX}`);
49
+ }
50
+ return rawKey;
51
+ }
52
+ toDer() {
53
+ return this.derKey;
54
+ }
55
+ toRaw() {
56
+ return this.rawKey;
57
+ }
58
+ }
59
+ // The length of secp256k1 public keys is always 65 bytes.
60
+ Secp256k1PublicKey.RAW_KEY_LENGTH = 65;
61
+ // Adding this prefix to a raw public key is sufficient to DER-encode it.
62
+ // prettier-ignore
63
+ Secp256k1PublicKey.DER_PREFIX = Uint8Array.from([
64
+ 0x30, 0x56,
65
+ 0x30, 0x10,
66
+ 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01,
67
+ 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x0a,
68
+ 0x03, 0x42,
69
+ 0x00, // no padding
70
+ ]);
71
+ //# sourceMappingURL=secp256k1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secp256k1.js","sourceRoot":"","sources":["../../../src/identity/secp256k1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './identity/ledger';
2
+ export * from './identity/secp256k1';
@@ -0,0 +1,3 @@
1
+ export * from './identity/ledger';
2
+ export * from './identity/secp256k1';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC"}