@ledgerhq/coin-kaspa 1.1.1 → 1.2.0-nightly.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +21 -0
- package/lib/logic/bip32.d.ts +1 -0
- package/lib/logic/bip32.d.ts.map +1 -1
- package/lib/logic/bip32.js +10 -1
- package/lib/logic/bip32.js.map +1 -1
- package/lib/logic/tests/bip32.test.js +44 -0
- package/lib/logic/tests/bip32.test.js.map +1 -1
- package/lib-es/logic/bip32.d.ts +1 -0
- package/lib-es/logic/bip32.d.ts.map +1 -1
- package/lib-es/logic/bip32.js +10 -1
- package/lib-es/logic/bip32.js.map +1 -1
- package/lib-es/logic/tests/bip32.test.js +21 -0
- package/lib-es/logic/tests/bip32.test.js.map +1 -1
- package/package.json +6 -6
- package/src/logic/bip32.ts +10 -1
- package/src/logic/tests/bip32.test.ts +31 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
> @ledgerhq/coin-kaspa@1.
|
|
2
|
+
> @ledgerhq/coin-kaspa@1.2.0-nightly.0 build /home/runner/work/ledger-live/ledger-live/libs/coin-modules/coin-kaspa
|
|
3
3
|
> tsc && tsc -m esnext --moduleResolution bundler --outDir lib-es
|
|
4
4
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @ledgerhq/coin-framework
|
|
2
2
|
|
|
3
|
+
## 1.2.0-nightly.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`3979c07`](https://github.com/LedgerHQ/ledger-live/commit/3979c0715e4f54165c89d00ebe1441e064e1a110)]:
|
|
8
|
+
- @ledgerhq/coin-framework@6.6.0-nightly.1
|
|
9
|
+
|
|
10
|
+
## 1.2.0-nightly.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- [#11979](https://github.com/LedgerHQ/ledger-live/pull/11979) [`3b4dfe6`](https://github.com/LedgerHQ/ledger-live/commit/3b4dfe6fa227dabdd2603be890e2cea5c89c050d) Thanks [@semeano](https://github.com/semeano)! - Import and enable Kaspa custom fees for LLM. Add caching for KaspaBIP32 address generation.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [[`e04d493`](https://github.com/LedgerHQ/ledger-live/commit/e04d49340c65c8b4608a37bb726d21350fdd32f1), [`4d60b7e`](https://github.com/LedgerHQ/ledger-live/commit/4d60b7e0984f0f8ef75c1483e0cfaf5784fbc5ed), [`e3b568d`](https://github.com/LedgerHQ/ledger-live/commit/e3b568d2cbeee6dcf19a7047ce9fa11a04b0ae2a), [`0d368f0`](https://github.com/LedgerHQ/ledger-live/commit/0d368f0e682b3bd3daafa6af5b396648a95b1488), [`fe1abf6`](https://github.com/LedgerHQ/ledger-live/commit/fe1abf640cc1a30b2e78bf7aa4a12e983a068f2e)]:
|
|
19
|
+
- @ledgerhq/types-live@6.86.0-nightly.0
|
|
20
|
+
- @ledgerhq/types-cryptoassets@7.28.0-nightly.0
|
|
21
|
+
- @ledgerhq/cryptoassets@13.30.0-nightly.0
|
|
22
|
+
- @ledgerhq/coin-framework@6.6.0-nightly.0
|
|
23
|
+
|
|
3
24
|
## 1.1.1
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/lib/logic/bip32.d.ts
CHANGED
package/lib/logic/bip32.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bip32.d.ts","sourceRoot":"","sources":["../../src/logic/bip32.ts"],"names":[],"mappings":"AACA,OAAqB,EAAY,cAAc,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"bip32.d.ts","sourceRoot":"","sources":["../../src/logic/bip32.ts"],"names":[],"mappings":"AACA,OAAqB,EAAY,cAAc,EAAE,MAAM,OAAO,CAAC;AAM/D,MAAM,CAAC,OAAO,OAAO,UAAU;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;gBAER,mBAAmB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAK1D,UAAU,CAAC,IAAI,GAAE,MAAU,EAAE,KAAK,GAAE,MAAU;CAa/C"}
|
package/lib/logic/bip32.js
CHANGED
|
@@ -7,16 +7,25 @@ const secp256k1_1 = __importDefault(require("@bitcoinerlab/secp256k1"));
|
|
|
7
7
|
const bip32_1 = __importDefault(require("bip32"));
|
|
8
8
|
const kaspaAddresses_1 = require("./kaspaAddresses");
|
|
9
9
|
const bip32 = (0, bip32_1.default)(secp256k1_1.default);
|
|
10
|
+
const cache = new Map();
|
|
10
11
|
class KaspaBIP32 {
|
|
11
12
|
rootNode;
|
|
13
|
+
fingerprint;
|
|
12
14
|
constructor(compressedPublicKey, chainCode) {
|
|
13
15
|
this.rootNode = bip32.fromPublicKey(compressedPublicKey, chainCode);
|
|
16
|
+
this.fingerprint = this.rootNode.fingerprint.toString("hex");
|
|
14
17
|
}
|
|
15
18
|
getAddress(type = 0, index = 0) {
|
|
19
|
+
const cacheKey = `${this.fingerprint}'${type}/${index}`;
|
|
20
|
+
const cachedValue = cache.get(cacheKey);
|
|
21
|
+
if (cachedValue)
|
|
22
|
+
return cachedValue;
|
|
16
23
|
const child = this.rootNode.derivePath(`${type}/${index}`);
|
|
17
24
|
// child.publicKey is a compressed public key
|
|
18
25
|
const publicKeyBuffer = Buffer.from(child.publicKey.subarray(1, 33));
|
|
19
|
-
|
|
26
|
+
const kaspaAddress = (0, kaspaAddresses_1.publicKeyToAddress)(publicKeyBuffer, false);
|
|
27
|
+
cache.set(cacheKey, kaspaAddress);
|
|
28
|
+
return kaspaAddress;
|
|
20
29
|
}
|
|
21
30
|
}
|
|
22
31
|
exports.default = KaspaBIP32;
|
package/lib/logic/bip32.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bip32.js","sourceRoot":"","sources":["../../src/logic/bip32.ts"],"names":[],"mappings":";;;;;AAAA,wEAA0C;AAC1C,kDAA+D;AAC/D,qDAAsD;AAEtD,MAAM,KAAK,GAAa,IAAA,eAAY,EAAC,mBAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"bip32.js","sourceRoot":"","sources":["../../src/logic/bip32.ts"],"names":[],"mappings":";;;;;AAAA,wEAA0C;AAC1C,kDAA+D;AAC/D,qDAAsD;AAEtD,MAAM,KAAK,GAAa,IAAA,eAAY,EAAC,mBAAG,CAAC,CAAC;AAC1C,MAAM,KAAK,GAAwB,IAAI,GAAG,EAAE,CAAC;AAE7C,MAAqB,UAAU;IAC7B,QAAQ,CAAiB;IACzB,WAAW,CAAS;IAEpB,YAAY,mBAA2B,EAAE,SAAiB;QACxD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;QACpE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED,UAAU,CAAC,OAAe,CAAC,EAAE,QAAgB,CAAC;QAC5C,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QACxD,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,WAAW;YAAE,OAAO,WAAW,CAAC;QAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;QAE3D,6CAA6C;QAC7C,MAAM,eAAe,GAAW,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7E,MAAM,YAAY,GAAG,IAAA,mCAAkB,EAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QAChE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAClC,OAAO,YAAY,CAAC;IACtB,CAAC;CACF;AAtBD,6BAsBC"}
|
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
27
|
};
|
|
5
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
29
|
const bip32_1 = __importDefault(require("../bip32"));
|
|
30
|
+
const kaspaAddr = __importStar(require("../kaspaAddresses"));
|
|
7
31
|
describe("KaspaBIP32", () => {
|
|
8
32
|
it("should generate the expected addresses", () => {
|
|
9
33
|
// These addresses were generated from the ledger device, whose public key and chain code
|
|
@@ -37,6 +61,21 @@ describe("KaspaBIP32", () => {
|
|
|
37
61
|
}
|
|
38
62
|
expect(bip32.getAddress()).toBe("kaspa:qzese5lc37m2a9np8k5gect4l2jj8svyqq392p7aa7mxsqarjg9sjgxr4wvru");
|
|
39
63
|
});
|
|
64
|
+
it("should cache value", () => {
|
|
65
|
+
const compressedPublicKey = Buffer.from("035a19ab1842af431d3b4fa88a15b1fe7d7c3f6e26e808124a10dc0523352d462d", "hex");
|
|
66
|
+
const compressedPublicKey2 = Buffer.from("02bb257a3f0b6bc2104539be649e6f7fe0b42e38c660500598fb1dc833b7ecbb1a", "hex");
|
|
67
|
+
const chainCode = Buffer.from("0ba599a9c5bad1106065eab47b48efa070f4b31e9639c9d096f7756b248a6ff4", "hex");
|
|
68
|
+
const bip32 = new bip32_1.default(compressedPublicKey, chainCode);
|
|
69
|
+
const addrSpy = jest.spyOn(kaspaAddr, "publicKeyToAddress").mockReturnValue("dummy");
|
|
70
|
+
expect(bip32.getAddress(0, 1010)).toBe("dummy");
|
|
71
|
+
expect(addrSpy).toHaveBeenCalledTimes(1);
|
|
72
|
+
const bip32_2 = new bip32_1.default(compressedPublicKey, chainCode);
|
|
73
|
+
expect(bip32_2.getAddress(0, 1010)).toBe("dummy");
|
|
74
|
+
expect(addrSpy).toHaveBeenCalledTimes(1);
|
|
75
|
+
const bip32_3 = new bip32_1.default(compressedPublicKey2, chainCode);
|
|
76
|
+
expect(bip32_3.getAddress(0, 1010)).toBe("dummy");
|
|
77
|
+
expect(addrSpy).toHaveBeenCalledTimes(2);
|
|
78
|
+
});
|
|
40
79
|
it("result from ledger hw device", () => {
|
|
41
80
|
const testCases = [
|
|
42
81
|
{
|
|
@@ -60,5 +99,10 @@ describe("KaspaBIP32", () => {
|
|
|
60
99
|
expect(bip32.getAddress(Number(path[3]), Number(path[4]))).toBe(testCase.address);
|
|
61
100
|
}
|
|
62
101
|
});
|
|
102
|
+
afterEach(() => {
|
|
103
|
+
jest.restoreAllMocks();
|
|
104
|
+
jest.clearAllMocks();
|
|
105
|
+
jest.resetModules();
|
|
106
|
+
});
|
|
63
107
|
});
|
|
64
108
|
//# sourceMappingURL=bip32.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bip32.test.js","sourceRoot":"","sources":["../../../src/logic/tests/bip32.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bip32.test.js","sourceRoot":"","sources":["../../../src/logic/tests/bip32.test.ts"],"names":[],"mappings":"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"}
|
package/lib-es/logic/bip32.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bip32.d.ts","sourceRoot":"","sources":["../../src/logic/bip32.ts"],"names":[],"mappings":"AACA,OAAqB,EAAY,cAAc,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"bip32.d.ts","sourceRoot":"","sources":["../../src/logic/bip32.ts"],"names":[],"mappings":"AACA,OAAqB,EAAY,cAAc,EAAE,MAAM,OAAO,CAAC;AAM/D,MAAM,CAAC,OAAO,OAAO,UAAU;IAC7B,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;gBAER,mBAAmB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAK1D,UAAU,CAAC,IAAI,GAAE,MAAU,EAAE,KAAK,GAAE,MAAU;CAa/C"}
|
package/lib-es/logic/bip32.js
CHANGED
|
@@ -2,16 +2,25 @@ import ecc from "@bitcoinerlab/secp256k1";
|
|
|
2
2
|
import BIP32Factory from "bip32";
|
|
3
3
|
import { publicKeyToAddress } from "./kaspaAddresses";
|
|
4
4
|
const bip32 = BIP32Factory(ecc);
|
|
5
|
+
const cache = new Map();
|
|
5
6
|
export default class KaspaBIP32 {
|
|
6
7
|
rootNode;
|
|
8
|
+
fingerprint;
|
|
7
9
|
constructor(compressedPublicKey, chainCode) {
|
|
8
10
|
this.rootNode = bip32.fromPublicKey(compressedPublicKey, chainCode);
|
|
11
|
+
this.fingerprint = this.rootNode.fingerprint.toString("hex");
|
|
9
12
|
}
|
|
10
13
|
getAddress(type = 0, index = 0) {
|
|
14
|
+
const cacheKey = `${this.fingerprint}'${type}/${index}`;
|
|
15
|
+
const cachedValue = cache.get(cacheKey);
|
|
16
|
+
if (cachedValue)
|
|
17
|
+
return cachedValue;
|
|
11
18
|
const child = this.rootNode.derivePath(`${type}/${index}`);
|
|
12
19
|
// child.publicKey is a compressed public key
|
|
13
20
|
const publicKeyBuffer = Buffer.from(child.publicKey.subarray(1, 33));
|
|
14
|
-
|
|
21
|
+
const kaspaAddress = publicKeyToAddress(publicKeyBuffer, false);
|
|
22
|
+
cache.set(cacheKey, kaspaAddress);
|
|
23
|
+
return kaspaAddress;
|
|
15
24
|
}
|
|
16
25
|
}
|
|
17
26
|
//# sourceMappingURL=bip32.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bip32.js","sourceRoot":"","sources":["../../src/logic/bip32.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,yBAAyB,CAAC;AAC1C,OAAO,YAA0C,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,KAAK,GAAa,YAAY,CAAC,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"bip32.js","sourceRoot":"","sources":["../../src/logic/bip32.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,yBAAyB,CAAC;AAC1C,OAAO,YAA0C,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,KAAK,GAAa,YAAY,CAAC,GAAG,CAAC,CAAC;AAC1C,MAAM,KAAK,GAAwB,IAAI,GAAG,EAAE,CAAC;AAE7C,MAAM,CAAC,OAAO,OAAO,UAAU;IAC7B,QAAQ,CAAiB;IACzB,WAAW,CAAS;IAEpB,YAAY,mBAA2B,EAAE,SAAiB;QACxD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;QACpE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED,UAAU,CAAC,OAAe,CAAC,EAAE,QAAgB,CAAC;QAC5C,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QACxD,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,WAAW;YAAE,OAAO,WAAW,CAAC;QAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;QAE3D,6CAA6C;QAC7C,MAAM,eAAe,GAAW,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7E,MAAM,YAAY,GAAG,kBAAkB,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QAChE,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAClC,OAAO,YAAY,CAAC;IACtB,CAAC;CACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import KaspaBIP32 from "../bip32";
|
|
2
|
+
import * as kaspaAddr from "../kaspaAddresses";
|
|
2
3
|
describe("KaspaBIP32", () => {
|
|
3
4
|
it("should generate the expected addresses", () => {
|
|
4
5
|
// These addresses were generated from the ledger device, whose public key and chain code
|
|
@@ -32,6 +33,21 @@ describe("KaspaBIP32", () => {
|
|
|
32
33
|
}
|
|
33
34
|
expect(bip32.getAddress()).toBe("kaspa:qzese5lc37m2a9np8k5gect4l2jj8svyqq392p7aa7mxsqarjg9sjgxr4wvru");
|
|
34
35
|
});
|
|
36
|
+
it("should cache value", () => {
|
|
37
|
+
const compressedPublicKey = Buffer.from("035a19ab1842af431d3b4fa88a15b1fe7d7c3f6e26e808124a10dc0523352d462d", "hex");
|
|
38
|
+
const compressedPublicKey2 = Buffer.from("02bb257a3f0b6bc2104539be649e6f7fe0b42e38c660500598fb1dc833b7ecbb1a", "hex");
|
|
39
|
+
const chainCode = Buffer.from("0ba599a9c5bad1106065eab47b48efa070f4b31e9639c9d096f7756b248a6ff4", "hex");
|
|
40
|
+
const bip32 = new KaspaBIP32(compressedPublicKey, chainCode);
|
|
41
|
+
const addrSpy = jest.spyOn(kaspaAddr, "publicKeyToAddress").mockReturnValue("dummy");
|
|
42
|
+
expect(bip32.getAddress(0, 1010)).toBe("dummy");
|
|
43
|
+
expect(addrSpy).toHaveBeenCalledTimes(1);
|
|
44
|
+
const bip32_2 = new KaspaBIP32(compressedPublicKey, chainCode);
|
|
45
|
+
expect(bip32_2.getAddress(0, 1010)).toBe("dummy");
|
|
46
|
+
expect(addrSpy).toHaveBeenCalledTimes(1);
|
|
47
|
+
const bip32_3 = new KaspaBIP32(compressedPublicKey2, chainCode);
|
|
48
|
+
expect(bip32_3.getAddress(0, 1010)).toBe("dummy");
|
|
49
|
+
expect(addrSpy).toHaveBeenCalledTimes(2);
|
|
50
|
+
});
|
|
35
51
|
it("result from ledger hw device", () => {
|
|
36
52
|
const testCases = [
|
|
37
53
|
{
|
|
@@ -55,5 +71,10 @@ describe("KaspaBIP32", () => {
|
|
|
55
71
|
expect(bip32.getAddress(Number(path[3]), Number(path[4]))).toBe(testCase.address);
|
|
56
72
|
}
|
|
57
73
|
});
|
|
74
|
+
afterEach(() => {
|
|
75
|
+
jest.restoreAllMocks();
|
|
76
|
+
jest.clearAllMocks();
|
|
77
|
+
jest.resetModules();
|
|
78
|
+
});
|
|
58
79
|
});
|
|
59
80
|
//# sourceMappingURL=bip32.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bip32.test.js","sourceRoot":"","sources":["../../../src/logic/tests/bip32.test.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"bip32.test.js","sourceRoot":"","sources":["../../../src/logic/tests/bip32.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/coin-kaspa",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-nightly.1",
|
|
4
4
|
"description": "Ledger framework for Kaspa integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger",
|
|
@@ -97,15 +97,15 @@
|
|
|
97
97
|
"lru-cache": "^7.14.1",
|
|
98
98
|
"prando": "^6.0.1",
|
|
99
99
|
"rxjs": "^7.8.1",
|
|
100
|
-
"@ledgerhq/coin-framework": "^6.
|
|
101
|
-
"@ledgerhq/cryptoassets": "^13.
|
|
100
|
+
"@ledgerhq/coin-framework": "^6.6.0-nightly.1",
|
|
101
|
+
"@ledgerhq/cryptoassets": "^13.30.0-nightly.0",
|
|
102
102
|
"@ledgerhq/devices": "^8.6.0",
|
|
103
|
-
"@ledgerhq/errors": "^6.
|
|
103
|
+
"@ledgerhq/errors": "^6.26.0-nightly.0",
|
|
104
104
|
"@ledgerhq/live-env": "^2.17.0",
|
|
105
105
|
"@ledgerhq/live-network": "^2.0.18",
|
|
106
106
|
"@ledgerhq/logs": "^6.13.0",
|
|
107
|
-
"@ledgerhq/types-cryptoassets": "^7.
|
|
108
|
-
"@ledgerhq/types-live": "^6.
|
|
107
|
+
"@ledgerhq/types-cryptoassets": "^7.28.0-nightly.0",
|
|
108
|
+
"@ledgerhq/types-live": "^6.86.0-nightly.0"
|
|
109
109
|
},
|
|
110
110
|
"devDependencies": {
|
|
111
111
|
"@types/invariant": "^2.2.2",
|
package/src/logic/bip32.ts
CHANGED
|
@@ -3,19 +3,28 @@ import BIP32Factory, { BIP32API, BIP32Interface } from "bip32";
|
|
|
3
3
|
import { publicKeyToAddress } from "./kaspaAddresses";
|
|
4
4
|
|
|
5
5
|
const bip32: BIP32API = BIP32Factory(ecc);
|
|
6
|
+
const cache: Map<string, string> = new Map();
|
|
6
7
|
|
|
7
8
|
export default class KaspaBIP32 {
|
|
8
9
|
rootNode: BIP32Interface;
|
|
10
|
+
fingerprint: string;
|
|
9
11
|
|
|
10
12
|
constructor(compressedPublicKey: Buffer, chainCode: Buffer) {
|
|
11
13
|
this.rootNode = bip32.fromPublicKey(compressedPublicKey, chainCode);
|
|
14
|
+
this.fingerprint = this.rootNode.fingerprint.toString("hex");
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
getAddress(type: number = 0, index: number = 0) {
|
|
18
|
+
const cacheKey = `${this.fingerprint}'${type}/${index}`;
|
|
19
|
+
const cachedValue = cache.get(cacheKey);
|
|
20
|
+
if (cachedValue) return cachedValue;
|
|
21
|
+
|
|
15
22
|
const child = this.rootNode.derivePath(`${type}/${index}`);
|
|
16
23
|
|
|
17
24
|
// child.publicKey is a compressed public key
|
|
18
25
|
const publicKeyBuffer: Buffer = Buffer.from(child.publicKey.subarray(1, 33));
|
|
19
|
-
|
|
26
|
+
const kaspaAddress = publicKeyToAddress(publicKeyBuffer, false);
|
|
27
|
+
cache.set(cacheKey, kaspaAddress);
|
|
28
|
+
return kaspaAddress;
|
|
20
29
|
}
|
|
21
30
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import KaspaBIP32 from "../bip32";
|
|
2
|
+
import * as kaspaAddr from "../kaspaAddresses";
|
|
2
3
|
|
|
3
4
|
describe("KaspaBIP32", () => {
|
|
4
5
|
it("should generate the expected addresses", () => {
|
|
@@ -44,6 +45,31 @@ describe("KaspaBIP32", () => {
|
|
|
44
45
|
"kaspa:qzese5lc37m2a9np8k5gect4l2jj8svyqq392p7aa7mxsqarjg9sjgxr4wvru",
|
|
45
46
|
);
|
|
46
47
|
});
|
|
48
|
+
it("should cache value", () => {
|
|
49
|
+
const compressedPublicKey = Buffer.from(
|
|
50
|
+
"035a19ab1842af431d3b4fa88a15b1fe7d7c3f6e26e808124a10dc0523352d462d",
|
|
51
|
+
"hex",
|
|
52
|
+
);
|
|
53
|
+
const compressedPublicKey2 = Buffer.from(
|
|
54
|
+
"02bb257a3f0b6bc2104539be649e6f7fe0b42e38c660500598fb1dc833b7ecbb1a",
|
|
55
|
+
"hex",
|
|
56
|
+
);
|
|
57
|
+
const chainCode = Buffer.from(
|
|
58
|
+
"0ba599a9c5bad1106065eab47b48efa070f4b31e9639c9d096f7756b248a6ff4",
|
|
59
|
+
"hex",
|
|
60
|
+
);
|
|
61
|
+
const bip32 = new KaspaBIP32(compressedPublicKey, chainCode);
|
|
62
|
+
|
|
63
|
+
const addrSpy = jest.spyOn(kaspaAddr, "publicKeyToAddress").mockReturnValue("dummy");
|
|
64
|
+
expect(bip32.getAddress(0, 1010)).toBe("dummy");
|
|
65
|
+
expect(addrSpy).toHaveBeenCalledTimes(1);
|
|
66
|
+
const bip32_2 = new KaspaBIP32(compressedPublicKey, chainCode);
|
|
67
|
+
expect(bip32_2.getAddress(0, 1010)).toBe("dummy");
|
|
68
|
+
expect(addrSpy).toHaveBeenCalledTimes(1);
|
|
69
|
+
const bip32_3 = new KaspaBIP32(compressedPublicKey2, chainCode);
|
|
70
|
+
expect(bip32_3.getAddress(0, 1010)).toBe("dummy");
|
|
71
|
+
expect(addrSpy).toHaveBeenCalledTimes(2);
|
|
72
|
+
});
|
|
47
73
|
it("result from ledger hw device", () => {
|
|
48
74
|
const testCases = [
|
|
49
75
|
{
|
|
@@ -75,4 +101,9 @@ describe("KaspaBIP32", () => {
|
|
|
75
101
|
expect(bip32.getAddress(Number(path[3]), Number(path[4]))).toBe(testCase.address);
|
|
76
102
|
}
|
|
77
103
|
});
|
|
104
|
+
afterEach(() => {
|
|
105
|
+
jest.restoreAllMocks();
|
|
106
|
+
jest.clearAllMocks();
|
|
107
|
+
jest.resetModules();
|
|
108
|
+
});
|
|
78
109
|
});
|