@ledgerhq/coin-kaspa 1.1.1-nightly.4 → 1.2.0-nightly.0
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 +26 -40
- 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 +10 -10
- 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.1.1
|
|
2
|
+
> @ledgerhq/coin-kaspa@1.1.1 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,58 +1,44 @@
|
|
|
1
1
|
# @ledgerhq/coin-framework
|
|
2
2
|
|
|
3
|
-
## 1.
|
|
3
|
+
## 1.2.0-nightly.0
|
|
4
4
|
|
|
5
|
-
###
|
|
6
|
-
|
|
7
|
-
- Updated dependencies [[`a37c06f`](https://github.com/LedgerHQ/ledger-live/commit/a37c06f97b061a5db0dad3632bb5c3e8f293677c)]:
|
|
8
|
-
- @ledgerhq/types-live@6.85.0-nightly.4
|
|
9
|
-
- @ledgerhq/coin-framework@6.4.1-nightly.4
|
|
10
|
-
|
|
11
|
-
## 1.1.1-nightly.3
|
|
12
|
-
|
|
13
|
-
### Patch Changes
|
|
14
|
-
|
|
15
|
-
- Updated dependencies [[`ab0e1bc`](https://github.com/LedgerHQ/ledger-live/commit/ab0e1bcc97b66b750b6c29e618eb03ce6f25bb7b), [`c2d8d86`](https://github.com/LedgerHQ/ledger-live/commit/c2d8d8670f848989836c46ea08ae88c88086fdd6), [`f015ef3`](https://github.com/LedgerHQ/ledger-live/commit/f015ef32660905d00f55a45f451f38bc12aec9ba)]:
|
|
16
|
-
- @ledgerhq/cryptoassets@13.29.0-nightly.3
|
|
17
|
-
- @ledgerhq/types-cryptoassets@7.27.0-nightly.1
|
|
18
|
-
- @ledgerhq/errors@6.26.0-nightly.0
|
|
19
|
-
- @ledgerhq/live-env@2.17.0-nightly.2
|
|
20
|
-
- @ledgerhq/types-live@6.85.0-nightly.3
|
|
21
|
-
- @ledgerhq/coin-framework@6.4.1-nightly.3
|
|
22
|
-
- @ledgerhq/devices@8.5.2-nightly.1
|
|
23
|
-
- @ledgerhq/live-network@2.0.18-nightly.2
|
|
5
|
+
### Minor Changes
|
|
24
6
|
|
|
25
|
-
|
|
7
|
+
- [#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.
|
|
26
8
|
|
|
27
9
|
### Patch Changes
|
|
28
10
|
|
|
29
|
-
- Updated dependencies [[`
|
|
30
|
-
- @ledgerhq/live
|
|
31
|
-
- @ledgerhq/types-
|
|
32
|
-
- @ledgerhq/
|
|
33
|
-
- @ledgerhq/
|
|
34
|
-
- @ledgerhq/live-network@2.0.18-nightly.1
|
|
11
|
+
- 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)]:
|
|
12
|
+
- @ledgerhq/types-live@6.86.0-nightly.0
|
|
13
|
+
- @ledgerhq/types-cryptoassets@7.28.0-nightly.0
|
|
14
|
+
- @ledgerhq/cryptoassets@13.30.0-nightly.0
|
|
15
|
+
- @ledgerhq/coin-framework@6.6.0-nightly.0
|
|
35
16
|
|
|
36
|
-
## 1.1.1
|
|
17
|
+
## 1.1.1
|
|
37
18
|
|
|
38
19
|
### Patch Changes
|
|
39
20
|
|
|
40
|
-
- Updated dependencies [[`af64263`](https://github.com/LedgerHQ/ledger-live/commit/af642634bd4536183f766323d0ec5b9b99841dc6), [`13ac4d7`](https://github.com/LedgerHQ/ledger-live/commit/13ac4d7ed05f0fc448cc0a013688c917cb73e0f5)]:
|
|
41
|
-
- @ledgerhq/
|
|
42
|
-
- @ledgerhq/
|
|
43
|
-
- @ledgerhq/
|
|
21
|
+
- Updated dependencies [[`38a172c`](https://github.com/LedgerHQ/ledger-live/commit/38a172c23035040d077433c7f4fce60f72962ae0), [`aaa16b7`](https://github.com/LedgerHQ/ledger-live/commit/aaa16b718454dca51d59bb138ab1a638dc4b8243), [`9b8689a`](https://github.com/LedgerHQ/ledger-live/commit/9b8689ae2c44bdeccae26378e05cbf6899b83aec), [`d56bebe`](https://github.com/LedgerHQ/ledger-live/commit/d56bebe672a1ed825697b371662dbff19dcc63d8), [`c8fe586`](https://github.com/LedgerHQ/ledger-live/commit/c8fe586f1427d4d7a9fad092b51221ec8221399d), [`af64263`](https://github.com/LedgerHQ/ledger-live/commit/af642634bd4536183f766323d0ec5b9b99841dc6), [`0108eaf`](https://github.com/LedgerHQ/ledger-live/commit/0108eafb64e36ce68f44e03cc3f66ccdb5ee5a92), [`65c128a`](https://github.com/LedgerHQ/ledger-live/commit/65c128a93f07857b421bed3696bc9984f860ada9), [`3b5576e`](https://github.com/LedgerHQ/ledger-live/commit/3b5576e0b67fedad0f5dbbd6b9546281af4e6111), [`6941aac`](https://github.com/LedgerHQ/ledger-live/commit/6941aac638dcc8d4fb03aa92f42d2a71d4089202), [`fe97131`](https://github.com/LedgerHQ/ledger-live/commit/fe971313776194e5942dfa9a95d6082950c3111e), [`2a58b72`](https://github.com/LedgerHQ/ledger-live/commit/2a58b720de42e63e59ea430bd03b2c95e903634c), [`13ac4d7`](https://github.com/LedgerHQ/ledger-live/commit/13ac4d7ed05f0fc448cc0a013688c917cb73e0f5), [`ed4c073`](https://github.com/LedgerHQ/ledger-live/commit/ed4c073b304d85355cf510551bcb225de4a3391c)]:
|
|
22
|
+
- @ledgerhq/devices@8.6.0
|
|
23
|
+
- @ledgerhq/live-env@2.17.0
|
|
24
|
+
- @ledgerhq/types-live@6.85.0
|
|
25
|
+
- @ledgerhq/types-cryptoassets@7.27.0
|
|
26
|
+
- @ledgerhq/cryptoassets@13.29.0
|
|
27
|
+
- @ledgerhq/coin-framework@6.5.0
|
|
28
|
+
- @ledgerhq/live-network@2.0.18
|
|
44
29
|
|
|
45
|
-
## 1.1.1-
|
|
30
|
+
## 1.1.1-next.0
|
|
46
31
|
|
|
47
32
|
### Patch Changes
|
|
48
33
|
|
|
49
|
-
- Updated dependencies [[`38a172c`](https://github.com/LedgerHQ/ledger-live/commit/38a172c23035040d077433c7f4fce60f72962ae0), [`c8fe586`](https://github.com/LedgerHQ/ledger-live/commit/c8fe586f1427d4d7a9fad092b51221ec8221399d), [`3b5576e`](https://github.com/LedgerHQ/ledger-live/commit/3b5576e0b67fedad0f5dbbd6b9546281af4e6111), [`fe97131`](https://github.com/LedgerHQ/ledger-live/commit/fe971313776194e5942dfa9a95d6082950c3111e)]:
|
|
50
|
-
- @ledgerhq/devices@8.
|
|
51
|
-
- @ledgerhq/
|
|
52
|
-
- @ledgerhq/live
|
|
53
|
-
- @ledgerhq/
|
|
54
|
-
- @ledgerhq/cryptoassets@13.
|
|
55
|
-
- @ledgerhq/
|
|
34
|
+
- Updated dependencies [[`38a172c`](https://github.com/LedgerHQ/ledger-live/commit/38a172c23035040d077433c7f4fce60f72962ae0), [`aaa16b7`](https://github.com/LedgerHQ/ledger-live/commit/aaa16b718454dca51d59bb138ab1a638dc4b8243), [`9b8689a`](https://github.com/LedgerHQ/ledger-live/commit/9b8689ae2c44bdeccae26378e05cbf6899b83aec), [`d56bebe`](https://github.com/LedgerHQ/ledger-live/commit/d56bebe672a1ed825697b371662dbff19dcc63d8), [`c8fe586`](https://github.com/LedgerHQ/ledger-live/commit/c8fe586f1427d4d7a9fad092b51221ec8221399d), [`af64263`](https://github.com/LedgerHQ/ledger-live/commit/af642634bd4536183f766323d0ec5b9b99841dc6), [`0108eaf`](https://github.com/LedgerHQ/ledger-live/commit/0108eafb64e36ce68f44e03cc3f66ccdb5ee5a92), [`65c128a`](https://github.com/LedgerHQ/ledger-live/commit/65c128a93f07857b421bed3696bc9984f860ada9), [`3b5576e`](https://github.com/LedgerHQ/ledger-live/commit/3b5576e0b67fedad0f5dbbd6b9546281af4e6111), [`6941aac`](https://github.com/LedgerHQ/ledger-live/commit/6941aac638dcc8d4fb03aa92f42d2a71d4089202), [`fe97131`](https://github.com/LedgerHQ/ledger-live/commit/fe971313776194e5942dfa9a95d6082950c3111e), [`2a58b72`](https://github.com/LedgerHQ/ledger-live/commit/2a58b720de42e63e59ea430bd03b2c95e903634c), [`13ac4d7`](https://github.com/LedgerHQ/ledger-live/commit/13ac4d7ed05f0fc448cc0a013688c917cb73e0f5), [`ed4c073`](https://github.com/LedgerHQ/ledger-live/commit/ed4c073b304d85355cf510551bcb225de4a3391c)]:
|
|
35
|
+
- @ledgerhq/devices@8.6.0-next.0
|
|
36
|
+
- @ledgerhq/live-env@2.17.0-next.0
|
|
37
|
+
- @ledgerhq/types-live@6.85.0-next.0
|
|
38
|
+
- @ledgerhq/types-cryptoassets@7.27.0-next.0
|
|
39
|
+
- @ledgerhq/cryptoassets@13.29.0-next.0
|
|
40
|
+
- @ledgerhq/coin-framework@6.5.0-next.0
|
|
41
|
+
- @ledgerhq/live-network@2.0.18-next.0
|
|
56
42
|
|
|
57
43
|
## 1.1.0
|
|
58
44
|
|
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.0",
|
|
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.
|
|
102
|
-
"@ledgerhq/devices": "^8.
|
|
100
|
+
"@ledgerhq/coin-framework": "^6.6.0-nightly.0",
|
|
101
|
+
"@ledgerhq/cryptoassets": "^13.30.0-nightly.0",
|
|
102
|
+
"@ledgerhq/devices": "^8.6.0",
|
|
103
103
|
"@ledgerhq/errors": "^6.26.0-nightly.0",
|
|
104
|
-
"@ledgerhq/live-env": "^2.17.0
|
|
105
|
-
"@ledgerhq/live-network": "^2.0.18
|
|
104
|
+
"@ledgerhq/live-env": "^2.17.0",
|
|
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",
|
|
@@ -117,8 +117,8 @@
|
|
|
117
117
|
"jest-sonar": "0.2.16",
|
|
118
118
|
"timemachine": "^0.3.2",
|
|
119
119
|
"ts-jest": "^29.1.1",
|
|
120
|
-
"@ledgerhq/hw-transport-node-speculos": "^6.29.11
|
|
121
|
-
"@ledgerhq/hw-transport-node-speculos-http": "^6.30.1
|
|
120
|
+
"@ledgerhq/hw-transport-node-speculos": "^6.29.11",
|
|
121
|
+
"@ledgerhq/hw-transport-node-speculos-http": "^6.30.1",
|
|
122
122
|
"@ledgerhq/disable-network-setup": "^0.0.0"
|
|
123
123
|
},
|
|
124
124
|
"scripts": {
|
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
|
});
|