@ledgerhq/hw-app-btc 10.0.4 → 10.0.5-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/CHANGELOG.md +7 -0
- package/lib/Btc.d.ts.map +1 -1
- package/lib/Btc.js +6 -8
- package/lib/Btc.js.map +1 -1
- package/lib/BtcNew.d.ts +1 -1
- package/lib/BtcNew.d.ts.map +1 -1
- package/lib/BtcNew.js +5 -6
- package/lib/BtcNew.js.map +1 -1
- package/lib/BtcOld.d.ts +1 -1
- package/lib/BtcOld.d.ts.map +1 -1
- package/lib/BtcOld.js +2 -5
- package/lib/BtcOld.js.map +1 -1
- package/lib/buffertools.js +3 -3
- package/lib/buffertools.js.map +1 -1
- package/lib/createTransaction.d.ts +1 -6
- package/lib/createTransaction.d.ts.map +1 -1
- package/lib/createTransaction.js +5 -13
- package/lib/createTransaction.js.map +1 -1
- package/lib/finalizeInput.d.ts.map +1 -1
- package/lib/finalizeInput.js.map +1 -1
- package/lib/getAppAndVersion.d.ts.map +1 -1
- package/lib/getAppAndVersion.js.map +1 -1
- package/lib/getTrustedInput.d.ts.map +1 -1
- package/lib/getTrustedInput.js +5 -12
- package/lib/getTrustedInput.js.map +1 -1
- package/lib/getTrustedInputBIP143.d.ts.map +1 -1
- package/lib/getTrustedInputBIP143.js.map +1 -1
- package/lib/getWalletPublicKey.d.ts.map +1 -1
- package/lib/getWalletPublicKey.js.map +1 -1
- package/lib/newops/accounttype.d.ts.map +1 -1
- package/lib/newops/accounttype.js +2 -6
- package/lib/newops/accounttype.js.map +1 -1
- package/lib/newops/appClient.d.ts.map +1 -1
- package/lib/newops/appClient.js +7 -14
- package/lib/newops/appClient.js.map +1 -1
- package/lib/newops/clientCommands.d.ts.map +1 -1
- package/lib/newops/clientCommands.js +2 -2
- package/lib/newops/clientCommands.js.map +1 -1
- package/lib/newops/merkelizedPsbt.d.ts.map +1 -1
- package/lib/newops/merkelizedPsbt.js +4 -4
- package/lib/newops/merkelizedPsbt.js.map +1 -1
- package/lib/newops/merkle.d.ts.map +1 -1
- package/lib/newops/merkle.js.map +1 -1
- package/lib/newops/merkleMap.js +2 -2
- package/lib/newops/merkleMap.js.map +1 -1
- package/lib/newops/policy.d.ts.map +1 -1
- package/lib/newops/policy.js +2 -2
- package/lib/newops/policy.js.map +1 -1
- package/lib/newops/psbtFinalizer.d.ts.map +1 -1
- package/lib/newops/psbtFinalizer.js.map +1 -1
- package/lib/newops/psbtv2.d.ts.map +1 -1
- package/lib/newops/psbtv2.js +6 -6
- package/lib/newops/psbtv2.js.map +1 -1
- package/lib/serializeTransaction.d.ts.map +1 -1
- package/lib/serializeTransaction.js +3 -4
- package/lib/serializeTransaction.js.map +1 -1
- package/lib/signMessage.d.ts.map +1 -1
- package/lib/signMessage.js +2 -6
- package/lib/signMessage.js.map +1 -1
- package/lib/signP2SHTransaction.d.ts +1 -6
- package/lib/signP2SHTransaction.d.ts.map +1 -1
- package/lib/signP2SHTransaction.js +2 -6
- package/lib/signP2SHTransaction.js.map +1 -1
- package/lib/signTransaction.d.ts.map +1 -1
- package/lib/signTransaction.js +2 -7
- package/lib/signTransaction.js.map +1 -1
- package/lib/splitTransaction.d.ts.map +1 -1
- package/lib/splitTransaction.js.map +1 -1
- package/lib/startUntrustedHashTransactionInput.d.ts.map +1 -1
- package/lib/startUntrustedHashTransactionInput.js +1 -4
- package/lib/startUntrustedHashTransactionInput.js.map +1 -1
- package/lib-es/Btc.d.ts.map +1 -1
- package/lib-es/Btc.js +6 -8
- package/lib-es/Btc.js.map +1 -1
- package/lib-es/BtcNew.d.ts +1 -1
- package/lib-es/BtcNew.d.ts.map +1 -1
- package/lib-es/BtcNew.js +6 -7
- package/lib-es/BtcNew.js.map +1 -1
- package/lib-es/BtcOld.d.ts +1 -1
- package/lib-es/BtcOld.d.ts.map +1 -1
- package/lib-es/BtcOld.js +2 -5
- package/lib-es/BtcOld.js.map +1 -1
- package/lib-es/buffertools.js +3 -3
- package/lib-es/buffertools.js.map +1 -1
- package/lib-es/createTransaction.d.ts +1 -6
- package/lib-es/createTransaction.d.ts.map +1 -1
- package/lib-es/createTransaction.js +5 -13
- package/lib-es/createTransaction.js.map +1 -1
- package/lib-es/finalizeInput.d.ts.map +1 -1
- package/lib-es/finalizeInput.js.map +1 -1
- package/lib-es/getAppAndVersion.d.ts.map +1 -1
- package/lib-es/getAppAndVersion.js.map +1 -1
- package/lib-es/getTrustedInput.d.ts.map +1 -1
- package/lib-es/getTrustedInput.js +5 -12
- package/lib-es/getTrustedInput.js.map +1 -1
- package/lib-es/getTrustedInputBIP143.d.ts.map +1 -1
- package/lib-es/getTrustedInputBIP143.js.map +1 -1
- package/lib-es/getWalletPublicKey.d.ts.map +1 -1
- package/lib-es/getWalletPublicKey.js.map +1 -1
- package/lib-es/newops/accounttype.d.ts.map +1 -1
- package/lib-es/newops/accounttype.js +3 -7
- package/lib-es/newops/accounttype.js.map +1 -1
- package/lib-es/newops/appClient.d.ts.map +1 -1
- package/lib-es/newops/appClient.js +7 -14
- package/lib-es/newops/appClient.js.map +1 -1
- package/lib-es/newops/clientCommands.d.ts.map +1 -1
- package/lib-es/newops/clientCommands.js +2 -2
- package/lib-es/newops/clientCommands.js.map +1 -1
- package/lib-es/newops/merkelizedPsbt.d.ts.map +1 -1
- package/lib-es/newops/merkelizedPsbt.js +4 -4
- package/lib-es/newops/merkelizedPsbt.js.map +1 -1
- package/lib-es/newops/merkle.d.ts.map +1 -1
- package/lib-es/newops/merkle.js.map +1 -1
- package/lib-es/newops/merkleMap.js +2 -2
- package/lib-es/newops/merkleMap.js.map +1 -1
- package/lib-es/newops/policy.d.ts.map +1 -1
- package/lib-es/newops/policy.js +2 -2
- package/lib-es/newops/policy.js.map +1 -1
- package/lib-es/newops/psbtFinalizer.d.ts.map +1 -1
- package/lib-es/newops/psbtFinalizer.js.map +1 -1
- package/lib-es/newops/psbtv2.d.ts.map +1 -1
- package/lib-es/newops/psbtv2.js +7 -7
- package/lib-es/newops/psbtv2.js.map +1 -1
- package/lib-es/serializeTransaction.d.ts.map +1 -1
- package/lib-es/serializeTransaction.js +3 -4
- package/lib-es/serializeTransaction.js.map +1 -1
- package/lib-es/signMessage.d.ts.map +1 -1
- package/lib-es/signMessage.js +2 -6
- package/lib-es/signMessage.js.map +1 -1
- package/lib-es/signP2SHTransaction.d.ts +1 -6
- package/lib-es/signP2SHTransaction.d.ts.map +1 -1
- package/lib-es/signP2SHTransaction.js +3 -7
- package/lib-es/signP2SHTransaction.js.map +1 -1
- package/lib-es/signTransaction.d.ts.map +1 -1
- package/lib-es/signTransaction.js +2 -7
- package/lib-es/signTransaction.js.map +1 -1
- package/lib-es/splitTransaction.d.ts.map +1 -1
- package/lib-es/splitTransaction.js.map +1 -1
- package/lib-es/startUntrustedHashTransactionInput.d.ts.map +1 -1
- package/lib-es/startUntrustedHashTransactionInput.js +1 -4
- package/lib-es/startUntrustedHashTransactionInput.js.map +1 -1
- package/package.json +5 -5
- package/src/Btc.ts +17 -31
- package/src/BtcNew.ts +27 -62
- package/src/BtcOld.ts +8 -19
- package/src/buffertools.ts +3 -3
- package/src/createTransaction.ts +20 -52
- package/src/finalizeInput.ts +2 -5
- package/src/getAppAndVersion.ts +2 -6
- package/src/getTrustedInput.ts +12 -32
- package/src/getTrustedInputBIP143.ts +2 -4
- package/src/getWalletPublicKey.ts +3 -11
- package/src/newops/accounttype.ts +21 -76
- package/src/newops/appClient.ts +17 -39
- package/src/newops/clientCommands.ts +7 -16
- package/src/newops/merkelizedPsbt.ts +6 -14
- package/src/newops/merkle.ts +3 -10
- package/src/newops/merkleMap.ts +2 -2
- package/src/newops/policy.ts +5 -15
- package/src/newops/psbtFinalizer.ts +3 -8
- package/src/newops/psbtv2.ts +32 -85
- package/src/serializeTransaction.ts +5 -9
- package/src/signMessage.ts +5 -16
- package/src/signP2SHTransaction.ts +11 -34
- package/src/signTransaction.ts +3 -8
- package/src/splitTransaction.ts +3 -7
- package/src/startUntrustedHashTransactionInput.ts +7 -10
package/src/newops/policy.ts
CHANGED
|
@@ -3,11 +3,7 @@ import { pathArrayToString } from "../bip32";
|
|
|
3
3
|
import { BufferWriter } from "../buffertools";
|
|
4
4
|
import { hashLeaf, Merkle } from "./merkle";
|
|
5
5
|
|
|
6
|
-
export type DefaultDescriptorTemplate =
|
|
7
|
-
| "pkh(@0)"
|
|
8
|
-
| "sh(wpkh(@0))"
|
|
9
|
-
| "wpkh(@0)"
|
|
10
|
-
| "tr(@0)";
|
|
6
|
+
export type DefaultDescriptorTemplate = "pkh(@0)" | "sh(wpkh(@0))" | "wpkh(@0)" | "tr(@0)";
|
|
11
7
|
|
|
12
8
|
/**
|
|
13
9
|
* The Bitcon hardware app uses a descriptors-like thing to describe
|
|
@@ -34,10 +30,10 @@ export class WalletPolicy {
|
|
|
34
30
|
}
|
|
35
31
|
|
|
36
32
|
serialize(): Buffer {
|
|
37
|
-
const keyBuffers = this.keys.map(
|
|
33
|
+
const keyBuffers = this.keys.map(k => {
|
|
38
34
|
return Buffer.from(k, "ascii");
|
|
39
35
|
});
|
|
40
|
-
const m = new Merkle(keyBuffers.map(
|
|
36
|
+
const m = new Merkle(keyBuffers.map(k => hashLeaf(k)));
|
|
41
37
|
|
|
42
38
|
const buf = new BufferWriter();
|
|
43
39
|
buf.writeUInt8(0x01); // wallet type (policy map)
|
|
@@ -48,13 +44,7 @@ export class WalletPolicy {
|
|
|
48
44
|
}
|
|
49
45
|
}
|
|
50
46
|
|
|
51
|
-
export function createKey(
|
|
52
|
-
masterFingerprint: Buffer,
|
|
53
|
-
path: number[],
|
|
54
|
-
xpub: string
|
|
55
|
-
): string {
|
|
47
|
+
export function createKey(masterFingerprint: Buffer, path: number[], xpub: string): string {
|
|
56
48
|
const accountPath = pathArrayToString(path);
|
|
57
|
-
return `[${masterFingerprint.toString("hex")}${accountPath.substring(
|
|
58
|
-
1
|
|
59
|
-
)}]${xpub}/**`;
|
|
49
|
+
return `[${masterFingerprint.toString("hex")}${accountPath.substring(1)}]${xpub}/**`;
|
|
60
50
|
}
|
|
@@ -26,9 +26,7 @@ export function finalize(psbt: PsbtV2): void {
|
|
|
26
26
|
}
|
|
27
27
|
if (legacyPubkeys.length > 0) {
|
|
28
28
|
if (legacyPubkeys.length > 1) {
|
|
29
|
-
throw Error(
|
|
30
|
-
`Expected exactly one signature, got ${legacyPubkeys.length}`
|
|
31
|
-
);
|
|
29
|
+
throw Error(`Expected exactly one signature, got ${legacyPubkeys.length}`);
|
|
32
30
|
}
|
|
33
31
|
if (taprootSig) {
|
|
34
32
|
throw Error("Both taproot and non-taproot signatures present.");
|
|
@@ -38,8 +36,7 @@ export function finalize(psbt: PsbtV2): void {
|
|
|
38
36
|
const redeemScript = psbt.getInputRedeemScript(i);
|
|
39
37
|
const isWrappedSegwit = !!redeemScript;
|
|
40
38
|
const signature = psbt.getInputPartialSig(i, legacyPubkeys[0]);
|
|
41
|
-
if (!signature)
|
|
42
|
-
throw new Error("Expected partial signature for input " + i);
|
|
39
|
+
if (!signature) throw new Error("Expected partial signature for input " + i);
|
|
43
40
|
if (isSegwitV0) {
|
|
44
41
|
const witnessBuf = new BufferWriter();
|
|
45
42
|
witnessBuf.writeVarInt(2);
|
|
@@ -50,9 +47,7 @@ export function finalize(psbt: PsbtV2): void {
|
|
|
50
47
|
psbt.setInputFinalScriptwitness(i, witnessBuf.buffer());
|
|
51
48
|
if (isWrappedSegwit) {
|
|
52
49
|
if (!redeemScript || redeemScript.length == 0) {
|
|
53
|
-
throw new Error(
|
|
54
|
-
"Expected non-empty redeemscript. Can't finalize intput " + i
|
|
55
|
-
);
|
|
50
|
+
throw new Error("Expected non-empty redeemscript. Can't finalize intput " + i);
|
|
56
51
|
}
|
|
57
52
|
const scriptSigBuf = new BufferWriter();
|
|
58
53
|
// Push redeemScript length
|
package/src/newops/psbtv2.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
2
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
3
|
-
import {
|
|
4
|
-
BufferReader,
|
|
5
|
-
BufferWriter,
|
|
6
|
-
unsafeFrom64bitLE,
|
|
7
|
-
unsafeTo64bitLE,
|
|
8
|
-
} from "../buffertools";
|
|
3
|
+
import { BufferReader, BufferWriter, unsafeFrom64bitLE, unsafeTo64bitLE } from "../buffertools";
|
|
9
4
|
|
|
10
5
|
export enum psbtGlobal {
|
|
11
6
|
TX_VERSION = 0x02,
|
|
@@ -75,9 +70,7 @@ export class PsbtV2 {
|
|
|
75
70
|
this.setGlobal(psbtGlobal.FALLBACK_LOCKTIME, uint32LE(locktime));
|
|
76
71
|
}
|
|
77
72
|
getGlobalFallbackLocktime(): number | undefined {
|
|
78
|
-
return this.getGlobalOptional(psbtGlobal.FALLBACK_LOCKTIME)?.readUInt32LE(
|
|
79
|
-
0
|
|
80
|
-
);
|
|
73
|
+
return this.getGlobalOptional(psbtGlobal.FALLBACK_LOCKTIME)?.readUInt32LE(0);
|
|
81
74
|
}
|
|
82
75
|
setGlobalInputCount(inputCount: number) {
|
|
83
76
|
this.setGlobal(psbtGlobal.INPUT_COUNT, varint(inputCount));
|
|
@@ -110,19 +103,13 @@ export class PsbtV2 {
|
|
|
110
103
|
getInputNonWitnessUtxo(inputIndex: number): Buffer | undefined {
|
|
111
104
|
return this.getInputOptional(inputIndex, psbtIn.NON_WITNESS_UTXO, b());
|
|
112
105
|
}
|
|
113
|
-
setInputWitnessUtxo(
|
|
114
|
-
inputIndex: number,
|
|
115
|
-
amount: Buffer,
|
|
116
|
-
scriptPubKey: Buffer
|
|
117
|
-
) {
|
|
106
|
+
setInputWitnessUtxo(inputIndex: number, amount: Buffer, scriptPubKey: Buffer) {
|
|
118
107
|
const buf = new BufferWriter();
|
|
119
108
|
buf.writeSlice(amount);
|
|
120
109
|
buf.writeVarSlice(scriptPubKey);
|
|
121
110
|
this.setInput(inputIndex, psbtIn.WITNESS_UTXO, b(), buf.buffer());
|
|
122
111
|
}
|
|
123
|
-
getInputWitnessUtxo(
|
|
124
|
-
inputIndex: number
|
|
125
|
-
): { amount: Buffer; scriptPubKey: Buffer } | undefined {
|
|
112
|
+
getInputWitnessUtxo(inputIndex: number): { amount: Buffer; scriptPubKey: Buffer } | undefined {
|
|
126
113
|
const utxo = this.getInputOptional(inputIndex, psbtIn.WITNESS_UTXO, b());
|
|
127
114
|
if (!utxo) return undefined;
|
|
128
115
|
const buf = new BufferReader(utxo);
|
|
@@ -152,26 +139,21 @@ export class PsbtV2 {
|
|
|
152
139
|
inputIndex: number,
|
|
153
140
|
pubkey: Buffer,
|
|
154
141
|
masterFingerprint: Buffer,
|
|
155
|
-
path: number[]
|
|
142
|
+
path: number[],
|
|
156
143
|
) {
|
|
157
|
-
if (pubkey.length != 33)
|
|
158
|
-
throw new Error("Invalid pubkey length: " + pubkey.length);
|
|
144
|
+
if (pubkey.length != 33) throw new Error("Invalid pubkey length: " + pubkey.length);
|
|
159
145
|
this.setInput(
|
|
160
146
|
inputIndex,
|
|
161
147
|
psbtIn.BIP32_DERIVATION,
|
|
162
148
|
pubkey,
|
|
163
|
-
this.encodeBip32Derivation(masterFingerprint, path)
|
|
149
|
+
this.encodeBip32Derivation(masterFingerprint, path),
|
|
164
150
|
);
|
|
165
151
|
}
|
|
166
152
|
getInputBip32Derivation(
|
|
167
153
|
inputIndex: number,
|
|
168
|
-
pubkey: Buffer
|
|
154
|
+
pubkey: Buffer,
|
|
169
155
|
): { masterFingerprint: Buffer; path: number[] } | undefined {
|
|
170
|
-
const buf = this.getInputOptional(
|
|
171
|
-
inputIndex,
|
|
172
|
-
psbtIn.BIP32_DERIVATION,
|
|
173
|
-
pubkey
|
|
174
|
-
);
|
|
156
|
+
const buf = this.getInputOptional(inputIndex, psbtIn.BIP32_DERIVATION, pubkey);
|
|
175
157
|
if (!buf) return undefined;
|
|
176
158
|
return this.decodeBip32Derivation(buf);
|
|
177
159
|
}
|
|
@@ -203,11 +185,7 @@ export class PsbtV2 {
|
|
|
203
185
|
this.setInput(inputIndex, psbtIn.SEQUENCE, b(), uint32LE(sequence));
|
|
204
186
|
}
|
|
205
187
|
getInputSequence(inputIndex: number): number {
|
|
206
|
-
return (
|
|
207
|
-
this.getInputOptional(inputIndex, psbtIn.SEQUENCE, b())?.readUInt32LE(
|
|
208
|
-
0
|
|
209
|
-
) ?? 0xffffffff
|
|
210
|
-
);
|
|
188
|
+
return this.getInputOptional(inputIndex, psbtIn.SEQUENCE, b())?.readUInt32LE(0) ?? 0xffffffff;
|
|
211
189
|
}
|
|
212
190
|
setInputTapKeySig(inputIndex: number, sig: Buffer) {
|
|
213
191
|
this.setInput(inputIndex, psbtIn.TAP_KEY_SIG, b(), sig);
|
|
@@ -220,16 +198,15 @@ export class PsbtV2 {
|
|
|
220
198
|
pubkey: Buffer,
|
|
221
199
|
hashes: Buffer[],
|
|
222
200
|
masterFingerprint: Buffer,
|
|
223
|
-
path: number[]
|
|
201
|
+
path: number[],
|
|
224
202
|
) {
|
|
225
|
-
if (pubkey.length != 32)
|
|
226
|
-
throw new Error("Invalid pubkey length: " + pubkey.length);
|
|
203
|
+
if (pubkey.length != 32) throw new Error("Invalid pubkey length: " + pubkey.length);
|
|
227
204
|
const buf = this.encodeTapBip32Derivation(hashes, masterFingerprint, path);
|
|
228
205
|
this.setInput(inputIndex, psbtIn.TAP_BIP32_DERIVATION, pubkey, buf);
|
|
229
206
|
}
|
|
230
207
|
getInputTapBip32Derivation(
|
|
231
208
|
inputIndex: number,
|
|
232
|
-
pubkey: Buffer
|
|
209
|
+
pubkey: Buffer,
|
|
233
210
|
): { hashes: Buffer[]; masterFingerprint: Buffer; path: number[] } {
|
|
234
211
|
const buf = this.getInput(inputIndex, psbtIn.TAP_BIP32_DERIVATION, pubkey);
|
|
235
212
|
return this.decodeTapBip32Derivation(buf);
|
|
@@ -248,18 +225,18 @@ export class PsbtV2 {
|
|
|
248
225
|
outputIndex: number,
|
|
249
226
|
pubkey: Buffer,
|
|
250
227
|
masterFingerprint: Buffer,
|
|
251
|
-
path: number[]
|
|
228
|
+
path: number[],
|
|
252
229
|
) {
|
|
253
230
|
this.setOutput(
|
|
254
231
|
outputIndex,
|
|
255
232
|
psbtOut.BIP_32_DERIVATION,
|
|
256
233
|
pubkey,
|
|
257
|
-
this.encodeBip32Derivation(masterFingerprint, path)
|
|
234
|
+
this.encodeBip32Derivation(masterFingerprint, path),
|
|
258
235
|
);
|
|
259
236
|
}
|
|
260
237
|
getOutputBip32Derivation(
|
|
261
238
|
outputIndex: number,
|
|
262
|
-
pubkey: Buffer
|
|
239
|
+
pubkey: Buffer,
|
|
263
240
|
): { masterFingerprint: Buffer; path: number[] } {
|
|
264
241
|
const buf = this.getOutput(outputIndex, psbtOut.BIP_32_DERIVATION, pubkey);
|
|
265
242
|
return this.decodeBip32Derivation(buf);
|
|
@@ -282,20 +259,16 @@ export class PsbtV2 {
|
|
|
282
259
|
pubkey: Buffer,
|
|
283
260
|
hashes: Buffer[],
|
|
284
261
|
fingerprint: Buffer,
|
|
285
|
-
path: number[]
|
|
262
|
+
path: number[],
|
|
286
263
|
) {
|
|
287
264
|
const buf = this.encodeTapBip32Derivation(hashes, fingerprint, path);
|
|
288
265
|
this.setOutput(outputIndex, psbtOut.TAP_BIP32_DERIVATION, pubkey, buf);
|
|
289
266
|
}
|
|
290
267
|
getOutputTapBip32Derivation(
|
|
291
268
|
outputIndex: number,
|
|
292
|
-
pubkey: Buffer
|
|
269
|
+
pubkey: Buffer,
|
|
293
270
|
): { hashes: Buffer[]; masterFingerprint: Buffer; path: number[] } {
|
|
294
|
-
const buf = this.getOutput(
|
|
295
|
-
outputIndex,
|
|
296
|
-
psbtOut.TAP_BIP32_DERIVATION,
|
|
297
|
-
pubkey
|
|
298
|
-
);
|
|
271
|
+
const buf = this.getOutput(outputIndex, psbtOut.TAP_BIP32_DERIVATION, pubkey);
|
|
299
272
|
return this.decodeTapBip32Derivation(buf);
|
|
300
273
|
}
|
|
301
274
|
|
|
@@ -327,10 +300,10 @@ export class PsbtV2 {
|
|
|
327
300
|
const buf = new BufferWriter();
|
|
328
301
|
buf.writeSlice(Buffer.from([0x70, 0x73, 0x62, 0x74, 0xff]));
|
|
329
302
|
serializeMap(buf, this.globalMap);
|
|
330
|
-
this.inputMaps.forEach(
|
|
303
|
+
this.inputMaps.forEach(map => {
|
|
331
304
|
serializeMap(buf, map);
|
|
332
305
|
});
|
|
333
|
-
this.outputMaps.forEach(
|
|
306
|
+
this.outputMaps.forEach(map => {
|
|
334
307
|
serializeMap(buf, map);
|
|
335
308
|
});
|
|
336
309
|
return buf.buffer();
|
|
@@ -372,7 +345,7 @@ export class PsbtV2 {
|
|
|
372
345
|
}
|
|
373
346
|
private isKeyType(hexKey: string, keyTypes: KeyType[]): boolean {
|
|
374
347
|
const keyType = Buffer.from(hexKey.substring(0, 2), "hex").readUInt8(0);
|
|
375
|
-
return keyTypes.some(
|
|
348
|
+
return keyTypes.some(k => k == keyType);
|
|
376
349
|
}
|
|
377
350
|
private setGlobal(keyType: KeyType, value: Buffer) {
|
|
378
351
|
const key = new Key(keyType, Buffer.from([]));
|
|
@@ -384,39 +357,22 @@ export class PsbtV2 {
|
|
|
384
357
|
private getGlobalOptional(keyType: KeyType): Buffer | undefined {
|
|
385
358
|
return get(this.globalMap, keyType, b(), true);
|
|
386
359
|
}
|
|
387
|
-
private setInput(
|
|
388
|
-
index: number,
|
|
389
|
-
keyType: KeyType,
|
|
390
|
-
keyData: Buffer,
|
|
391
|
-
value: Buffer
|
|
392
|
-
) {
|
|
360
|
+
private setInput(index: number, keyType: KeyType, keyData: Buffer, value: Buffer) {
|
|
393
361
|
set(this.getMap(index, this.inputMaps), keyType, keyData, value);
|
|
394
362
|
}
|
|
395
363
|
private getInput(index: number, keyType: KeyType, keyData: Buffer): Buffer {
|
|
396
364
|
return get(this.inputMaps[index], keyType, keyData, false)!;
|
|
397
365
|
}
|
|
398
|
-
private getInputOptional(
|
|
399
|
-
index: number,
|
|
400
|
-
keyType: KeyType,
|
|
401
|
-
keyData: Buffer
|
|
402
|
-
): Buffer | undefined {
|
|
366
|
+
private getInputOptional(index: number, keyType: KeyType, keyData: Buffer): Buffer | undefined {
|
|
403
367
|
return get(this.inputMaps[index], keyType, keyData, true);
|
|
404
368
|
}
|
|
405
|
-
private setOutput(
|
|
406
|
-
index: number,
|
|
407
|
-
keyType: KeyType,
|
|
408
|
-
keyData: Buffer,
|
|
409
|
-
value: Buffer
|
|
410
|
-
) {
|
|
369
|
+
private setOutput(index: number, keyType: KeyType, keyData: Buffer, value: Buffer) {
|
|
411
370
|
set(this.getMap(index, this.outputMaps), keyType, keyData, value);
|
|
412
371
|
}
|
|
413
372
|
private getOutput(index: number, keyType: KeyType, keyData: Buffer): Buffer {
|
|
414
373
|
return get(this.outputMaps[index], keyType, keyData, false)!;
|
|
415
374
|
}
|
|
416
|
-
private getMap(
|
|
417
|
-
index: number,
|
|
418
|
-
maps: Map<string, Buffer>[]
|
|
419
|
-
): Map<string, Buffer> {
|
|
375
|
+
private getMap(index: number, maps: Map<string, Buffer>[]): Map<string, Buffer> {
|
|
420
376
|
if (maps[index]) {
|
|
421
377
|
return maps[index];
|
|
422
378
|
}
|
|
@@ -434,13 +390,9 @@ export class PsbtV2 {
|
|
|
434
390
|
const buf = new BufferReader(buffer);
|
|
435
391
|
return this.readBip32Derivation(buf);
|
|
436
392
|
}
|
|
437
|
-
private writeBip32Derivation(
|
|
438
|
-
buf: BufferWriter,
|
|
439
|
-
masterFingerprint: Buffer,
|
|
440
|
-
path: number[]
|
|
441
|
-
) {
|
|
393
|
+
private writeBip32Derivation(buf: BufferWriter, masterFingerprint: Buffer, path: number[]) {
|
|
442
394
|
buf.writeSlice(masterFingerprint);
|
|
443
|
-
path.forEach(
|
|
395
|
+
path.forEach(element => {
|
|
444
396
|
buf.writeUInt32(element);
|
|
445
397
|
});
|
|
446
398
|
}
|
|
@@ -458,11 +410,11 @@ export class PsbtV2 {
|
|
|
458
410
|
private encodeTapBip32Derivation(
|
|
459
411
|
hashes: Buffer[],
|
|
460
412
|
masterFingerprint: Buffer,
|
|
461
|
-
path: number[]
|
|
413
|
+
path: number[],
|
|
462
414
|
): Buffer {
|
|
463
415
|
const buf = new BufferWriter();
|
|
464
416
|
buf.writeVarInt(hashes.length);
|
|
465
|
-
hashes.forEach(
|
|
417
|
+
hashes.forEach(h => {
|
|
466
418
|
buf.writeSlice(h);
|
|
467
419
|
});
|
|
468
420
|
this.writeBip32Derivation(buf, masterFingerprint, path);
|
|
@@ -487,7 +439,7 @@ function get(
|
|
|
487
439
|
map: Map<string, Buffer>,
|
|
488
440
|
keyType: KeyType,
|
|
489
441
|
keyData: Buffer,
|
|
490
|
-
acceptUndefined: boolean
|
|
442
|
+
acceptUndefined: boolean,
|
|
491
443
|
): Buffer | undefined {
|
|
492
444
|
if (!map) throw Error("No such map");
|
|
493
445
|
const key = new Key(keyType, keyData);
|
|
@@ -551,12 +503,7 @@ function serializeMap(buf: BufferWriter, map: Map<string, Buffer>) {
|
|
|
551
503
|
function b(): Buffer {
|
|
552
504
|
return Buffer.from([]);
|
|
553
505
|
}
|
|
554
|
-
function set(
|
|
555
|
-
map: Map<string, Buffer>,
|
|
556
|
-
keyType: KeyType,
|
|
557
|
-
keyData: Buffer,
|
|
558
|
-
value: Buffer
|
|
559
|
-
) {
|
|
506
|
+
function set(map: Map<string, Buffer>, keyType: KeyType, keyData: Buffer, value: Buffer) {
|
|
560
507
|
const key = new Key(keyType, keyData);
|
|
561
508
|
map.set(key.toString(), value);
|
|
562
509
|
}
|
|
@@ -11,7 +11,7 @@ export function serializeTransactionOutputs({ outputs }: Transaction): Buffer {
|
|
|
11
11
|
|
|
12
12
|
if (typeof outputs !== "undefined") {
|
|
13
13
|
outputBuffer = Buffer.concat([outputBuffer, createVarint(outputs.length)]);
|
|
14
|
-
outputs.forEach(
|
|
14
|
+
outputs.forEach(output => {
|
|
15
15
|
outputBuffer = Buffer.concat([
|
|
16
16
|
outputBuffer,
|
|
17
17
|
output.amount,
|
|
@@ -27,15 +27,14 @@ export function serializeTransaction(
|
|
|
27
27
|
transaction: Transaction,
|
|
28
28
|
skipWitness: boolean,
|
|
29
29
|
timestamp?: Buffer,
|
|
30
|
-
additionals: string[] = []
|
|
30
|
+
additionals: string[] = [],
|
|
31
31
|
) {
|
|
32
32
|
const isDecred = additionals.includes("decred");
|
|
33
33
|
const isZcash = additionals.includes("zcash");
|
|
34
34
|
const isBech32 = additionals.includes("bech32");
|
|
35
35
|
let inputBuffer = Buffer.alloc(0);
|
|
36
|
-
const useWitness =
|
|
37
|
-
|
|
38
|
-
transaction.inputs.forEach((input) => {
|
|
36
|
+
const useWitness = typeof transaction["witness"] != "undefined" && !skipWitness;
|
|
37
|
+
transaction.inputs.forEach(input => {
|
|
39
38
|
inputBuffer =
|
|
40
39
|
isDecred || isBech32
|
|
41
40
|
? Buffer.concat([
|
|
@@ -54,10 +53,7 @@ export function serializeTransaction(
|
|
|
54
53
|
});
|
|
55
54
|
let outputBuffer = serializeTransactionOutputs(transaction);
|
|
56
55
|
|
|
57
|
-
if (
|
|
58
|
-
typeof transaction.outputs !== "undefined" &&
|
|
59
|
-
typeof transaction.locktime !== "undefined"
|
|
60
|
-
) {
|
|
56
|
+
if (typeof transaction.outputs !== "undefined" && typeof transaction.locktime !== "undefined") {
|
|
61
57
|
outputBuffer = Buffer.concat([
|
|
62
58
|
outputBuffer,
|
|
63
59
|
(useWitness && transaction.witness) || Buffer.alloc(0),
|
package/src/signMessage.ts
CHANGED
|
@@ -9,7 +9,7 @@ export async function signMessage(
|
|
|
9
9
|
}: {
|
|
10
10
|
path: string;
|
|
11
11
|
messageHex: string;
|
|
12
|
-
}
|
|
12
|
+
},
|
|
13
13
|
): Promise<{
|
|
14
14
|
v: number;
|
|
15
15
|
r: string;
|
|
@@ -21,16 +21,10 @@ export async function signMessage(
|
|
|
21
21
|
|
|
22
22
|
while (offset !== message.length) {
|
|
23
23
|
const maxChunkSize =
|
|
24
|
-
offset === 0
|
|
25
|
-
? MAX_SCRIPT_BLOCK - 1 - paths.length * 4 - 4
|
|
26
|
-
: MAX_SCRIPT_BLOCK;
|
|
24
|
+
offset === 0 ? MAX_SCRIPT_BLOCK - 1 - paths.length * 4 - 4 : MAX_SCRIPT_BLOCK;
|
|
27
25
|
const chunkSize =
|
|
28
|
-
offset + maxChunkSize > message.length
|
|
29
|
-
|
|
30
|
-
: maxChunkSize;
|
|
31
|
-
const buffer = Buffer.alloc(
|
|
32
|
-
offset === 0 ? 1 + paths.length * 4 + 2 + chunkSize : chunkSize
|
|
33
|
-
);
|
|
26
|
+
offset + maxChunkSize > message.length ? message.length - offset : maxChunkSize;
|
|
27
|
+
const buffer = Buffer.alloc(offset === 0 ? 1 + paths.length * 4 + 2 + chunkSize : chunkSize);
|
|
34
28
|
|
|
35
29
|
if (offset === 0) {
|
|
36
30
|
buffer[0] = paths.length;
|
|
@@ -38,12 +32,7 @@ export async function signMessage(
|
|
|
38
32
|
buffer.writeUInt32BE(element, 1 + 4 * index);
|
|
39
33
|
});
|
|
40
34
|
buffer.writeUInt16BE(message.length, 1 + 4 * paths.length);
|
|
41
|
-
message.copy(
|
|
42
|
-
buffer,
|
|
43
|
-
1 + 4 * paths.length + 2,
|
|
44
|
-
offset,
|
|
45
|
-
offset + chunkSize
|
|
46
|
-
);
|
|
35
|
+
message.copy(buffer, 1 + 4 * paths.length + 2, offset, offset + chunkSize);
|
|
47
36
|
} else {
|
|
48
37
|
message.copy(buffer, 0, offset, offset + chunkSize);
|
|
49
38
|
}
|
|
@@ -5,12 +5,7 @@ import { getTrustedInputBIP143 } from "./getTrustedInputBIP143";
|
|
|
5
5
|
import { signTransaction } from "./signTransaction";
|
|
6
6
|
import { hashOutputFull } from "./finalizeInput";
|
|
7
7
|
import type { TransactionOutput, Transaction, TrustedInput } from "./types";
|
|
8
|
-
import {
|
|
9
|
-
DEFAULT_LOCKTIME,
|
|
10
|
-
DEFAULT_VERSION,
|
|
11
|
-
DEFAULT_SEQUENCE,
|
|
12
|
-
SIGHASH_ALL,
|
|
13
|
-
} from "./constants";
|
|
8
|
+
import { DEFAULT_LOCKTIME, DEFAULT_VERSION, DEFAULT_SEQUENCE, SIGHASH_ALL } from "./constants";
|
|
14
9
|
const defaultArg = {
|
|
15
10
|
lockTime: DEFAULT_LOCKTIME,
|
|
16
11
|
sigHashType: SIGHASH_ALL,
|
|
@@ -22,9 +17,7 @@ const defaultArg = {
|
|
|
22
17
|
*
|
|
23
18
|
*/
|
|
24
19
|
export type SignP2SHTransactionArg = {
|
|
25
|
-
inputs: Array<
|
|
26
|
-
[Transaction, number, string | null | undefined, number | null | undefined]
|
|
27
|
-
>;
|
|
20
|
+
inputs: Array<[Transaction, number, string | null | undefined, number | null | undefined]>;
|
|
28
21
|
associatedKeysets: string[];
|
|
29
22
|
outputScriptHex: string;
|
|
30
23
|
lockTime?: number;
|
|
@@ -32,10 +25,7 @@ export type SignP2SHTransactionArg = {
|
|
|
32
25
|
segwit?: boolean;
|
|
33
26
|
transactionVersion?: number;
|
|
34
27
|
};
|
|
35
|
-
export async function signP2SHTransaction(
|
|
36
|
-
transport: Transport,
|
|
37
|
-
arg: SignP2SHTransactionArg
|
|
38
|
-
) {
|
|
28
|
+
export async function signP2SHTransaction(transport: Transport, arg: SignP2SHTransactionArg) {
|
|
39
29
|
const {
|
|
40
30
|
inputs,
|
|
41
31
|
associatedKeysets,
|
|
@@ -65,17 +55,11 @@ export async function signP2SHTransaction(
|
|
|
65
55
|
|
|
66
56
|
for (const input of inputs) {
|
|
67
57
|
if (!resuming) {
|
|
68
|
-
const trustedInput = await getTrustedInputCall(
|
|
69
|
-
transport,
|
|
70
|
-
input[1],
|
|
71
|
-
input[0]
|
|
72
|
-
);
|
|
58
|
+
const trustedInput = await getTrustedInputCall(transport, input[1], input[0]);
|
|
73
59
|
const sequence = Buffer.alloc(4);
|
|
74
60
|
sequence.writeUInt32LE(
|
|
75
|
-
input.length >= 4 && typeof input[3] === "number"
|
|
76
|
-
|
|
77
|
-
: DEFAULT_SEQUENCE,
|
|
78
|
-
0
|
|
61
|
+
input.length >= 4 && typeof input[3] === "number" ? input[3] : DEFAULT_SEQUENCE,
|
|
62
|
+
0,
|
|
79
63
|
);
|
|
80
64
|
trustedInputs.push({
|
|
81
65
|
trustedInput: false,
|
|
@@ -101,7 +85,7 @@ export async function signP2SHTransaction(
|
|
|
101
85
|
inputs[i].length >= 4 && typeof inputs[i][3] === "number"
|
|
102
86
|
? (inputs[i][3] as number)
|
|
103
87
|
: DEFAULT_SEQUENCE,
|
|
104
|
-
0
|
|
88
|
+
0,
|
|
105
89
|
);
|
|
106
90
|
targetTransaction.inputs.push({
|
|
107
91
|
script: nullScript,
|
|
@@ -116,7 +100,7 @@ export async function signP2SHTransaction(
|
|
|
116
100
|
true,
|
|
117
101
|
targetTransaction,
|
|
118
102
|
trustedInputs,
|
|
119
|
-
true
|
|
103
|
+
true,
|
|
120
104
|
);
|
|
121
105
|
await hashOutputFull(transport, outputScript);
|
|
122
106
|
}
|
|
@@ -141,23 +125,16 @@ export async function signP2SHTransaction(
|
|
|
141
125
|
!segwit && firstRun,
|
|
142
126
|
pseudoTX,
|
|
143
127
|
pseudoTrustedInputs,
|
|
144
|
-
segwit
|
|
128
|
+
segwit,
|
|
145
129
|
);
|
|
146
130
|
|
|
147
131
|
if (!segwit) {
|
|
148
132
|
await hashOutputFull(transport, outputScript);
|
|
149
133
|
}
|
|
150
134
|
|
|
151
|
-
const signature = await signTransaction(
|
|
152
|
-
transport,
|
|
153
|
-
associatedKeysets[i],
|
|
154
|
-
lockTime,
|
|
155
|
-
sigHashType
|
|
156
|
-
);
|
|
135
|
+
const signature = await signTransaction(transport, associatedKeysets[i], lockTime, sigHashType);
|
|
157
136
|
signatures.push(
|
|
158
|
-
segwit
|
|
159
|
-
? signature.toString("hex")
|
|
160
|
-
: signature.slice(0, signature.length - 1).toString("hex")
|
|
137
|
+
segwit ? signature.toString("hex") : signature.slice(0, signature.length - 1).toString("hex"),
|
|
161
138
|
);
|
|
162
139
|
targetTransaction.inputs[i].script = nullScript;
|
|
163
140
|
|
package/src/signTransaction.ts
CHANGED
|
@@ -6,7 +6,7 @@ export function signTransaction(
|
|
|
6
6
|
lockTime: number,
|
|
7
7
|
sigHashType: number,
|
|
8
8
|
expiryHeight?: Buffer,
|
|
9
|
-
additionals: Array<string> = []
|
|
9
|
+
additionals: Array<string> = [],
|
|
10
10
|
): Promise<Buffer> {
|
|
11
11
|
const isDecred = additionals.includes("decred");
|
|
12
12
|
const pathsBuffer = bip32asBuffer(path);
|
|
@@ -19,18 +19,13 @@ export function signTransaction(
|
|
|
19
19
|
expiryHeight || Buffer.from([0x00, 0x00, 0x00, 0x00]),
|
|
20
20
|
Buffer.from([sigHashType]),
|
|
21
21
|
])
|
|
22
|
-
: Buffer.concat([
|
|
23
|
-
pathsBuffer,
|
|
24
|
-
Buffer.from([0x00]),
|
|
25
|
-
lockTimeBuffer,
|
|
26
|
-
Buffer.from([sigHashType]),
|
|
27
|
-
]);
|
|
22
|
+
: Buffer.concat([pathsBuffer, Buffer.from([0x00]), lockTimeBuffer, Buffer.from([sigHashType])]);
|
|
28
23
|
|
|
29
24
|
if (expiryHeight && !isDecred) {
|
|
30
25
|
buffer = Buffer.concat([buffer, expiryHeight]);
|
|
31
26
|
}
|
|
32
27
|
|
|
33
|
-
return transport.send(0xe0, 0x48, 0x00, 0x00, buffer).then(
|
|
28
|
+
return transport.send(0xe0, 0x48, 0x00, 0x00, buffer).then(result => {
|
|
34
29
|
if (result.length > 0) {
|
|
35
30
|
result[0] = 0x30;
|
|
36
31
|
return result.slice(0, result.length - 2);
|
package/src/splitTransaction.ts
CHANGED
|
@@ -7,7 +7,7 @@ export function splitTransaction(
|
|
|
7
7
|
isSegwitSupported: boolean | null | undefined = false,
|
|
8
8
|
hasTimestamp = false,
|
|
9
9
|
hasExtraData = false,
|
|
10
|
-
additionals: Array<string> = []
|
|
10
|
+
additionals: Array<string> = [],
|
|
11
11
|
): Transaction {
|
|
12
12
|
const inputs: TransactionInput[] = [];
|
|
13
13
|
const outputs: TransactionOutput[] = [];
|
|
@@ -27,8 +27,7 @@ export function splitTransaction(
|
|
|
27
27
|
version.equals(Buffer.from([0x03, 0x00, 0x00, 0x80])) ||
|
|
28
28
|
version.equals(Buffer.from([0x04, 0x00, 0x00, 0x80])) ||
|
|
29
29
|
version.equals(Buffer.from([0x05, 0x00, 0x00, 0x80]));
|
|
30
|
-
const isZcashv5 =
|
|
31
|
-
isZcash && version.equals(Buffer.from([0x05, 0x00, 0x00, 0x80]));
|
|
30
|
+
const isZcashv5 = isZcash && version.equals(Buffer.from([0x05, 0x00, 0x00, 0x80]));
|
|
32
31
|
offset += 4;
|
|
33
32
|
if (
|
|
34
33
|
!hasTimestamp &&
|
|
@@ -162,9 +161,6 @@ export function splitTransaction(
|
|
|
162
161
|
nExpiryHeight,
|
|
163
162
|
extraData,
|
|
164
163
|
};
|
|
165
|
-
log(
|
|
166
|
-
"btc",
|
|
167
|
-
`splitTransaction ${transactionHex}:\n${formatTransactionDebug(t)}`
|
|
168
|
-
);
|
|
164
|
+
log("btc", `splitTransaction ${transactionHex}:\n${formatTransactionDebug(t)}`);
|
|
169
165
|
return t;
|
|
170
166
|
}
|
|
@@ -9,7 +9,7 @@ export function startUntrustedHashTransactionInputRaw(
|
|
|
9
9
|
transactionData: Buffer,
|
|
10
10
|
bip143 = false,
|
|
11
11
|
overwinter = false,
|
|
12
|
-
additionals: Array<string> = []
|
|
12
|
+
additionals: Array<string> = [],
|
|
13
13
|
): Promise<Buffer> {
|
|
14
14
|
const p2 = additionals.includes("cashaddr")
|
|
15
15
|
? 0x03
|
|
@@ -25,7 +25,7 @@ export function startUntrustedHashTransactionInputRaw(
|
|
|
25
25
|
0x44,
|
|
26
26
|
firstRound ? 0x00 : 0x80,
|
|
27
27
|
newTransaction ? p2 : 0x80,
|
|
28
|
-
transactionData
|
|
28
|
+
transactionData,
|
|
29
29
|
);
|
|
30
30
|
}
|
|
31
31
|
export async function startUntrustedHashTransactionInput(
|
|
@@ -39,7 +39,7 @@ export async function startUntrustedHashTransactionInput(
|
|
|
39
39
|
bip143 = false,
|
|
40
40
|
overwinter = false,
|
|
41
41
|
additionals: Array<string> = [],
|
|
42
|
-
useTrustedInputForSegwit = false
|
|
42
|
+
useTrustedInputForSegwit = false,
|
|
43
43
|
): Promise<any> {
|
|
44
44
|
let data = Buffer.concat([
|
|
45
45
|
transaction.version,
|
|
@@ -54,7 +54,7 @@ export async function startUntrustedHashTransactionInput(
|
|
|
54
54
|
data,
|
|
55
55
|
bip143,
|
|
56
56
|
overwinter,
|
|
57
|
-
additionals
|
|
57
|
+
additionals,
|
|
58
58
|
);
|
|
59
59
|
let i = 0;
|
|
60
60
|
const isDecred = additionals.includes("decred");
|
|
@@ -90,7 +90,7 @@ export async function startUntrustedHashTransactionInput(
|
|
|
90
90
|
data,
|
|
91
91
|
bip143,
|
|
92
92
|
overwinter,
|
|
93
|
-
additionals
|
|
93
|
+
additionals,
|
|
94
94
|
);
|
|
95
95
|
const scriptBlocks: Buffer[] = [];
|
|
96
96
|
let offset = 0;
|
|
@@ -108,10 +108,7 @@ export async function startUntrustedHashTransactionInput(
|
|
|
108
108
|
scriptBlocks.push(input.script.slice(offset, offset + blockSize));
|
|
109
109
|
} else {
|
|
110
110
|
scriptBlocks.push(
|
|
111
|
-
Buffer.concat([
|
|
112
|
-
input.script.slice(offset, offset + blockSize),
|
|
113
|
-
input.sequence,
|
|
114
|
-
])
|
|
111
|
+
Buffer.concat([input.script.slice(offset, offset + blockSize), input.sequence]),
|
|
115
112
|
);
|
|
116
113
|
}
|
|
117
114
|
|
|
@@ -127,7 +124,7 @@ export async function startUntrustedHashTransactionInput(
|
|
|
127
124
|
scriptBlock,
|
|
128
125
|
bip143,
|
|
129
126
|
overwinter,
|
|
130
|
-
additionals
|
|
127
|
+
additionals,
|
|
131
128
|
);
|
|
132
129
|
}
|
|
133
130
|
|