@ledgerhq/hw-app-btc 6.11.2 → 6.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Btc.js +1 -1
- package/lib/Btc.js.map +1 -1
- package/lib/BtcNew.js +3 -3
- package/lib/BtcNew.js.map +1 -1
- package/lib/buffertools.d.ts +4 -2
- package/lib/buffertools.d.ts.map +1 -1
- package/lib/buffertools.js +37 -5
- package/lib/buffertools.js.map +1 -1
- package/lib/newops/accounttype.d.ts.map +1 -1
- package/lib/newops/accounttype.js +9 -6
- package/lib/newops/accounttype.js.map +1 -1
- package/lib/newops/appClient.js +4 -4
- package/lib/newops/appClient.js.map +1 -1
- package/lib/newops/merkle.js +2 -2
- package/lib/newops/merkle.js.map +1 -1
- package/lib/newops/psbtExtractor.js +3 -3
- package/lib/newops/psbtExtractor.js.map +1 -1
- package/lib/newops/psbtv2.d.ts.map +1 -1
- package/lib/newops/psbtv2.js +7 -8
- package/lib/newops/psbtv2.js.map +1 -1
- package/lib-es/Btc.js +1 -1
- package/lib-es/Btc.js.map +1 -1
- package/lib-es/BtcNew.js +3 -3
- package/lib-es/BtcNew.js.map +1 -1
- package/lib-es/buffertools.d.ts +4 -2
- package/lib-es/buffertools.d.ts.map +1 -1
- package/lib-es/buffertools.js +34 -4
- package/lib-es/buffertools.js.map +1 -1
- package/lib-es/newops/accounttype.d.ts.map +1 -1
- package/lib-es/newops/accounttype.js +9 -6
- package/lib-es/newops/accounttype.js.map +1 -1
- package/lib-es/newops/appClient.js +4 -4
- package/lib-es/newops/appClient.js.map +1 -1
- package/lib-es/newops/merkle.js +2 -2
- package/lib-es/newops/merkle.js.map +1 -1
- package/lib-es/newops/psbtExtractor.js +3 -3
- package/lib-es/newops/psbtExtractor.js.map +1 -1
- package/lib-es/newops/psbtv2.d.ts.map +1 -1
- package/lib-es/newops/psbtv2.js +8 -9
- package/lib-es/newops/psbtv2.js.map +1 -1
- package/package.json +2 -2
- package/src/Btc.ts +1 -1
- package/src/BtcNew.ts +3 -3
- package/src/buffertools.ts +38 -6
- package/src/newops/accounttype.ts +9 -6
- package/src/newops/appClient.ts +4 -4
- package/src/newops/merkle.ts +2 -2
- package/src/newops/psbtExtractor.ts +3 -3
- package/src/newops/psbtv2.ts +13 -11
- package/tests/Btc.test.ts +68 -44
- package/tests/buffertools.test.ts +25 -0
- package/tests/newops/BtcNew.test.ts +13 -0
- package/tests/newops/integrationtools.ts +58 -28
- package/tests/newops/merkle.test.ts +1 -1
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
WalletPolicy
|
|
10
10
|
} from "../../src/newops/policy";
|
|
11
11
|
import { PsbtV2 } from "../../src/newops/psbtv2";
|
|
12
|
+
import { splitTransaction } from "../../src/splitTransaction";
|
|
12
13
|
import { StandardPurpose, addressFormatFromDescriptorTemplate, creatDummyXpub, masterFingerprint, runSignTransaction, TestingClient } from "./integrationtools";
|
|
13
14
|
import { CoreInput, CoreTx, p2pkh, p2tr, p2wpkh, wrappedP2wpkh, wrappedP2wpkhTwoInputs } from "./testtx";
|
|
14
15
|
|
|
@@ -83,6 +84,18 @@ test("Sign p2tr with sigHashType", async () => {
|
|
|
83
84
|
// The verification of the sighashtype is done in MockClient.signPsbt
|
|
84
85
|
})
|
|
85
86
|
|
|
87
|
+
test("Sign p2tr sequence 0", async() => {
|
|
88
|
+
const testTx = JSON.parse(JSON.stringify(p2tr));
|
|
89
|
+
testTx.vin.forEach((input: CoreInput, index: number) => {
|
|
90
|
+
input.sequence = 0;
|
|
91
|
+
})
|
|
92
|
+
const tx = await runSignTransactionNoVerification(testTx, StandardPurpose.p2tr);
|
|
93
|
+
const txObj = splitTransaction(tx, true);
|
|
94
|
+
txObj.inputs.forEach((input, index) => {
|
|
95
|
+
expect(input.sequence.toString("hex")).toEqual("00000000");
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
86
99
|
async function runSignTransactionTest(testTx: CoreTx, accountType: StandardPurpose, changePubkey?: string) {
|
|
87
100
|
const tx = await runSignTransactionNoVerification(testTx, accountType, changePubkey);
|
|
88
101
|
expect(tx).toEqual(testTx.hex);
|
|
@@ -9,17 +9,17 @@ import { AddressFormat } from "../../src/getWalletPublicKey";
|
|
|
9
9
|
import { AppClient } from "../../src/newops/appClient";
|
|
10
10
|
import {
|
|
11
11
|
DefaultDescriptorTemplate,
|
|
12
|
-
WalletPolicy
|
|
12
|
+
WalletPolicy,
|
|
13
13
|
} from "../../src/newops/policy";
|
|
14
14
|
import { Transaction } from "../../src/types";
|
|
15
15
|
import { CoreInput, CoreTx, spentTxs } from "./testtx";
|
|
16
16
|
|
|
17
|
-
|
|
18
17
|
export async function runSignTransaction(
|
|
19
18
|
testTx: CoreTx,
|
|
20
|
-
testPaths: { ins: string[]
|
|
19
|
+
testPaths: { ins: string[]; out?: string },
|
|
21
20
|
client: TestingClient,
|
|
22
|
-
transport: Transport
|
|
21
|
+
transport: Transport
|
|
22
|
+
): Promise<string> {
|
|
23
23
|
const btcNew = new BtcNew(client);
|
|
24
24
|
// btc is needed to perform some functions like splitTransaction.
|
|
25
25
|
const btc = new Btc(transport);
|
|
@@ -37,30 +37,38 @@ export async function runSignTransaction(
|
|
|
37
37
|
const path = testPaths.ins[index];
|
|
38
38
|
associatedKeysets.push(path);
|
|
39
39
|
const inputData = createInput(input, btc);
|
|
40
|
-
const pubkey = getPubkey(
|
|
40
|
+
const pubkey = getPubkey(
|
|
41
|
+
index,
|
|
42
|
+
accountType,
|
|
43
|
+
testTx,
|
|
44
|
+
inputData[0],
|
|
45
|
+
inputData[1]
|
|
46
|
+
);
|
|
41
47
|
const mockXpub = creatDummyXpub(pubkey);
|
|
42
48
|
client.mockGetPubkeyResponse(path, mockXpub);
|
|
43
49
|
yieldSigs.set(index, getSignature(input, accountType));
|
|
44
50
|
return inputData;
|
|
45
51
|
});
|
|
46
52
|
const sig0 = yieldSigs.get(0)!;
|
|
47
|
-
let sigHashType: number | undefined = sig0.readUInt8(sig0.length - 1)
|
|
53
|
+
let sigHashType: number | undefined = sig0.readUInt8(sig0.length - 1);
|
|
48
54
|
if (sigHashType == 0x01) {
|
|
49
55
|
sigHashType = undefined;
|
|
50
56
|
}
|
|
51
57
|
client.mockSignPsbt(yieldSigs);
|
|
52
58
|
const outputWriter = new BufferWriter();
|
|
53
59
|
outputWriter.writeVarInt(testTx.vout.length);
|
|
54
|
-
testTx.vout.forEach(output => {
|
|
55
|
-
outputWriter.writeUInt64(
|
|
60
|
+
testTx.vout.forEach((output) => {
|
|
61
|
+
outputWriter.writeUInt64(
|
|
62
|
+
Number.parseFloat((output.value * 100000000).toFixed(8))
|
|
63
|
+
);
|
|
56
64
|
outputWriter.writeVarSlice(Buffer.from(output.scriptPubKey.hex, "hex"));
|
|
57
65
|
});
|
|
58
|
-
const outputScriptHex = outputWriter.buffer().toString("hex");
|
|
66
|
+
const outputScriptHex = outputWriter.buffer().toString("hex");
|
|
59
67
|
let callbacks = "";
|
|
60
68
|
function logCallback(message: string) {
|
|
61
69
|
callbacks += new Date().toISOString() + " " + message + "\n";
|
|
62
70
|
}
|
|
63
|
-
const arg: CreateTransactionArg = {
|
|
71
|
+
const arg: CreateTransactionArg = {
|
|
64
72
|
inputs,
|
|
65
73
|
additionals,
|
|
66
74
|
associatedKeysets,
|
|
@@ -70,19 +78,20 @@ export async function runSignTransaction(
|
|
|
70
78
|
sigHashType,
|
|
71
79
|
segwit: accountType != StandardPurpose.p2pkh,
|
|
72
80
|
onDeviceSignatureGranted: () => logCallback("CALLBACK: signature granted"),
|
|
73
|
-
onDeviceSignatureRequested: () =>
|
|
74
|
-
|
|
81
|
+
onDeviceSignatureRequested: () =>
|
|
82
|
+
logCallback("CALLBACK: signature requested"),
|
|
83
|
+
onDeviceStreaming: (arg) => logCallback("CALLBACK: " + JSON.stringify(arg)),
|
|
75
84
|
};
|
|
76
85
|
logCallback("Start createPaymentTransactionNew");
|
|
77
86
|
const tx = await btcNew.createPaymentTransactionNew(arg);
|
|
78
87
|
logCallback("Done createPaymentTransactionNew");
|
|
79
88
|
// console.log(callbacks);
|
|
80
89
|
return tx;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
90
|
+
}
|
|
84
91
|
|
|
85
|
-
export function addressFormatFromDescriptorTemplate(
|
|
92
|
+
export function addressFormatFromDescriptorTemplate(
|
|
93
|
+
descTemp: DefaultDescriptorTemplate
|
|
94
|
+
): AddressFormat {
|
|
86
95
|
if (descTemp == "tr(@0)") return "bech32m";
|
|
87
96
|
if (descTemp == "pkh(@0)") return "legacy";
|
|
88
97
|
if (descTemp == "wpkh(@0)") return "bech32";
|
|
@@ -94,10 +103,16 @@ export enum StandardPurpose {
|
|
|
94
103
|
p2tr = "86'",
|
|
95
104
|
p2wpkh = "84'",
|
|
96
105
|
p2wpkhInP2sh = "49'",
|
|
97
|
-
p2pkh = "44'"
|
|
106
|
+
p2pkh = "44'",
|
|
98
107
|
}
|
|
99
108
|
|
|
100
|
-
function getPubkey(
|
|
109
|
+
function getPubkey(
|
|
110
|
+
inputIndex: number,
|
|
111
|
+
accountType: StandardPurpose,
|
|
112
|
+
testTx: CoreTx,
|
|
113
|
+
spentTx: Transaction,
|
|
114
|
+
spentOutputIndex: number
|
|
115
|
+
): Buffer {
|
|
101
116
|
const scriptSig = Buffer.from(testTx.vin[inputIndex].scriptSig.hex, "hex");
|
|
102
117
|
if (accountType == StandardPurpose.p2pkh) {
|
|
103
118
|
return scriptSig.slice(scriptSig.length - 33);
|
|
@@ -105,13 +120,19 @@ function getPubkey(inputIndex: number, accountType: StandardPurpose, testTx: Cor
|
|
|
105
120
|
if (accountType == StandardPurpose.p2tr) {
|
|
106
121
|
return spentTx.outputs![spentOutputIndex].script.slice(2, 34); // 32 bytes x-only pubkey
|
|
107
122
|
}
|
|
108
|
-
if (
|
|
123
|
+
if (
|
|
124
|
+
accountType == StandardPurpose.p2wpkh ||
|
|
125
|
+
accountType == StandardPurpose.p2wpkhInP2sh
|
|
126
|
+
) {
|
|
109
127
|
return Buffer.from(testTx.vin[inputIndex].txinwitness![1], "hex");
|
|
110
128
|
}
|
|
111
129
|
throw new Error();
|
|
112
130
|
}
|
|
113
131
|
|
|
114
|
-
function getSignature(
|
|
132
|
+
function getSignature(
|
|
133
|
+
testTxInput: CoreInput,
|
|
134
|
+
accountType: StandardPurpose
|
|
135
|
+
): Buffer {
|
|
115
136
|
const scriptSig = Buffer.from(testTxInput.scriptSig.hex, "hex");
|
|
116
137
|
if (accountType == StandardPurpose.p2pkh) {
|
|
117
138
|
return scriptSig.slice(1, scriptSig.length - 34);
|
|
@@ -119,7 +140,10 @@ function getSignature(testTxInput: CoreInput, accountType: StandardPurpose): Buf
|
|
|
119
140
|
if (accountType == StandardPurpose.p2tr) {
|
|
120
141
|
return Buffer.from(testTxInput.txinwitness![0], "hex");
|
|
121
142
|
}
|
|
122
|
-
if (
|
|
143
|
+
if (
|
|
144
|
+
accountType == StandardPurpose.p2wpkh ||
|
|
145
|
+
accountType == StandardPurpose.p2wpkhInP2sh
|
|
146
|
+
) {
|
|
123
147
|
return Buffer.from(testTxInput.txinwitness![0], "hex");
|
|
124
148
|
}
|
|
125
149
|
throw new Error();
|
|
@@ -146,13 +170,19 @@ function getAccountType(coreInput: CoreInput, btc: Btc): StandardPurpose {
|
|
|
146
170
|
}
|
|
147
171
|
|
|
148
172
|
export function creatDummyXpub(pubkey: Buffer): string {
|
|
149
|
-
const xpubDecoded = bs58check.decode(
|
|
150
|
-
|
|
173
|
+
const xpubDecoded = bs58check.decode(
|
|
174
|
+
"tpubDHcN44A4UHqdHJZwBxgTbu8Cy87ZrZkN8tQnmJGhcijHqe4rztuvGcD4wo36XSviLmiqL5fUbDnekYaQ7LzAnaqauBb9RsyahsTTFHdeJGd"
|
|
175
|
+
);
|
|
176
|
+
const pubkey33 =
|
|
177
|
+
pubkey.length == 33 ? pubkey : Buffer.concat([Buffer.from([2]), pubkey]);
|
|
151
178
|
xpubDecoded.fill(pubkey33, xpubDecoded.length - 33);
|
|
152
179
|
return bs58check.encode(xpubDecoded);
|
|
153
180
|
}
|
|
154
181
|
|
|
155
|
-
function createInput(
|
|
182
|
+
function createInput(
|
|
183
|
+
coreInput: CoreInput,
|
|
184
|
+
btc: Btc
|
|
185
|
+
): [Transaction, number, string | null, number] {
|
|
156
186
|
const spentTx = spentTxs[coreInput.txid];
|
|
157
187
|
if (!spentTx) {
|
|
158
188
|
throw new Error("Spent tx " + coreInput.txid + " unavailable.");
|
|
@@ -161,14 +191,14 @@ function createInput(coreInput: CoreInput, btc: Btc): [Transaction, number, stri
|
|
|
161
191
|
return [splitSpentTx, coreInput.vout, null, coreInput.sequence];
|
|
162
192
|
}
|
|
163
193
|
|
|
164
|
-
export const masterFingerprint = Buffer.
|
|
194
|
+
export const masterFingerprint = Buffer.from([1, 2, 3, 4]);
|
|
165
195
|
export class TestingClient extends AppClient {
|
|
166
|
-
mockGetPubkeyResponse(_pathElements: string, _response: string): void {
|
|
196
|
+
mockGetPubkeyResponse(_pathElements: string, _response: string): void {}
|
|
167
197
|
mockGetWalletAddressResponse(
|
|
168
198
|
_walletPolicy: WalletPolicy,
|
|
169
199
|
_change: number,
|
|
170
200
|
_addressIndex: number,
|
|
171
201
|
_response: string
|
|
172
|
-
): void {
|
|
173
|
-
mockSignPsbt(_yieldSigs: Map<number, Buffer>): void {
|
|
202
|
+
): void {}
|
|
203
|
+
mockSignPsbt(_yieldSigs: Map<number, Buffer>): void {}
|
|
174
204
|
}
|