@ledgerhq/coin-bitcoin 0.28.0 → 0.29.0-nightly.20260116024452
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/.unimportedrc.json +4 -1
- package/CHANGELOG.md +19 -0
- package/jest.config.js +10 -2
- package/jest.integ.config.js +15 -4
- package/lib/explorer.d.ts.map +1 -1
- package/lib/explorer.js +0 -7
- package/lib/explorer.js.map +1 -1
- package/lib-es/explorer.d.ts.map +1 -1
- package/lib-es/explorer.js +0 -7
- package/lib-es/explorer.js.map +1 -1
- package/package.json +17 -16
- package/src/__tests__/unit/buildTransaction.fees.unit.test.ts +19 -18
- package/src/explorer.ts +0 -8
- package/src/getTransactionStatus.test.ts +24 -5
- package/lib/descriptor.d.ts +0 -19
- package/lib/descriptor.d.ts.map +0 -1
- package/lib/descriptor.js +0 -127
- package/lib/descriptor.js.map +0 -1
- package/lib-es/descriptor.d.ts +0 -19
- package/lib-es/descriptor.d.ts.map +0 -1
- package/lib-es/descriptor.js +0 -118
- package/lib-es/descriptor.js.map +0 -1
- package/src/descriptor.test.ts +0 -76
- package/src/descriptor.ts +0 -204
package/.unimportedrc.json
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @ledgerhq/coin-bitcoin
|
|
2
2
|
|
|
3
|
+
## 0.29.0-nightly.20260116024452
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#13396](https://github.com/LedgerHQ/ledger-live/pull/13396) [`b9a3e43`](https://github.com/LedgerHQ/ledger-live/commit/b9a3e431be33943ab4feb4294d6a7f27b966e61b) Thanks [@gre-ledger](https://github.com/gre-ledger)! - Update Jest to v30
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`537a975`](https://github.com/LedgerHQ/ledger-live/commit/537a975536ca3669d3b88371e1e1f651c4cb9a1b), [`cbcae7c`](https://github.com/LedgerHQ/ledger-live/commit/cbcae7c0ba9b54b1167d26e4227bd2b847207cb9), [`8754614`](https://github.com/LedgerHQ/ledger-live/commit/87546149a62b81f8a25bb6222626592ead629f62), [`50bae0f`](https://github.com/LedgerHQ/ledger-live/commit/50bae0f13a95ef166b2c5609ccbcf5ef01ba1579), [`cf08174`](https://github.com/LedgerHQ/ledger-live/commit/cf0817462e9f0210fceff29ec60b0699e4e69b71), [`b9a3e43`](https://github.com/LedgerHQ/ledger-live/commit/b9a3e431be33943ab4feb4294d6a7f27b966e61b), [`3ac5f26`](https://github.com/LedgerHQ/ledger-live/commit/3ac5f26111f8596327fa7e588e514509de3f8a59), [`7f05536`](https://github.com/LedgerHQ/ledger-live/commit/7f0553665e9c8721f263825cc79994bfc6729d9b)]:
|
|
12
|
+
- @ledgerhq/cryptoassets@13.37.0-nightly.20260116024452
|
|
13
|
+
- @ledgerhq/coin-framework@6.13.0-nightly.20260116024452
|
|
14
|
+
- @ledgerhq/types-live@6.93.0-nightly.20260116024452
|
|
15
|
+
- @ledgerhq/live-env@2.25.0-nightly.20260116024452
|
|
16
|
+
- @ledgerhq/types-cryptoassets@7.32.0-nightly.20260116024452
|
|
17
|
+
- @ledgerhq/devices@8.10.0-nightly.20260116024452
|
|
18
|
+
- @ledgerhq/errors@6.29.0-nightly.20260116024452
|
|
19
|
+
- @ledgerhq/logs@6.14.0-nightly.20260116024452
|
|
20
|
+
- @ledgerhq/live-network@2.2.0-nightly.20260116024452
|
|
21
|
+
|
|
3
22
|
## 0.28.0
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
package/jest.config.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */
|
|
2
1
|
module.exports = {
|
|
3
2
|
passWithNoTests: true,
|
|
4
3
|
collectCoverageFrom: [
|
|
@@ -11,8 +10,17 @@ module.exports = {
|
|
|
11
10
|
"!src/wallet-btc/__tests__/**/*.ts",
|
|
12
11
|
],
|
|
13
12
|
coverageReporters: ["json", ["lcov", { file: "lcov.info", projectRoot: "../../../" }], "text"],
|
|
14
|
-
preset: "ts-jest",
|
|
15
13
|
testEnvironment: "node",
|
|
14
|
+
transform: {
|
|
15
|
+
"^.+\\.(ts|tsx)$": [
|
|
16
|
+
"@swc/jest",
|
|
17
|
+
{
|
|
18
|
+
jsc: {
|
|
19
|
+
target: "esnext",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
},
|
|
16
24
|
testPathIgnorePatterns: ["lib/", "lib-es/", ".integration.test.ts"],
|
|
17
25
|
modulePathIgnorePatterns: ["__tests__/fixtures"],
|
|
18
26
|
reporters: [
|
package/jest.integ.config.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
|
-
/** @type {import('
|
|
1
|
+
/** @type {import('jest').Config} */
|
|
2
2
|
module.exports = {
|
|
3
|
-
preset: "ts-jest",
|
|
4
3
|
testEnvironment: "node",
|
|
5
|
-
testRegex: ".
|
|
6
|
-
testPathIgnorePatterns: ["lib/", "lib-es/"
|
|
4
|
+
testRegex: ".integ.test.ts$",
|
|
5
|
+
testPathIgnorePatterns: ["lib/", "lib-es/"],
|
|
7
6
|
testTimeout: 60_000,
|
|
7
|
+
forceExit: true,
|
|
8
|
+
passWithNoTests: true,
|
|
9
|
+
transform: {
|
|
10
|
+
"^.+\\.(t|j)sx?$": [
|
|
11
|
+
"@swc/jest",
|
|
12
|
+
{
|
|
13
|
+
jsc: {
|
|
14
|
+
target: "esnext",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
},
|
|
8
19
|
};
|
package/lib/explorer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAI9D,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;
|
|
1
|
+
{"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAI9D,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAqBF,eAAO,MAAM,mBAAmB,aAAc,cAAc,KAAG,cAI9D,CAAC;AAEF,eAAO,MAAM,iBAAiB,aAAc,cAAc,KAAG,MAG5D,CAAC"}
|
package/lib/explorer.js
CHANGED
|
@@ -7,13 +7,6 @@ exports.blockchainBaseURL = exports.getCurrencyExplorer = void 0;
|
|
|
7
7
|
const invariant_1 = __importDefault(require("invariant"));
|
|
8
8
|
const live_env_1 = require("@ledgerhq/live-env");
|
|
9
9
|
const findCurrencyExplorer = (currency) => {
|
|
10
|
-
if ((0, live_env_1.getEnv)("SATSTACK") && currency.id === "bitcoin") {
|
|
11
|
-
return {
|
|
12
|
-
endpoint: (0, live_env_1.getEnv)("EXPLORER_SATSTACK"),
|
|
13
|
-
id: "btc",
|
|
14
|
-
version: "v3",
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
10
|
if (!currency.explorerId) {
|
|
18
11
|
console.warn("no explorerId for", currency.id);
|
|
19
12
|
}
|
package/lib/explorer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer.js","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":";;;;;;AACA,0DAAkC;AAClC,iDAA4C;AAQ5C,MAAM,oBAAoB,GAAG,CAAC,QAAwB,EAAqC,EAAE;IAC3F,IAAI,
|
|
1
|
+
{"version":3,"file":"explorer.js","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":";;;;;;AACA,0DAAkC;AAClC,iDAA4C;AAQ5C,MAAM,oBAAoB,GAAG,CAAC,QAAwB,EAAqC,EAAE;IAC3F,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,QAAQ,CAAC,EAAE,KAAK,iBAAiB,EAAE,CAAC;QACtC,OAAO;YACL,QAAQ,EAAE,IAAA,iBAAM,EAAC,kBAAkB,CAAC;YACpC,EAAE,EAAE,aAAa;YACjB,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IACD,OAAO;QACL,QAAQ,EAAE,IAAA,iBAAM,EAAC,UAAU,CAAC;QAC5B,EAAE,EAAE,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,EAAE;QACtC,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC,CAAC;AAEK,MAAM,mBAAmB,GAAG,CAAC,QAAwB,EAAkB,EAAE;IAC9E,MAAM,GAAG,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAA,mBAAS,EAAC,GAAG,EAAE,0BAA0B,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAJW,QAAA,mBAAmB,uBAI9B;AAEK,MAAM,iBAAiB,GAAG,CAAC,QAAwB,EAAU,EAAE;IACpE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAA,2BAAmB,EAAC,QAAQ,CAAC,CAAC;IAChE,OAAO,GAAG,QAAQ,eAAe,OAAO,IAAI,EAAE,EAAE,CAAC;AACnD,CAAC,CAAC;AAHW,QAAA,iBAAiB,qBAG5B"}
|
package/lib-es/explorer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAI9D,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;
|
|
1
|
+
{"version":3,"file":"explorer.d.ts","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAI9D,KAAK,cAAc,GAAG;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAqBF,eAAO,MAAM,mBAAmB,aAAc,cAAc,KAAG,cAI9D,CAAC;AAEF,eAAO,MAAM,iBAAiB,aAAc,cAAc,KAAG,MAG5D,CAAC"}
|
package/lib-es/explorer.js
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import invariant from "invariant";
|
|
2
2
|
import { getEnv } from "@ledgerhq/live-env";
|
|
3
3
|
const findCurrencyExplorer = (currency) => {
|
|
4
|
-
if (getEnv("SATSTACK") && currency.id === "bitcoin") {
|
|
5
|
-
return {
|
|
6
|
-
endpoint: getEnv("EXPLORER_SATSTACK"),
|
|
7
|
-
id: "btc",
|
|
8
|
-
version: "v3",
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
4
|
if (!currency.explorerId) {
|
|
12
5
|
console.warn("no explorerId for", currency.id);
|
|
13
6
|
}
|
package/lib-es/explorer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer.js","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAQ5C,MAAM,oBAAoB,GAAG,CAAC,QAAwB,EAAqC,EAAE;IAC3F,IAAI,
|
|
1
|
+
{"version":3,"file":"explorer.js","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAQ5C,MAAM,oBAAoB,GAAG,CAAC,QAAwB,EAAqC,EAAE;IAC3F,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,QAAQ,CAAC,EAAE,KAAK,iBAAiB,EAAE,CAAC;QACtC,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,kBAAkB,CAAC;YACpC,EAAE,EAAE,aAAa;YACjB,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IACD,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC;QAC5B,EAAE,EAAE,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,EAAE;QACtC,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAwB,EAAkB,EAAE;IAC9E,MAAM,GAAG,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC3C,SAAS,CAAC,GAAG,EAAE,0BAA0B,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAwB,EAAU,EAAE;IACpE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAChE,OAAO,GAAG,QAAQ,eAAe,OAAO,IAAI,EAAE,EAAE,CAAC;AACnD,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/coin-bitcoin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0-nightly.20260116024452",
|
|
4
4
|
"description": "Ledger Bitcoin Coin integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger",
|
|
@@ -54,22 +54,22 @@
|
|
|
54
54
|
"cashaddrjs": "^0.4.4",
|
|
55
55
|
"coininfo": "^5.1.0",
|
|
56
56
|
"create-hmac": "^1.1.7",
|
|
57
|
-
"expect": "
|
|
57
|
+
"expect": "30.2.0",
|
|
58
58
|
"invariant": "^2.2.2",
|
|
59
59
|
"lodash": "^4.17.21",
|
|
60
60
|
"rxjs": "7.8.2",
|
|
61
61
|
"@noble/curves": "^1.9.7",
|
|
62
62
|
"utility-types": "^3.10.0",
|
|
63
63
|
"varuint-bitcoin": "1.1.2",
|
|
64
|
-
"@ledgerhq/coin-framework": "^6.
|
|
65
|
-
"@ledgerhq/cryptoassets": "^13.
|
|
66
|
-
"@ledgerhq/devices": "8.
|
|
67
|
-
"@ledgerhq/errors": "^6.
|
|
68
|
-
"@ledgerhq/live-env": "^2.
|
|
69
|
-
"@ledgerhq/live-network": "^2.
|
|
70
|
-
"@ledgerhq/logs": "^6.
|
|
71
|
-
"@ledgerhq/types-cryptoassets": "^7.
|
|
72
|
-
"@ledgerhq/types-live": "^6.
|
|
64
|
+
"@ledgerhq/coin-framework": "^6.13.0-nightly.20260116024452",
|
|
65
|
+
"@ledgerhq/cryptoassets": "^13.37.0-nightly.20260116024452",
|
|
66
|
+
"@ledgerhq/devices": "8.10.0-nightly.20260116024452",
|
|
67
|
+
"@ledgerhq/errors": "^6.29.0-nightly.20260116024452",
|
|
68
|
+
"@ledgerhq/live-env": "^2.25.0-nightly.20260116024452",
|
|
69
|
+
"@ledgerhq/live-network": "^2.2.0-nightly.20260116024452",
|
|
70
|
+
"@ledgerhq/logs": "^6.14.0-nightly.20260116024452",
|
|
71
|
+
"@ledgerhq/types-cryptoassets": "^7.32.0-nightly.20260116024452",
|
|
72
|
+
"@ledgerhq/types-live": "^6.93.0-nightly.20260116024452"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@types/bchaddrjs": "^0.4.3",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"@types/cashaddrjs": "^0.3.3",
|
|
79
79
|
"@types/create-hmac": "^1.1.3",
|
|
80
80
|
"@types/invariant": "^2.2.2",
|
|
81
|
-
"@types/jest": "
|
|
81
|
+
"@types/jest": "30.0.0",
|
|
82
82
|
"@types/lodash": "^4.14.191",
|
|
83
83
|
"@types/object-hash": "^2.1.0",
|
|
84
84
|
"@types/ripemd160": "^2.0.3",
|
|
@@ -87,11 +87,12 @@
|
|
|
87
87
|
"axios": "1.13.2",
|
|
88
88
|
"bip32": "^2.0.6",
|
|
89
89
|
"bip39": "^3.0.4",
|
|
90
|
-
"jest": "
|
|
91
|
-
"jest-file-snapshot": "
|
|
90
|
+
"jest": "30.2.0",
|
|
91
|
+
"jest-file-snapshot": "0.7.0",
|
|
92
92
|
"object-hash": "^2.2.0",
|
|
93
|
-
"
|
|
94
|
-
"@
|
|
93
|
+
"@swc/jest": "0.2.39",
|
|
94
|
+
"@swc/core": "1.15.8",
|
|
95
|
+
"@ledgerhq/disable-network-setup": "^0.2.0-nightly.20260116024452"
|
|
95
96
|
},
|
|
96
97
|
"scripts": {
|
|
97
98
|
"clean": "rimraf lib lib-es",
|
|
@@ -10,24 +10,25 @@ let currentExplorer: any = {
|
|
|
10
10
|
getNetwork: jest.fn().mockResolvedValue({ relay_fee: "0.00001000" }), // 1 sat/vB
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
13
|
+
jest.mock("../../wallet-btc", () => {
|
|
14
|
+
class DummyStrategy {
|
|
15
|
+
constructor(..._args: any[]) {}
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
__esModule: true,
|
|
19
|
+
default: {
|
|
20
|
+
estimateAccountMaxSpendable: (...args: any[]) => estimateAccountMaxSpendable(...args),
|
|
21
|
+
buildAccountTx: (...args: any[]) => buildAccountTx(...args),
|
|
22
|
+
},
|
|
23
|
+
getWalletAccount: jest.fn((_account: any) => ({
|
|
24
|
+
xpub: { explorer: currentExplorer, crypto: {} },
|
|
25
|
+
derivationMode: "native_segwit",
|
|
26
|
+
})),
|
|
27
|
+
CoinSelect: DummyStrategy,
|
|
28
|
+
DeepFirst: DummyStrategy,
|
|
29
|
+
Merge: DummyStrategy,
|
|
30
|
+
};
|
|
31
|
+
});
|
|
31
32
|
|
|
32
33
|
import { buildTransaction } from "../../buildTransaction";
|
|
33
34
|
|
package/src/explorer.ts
CHANGED
|
@@ -9,14 +9,6 @@ type LedgerExplorer = {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
const findCurrencyExplorer = (currency: CryptoCurrency): LedgerExplorer | null | undefined => {
|
|
12
|
-
if (getEnv("SATSTACK") && currency.id === "bitcoin") {
|
|
13
|
-
return {
|
|
14
|
-
endpoint: getEnv("EXPLORER_SATSTACK"),
|
|
15
|
-
id: "btc",
|
|
16
|
-
version: "v3",
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
12
|
if (!currency.explorerId) {
|
|
21
13
|
console.warn("no explorerId for", currency.id);
|
|
22
14
|
}
|
|
@@ -1,16 +1,35 @@
|
|
|
1
1
|
/* eslint @typescript-eslint/consistent-type-assertions: 0 */
|
|
2
2
|
|
|
3
3
|
import { Account } from "@ledgerhq/types-live";
|
|
4
|
-
import * as cache from "./cache";
|
|
5
4
|
import { BitcoinInput, Transaction } from "./types";
|
|
6
|
-
import getTransactionStatus, { MAX_BLOCK_HEIGHT_FOR_TAPROOT } from "./getTransactionStatus";
|
|
7
5
|
import { AddressesSanctionedError } from "@ledgerhq/coin-framework/sanction/errors";
|
|
8
6
|
import BigNumber from "bignumber.js";
|
|
7
|
+
|
|
8
|
+
// Mock modules before importing the module under test
|
|
9
|
+
jest.mock("./cache", () => {
|
|
10
|
+
const actual = jest.requireActual("./cache");
|
|
11
|
+
return {
|
|
12
|
+
...actual,
|
|
13
|
+
calculateFees: jest.fn(),
|
|
14
|
+
validateRecipient: jest.fn(),
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
jest.mock("@ledgerhq/coin-framework/sanction/index", () => {
|
|
19
|
+
const actual = jest.requireActual("@ledgerhq/coin-framework/sanction/index");
|
|
20
|
+
return {
|
|
21
|
+
...actual,
|
|
22
|
+
isAddressSanctioned: jest.fn(),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
import * as cache from "./cache";
|
|
9
27
|
import * as sanction from "@ledgerhq/coin-framework/sanction/index";
|
|
28
|
+
import getTransactionStatus, { MAX_BLOCK_HEIGHT_FOR_TAPROOT } from "./getTransactionStatus";
|
|
10
29
|
|
|
11
|
-
const calculateFeesSpy = jest.
|
|
12
|
-
const validateRecipientSpy = jest.
|
|
13
|
-
const isAddressSanctionedSpy = jest.
|
|
30
|
+
const calculateFeesSpy = cache.calculateFees as jest.Mock;
|
|
31
|
+
const validateRecipientSpy = cache.validateRecipient as jest.Mock;
|
|
32
|
+
const isAddressSanctionedSpy = sanction.isAddressSanctioned as jest.Mock;
|
|
14
33
|
|
|
15
34
|
describe("getTransactionStatus on Bitcoin", () => {
|
|
16
35
|
it("should return as sender error only sanctioned utxo addresses", async () => {
|
package/lib/descriptor.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Observable } from "rxjs";
|
|
2
|
-
import type { Result } from "@ledgerhq/coin-framework/derivation";
|
|
3
|
-
import type { Account, DerivationMode } from "@ledgerhq/types-live";
|
|
4
|
-
import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
|
|
5
|
-
import { SignerContext } from "./signer";
|
|
6
|
-
export type AccountDescriptor = {
|
|
7
|
-
internal: string;
|
|
8
|
-
external: string;
|
|
9
|
-
};
|
|
10
|
-
export declare function inferDescriptorFromAccount(account: Account): AccountDescriptor | null | undefined;
|
|
11
|
-
export declare function inferDescriptorFromDeviceInfo({ derivationMode, currency, index, parentDerivation, accountDerivation, }: {
|
|
12
|
-
derivationMode: DerivationMode;
|
|
13
|
-
currency: CryptoCurrency;
|
|
14
|
-
index: number;
|
|
15
|
-
parentDerivation: Result;
|
|
16
|
-
accountDerivation: Result;
|
|
17
|
-
}): AccountDescriptor | null | undefined;
|
|
18
|
-
export declare function scanDescriptors(deviceId: string, currency: CryptoCurrency, signerContext: SignerContext, limit?: number): Observable<AccountDescriptor>;
|
|
19
|
-
//# sourceMappingURL=descriptor.d.ts.map
|
package/lib/descriptor.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"descriptor.d.ts","sourceRoot":"","sources":["../src/descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,MAAM,CAAC;AAInD,OAAO,KAAK,EAGV,MAAM,EACP,MAAM,qCAAqC,CAAC;AAS7C,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AA2CF,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAYjG;AAwCD,wBAAgB,6BAA6B,CAAC,EAC5C,cAAc,EACd,QAAQ,EACR,KAAK,EACL,gBAAgB,EAChB,iBAAiB,GAClB,EAAE;IACD,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,iBAAiB,GAAG,IAAI,GAAG,SAAS,CA6BvC;AACD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,cAAc,EACxB,aAAa,EAAE,aAAa,EAC5B,KAAK,SAAK,GACT,UAAU,CAAC,iBAAiB,CAAC,CAoC/B"}
|
package/lib/descriptor.js
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.scanDescriptors = exports.inferDescriptorFromDeviceInfo = exports.inferDescriptorFromAccount = void 0;
|
|
7
|
-
const rxjs_1 = require("rxjs");
|
|
8
|
-
const operators_1 = require("rxjs/operators");
|
|
9
|
-
const invariant_1 = __importDefault(require("invariant"));
|
|
10
|
-
const bs58_1 = __importDefault(require("bs58"));
|
|
11
|
-
const crypto_util_1 = require("./crypto-util");
|
|
12
|
-
const derivation_1 = require("@ledgerhq/coin-framework/derivation");
|
|
13
|
-
const hw_getAddress_1 = __importDefault(require("./hw-getAddress"));
|
|
14
|
-
const index_1 = require("@ledgerhq/coin-framework/account/index");
|
|
15
|
-
const perDerivation = {
|
|
16
|
-
"": fragment => `pkh(${fragment})`,
|
|
17
|
-
segwit: fragment => `sh(wpkh(${fragment}))`,
|
|
18
|
-
native_segwit: fragment => `wpkh(${fragment})`,
|
|
19
|
-
taproot: fragment => `tr(${fragment})`,
|
|
20
|
-
};
|
|
21
|
-
function makeFingerprint(compressedPubKey) {
|
|
22
|
-
return (0, crypto_util_1.hash160)(compressedPubKey).slice(0, 4);
|
|
23
|
-
}
|
|
24
|
-
function makeDescriptor({ currency, index, derivationMode, fingerprint, xpub, }) {
|
|
25
|
-
const tmpl = perDerivation[derivationMode];
|
|
26
|
-
if (!tmpl || !xpub)
|
|
27
|
-
return;
|
|
28
|
-
const keyOrigin = fingerprint.toString("hex");
|
|
29
|
-
const scheme = (0, derivation_1.getDerivationScheme)({
|
|
30
|
-
currency,
|
|
31
|
-
derivationMode,
|
|
32
|
-
});
|
|
33
|
-
const accountPath = (0, derivation_1.runAccountDerivationScheme)(scheme, currency, {
|
|
34
|
-
account: index,
|
|
35
|
-
});
|
|
36
|
-
return {
|
|
37
|
-
external: tmpl(`[${keyOrigin}/${accountPath}]${xpub}/0/*`),
|
|
38
|
-
internal: tmpl(`[${keyOrigin}/${accountPath}]${xpub}/1/*`),
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
function inferDescriptorFromAccount(account) {
|
|
42
|
-
if (account.currency.family !== "bitcoin")
|
|
43
|
-
return;
|
|
44
|
-
const { id, derivationMode, seedIdentifier, currency, index } = account;
|
|
45
|
-
const xpub = (0, index_1.decodeAccountId)(id).xpubOrAddress;
|
|
46
|
-
const fingerprint = makeFingerprint(compressPublicKeySECP256(Buffer.from(seedIdentifier, "hex")));
|
|
47
|
-
return makeDescriptor({
|
|
48
|
-
derivationMode,
|
|
49
|
-
currency,
|
|
50
|
-
fingerprint,
|
|
51
|
-
xpub,
|
|
52
|
-
index,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
exports.inferDescriptorFromAccount = inferDescriptorFromAccount;
|
|
56
|
-
function asBufferUInt32BE(n) {
|
|
57
|
-
const buf = Buffer.allocUnsafe(4);
|
|
58
|
-
buf.writeUInt32BE(n, 0);
|
|
59
|
-
return buf;
|
|
60
|
-
}
|
|
61
|
-
const compressPublicKeySECP256 = (publicKey) => Buffer.concat([Buffer.from([0x02 + (publicKey[64] & 0x01)]), publicKey.slice(1, 33)]);
|
|
62
|
-
function makeXpub({ version, depth, parentFingerprint, index, chainCode, pubKey, }) {
|
|
63
|
-
const indexBuffer = asBufferUInt32BE(index);
|
|
64
|
-
indexBuffer[0] |= 0x80;
|
|
65
|
-
const extendedKeyBytes = Buffer.concat([
|
|
66
|
-
asBufferUInt32BE(version),
|
|
67
|
-
Buffer.from([depth]),
|
|
68
|
-
parentFingerprint,
|
|
69
|
-
indexBuffer,
|
|
70
|
-
chainCode,
|
|
71
|
-
pubKey,
|
|
72
|
-
]);
|
|
73
|
-
const checksum = (0, crypto_util_1.hash256)(extendedKeyBytes).slice(0, 4);
|
|
74
|
-
return bs58_1.default.encode(Buffer.concat([extendedKeyBytes, checksum]));
|
|
75
|
-
}
|
|
76
|
-
function inferDescriptorFromDeviceInfo({ derivationMode, currency, index, parentDerivation, accountDerivation, }) {
|
|
77
|
-
(0, invariant_1.default)(currency.bitcoinLikeInfo, "bitcoin currency expected");
|
|
78
|
-
const { bitcoinLikeInfo } = currency;
|
|
79
|
-
const { XPUBVersion } = bitcoinLikeInfo;
|
|
80
|
-
(0, invariant_1.default)(XPUBVersion, "unsupported bitcoin fork %s", currency.id);
|
|
81
|
-
const { chainCode } = accountDerivation;
|
|
82
|
-
(0, invariant_1.default)(chainCode, "chainCode is required");
|
|
83
|
-
const fingerprint = makeFingerprint(compressPublicKeySECP256(Buffer.from(parentDerivation.publicKey, "hex")));
|
|
84
|
-
const xpub = makeXpub({
|
|
85
|
-
version: XPUBVersion,
|
|
86
|
-
depth: 3,
|
|
87
|
-
parentFingerprint: fingerprint,
|
|
88
|
-
index,
|
|
89
|
-
chainCode: Buffer.from(chainCode, "hex"),
|
|
90
|
-
pubKey: compressPublicKeySECP256(Buffer.from(accountDerivation.publicKey, "hex")),
|
|
91
|
-
});
|
|
92
|
-
return makeDescriptor({
|
|
93
|
-
derivationMode,
|
|
94
|
-
currency,
|
|
95
|
-
fingerprint,
|
|
96
|
-
xpub,
|
|
97
|
-
index,
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
exports.inferDescriptorFromDeviceInfo = inferDescriptorFromDeviceInfo;
|
|
101
|
-
function scanDescriptors(deviceId, currency, signerContext, limit = 10) {
|
|
102
|
-
const derivateAddress = (opts) => (0, rxjs_1.from)((0, hw_getAddress_1.default)(signerContext)(deviceId, opts));
|
|
103
|
-
function stepAddress({ index, accountDerivation, parentDerivation, derivationMode, }) {
|
|
104
|
-
const result = inferDescriptorFromDeviceInfo({
|
|
105
|
-
derivationMode,
|
|
106
|
-
currency,
|
|
107
|
-
index,
|
|
108
|
-
parentDerivation,
|
|
109
|
-
accountDerivation,
|
|
110
|
-
});
|
|
111
|
-
return !result
|
|
112
|
-
? rxjs_1.EMPTY
|
|
113
|
-
: (0, rxjs_1.of)({
|
|
114
|
-
result,
|
|
115
|
-
complete: index >= limit,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
return (0, rxjs_1.from)((0, derivation_1.getDerivationModesForCurrency)(currency)).pipe((0, operators_1.concatMap)(derivationMode => (0, derivation_1.walletDerivation)({
|
|
119
|
-
currency,
|
|
120
|
-
derivationMode,
|
|
121
|
-
derivateAddress,
|
|
122
|
-
stepAddress,
|
|
123
|
-
shouldDerivesOnAccount: true,
|
|
124
|
-
})));
|
|
125
|
-
}
|
|
126
|
-
exports.scanDescriptors = scanDescriptors;
|
|
127
|
-
//# sourceMappingURL=descriptor.js.map
|
package/lib/descriptor.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"descriptor.js","sourceRoot":"","sources":["../src/descriptor.ts"],"names":[],"mappings":"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"}
|
package/lib-es/descriptor.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { Observable } from "rxjs";
|
|
2
|
-
import type { Result } from "@ledgerhq/coin-framework/derivation";
|
|
3
|
-
import type { Account, DerivationMode } from "@ledgerhq/types-live";
|
|
4
|
-
import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
|
|
5
|
-
import { SignerContext } from "./signer";
|
|
6
|
-
export type AccountDescriptor = {
|
|
7
|
-
internal: string;
|
|
8
|
-
external: string;
|
|
9
|
-
};
|
|
10
|
-
export declare function inferDescriptorFromAccount(account: Account): AccountDescriptor | null | undefined;
|
|
11
|
-
export declare function inferDescriptorFromDeviceInfo({ derivationMode, currency, index, parentDerivation, accountDerivation, }: {
|
|
12
|
-
derivationMode: DerivationMode;
|
|
13
|
-
currency: CryptoCurrency;
|
|
14
|
-
index: number;
|
|
15
|
-
parentDerivation: Result;
|
|
16
|
-
accountDerivation: Result;
|
|
17
|
-
}): AccountDescriptor | null | undefined;
|
|
18
|
-
export declare function scanDescriptors(deviceId: string, currency: CryptoCurrency, signerContext: SignerContext, limit?: number): Observable<AccountDescriptor>;
|
|
19
|
-
//# sourceMappingURL=descriptor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"descriptor.d.ts","sourceRoot":"","sources":["../src/descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,MAAM,CAAC;AAInD,OAAO,KAAK,EAGV,MAAM,EACP,MAAM,qCAAqC,CAAC;AAS7C,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AA2CF,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAYjG;AAwCD,wBAAgB,6BAA6B,CAAC,EAC5C,cAAc,EACd,QAAQ,EACR,KAAK,EACL,gBAAgB,EAChB,iBAAiB,GAClB,EAAE;IACD,cAAc,EAAE,cAAc,CAAC;IAC/B,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,GAAG,iBAAiB,GAAG,IAAI,GAAG,SAAS,CA6BvC;AACD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,cAAc,EACxB,aAAa,EAAE,aAAa,EAC5B,KAAK,SAAK,GACT,UAAU,CAAC,iBAAiB,CAAC,CAoC/B"}
|
package/lib-es/descriptor.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { from, of, EMPTY } from "rxjs";
|
|
2
|
-
import { concatMap } from "rxjs/operators";
|
|
3
|
-
import invariant from "invariant";
|
|
4
|
-
import bs58 from "bs58";
|
|
5
|
-
import { hash256, hash160 } from "./crypto-util";
|
|
6
|
-
import { walletDerivation, getDerivationModesForCurrency, runAccountDerivationScheme, getDerivationScheme, } from "@ledgerhq/coin-framework/derivation";
|
|
7
|
-
import getAddress from "./hw-getAddress";
|
|
8
|
-
import { decodeAccountId } from "@ledgerhq/coin-framework/account/index";
|
|
9
|
-
const perDerivation = {
|
|
10
|
-
"": fragment => `pkh(${fragment})`,
|
|
11
|
-
segwit: fragment => `sh(wpkh(${fragment}))`,
|
|
12
|
-
native_segwit: fragment => `wpkh(${fragment})`,
|
|
13
|
-
taproot: fragment => `tr(${fragment})`,
|
|
14
|
-
};
|
|
15
|
-
function makeFingerprint(compressedPubKey) {
|
|
16
|
-
return hash160(compressedPubKey).slice(0, 4);
|
|
17
|
-
}
|
|
18
|
-
function makeDescriptor({ currency, index, derivationMode, fingerprint, xpub, }) {
|
|
19
|
-
const tmpl = perDerivation[derivationMode];
|
|
20
|
-
if (!tmpl || !xpub)
|
|
21
|
-
return;
|
|
22
|
-
const keyOrigin = fingerprint.toString("hex");
|
|
23
|
-
const scheme = getDerivationScheme({
|
|
24
|
-
currency,
|
|
25
|
-
derivationMode,
|
|
26
|
-
});
|
|
27
|
-
const accountPath = runAccountDerivationScheme(scheme, currency, {
|
|
28
|
-
account: index,
|
|
29
|
-
});
|
|
30
|
-
return {
|
|
31
|
-
external: tmpl(`[${keyOrigin}/${accountPath}]${xpub}/0/*`),
|
|
32
|
-
internal: tmpl(`[${keyOrigin}/${accountPath}]${xpub}/1/*`),
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
export function inferDescriptorFromAccount(account) {
|
|
36
|
-
if (account.currency.family !== "bitcoin")
|
|
37
|
-
return;
|
|
38
|
-
const { id, derivationMode, seedIdentifier, currency, index } = account;
|
|
39
|
-
const xpub = decodeAccountId(id).xpubOrAddress;
|
|
40
|
-
const fingerprint = makeFingerprint(compressPublicKeySECP256(Buffer.from(seedIdentifier, "hex")));
|
|
41
|
-
return makeDescriptor({
|
|
42
|
-
derivationMode,
|
|
43
|
-
currency,
|
|
44
|
-
fingerprint,
|
|
45
|
-
xpub,
|
|
46
|
-
index,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
function asBufferUInt32BE(n) {
|
|
50
|
-
const buf = Buffer.allocUnsafe(4);
|
|
51
|
-
buf.writeUInt32BE(n, 0);
|
|
52
|
-
return buf;
|
|
53
|
-
}
|
|
54
|
-
const compressPublicKeySECP256 = (publicKey) => Buffer.concat([Buffer.from([0x02 + (publicKey[64] & 0x01)]), publicKey.slice(1, 33)]);
|
|
55
|
-
function makeXpub({ version, depth, parentFingerprint, index, chainCode, pubKey, }) {
|
|
56
|
-
const indexBuffer = asBufferUInt32BE(index);
|
|
57
|
-
indexBuffer[0] |= 0x80;
|
|
58
|
-
const extendedKeyBytes = Buffer.concat([
|
|
59
|
-
asBufferUInt32BE(version),
|
|
60
|
-
Buffer.from([depth]),
|
|
61
|
-
parentFingerprint,
|
|
62
|
-
indexBuffer,
|
|
63
|
-
chainCode,
|
|
64
|
-
pubKey,
|
|
65
|
-
]);
|
|
66
|
-
const checksum = hash256(extendedKeyBytes).slice(0, 4);
|
|
67
|
-
return bs58.encode(Buffer.concat([extendedKeyBytes, checksum]));
|
|
68
|
-
}
|
|
69
|
-
export function inferDescriptorFromDeviceInfo({ derivationMode, currency, index, parentDerivation, accountDerivation, }) {
|
|
70
|
-
invariant(currency.bitcoinLikeInfo, "bitcoin currency expected");
|
|
71
|
-
const { bitcoinLikeInfo } = currency;
|
|
72
|
-
const { XPUBVersion } = bitcoinLikeInfo;
|
|
73
|
-
invariant(XPUBVersion, "unsupported bitcoin fork %s", currency.id);
|
|
74
|
-
const { chainCode } = accountDerivation;
|
|
75
|
-
invariant(chainCode, "chainCode is required");
|
|
76
|
-
const fingerprint = makeFingerprint(compressPublicKeySECP256(Buffer.from(parentDerivation.publicKey, "hex")));
|
|
77
|
-
const xpub = makeXpub({
|
|
78
|
-
version: XPUBVersion,
|
|
79
|
-
depth: 3,
|
|
80
|
-
parentFingerprint: fingerprint,
|
|
81
|
-
index,
|
|
82
|
-
chainCode: Buffer.from(chainCode, "hex"),
|
|
83
|
-
pubKey: compressPublicKeySECP256(Buffer.from(accountDerivation.publicKey, "hex")),
|
|
84
|
-
});
|
|
85
|
-
return makeDescriptor({
|
|
86
|
-
derivationMode,
|
|
87
|
-
currency,
|
|
88
|
-
fingerprint,
|
|
89
|
-
xpub,
|
|
90
|
-
index,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
export function scanDescriptors(deviceId, currency, signerContext, limit = 10) {
|
|
94
|
-
const derivateAddress = (opts) => from(getAddress(signerContext)(deviceId, opts));
|
|
95
|
-
function stepAddress({ index, accountDerivation, parentDerivation, derivationMode, }) {
|
|
96
|
-
const result = inferDescriptorFromDeviceInfo({
|
|
97
|
-
derivationMode,
|
|
98
|
-
currency,
|
|
99
|
-
index,
|
|
100
|
-
parentDerivation,
|
|
101
|
-
accountDerivation,
|
|
102
|
-
});
|
|
103
|
-
return !result
|
|
104
|
-
? EMPTY
|
|
105
|
-
: of({
|
|
106
|
-
result,
|
|
107
|
-
complete: index >= limit,
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
return from(getDerivationModesForCurrency(currency)).pipe(concatMap(derivationMode => walletDerivation({
|
|
111
|
-
currency,
|
|
112
|
-
derivationMode,
|
|
113
|
-
derivateAddress,
|
|
114
|
-
stepAddress,
|
|
115
|
-
shouldDerivesOnAccount: true,
|
|
116
|
-
})));
|
|
117
|
-
}
|
|
118
|
-
//# sourceMappingURL=descriptor.js.map
|
package/lib-es/descriptor.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"descriptor.js","sourceRoot":"","sources":["../src/descriptor.ts"],"names":[],"mappings":"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"}
|
package/src/descriptor.test.ts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import invariant from "invariant";
|
|
2
|
-
import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/index";
|
|
3
|
-
import { setSupportedCurrencies } from "@ledgerhq/coin-framework/currencies/index";
|
|
4
|
-
import { fromAccountRaw } from "@ledgerhq/coin-framework/serialization/index";
|
|
5
|
-
import { inferDescriptorFromDeviceInfo, inferDescriptorFromAccount } from "./descriptor";
|
|
6
|
-
import bitcoinDatasets from "./datasets/bitcoin";
|
|
7
|
-
import { assignFromAccountRaw } from "./serialization";
|
|
8
|
-
import type { CryptoAssetsStore } from "@ledgerhq/types-live";
|
|
9
|
-
import { setCryptoAssetsStore } from "@ledgerhq/cryptoassets/state";
|
|
10
|
-
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
12
|
-
setCryptoAssetsStore({
|
|
13
|
-
findTokenById: () => Promise.resolve(undefined),
|
|
14
|
-
findTokenByAddressInCurrency: () => Promise.resolve(undefined),
|
|
15
|
-
getTokensSyncHash: () => Promise.resolve("0"),
|
|
16
|
-
} as CryptoAssetsStore);
|
|
17
|
-
|
|
18
|
-
setSupportedCurrencies(["bitcoin"]);
|
|
19
|
-
describe("inferDescriptorFromAccount", () => {
|
|
20
|
-
invariant(bitcoinDatasets.accounts, "bitcoin datasets have accounts");
|
|
21
|
-
|
|
22
|
-
let bitcoin1: any, bitcoin2: any;
|
|
23
|
-
|
|
24
|
-
beforeAll(async () => {
|
|
25
|
-
invariant(bitcoinDatasets.accounts, "bitcoin datasets have accounts in beforeAll");
|
|
26
|
-
[bitcoin1, bitcoin2] = await Promise.all(
|
|
27
|
-
bitcoinDatasets.accounts.map(a => fromAccountRaw(a.raw, { assignFromAccountRaw })),
|
|
28
|
-
);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("should work on bitcoin account 1", () => {
|
|
32
|
-
expect(inferDescriptorFromAccount(bitcoin1)).toEqual({
|
|
33
|
-
external:
|
|
34
|
-
"pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/0/*)",
|
|
35
|
-
internal:
|
|
36
|
-
"pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/1/*)",
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
it("should work on bitcoin account 2", () => {
|
|
40
|
-
expect(inferDescriptorFromAccount(bitcoin2)).toEqual({
|
|
41
|
-
external:
|
|
42
|
-
"wpkh([d6a9e45e/84'/0'/1']xpub6DEHKg8fgKcb9at2u9Xhjtx4tXGyWqUPQAx2zNCzr41gQRyCqpCn7onSoJU4VS96GXyCtAhhFxErnG2pGVvVexaqF7DEfqGGnGk7Havn7C2/0/*)",
|
|
43
|
-
internal:
|
|
44
|
-
"wpkh([d6a9e45e/84'/0'/1']xpub6DEHKg8fgKcb9at2u9Xhjtx4tXGyWqUPQAx2zNCzr41gQRyCqpCn7onSoJU4VS96GXyCtAhhFxErnG2pGVvVexaqF7DEfqGGnGk7Havn7C2/1/*)",
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
describe("inferDescriptorFromDeviceInfo", () => {
|
|
49
|
-
it("should work on a first Bitcoin legacy derivation", () => {
|
|
50
|
-
const descriptor = inferDescriptorFromDeviceInfo({
|
|
51
|
-
derivationMode: "",
|
|
52
|
-
currency: getCryptoCurrencyById("bitcoin"),
|
|
53
|
-
index: 0,
|
|
54
|
-
parentDerivation: {
|
|
55
|
-
address: "148LHFgQkoPKHUFeVzFNmUjKT7ZwB47fTR",
|
|
56
|
-
path: "44'/0'",
|
|
57
|
-
publicKey:
|
|
58
|
-
"041caa3a42db5bdd125b2530c47cfbe829539b5a20a5562ec839d241c67d1862f2980d26ebffee25e4f924410c3316b397f34bd572543e72c59a7569ef9032f498",
|
|
59
|
-
chainCode: "9f819c7d45eb9eb1e9bd5fa695158cca9e493182f95068b22c8c440ae6eb0720",
|
|
60
|
-
},
|
|
61
|
-
accountDerivation: {
|
|
62
|
-
address: "15o6uBtRzKojbxqBe4Kni66BSvXfKYT2GY",
|
|
63
|
-
path: "44'/0'/0'",
|
|
64
|
-
publicKey:
|
|
65
|
-
"04238878d371ce61cdd04d22ccab50c542e94ffa7a27d02d6bcefaa22e4fcee6db4c2029fd4de0b595e98002c0be01fc1fbd3568671e394c97a6d52c3d4c113fb5",
|
|
66
|
-
chainCode: "44728146118df8d18d38c2615154eaffcdd53829957f4e26863344f35653364e",
|
|
67
|
-
},
|
|
68
|
-
});
|
|
69
|
-
expect(descriptor).toEqual({
|
|
70
|
-
external:
|
|
71
|
-
"pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/0/*)",
|
|
72
|
-
internal:
|
|
73
|
-
"pkh([224b6226/44'/0'/0']xpub6BuPWhjLqutPV8SF4RMrrn8c3t7uBZbz4CBbThpbg9GYjqRMncra9mjgSfWSK7uMDz37hhzJ8wvkbDDQQJt6VgwLoszvmPiSBtLA1bPLLSn/1/*)",
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
});
|
package/src/descriptor.ts
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
import { Observable, from, of, EMPTY } from "rxjs";
|
|
2
|
-
import { concatMap } from "rxjs/operators";
|
|
3
|
-
import invariant from "invariant";
|
|
4
|
-
import bs58 from "bs58";
|
|
5
|
-
import type {
|
|
6
|
-
GetAddressOptions,
|
|
7
|
-
StepAddressInput,
|
|
8
|
-
Result,
|
|
9
|
-
} from "@ledgerhq/coin-framework/derivation";
|
|
10
|
-
import { hash256, hash160 } from "./crypto-util";
|
|
11
|
-
import {
|
|
12
|
-
walletDerivation,
|
|
13
|
-
getDerivationModesForCurrency,
|
|
14
|
-
runAccountDerivationScheme,
|
|
15
|
-
getDerivationScheme,
|
|
16
|
-
} from "@ledgerhq/coin-framework/derivation";
|
|
17
|
-
import getAddress from "./hw-getAddress";
|
|
18
|
-
import type { Account, DerivationMode } from "@ledgerhq/types-live";
|
|
19
|
-
import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
|
|
20
|
-
import { decodeAccountId } from "@ledgerhq/coin-framework/account/index";
|
|
21
|
-
import { SignerContext } from "./signer";
|
|
22
|
-
|
|
23
|
-
export type AccountDescriptor = {
|
|
24
|
-
internal: string;
|
|
25
|
-
external: string;
|
|
26
|
-
};
|
|
27
|
-
const perDerivation: Partial<
|
|
28
|
-
Record<DerivationMode, ((arg0: string) => string) | null | undefined>
|
|
29
|
-
> = {
|
|
30
|
-
"": fragment => `pkh(${fragment})`,
|
|
31
|
-
segwit: fragment => `sh(wpkh(${fragment}))`,
|
|
32
|
-
native_segwit: fragment => `wpkh(${fragment})`,
|
|
33
|
-
taproot: fragment => `tr(${fragment})`,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
function makeFingerprint(compressedPubKey: Buffer) {
|
|
37
|
-
return hash160(compressedPubKey).slice(0, 4);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function makeDescriptor({
|
|
41
|
-
currency,
|
|
42
|
-
index,
|
|
43
|
-
derivationMode,
|
|
44
|
-
fingerprint,
|
|
45
|
-
xpub,
|
|
46
|
-
}: {
|
|
47
|
-
currency: CryptoCurrency;
|
|
48
|
-
index: number;
|
|
49
|
-
derivationMode: DerivationMode;
|
|
50
|
-
fingerprint: Buffer;
|
|
51
|
-
xpub: string;
|
|
52
|
-
}) {
|
|
53
|
-
const tmpl = perDerivation[derivationMode];
|
|
54
|
-
if (!tmpl || !xpub) return;
|
|
55
|
-
const keyOrigin = fingerprint.toString("hex");
|
|
56
|
-
const scheme = getDerivationScheme({
|
|
57
|
-
currency,
|
|
58
|
-
derivationMode,
|
|
59
|
-
});
|
|
60
|
-
const accountPath = runAccountDerivationScheme(scheme, currency, {
|
|
61
|
-
account: index,
|
|
62
|
-
});
|
|
63
|
-
return {
|
|
64
|
-
external: tmpl(`[${keyOrigin}/${accountPath}]${xpub}/0/*`),
|
|
65
|
-
internal: tmpl(`[${keyOrigin}/${accountPath}]${xpub}/1/*`),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function inferDescriptorFromAccount(account: Account): AccountDescriptor | null | undefined {
|
|
70
|
-
if (account.currency.family !== "bitcoin") return;
|
|
71
|
-
const { id, derivationMode, seedIdentifier, currency, index } = account;
|
|
72
|
-
const xpub = decodeAccountId(id).xpubOrAddress;
|
|
73
|
-
const fingerprint = makeFingerprint(compressPublicKeySECP256(Buffer.from(seedIdentifier, "hex")));
|
|
74
|
-
return makeDescriptor({
|
|
75
|
-
derivationMode,
|
|
76
|
-
currency,
|
|
77
|
-
fingerprint,
|
|
78
|
-
xpub,
|
|
79
|
-
index,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function asBufferUInt32BE(n: number) {
|
|
84
|
-
const buf = Buffer.allocUnsafe(4);
|
|
85
|
-
buf.writeUInt32BE(n, 0);
|
|
86
|
-
return buf;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const compressPublicKeySECP256 = (publicKey: Buffer) =>
|
|
90
|
-
Buffer.concat([Buffer.from([0x02 + (publicKey[64] & 0x01)]), publicKey.slice(1, 33)]);
|
|
91
|
-
|
|
92
|
-
function makeXpub({
|
|
93
|
-
version,
|
|
94
|
-
depth,
|
|
95
|
-
parentFingerprint,
|
|
96
|
-
index,
|
|
97
|
-
chainCode,
|
|
98
|
-
pubKey,
|
|
99
|
-
}: {
|
|
100
|
-
version: number;
|
|
101
|
-
depth: number;
|
|
102
|
-
parentFingerprint: Buffer;
|
|
103
|
-
index: number;
|
|
104
|
-
chainCode: Buffer;
|
|
105
|
-
pubKey: Buffer;
|
|
106
|
-
}) {
|
|
107
|
-
const indexBuffer = asBufferUInt32BE(index);
|
|
108
|
-
indexBuffer[0] |= 0x80;
|
|
109
|
-
const extendedKeyBytes = Buffer.concat([
|
|
110
|
-
asBufferUInt32BE(version),
|
|
111
|
-
Buffer.from([depth]),
|
|
112
|
-
parentFingerprint,
|
|
113
|
-
indexBuffer,
|
|
114
|
-
chainCode,
|
|
115
|
-
pubKey,
|
|
116
|
-
]);
|
|
117
|
-
const checksum = hash256(extendedKeyBytes).slice(0, 4);
|
|
118
|
-
return bs58.encode(Buffer.concat([extendedKeyBytes, checksum]));
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function inferDescriptorFromDeviceInfo({
|
|
122
|
-
derivationMode,
|
|
123
|
-
currency,
|
|
124
|
-
index,
|
|
125
|
-
parentDerivation,
|
|
126
|
-
accountDerivation,
|
|
127
|
-
}: {
|
|
128
|
-
derivationMode: DerivationMode;
|
|
129
|
-
currency: CryptoCurrency;
|
|
130
|
-
index: number;
|
|
131
|
-
parentDerivation: Result;
|
|
132
|
-
accountDerivation: Result;
|
|
133
|
-
}): AccountDescriptor | null | undefined {
|
|
134
|
-
invariant(currency.bitcoinLikeInfo, "bitcoin currency expected");
|
|
135
|
-
const { bitcoinLikeInfo } = currency;
|
|
136
|
-
const { XPUBVersion } = bitcoinLikeInfo as {
|
|
137
|
-
P2PKH: number;
|
|
138
|
-
P2SH: number;
|
|
139
|
-
XPUBVersion?: number;
|
|
140
|
-
};
|
|
141
|
-
invariant(XPUBVersion, "unsupported bitcoin fork %s", currency.id);
|
|
142
|
-
const { chainCode } = accountDerivation;
|
|
143
|
-
invariant(chainCode, "chainCode is required");
|
|
144
|
-
const fingerprint = makeFingerprint(
|
|
145
|
-
compressPublicKeySECP256(Buffer.from(parentDerivation.publicKey, "hex")),
|
|
146
|
-
);
|
|
147
|
-
const xpub = makeXpub({
|
|
148
|
-
version: XPUBVersion,
|
|
149
|
-
depth: 3,
|
|
150
|
-
parentFingerprint: fingerprint,
|
|
151
|
-
index,
|
|
152
|
-
chainCode: Buffer.from(chainCode as string, "hex"),
|
|
153
|
-
pubKey: compressPublicKeySECP256(Buffer.from(accountDerivation.publicKey, "hex")),
|
|
154
|
-
});
|
|
155
|
-
return makeDescriptor({
|
|
156
|
-
derivationMode,
|
|
157
|
-
currency,
|
|
158
|
-
fingerprint,
|
|
159
|
-
xpub,
|
|
160
|
-
index,
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
export function scanDescriptors(
|
|
164
|
-
deviceId: string,
|
|
165
|
-
currency: CryptoCurrency,
|
|
166
|
-
signerContext: SignerContext,
|
|
167
|
-
limit = 10,
|
|
168
|
-
): Observable<AccountDescriptor> {
|
|
169
|
-
const derivateAddress = (opts: GetAddressOptions) =>
|
|
170
|
-
from(getAddress(signerContext)(deviceId, opts));
|
|
171
|
-
|
|
172
|
-
function stepAddress({
|
|
173
|
-
index,
|
|
174
|
-
accountDerivation,
|
|
175
|
-
parentDerivation,
|
|
176
|
-
derivationMode,
|
|
177
|
-
}: StepAddressInput) {
|
|
178
|
-
const result = inferDescriptorFromDeviceInfo({
|
|
179
|
-
derivationMode,
|
|
180
|
-
currency,
|
|
181
|
-
index,
|
|
182
|
-
parentDerivation,
|
|
183
|
-
accountDerivation,
|
|
184
|
-
});
|
|
185
|
-
return !result
|
|
186
|
-
? EMPTY
|
|
187
|
-
: of({
|
|
188
|
-
result,
|
|
189
|
-
complete: index >= limit,
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return from(getDerivationModesForCurrency(currency)).pipe(
|
|
194
|
-
concatMap(derivationMode =>
|
|
195
|
-
walletDerivation({
|
|
196
|
-
currency,
|
|
197
|
-
derivationMode,
|
|
198
|
-
derivateAddress,
|
|
199
|
-
stepAddress,
|
|
200
|
-
shouldDerivesOnAccount: true,
|
|
201
|
-
}),
|
|
202
|
-
),
|
|
203
|
-
);
|
|
204
|
-
}
|