@ledgerhq/coin-bitcoin 0.29.0-nightly.20260115024415 → 0.29.0-nightly.20260116124336
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/CHANGELOG.md +12 -10
- package/lib/bridge/js.d.ts +1 -1
- package/lib/bridge/js.d.ts.map +1 -1
- package/lib/bridge/js.js +2 -3
- package/lib/bridge/js.js.map +1 -1
- package/lib/buildOptimisticOperation.d.ts +13 -0
- package/lib/buildOptimisticOperation.d.ts.map +1 -0
- package/lib/buildOptimisticOperation.js +20 -0
- package/lib/buildOptimisticOperation.js.map +1 -0
- package/lib/explorer.d.ts.map +1 -1
- package/lib/explorer.js +0 -7
- package/lib/explorer.js.map +1 -1
- package/lib/observable.d.ts +4 -0
- package/lib/observable.d.ts.map +1 -0
- package/lib/observable.js +9 -0
- package/lib/observable.js.map +1 -0
- package/lib/psbtFees.d.ts +9 -0
- package/lib/psbtFees.d.ts.map +1 -0
- package/lib/psbtFees.js +73 -0
- package/lib/psbtFees.js.map +1 -0
- package/lib/signOperation.d.ts.map +1 -1
- package/lib/signOperation.js +94 -99
- package/lib/signOperation.js.map +1 -1
- package/lib/signRawOperation.d.ts +6 -0
- package/lib/signRawOperation.d.ts.map +1 -0
- package/lib/signRawOperation.js +70 -0
- package/lib/signRawOperation.js.map +1 -0
- package/lib/signer.d.ts +15 -0
- package/lib/signer.d.ts.map +1 -1
- package/lib/types.d.ts +2 -0
- package/lib/types.d.ts.map +1 -1
- package/lib-es/bridge/js.d.ts +1 -1
- package/lib-es/bridge/js.d.ts.map +1 -1
- package/lib-es/bridge/js.js +2 -3
- package/lib-es/bridge/js.js.map +1 -1
- package/lib-es/buildOptimisticOperation.d.ts +13 -0
- package/lib-es/buildOptimisticOperation.d.ts.map +1 -0
- package/lib-es/buildOptimisticOperation.js +16 -0
- package/lib-es/buildOptimisticOperation.js.map +1 -0
- 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/lib-es/observable.d.ts +4 -0
- package/lib-es/observable.d.ts.map +1 -0
- package/lib-es/observable.js +5 -0
- package/lib-es/observable.js.map +1 -0
- package/lib-es/psbtFees.d.ts +9 -0
- package/lib-es/psbtFees.d.ts.map +1 -0
- package/lib-es/psbtFees.js +69 -0
- package/lib-es/psbtFees.js.map +1 -0
- package/lib-es/signOperation.d.ts.map +1 -1
- package/lib-es/signOperation.js +94 -99
- package/lib-es/signOperation.js.map +1 -1
- package/lib-es/signRawOperation.d.ts +6 -0
- package/lib-es/signRawOperation.d.ts.map +1 -0
- package/lib-es/signRawOperation.js +66 -0
- package/lib-es/signRawOperation.js.map +1 -0
- package/lib-es/signer.d.ts +15 -0
- package/lib-es/signer.d.ts.map +1 -1
- package/lib-es/types.d.ts +2 -0
- package/lib-es/types.d.ts.map +1 -1
- package/package.json +13 -12
- package/src/__tests__/fixtures/common.fixtures.ts +6 -0
- package/src/__tests__/unit/psbtFees.fromFixture.unit.test.ts +31 -0
- package/src/__tests__/unit/signOperation.test.ts +226 -0
- package/src/__tests__/unit/signRawOperation.test.ts +188 -0
- package/src/bridge/js.test.ts +30 -0
- package/src/bridge/js.ts +2 -3
- package/src/buildOptimisticOperation.ts +34 -0
- package/src/explorer.ts +0 -8
- package/src/hw-signMessage.test.ts +1 -0
- package/src/observable.ts +12 -0
- package/src/observable.unit.test.ts +27 -0
- package/src/psbtFees.ts +77 -0
- package/src/signOperation.ts +140 -126
- package/src/signRawOperation.ts +104 -0
- package/src/signer.ts +13 -0
- package/src/types.ts +2 -0
- package/src/wallet-btc/__tests__/fixtures/common.fixtures.ts +64 -1
- package/src/wallet-btc/__tests__/wallet.integration.test.ts +1 -1
- package/src/wallet-btc/__tests__/xpub.txs.dogecoin.integration.test.ts +1 -1
- package/src/wallet-btc/__tests__/xpub.txs.zcash.integration.test.ts +1 -1
- package/tsconfig.json +3 -12
- 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/mockBtcSigner.d.ts +0 -20
- package/lib/mockBtcSigner.d.ts.map +0 -1
- package/lib/mockBtcSigner.js +0 -50
- package/lib/mockBtcSigner.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/lib-es/mockBtcSigner.d.ts +0 -20
- package/lib-es/mockBtcSigner.d.ts.map +0 -1
- package/lib-es/mockBtcSigner.js +0 -45
- package/lib-es/mockBtcSigner.js.map +0 -1
- package/src/descriptor.test.ts +0 -76
- package/src/descriptor.ts +0 -204
- package/src/mockBtcSigner.ts +0 -65
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signRawOperation.js","sourceRoot":"","sources":["../src/signRawOperation.ts"],"names":[],"mappings":"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"}
|
package/lib-es/signer.d.ts
CHANGED
|
@@ -23,6 +23,21 @@ export interface BitcoinSigner {
|
|
|
23
23
|
signMessage(path: string, messageHex: string): Promise<BitcoinSignature>;
|
|
24
24
|
splitTransaction(transactionHex: string, isSegwitSupported: boolean | null | undefined, hasExtraData: boolean | null | undefined, additionals: Array<string> | null | undefined): SignerTransaction;
|
|
25
25
|
createPaymentTransaction(arg: CreateTransaction): Promise<string>;
|
|
26
|
+
signPsbtBuffer?(psbtBuffer: Buffer, options?: {
|
|
27
|
+
finalizePsbt?: boolean;
|
|
28
|
+
accountPath?: string;
|
|
29
|
+
addressFormat?: AddressFormat;
|
|
30
|
+
onDeviceSignatureRequested: (() => void) | undefined;
|
|
31
|
+
onDeviceSignatureGranted: (() => void) | undefined;
|
|
32
|
+
onDeviceStreaming: ((arg: {
|
|
33
|
+
progress: number;
|
|
34
|
+
total: number;
|
|
35
|
+
index: number;
|
|
36
|
+
}) => void) | undefined;
|
|
37
|
+
}): Promise<{
|
|
38
|
+
psbt: Buffer;
|
|
39
|
+
tx: string;
|
|
40
|
+
}>;
|
|
26
41
|
}
|
|
27
42
|
export type SignerResult = BitcoinXPub | BitcoinAddress | BitcoinSignature;
|
|
28
43
|
export type SignerContext = <T>(deviceId: string, crypto: CryptoCurrency, fn: (signer: BitcoinSigner) => Promise<T>) => Promise<T>;
|
package/lib-es/signer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AACjC,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AACF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AACF,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;AAElF,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChF,kBAAkB,CAChB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QACL,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,aAAa,CAAC;KACxB,GACA,OAAO,CAAC,cAAc,CAAC,CAAC;IAC3B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEzE,gBAAgB,CACd,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,EAC7C,YAAY,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,EACxC,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,GAC5C,iBAAiB,CAAC;IACrB,wBAAwB,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"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"}
|
package/lib-es/types.d.ts
CHANGED
|
@@ -113,6 +113,8 @@ export type Transaction = TransactionCommon & {
|
|
|
113
113
|
networkInfo: NetworkInfo | null | undefined;
|
|
114
114
|
opReturnData?: Buffer | undefined;
|
|
115
115
|
changeAddress?: string | undefined;
|
|
116
|
+
psbt?: string;
|
|
117
|
+
finalizePsbt?: boolean;
|
|
116
118
|
};
|
|
117
119
|
export type TransactionRaw = TransactionCommonRaw & {
|
|
118
120
|
family: "bitcoin";
|
package/lib-es/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/coin-bitcoin",
|
|
3
|
-
"version": "0.29.0-nightly.
|
|
3
|
+
"version": "0.29.0-nightly.20260116124336",
|
|
4
4
|
"description": "Ledger Bitcoin Coin integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger",
|
|
@@ -61,15 +61,16 @@
|
|
|
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.13.0-nightly.
|
|
65
|
-
"@ledgerhq/cryptoassets": "^13.37.0-nightly.
|
|
66
|
-
"@ledgerhq/devices": "8.10.0-nightly.
|
|
67
|
-
"@ledgerhq/errors": "^6.29.0-nightly.
|
|
68
|
-
"@ledgerhq/
|
|
69
|
-
"@ledgerhq/live-
|
|
70
|
-
"@ledgerhq/
|
|
71
|
-
"@ledgerhq/
|
|
72
|
-
"@ledgerhq/types-
|
|
64
|
+
"@ledgerhq/coin-framework": "^6.13.0-nightly.20260116124336",
|
|
65
|
+
"@ledgerhq/cryptoassets": "^13.37.0-nightly.20260116124336",
|
|
66
|
+
"@ledgerhq/devices": "8.10.0-nightly.20260116124336",
|
|
67
|
+
"@ledgerhq/errors": "^6.29.0-nightly.20260116124336",
|
|
68
|
+
"@ledgerhq/psbtv2": "^0.1.0",
|
|
69
|
+
"@ledgerhq/live-env": "^2.25.0-nightly.20260116124336",
|
|
70
|
+
"@ledgerhq/live-network": "^2.2.0-nightly.20260116124336",
|
|
71
|
+
"@ledgerhq/logs": "^6.14.0-nightly.20260116124336",
|
|
72
|
+
"@ledgerhq/types-cryptoassets": "^7.32.0-nightly.20260116124336",
|
|
73
|
+
"@ledgerhq/types-live": "^6.93.0-nightly.20260116124336"
|
|
73
74
|
},
|
|
74
75
|
"devDependencies": {
|
|
75
76
|
"@types/bchaddrjs": "^0.4.3",
|
|
@@ -92,12 +93,13 @@
|
|
|
92
93
|
"object-hash": "^2.2.0",
|
|
93
94
|
"@swc/jest": "0.2.39",
|
|
94
95
|
"@swc/core": "1.15.8",
|
|
95
|
-
"@ledgerhq/disable-network-setup": "^0.2.0-nightly.
|
|
96
|
+
"@ledgerhq/disable-network-setup": "^0.2.0-nightly.20260116124336"
|
|
96
97
|
},
|
|
97
98
|
"scripts": {
|
|
98
99
|
"clean": "rimraf lib lib-es",
|
|
99
100
|
"build": "tsc && tsc -m esnext --moduleResolution bundler --outDir lib-es",
|
|
100
101
|
"coverage": "jest --coverage",
|
|
102
|
+
"test-integ": "jest --config=jest.integ.config.js",
|
|
101
103
|
"prewatch": "pnpm build",
|
|
102
104
|
"watch": "tsc --watch",
|
|
103
105
|
"watch:es": "tsc --watch -m esnext --moduleResolution bundler --outDir lib-es",
|
|
@@ -106,7 +108,6 @@
|
|
|
106
108
|
"lint:fix": "pnpm lint --fix",
|
|
107
109
|
"test": "jest",
|
|
108
110
|
"test:debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand",
|
|
109
|
-
"test-integ": "jest --config=jest.integ.config.js",
|
|
110
111
|
"typecheck": "tsc --noEmit",
|
|
111
112
|
"unimported": "unimported"
|
|
112
113
|
}
|
|
@@ -127,6 +127,9 @@ export const mockSigner: BitcoinSigner = {
|
|
|
127
127
|
}),
|
|
128
128
|
createPaymentTransaction: (_arg: CreateTransaction): Promise<string> =>
|
|
129
129
|
Promise.resolve("createPaymentTransactionReturn"),
|
|
130
|
+
signPsbtBuffer(_psbtBuffer: Buffer): Promise<{ psbt: Buffer; tx: string }> {
|
|
131
|
+
return Promise.resolve({ psbt: Buffer.from(""), tx: "" });
|
|
132
|
+
},
|
|
130
133
|
};
|
|
131
134
|
|
|
132
135
|
export const mockSignerContext = <T>(
|
|
@@ -172,4 +175,7 @@ export const mockSignerContext = <T>(
|
|
|
172
175
|
],
|
|
173
176
|
}),
|
|
174
177
|
createPaymentTransaction: (_arg: CreateTransaction): Promise<string> => Promise.resolve(""),
|
|
178
|
+
signPsbtBuffer(_psbtBuffer: Buffer): Promise<{ psbt: Buffer; tx: string }> {
|
|
179
|
+
return Promise.resolve({ psbt: Buffer.from(""), tx: "" });
|
|
180
|
+
},
|
|
175
181
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { feeFromPsbt } from "../../psbtFees";
|
|
2
|
+
import { parsePsbt } from "@ledgerhq/psbtv2";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* NOTE: in all psbts below, the fee is 5000 since:
|
|
6
|
+
* The input has a WITNESS_UTXO amount: first 8 bytes of data = 20 4e 00 00 00 00 00 00 (little-endian) → 0x0000000000004e20 = 20,000 sats.
|
|
7
|
+
* The output AMOUNT is 98 3a 00 00 00 00 00 00 (little-endian) → 0x0000000000003a98 = 15,000 sats.
|
|
8
|
+
* Fee = Σinputs − Σoutputs = 20,000 − 15,000 = 5,000 sats.
|
|
9
|
+
* all the psbts where generated from https://learnmeabitcoin.com/technical/transaction/psbt/
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
describe("feeFromPsbt (PSBT v2 via PsbtV2)", () => {
|
|
14
|
+
it("parses the v2 PSBT (signer stage) and returns the correct fee", () => {
|
|
15
|
+
// signer stage, decode it https://learnmeabitcoin.com/technical/transaction/psbt/
|
|
16
|
+
const psbtB64 =
|
|
17
|
+
"cHNidP8BAgQCAAAAAQMEAAAAAAEEAQEBBQEBAQYBAAH7BAIAAAAAAQEfIE4AAAAAAAAWABRtTfPDGS0+/pTZAN6itD4d+v/DdyICAoHczplgGVV4+rXYBtC/VsKfZU8OhrrUST2++hq4Lzy9SDBFAiEAisjYLjV0afIPV8fNtfKDEep5qWE+Q4ykeLRVQFMVhJsCIE9Q+4CcW6Cwmnuox4kYpUocoFIWp8pa2OGcuf801ecvAQEOIBpm0EPKluAy05yTYGzOS3gm/qhPQLDCSWqQpVE2pyVMAQ8EAQAAAAABAwiYOgAAAAAAAAEEFgAUgOCAoBDcwBoMygQ0Q5VYjll5FTgA";
|
|
18
|
+
|
|
19
|
+
const fee = feeFromPsbt(parsePsbt(psbtB64));
|
|
20
|
+
expect(fee!.toNumber()).toBe(5000);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("parses the v2 PSBT (input finalizer stage) and returns the correct fee", () => {
|
|
24
|
+
// input finalizer stage, decode it https://learnmeabitcoin.com/technical/transaction/psbt/
|
|
25
|
+
const psbtB64 =
|
|
26
|
+
"cHNidP8BAgQCAAAAAQMEAAAAAAEEAQEBBQEBAQYBAAH7BAIAAAAAAQEfIE4AAAAAAAAWABRtTfPDGS0+/pTZAN6itD4d+v/DdwEIbAJIMEUCIQCKyNguNXRp8g9Xx8218oMR6nmpYT5DjKR4tFVAUxWEmwIgT1D7gJxboLCae6jHiRilShygUhanylrY4Zy5/zTV5y8BIQKB3M6ZYBlVePq12AbQv1bCn2VPDoa61Ek9vvoauC88vQEOIBpm0EPKluAy05yTYGzOS3gm/qhPQLDCSWqQpVE2pyVMAQ8EAQAAAAABAwiYOgAAAAAAAAEEFgAUgOCAoBDcwBoMygQ0Q5VYjll5FTgA";
|
|
27
|
+
|
|
28
|
+
const fee = feeFromPsbt(parsePsbt(psbtB64));
|
|
29
|
+
expect(fee!.toNumber()).toBe(5000);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { BigNumber } from "bignumber.js";
|
|
2
|
+
import { firstValueFrom, toArray } from "rxjs";
|
|
3
|
+
import buildSignOperation from "../../signOperation";
|
|
4
|
+
import type { Account, Operation } from "@ledgerhq/types-live";
|
|
5
|
+
import { findCryptoCurrencyById } from "@ledgerhq/cryptoassets";
|
|
6
|
+
import type { Transaction } from "../../types";
|
|
7
|
+
|
|
8
|
+
// ---- Mocks ---------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
jest.mock("../../cache", () => ({
|
|
11
|
+
calculateFees: jest.fn().mockResolvedValue({
|
|
12
|
+
fees: new BigNumber(1000), // 1000 sats
|
|
13
|
+
txInputs: [
|
|
14
|
+
{ address: "bc1qsender1..." },
|
|
15
|
+
{ address: "bc1qsender2..." },
|
|
16
|
+
{ address: "bc1qsender1..." }, // duplicate to test Set behavior
|
|
17
|
+
],
|
|
18
|
+
txOutputs: [
|
|
19
|
+
{ address: "bc1qrecipient...", isChange: false, value: new BigNumber(5000) },
|
|
20
|
+
{ address: "bc1qchange...", isChange: true, value: new BigNumber(15000) },
|
|
21
|
+
{ address: null, isChange: false, value: new BigNumber(0) },
|
|
22
|
+
],
|
|
23
|
+
}),
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
jest.mock("../../buildTransaction", () => ({
|
|
27
|
+
buildTransaction: jest.fn().mockResolvedValue({
|
|
28
|
+
// shape not relevant for test, passed through to wallet.signAccountTx
|
|
29
|
+
}),
|
|
30
|
+
}));
|
|
31
|
+
|
|
32
|
+
jest.mock("../../networks", () => ({
|
|
33
|
+
getNetworkParameters: jest.fn().mockReturnValue({ sigHash: 1 }),
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
// Wallet mock to capture parameters and simulate device callbacks
|
|
37
|
+
jest.mock("../../wallet-btc", () => ({
|
|
38
|
+
__esModule: true,
|
|
39
|
+
default: {
|
|
40
|
+
// will be inspected and controlled via jest.requireMock in tests
|
|
41
|
+
signAccountTx: jest.fn(),
|
|
42
|
+
},
|
|
43
|
+
getWalletAccount: jest.fn().mockReturnValue({
|
|
44
|
+
params: { path: "m/84'/0'/0'", index: 0 },
|
|
45
|
+
xpub: {},
|
|
46
|
+
}),
|
|
47
|
+
}));
|
|
48
|
+
|
|
49
|
+
// Keep derivation helpers deterministic
|
|
50
|
+
jest.mock("@ledgerhq/coin-framework/derivation", () => {
|
|
51
|
+
const actual = jest.requireActual("@ledgerhq/coin-framework/derivation");
|
|
52
|
+
return {
|
|
53
|
+
...actual,
|
|
54
|
+
isSegwitDerivationMode: () => true,
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// ---- Helpers -------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
const makeAccount = (over: Partial<Account> = {}): Account => ({
|
|
61
|
+
id: "js:2:bitcoin:dummy",
|
|
62
|
+
type: "Account",
|
|
63
|
+
used: true,
|
|
64
|
+
operationsCount: 0,
|
|
65
|
+
balanceHistoryCache: {
|
|
66
|
+
HOUR: {
|
|
67
|
+
latestDate: null,
|
|
68
|
+
balances: [],
|
|
69
|
+
},
|
|
70
|
+
DAY: {
|
|
71
|
+
latestDate: null,
|
|
72
|
+
balances: [],
|
|
73
|
+
},
|
|
74
|
+
WEEK: {
|
|
75
|
+
latestDate: null,
|
|
76
|
+
balances: [],
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
swapHistory: [],
|
|
80
|
+
freshAddress: "bc1q...",
|
|
81
|
+
freshAddressPath: "m/84'/0'/0'/0/0",
|
|
82
|
+
currency: findCryptoCurrencyById("bitcoin")!,
|
|
83
|
+
derivationMode: "native_segwit",
|
|
84
|
+
seedIdentifier: "seed",
|
|
85
|
+
xpub: "xpub...",
|
|
86
|
+
index: 0,
|
|
87
|
+
balance: new BigNumber(0),
|
|
88
|
+
spendableBalance: new BigNumber(0),
|
|
89
|
+
blockHeight: 0,
|
|
90
|
+
operations: [],
|
|
91
|
+
pendingOperations: [],
|
|
92
|
+
lastSyncDate: new Date(0),
|
|
93
|
+
creationDate: new Date(0),
|
|
94
|
+
...over,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
import type { BitcoinSigner, SignerContext } from "../../signer";
|
|
98
|
+
|
|
99
|
+
type WalletBtcMock = {
|
|
100
|
+
default: {
|
|
101
|
+
// narrow to the shape we exercise in these tests
|
|
102
|
+
signAccountTx: jest.Mock<
|
|
103
|
+
Promise<string>,
|
|
104
|
+
[
|
|
105
|
+
{
|
|
106
|
+
onDeviceSignatureRequested?: () => void;
|
|
107
|
+
onDeviceSignatureGranted?: () => void;
|
|
108
|
+
onDeviceStreaming?: (arg: { progress: number; total: number; index: number }) => void;
|
|
109
|
+
},
|
|
110
|
+
]
|
|
111
|
+
>;
|
|
112
|
+
};
|
|
113
|
+
getWalletAccount: jest.Mock;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const walletBtcMock: WalletBtcMock = jest.requireMock("../../wallet-btc");
|
|
117
|
+
|
|
118
|
+
const signAccountTx = walletBtcMock.default.signAccountTx;
|
|
119
|
+
const getWalletAccount = walletBtcMock.getWalletAccount;
|
|
120
|
+
|
|
121
|
+
const dummySigner: BitcoinSigner = {
|
|
122
|
+
getWalletXpub: jest.fn(),
|
|
123
|
+
getWalletPublicKey: jest.fn(),
|
|
124
|
+
signMessage: jest.fn(),
|
|
125
|
+
splitTransaction: jest.fn(),
|
|
126
|
+
createPaymentTransaction: jest.fn(),
|
|
127
|
+
signPsbtBuffer: jest.fn(),
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// SignerContext: (deviceId, currency, fn) => Promise<ReturnType<fn>>
|
|
131
|
+
const makeSignerContext = (): SignerContext => (deviceId, currency, fn) => fn(dummySigner);
|
|
132
|
+
|
|
133
|
+
// -------------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
describe("signOperation (bitcoin)", () => {
|
|
136
|
+
beforeEach(() => {
|
|
137
|
+
jest.clearAllMocks();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
test("emits device events and builds optimistic operation from fee data", async () => {
|
|
141
|
+
const signerContext = makeSignerContext();
|
|
142
|
+
const signOperation = buildSignOperation(signerContext);
|
|
143
|
+
|
|
144
|
+
// Minimal transaction shape for this test
|
|
145
|
+
const transaction: Transaction = {
|
|
146
|
+
family: "bitcoin",
|
|
147
|
+
amount: new BigNumber(20000),
|
|
148
|
+
recipient: "bc1qrecipient...",
|
|
149
|
+
useAllAmount: false,
|
|
150
|
+
feePerByte: new BigNumber(1),
|
|
151
|
+
networkInfo: null,
|
|
152
|
+
utxoStrategy: { strategy: 0, excludeUTXOs: [] },
|
|
153
|
+
rbf: false,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// signAccountTx should simulate device callbacks and return a tx hex
|
|
157
|
+
signAccountTx.mockImplementation(
|
|
158
|
+
(params: {
|
|
159
|
+
onDeviceSignatureRequested?: () => void;
|
|
160
|
+
onDeviceSignatureGranted?: () => void;
|
|
161
|
+
onDeviceStreaming?: (arg: { progress: number; index: number; total: number }) => void;
|
|
162
|
+
}) => {
|
|
163
|
+
const { onDeviceSignatureRequested, onDeviceSignatureGranted, onDeviceStreaming } = params;
|
|
164
|
+
if (onDeviceSignatureRequested) {
|
|
165
|
+
onDeviceSignatureRequested();
|
|
166
|
+
}
|
|
167
|
+
if (onDeviceStreaming) {
|
|
168
|
+
onDeviceStreaming({ progress: 50, index: 0, total: 1 });
|
|
169
|
+
}
|
|
170
|
+
if (onDeviceSignatureGranted) {
|
|
171
|
+
onDeviceSignatureGranted();
|
|
172
|
+
}
|
|
173
|
+
return Promise.resolve("01020304");
|
|
174
|
+
},
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const account = makeAccount();
|
|
178
|
+
|
|
179
|
+
const events = await firstValueFrom(
|
|
180
|
+
signOperation({ account, deviceId: "mock", transaction }).pipe(toArray()),
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
// Events should include requested, streaming and granted
|
|
184
|
+
const types = events.map(e => e.type);
|
|
185
|
+
expect(types).toContain("device-signature-requested");
|
|
186
|
+
expect(types).toContain("device-signature-granted");
|
|
187
|
+
expect(types).toContain("device-streaming");
|
|
188
|
+
|
|
189
|
+
const streamingEvt = events.find(e => e.type === "device-streaming");
|
|
190
|
+
expect(streamingEvt).toMatchObject({
|
|
191
|
+
type: "device-streaming",
|
|
192
|
+
progress: 50,
|
|
193
|
+
index: 0,
|
|
194
|
+
total: 1,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const signedEvt = events.find(e => e.type === "signed");
|
|
198
|
+
if (!signedEvt || signedEvt.type !== "signed") {
|
|
199
|
+
throw new Error("No signed event");
|
|
200
|
+
}
|
|
201
|
+
const { signedOperation } = signedEvt;
|
|
202
|
+
|
|
203
|
+
// raw signature checks
|
|
204
|
+
expect(signedOperation.signature).toBe("01020304");
|
|
205
|
+
|
|
206
|
+
const op: Operation = signedOperation.operation;
|
|
207
|
+
// fee/value taken from calculateFees mock
|
|
208
|
+
expect(op.fee.toNumber()).toBe(1000);
|
|
209
|
+
expect(op.value.toNumber()).toBe(21000); // amount + fee
|
|
210
|
+
expect(op.senders).toEqual(["bc1qsender1...", "bc1qsender2..."]);
|
|
211
|
+
expect(op.recipients).toEqual(["bc1qrecipient..."]);
|
|
212
|
+
expect(op.accountId).toBe(account.id);
|
|
213
|
+
expect(op.type).toBe("OUT");
|
|
214
|
+
expect(op.date).toBeInstanceOf(Date);
|
|
215
|
+
|
|
216
|
+
// Wallet helpers and additionals wiring
|
|
217
|
+
expect(getWalletAccount).toHaveBeenCalledWith(account);
|
|
218
|
+
expect(signAccountTx).toHaveBeenCalledTimes(1);
|
|
219
|
+
const [params] = signAccountTx.mock.calls[0];
|
|
220
|
+
expect(params).toMatchObject({
|
|
221
|
+
sigHashType: 1,
|
|
222
|
+
segwit: true,
|
|
223
|
+
additionals: ["bitcoin", "bech32"], // For bitcoin + native_segwit we expect bech32 flag
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
});
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { BigNumber } from "bignumber.js";
|
|
2
|
+
import { firstValueFrom, skip, toArray } from "rxjs";
|
|
3
|
+
import buildSignRawOperation from "../../signRawOperation";
|
|
4
|
+
import type { Account, Operation } from "@ledgerhq/types-live";
|
|
5
|
+
import { findCryptoCurrencyById } from "@ledgerhq/cryptoassets";
|
|
6
|
+
|
|
7
|
+
// ---- Mocks ---------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
jest.mock("../../cache", () => ({
|
|
10
|
+
// Deterministic fallback fees (used if PSBT parsing fails)
|
|
11
|
+
calculateFees: jest.fn().mockResolvedValue({
|
|
12
|
+
fees: new BigNumber(1000), // 1000 sats
|
|
13
|
+
txInputs: [{ address: "bc1qsender..." }],
|
|
14
|
+
txOutputs: [{ address: "bc1qrecipient...", isChange: false, value: 5000 }],
|
|
15
|
+
}),
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
jest.mock("../../buildTransaction", () => ({
|
|
19
|
+
buildTransaction: jest.fn().mockResolvedValue({
|
|
20
|
+
/* not used by PSBT path */
|
|
21
|
+
}),
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
jest.mock("../../networks", () => ({
|
|
25
|
+
getNetworkParameters: jest.fn().mockReturnValue({ sigHash: 1 }),
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
jest.mock("../../wallet-btc", () => ({
|
|
29
|
+
getWalletAccount: jest.fn().mockReturnValue({
|
|
30
|
+
params: { path: "m/84'/0'/0'", index: 0 },
|
|
31
|
+
}),
|
|
32
|
+
default: {}, // default export not used in PSBT path
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
// Keep derivation helpers deterministic
|
|
36
|
+
jest.mock("@ledgerhq/coin-framework/derivation", () => {
|
|
37
|
+
const actual = jest.requireActual("@ledgerhq/coin-framework/derivation");
|
|
38
|
+
return {
|
|
39
|
+
...actual,
|
|
40
|
+
isSegwitDerivationMode: () => true,
|
|
41
|
+
getAddressFormatDerivationMode: jest.fn().mockReturnValue("p2wpkh"),
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// ---- Helpers -------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
const makeAccount = (over: Partial<Account> = {}): Account => ({
|
|
48
|
+
id: "js:2:bitcoin:dummy",
|
|
49
|
+
type: "Account",
|
|
50
|
+
used: true,
|
|
51
|
+
operationsCount: 0,
|
|
52
|
+
balanceHistoryCache: {
|
|
53
|
+
HOUR: {
|
|
54
|
+
latestDate: null,
|
|
55
|
+
balances: [],
|
|
56
|
+
},
|
|
57
|
+
DAY: {
|
|
58
|
+
latestDate: null,
|
|
59
|
+
balances: [],
|
|
60
|
+
},
|
|
61
|
+
WEEK: {
|
|
62
|
+
latestDate: null,
|
|
63
|
+
balances: [],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
swapHistory: [],
|
|
67
|
+
freshAddress: "bc1q...",
|
|
68
|
+
freshAddressPath: "m/84'/0'/0'/0/0",
|
|
69
|
+
currency: findCryptoCurrencyById("bitcoin")!,
|
|
70
|
+
derivationMode: "native_segwit",
|
|
71
|
+
seedIdentifier: "seed",
|
|
72
|
+
xpub: "xpub...",
|
|
73
|
+
index: 0,
|
|
74
|
+
balance: new BigNumber(0),
|
|
75
|
+
spendableBalance: new BigNumber(0),
|
|
76
|
+
blockHeight: 0,
|
|
77
|
+
operations: [],
|
|
78
|
+
pendingOperations: [],
|
|
79
|
+
lastSyncDate: new Date(0),
|
|
80
|
+
creationDate: new Date(0),
|
|
81
|
+
...over,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
type MockSigner = {
|
|
85
|
+
signPsbtBuffer: jest.Mock<any, any>;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const makeSignerContext =
|
|
89
|
+
(signer: MockSigner) =>
|
|
90
|
+
// SignerContext: (deviceId, currency, fn) => Promise<ReturnType<fn>>
|
|
91
|
+
async (_deviceId: string, _currency: any, fn: (s: any) => any) =>
|
|
92
|
+
fn(signer);
|
|
93
|
+
|
|
94
|
+
// A real PSBTv2 (base64) with: input 20_000 sats, output 15_000 sats => fee 5_000 sats
|
|
95
|
+
const PSBT_V2_B64 =
|
|
96
|
+
"cHNidP8BAgQCAAAAAQMEAAAAAAEEAQEBBQEBAQYBAAH7BAIAAAAAAQEfIE4AAAAAAAAWABRtTfPDGS0+/pTZAN6itD4d+v/DdwEIbAJIMEUCIQCKyNguNXRp8g9Xx8218oMR6nmpYT5DjKR4tFVAUxWEmwIgT1D7gJxboLCae6jHiRilShygUhanylrY4Zy5/zTV5y8BIQKB3M6ZYBlVePq12AbQv1bCn2VPDoa61Ek9vvoauC88vQEOIBpm0EPKluAy05yTYGzOS3gm/qhPQLDCSWqQpVE2pyVMAQ8EAQAAAAABAwiYOgAAAAAAAAEEFgAUgOCAoBDcwBoMygQ0Q5VYjll5FTgA";
|
|
97
|
+
const EXPECTED_PSBT_FEE = 5000; // sats
|
|
98
|
+
|
|
99
|
+
// -------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
describe("signRawOperation (PSBT path)", () => {
|
|
102
|
+
test("returns tx hex in signature and psbtSigned in rawData; value/fee from PSBT", async () => {
|
|
103
|
+
const txHex = "01020304";
|
|
104
|
+
const signer: MockSigner = {
|
|
105
|
+
signPsbtBuffer: jest.fn().mockImplementation((_psbtBuffer: Buffer, options?: any) => {
|
|
106
|
+
// Simulate the actual behavior of signPsbtBuffer by calling the callbacks
|
|
107
|
+
if (options?.onDeviceSignatureRequested) {
|
|
108
|
+
options.onDeviceSignatureRequested();
|
|
109
|
+
}
|
|
110
|
+
if (options?.onDeviceSignatureGranted) {
|
|
111
|
+
options.onDeviceSignatureGranted();
|
|
112
|
+
}
|
|
113
|
+
if (options?.onDeviceStreaming) {
|
|
114
|
+
options.onDeviceStreaming({ progress: 0.5, index: 1, total: 2 });
|
|
115
|
+
}
|
|
116
|
+
return Promise.resolve({
|
|
117
|
+
psbt: Buffer.from(PSBT_V2_B64, "base64"),
|
|
118
|
+
tx: txHex,
|
|
119
|
+
});
|
|
120
|
+
}),
|
|
121
|
+
};
|
|
122
|
+
const signerContext = makeSignerContext(signer);
|
|
123
|
+
const signRawOperation = buildSignRawOperation(signerContext);
|
|
124
|
+
|
|
125
|
+
const account = makeAccount();
|
|
126
|
+
|
|
127
|
+
const events = await firstValueFrom(
|
|
128
|
+
signRawOperation({ account, deviceId: "mock", transaction: PSBT_V2_B64 }).pipe(toArray()),
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
// Events should include requested and granted
|
|
132
|
+
const types = events.map(e => e.type);
|
|
133
|
+
expect(types).toContain("device-streaming");
|
|
134
|
+
expect(types).toContain("device-signature-requested");
|
|
135
|
+
expect(types).toContain("device-signature-granted");
|
|
136
|
+
|
|
137
|
+
const streamingEvents = events.filter(e => e.type === "device-streaming");
|
|
138
|
+
expect(streamingEvents).toHaveLength(1);
|
|
139
|
+
expect(streamingEvents[0]).toEqual({
|
|
140
|
+
type: "device-streaming",
|
|
141
|
+
progress: 0.5,
|
|
142
|
+
index: 1,
|
|
143
|
+
total: 2,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const signedEvt = events.find(e => e.type === "signed");
|
|
147
|
+
if (!signedEvt || signedEvt.type !== "signed") {
|
|
148
|
+
throw new Error("No signed event");
|
|
149
|
+
}
|
|
150
|
+
const { signedOperation } = signedEvt;
|
|
151
|
+
|
|
152
|
+
// rawData and signature checks
|
|
153
|
+
expect(signedOperation.rawData?.psbtSigned).toBe(PSBT_V2_B64);
|
|
154
|
+
expect(signedOperation.signature).toBe(txHex);
|
|
155
|
+
|
|
156
|
+
// fee/value taken from PSBT
|
|
157
|
+
const op: Operation = signedOperation.operation;
|
|
158
|
+
expect(op.fee.toNumber()).toBe(EXPECTED_PSBT_FEE);
|
|
159
|
+
expect(op.value.toNumber()).toBe(EXPECTED_PSBT_FEE);
|
|
160
|
+
expect(op.senders).toEqual([]);
|
|
161
|
+
expect(op.recipients).toEqual([]);
|
|
162
|
+
|
|
163
|
+
// Options propagated
|
|
164
|
+
const [, opts] = signer.signPsbtBuffer.mock.calls[0];
|
|
165
|
+
expect(opts).toMatchObject({
|
|
166
|
+
accountPath: "m/84'/0'/0'/0'",
|
|
167
|
+
addressFormat: "p2wpkh",
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test("invalid base64 PSBT errors early", async () => {
|
|
172
|
+
const signer: MockSigner = {
|
|
173
|
+
signPsbtBuffer: jest.fn(),
|
|
174
|
+
};
|
|
175
|
+
const signerContext = makeSignerContext(signer);
|
|
176
|
+
const signRawOperation = buildSignRawOperation(signerContext);
|
|
177
|
+
|
|
178
|
+
const account = makeAccount();
|
|
179
|
+
|
|
180
|
+
await expect(
|
|
181
|
+
firstValueFrom(
|
|
182
|
+
signRawOperation({ account, deviceId: "mock", transaction: "!!!not-base64!!!" }).pipe(
|
|
183
|
+
skip(1),
|
|
184
|
+
),
|
|
185
|
+
),
|
|
186
|
+
).rejects.toThrow(/PSBT signing failed: no result from device for account/);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createBridges } from "./js";
|
|
2
|
+
|
|
3
|
+
describe("createBridges", () => {
|
|
4
|
+
it("has a currency bridge and an account bridge with required methods", () => {
|
|
5
|
+
expect(createBridges(undefined as any, {} as any)).toEqual({
|
|
6
|
+
accountBridge: {
|
|
7
|
+
assignFromAccountRaw: expect.any(Function),
|
|
8
|
+
assignToAccountRaw: expect.any(Function),
|
|
9
|
+
broadcast: expect.any(Function),
|
|
10
|
+
createTransaction: expect.any(Function),
|
|
11
|
+
estimateMaxSpendable: expect.any(Function),
|
|
12
|
+
formatAccountSpecifics: expect.any(Function),
|
|
13
|
+
getSerializedAddressParameters: expect.any(Function),
|
|
14
|
+
getTransactionStatus: expect.any(Function),
|
|
15
|
+
prepareTransaction: expect.any(Function),
|
|
16
|
+
receive: expect.any(Function),
|
|
17
|
+
signOperation: expect.any(Function),
|
|
18
|
+
signRawOperation: expect.any(Function),
|
|
19
|
+
sync: expect.any(Function),
|
|
20
|
+
updateTransaction: expect.any(Function),
|
|
21
|
+
validateAddress: expect.any(Function),
|
|
22
|
+
},
|
|
23
|
+
currencyBridge: {
|
|
24
|
+
preload: expect.any(Function),
|
|
25
|
+
hydrate: expect.any(Function),
|
|
26
|
+
scanAccounts: expect.any(Function),
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
});
|
package/src/bridge/js.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { broadcast } from "../broadcast";
|
|
|
23
23
|
import { perCoinLogic } from "../logic";
|
|
24
24
|
import resolver from "../hw-getAddress";
|
|
25
25
|
import { validateAddress } from "../validateAddress";
|
|
26
|
+
import buildSignRawOperation from "../signRawOperation";
|
|
26
27
|
|
|
27
28
|
function buildCurrencyBridge(signerContext: SignerContext) {
|
|
28
29
|
const getAddress = resolver(signerContext);
|
|
@@ -78,9 +79,7 @@ function buildAccountBridge(signerContext: SignerContext) {
|
|
|
78
79
|
receive,
|
|
79
80
|
sync,
|
|
80
81
|
signOperation: buildSignOperation(signerContext),
|
|
81
|
-
signRawOperation: ()
|
|
82
|
-
throw new Error("signRawOperation is not supported");
|
|
83
|
-
},
|
|
82
|
+
signRawOperation: buildSignRawOperation(signerContext),
|
|
84
83
|
broadcast: wrappedBroadcast,
|
|
85
84
|
assignFromAccountRaw,
|
|
86
85
|
assignToAccountRaw,
|