@btc-vision/bitcoin 6.3.5 → 6.4.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.
Files changed (72) hide show
  1. package/.mocharc.json +13 -0
  2. package/browser/address.d.ts +1 -1
  3. package/browser/index.js +1 -1
  4. package/browser/index.js.LICENSE.txt +3 -3
  5. package/browser/networks.d.ts +1 -0
  6. package/browser/psbt/psbtutils.d.ts +1 -1
  7. package/build/address.d.ts +1 -1
  8. package/build/address.js +12 -5
  9. package/build/block.js +2 -2
  10. package/build/bufferutils.js +5 -5
  11. package/build/networks.d.ts +1 -0
  12. package/build/networks.js +11 -0
  13. package/build/psbt/psbtutils.js +2 -2
  14. package/build/psbt.js +3 -7
  15. package/package.json +26 -26
  16. package/src/address.ts +20 -6
  17. package/src/block.ts +233 -233
  18. package/src/bufferutils.ts +188 -180
  19. package/src/index.ts +86 -86
  20. package/src/networks.ts +12 -0
  21. package/src/psbt/bip371.ts +441 -441
  22. package/src/psbt/psbtutils.ts +4 -3
  23. package/src/psbt.ts +2187 -2187
  24. package/test/address.spec.ts +155 -177
  25. package/test/bitcoin.core.spec.ts +212 -234
  26. package/test/block.spec.ts +171 -194
  27. package/test/bufferutils.spec.ts +450 -513
  28. package/test/crypto.spec.ts +49 -55
  29. package/test/fixtures/address.json +3 -3
  30. package/test/integration/addresses.spec.ts +142 -154
  31. package/test/integration/bip32.spec.ts +130 -151
  32. package/test/integration/blocks.spec.ts +28 -28
  33. package/test/integration/cltv.spec.ts +241 -283
  34. package/test/integration/csv.spec.ts +452 -527
  35. package/test/integration/payments.spec.ts +110 -135
  36. package/test/integration/taproot.spec.ts +663 -707
  37. package/test/integration/transactions.spec.ts +668 -769
  38. package/test/payments.spec.ts +114 -125
  39. package/test/payments.utils.ts +165 -208
  40. package/test/psbt.spec.ts +1285 -1414
  41. package/test/script.spec.ts +186 -210
  42. package/test/script_number.spec.ts +26 -29
  43. package/test/script_signature.spec.ts +66 -66
  44. package/test/transaction.spec.ts +337 -387
  45. package/test/ts-node-register.js +7 -5
  46. package/test/tsconfig.json +4 -1
  47. package/test/types.spec.ts +53 -58
  48. package/.nyc_output/6368a5b2-daa5-4821-8ed0-b742d6fc7eab.json +0 -1
  49. package/.nyc_output/processinfo/6368a5b2-daa5-4821-8ed0-b742d6fc7eab.json +0 -1
  50. package/.nyc_output/processinfo/index.json +0 -1
  51. package/test/address.spec.js +0 -124
  52. package/test/bitcoin.core.spec.js +0 -170
  53. package/test/block.spec.js +0 -141
  54. package/test/bufferutils.spec.js +0 -427
  55. package/test/crypto.spec.js +0 -41
  56. package/test/integration/_regtest.js +0 -7
  57. package/test/integration/addresses.spec.js +0 -116
  58. package/test/integration/bip32.spec.js +0 -85
  59. package/test/integration/blocks.spec.js +0 -26
  60. package/test/integration/cltv.spec.js +0 -199
  61. package/test/integration/csv.spec.js +0 -362
  62. package/test/integration/payments.spec.js +0 -98
  63. package/test/integration/taproot.spec.js +0 -532
  64. package/test/integration/transactions.spec.js +0 -561
  65. package/test/payments.spec.js +0 -97
  66. package/test/payments.utils.js +0 -190
  67. package/test/psbt.spec.js +0 -1044
  68. package/test/script.spec.js +0 -151
  69. package/test/script_number.spec.js +0 -24
  70. package/test/script_signature.spec.js +0 -52
  71. package/test/transaction.spec.js +0 -269
  72. package/test/types.spec.js +0 -46
@@ -1,561 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const assert = require("assert");
4
- const bip32_1 = require("bip32");
5
- const ecc = require("tiny-secp256k1");
6
- const ecpair_1 = require("ecpair");
7
- const mocha_1 = require("mocha");
8
- const bitcoin = require("../..");
9
- const _regtest_1 = require("./_regtest");
10
- const ECPair = (0, ecpair_1.default)(ecc);
11
- const rng = require('randombytes');
12
- const regtest = _regtest_1.regtestUtils.network;
13
- const bip32 = (0, bip32_1.default)(ecc);
14
- const validator = (pubkey, msghash, signature) => ECPair.fromPublicKey(pubkey).verify(msghash, signature);
15
- // See bottom of file for some helper functions used to make the payment objects needed.
16
- (0, mocha_1.describe)('bitcoinjs-lib (transactions with psbt)', () => {
17
- (0, mocha_1.it)('can create a 1-to-1 Transaction', () => {
18
- const alice = ECPair.fromWIF('L2uPYXe17xSTqbCjZvL2DsyXPCbXspvcu5mHLDYUgzdUbZGSKrSr');
19
- const psbt = new bitcoin.Psbt();
20
- psbt.setVersion(2); // These are defaults. This line is not needed.
21
- psbt.setLocktime(0); // These are defaults. This line is not needed.
22
- psbt.addInput({
23
- // if hash is string, txid, if hash is Buffer, is reversed compared to txid
24
- hash: '7d067b4a697a09d2c3cff7d4d9506c9955e93bff41bf82d439da7d030382bc3e',
25
- index: 0,
26
- sequence: 0xffffffff,
27
- // non-segwit inputs now require passing the whole previous tx as Buffer
28
- nonWitnessUtxo: Buffer.from('0200000001f9f34e95b9d5c8abcd20fc5bd4a825d1517be62f0f775e5f36da944d9' +
29
- '452e550000000006b483045022100c86e9a111afc90f64b4904bd609e9eaed80d48' +
30
- 'ca17c162b1aca0a788ac3526f002207bb79b60d4fc6526329bf18a77135dc566020' +
31
- '9e761da46e1c2f1152ec013215801210211755115eabf846720f5cb18f248666fec' +
32
- '631e5e1e66009ce3710ceea5b1ad13ffffffff01' +
33
- // value in satoshis (Int64LE) = 0x015f90 = 90000
34
- '905f010000000000' +
35
- // scriptPubkey length
36
- '19' +
37
- // scriptPubkey
38
- '76a9148bbc95d2709c71607c60ee3f097c1217482f518d88ac' +
39
- // locktime
40
- '00000000', 'hex'),
41
- // // If this input was segwit, instead of nonWitnessUtxo, you would add
42
- // // a witnessUtxo as follows. The scriptPubkey and the value only are needed.
43
- // witnessUtxo: {
44
- // script: Buffer.from(
45
- // '76a9148bbc95d2709c71607c60ee3f097c1217482f518d88ac',
46
- // 'hex',
47
- // ),
48
- // value: 90000,
49
- // },
50
- // Not featured here:
51
- // redeemScript. A Buffer of the redeemScript for P2SH
52
- // witnessScript. A Buffer of the witnessScript for P2WSH
53
- });
54
- psbt.addOutput({
55
- address: '1KRMKfeZcmosxALVYESdPNez1AP1mEtywp',
56
- value: 80000,
57
- });
58
- psbt.signInput(0, alice);
59
- psbt.validateSignaturesOfInput(0, validator);
60
- psbt.finalizeAllInputs();
61
- assert.strictEqual(psbt.extractTransaction().toHex(), '02000000013ebc8203037dda39d482bf41ff3be955996c50d9d4f7cfc3d2097a694a7' +
62
- 'b067d000000006b483045022100931b6db94aed25d5486884d83fc37160f37f3368c0' +
63
- 'd7f48c757112abefec983802205fda64cff98c849577026eb2ce916a50ea70626a766' +
64
- '9f8596dd89b720a26b4d501210365db9da3f8a260078a7e8f8b708a1161468fb2323f' +
65
- 'fda5ec16b261ec1056f455ffffffff0180380100000000001976a914ca0d36044e0dc' +
66
- '08a22724efa6f6a07b0ec4c79aa88ac00000000');
67
- });
68
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a typical Transaction', async () => {
69
- // these are { payment: Payment; keys: ECPair[] }
70
- const alice1 = createPayment('p2pkh');
71
- const alice2 = createPayment('p2pkh');
72
- // give Alice 2 unspent outputs
73
- const inputData1 = await getInputData(5e4, alice1.payment, false, 'noredeem');
74
- const inputData2 = await getInputData(7e4, alice2.payment, false, 'noredeem');
75
- {
76
- const { hash, // string of txid or Buffer of tx hash. (txid and hash are reverse order)
77
- index, // the output index of the txo you are spending
78
- nonWitnessUtxo, // the full previous transaction as a Buffer
79
- } = inputData1;
80
- assert.deepStrictEqual({ hash, index, nonWitnessUtxo }, inputData1);
81
- }
82
- // network is only needed if you pass an address to addOutput
83
- // using script (Buffer of scriptPubkey) instead will avoid needed network.
84
- const psbt = new bitcoin.Psbt({ network: regtest })
85
- .addInput(inputData1) // alice1 unspent
86
- .addInput(inputData2) // alice2 unspent
87
- .addOutput({
88
- address: 'mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf',
89
- value: 8e4,
90
- }) // the actual "spend"
91
- .addOutput({
92
- address: alice2.payment.address,
93
- value: 1e4,
94
- }); // Alice's change
95
- // (in)(5e4 + 7e4) - (out)(8e4 + 1e4) = (fee)3e4 = 30000, this is the miner fee
96
- // Let's show a new feature with PSBT.
97
- // We can have multiple signers sign in parallel and combine them.
98
- // (this is not necessary, but a nice feature)
99
- // encode to send out to the signers
100
- const psbtBaseText = psbt.toBase64();
101
- // each signer imports
102
- const signer1 = bitcoin.Psbt.fromBase64(psbtBaseText);
103
- const signer2 = bitcoin.Psbt.fromBase64(psbtBaseText);
104
- // Alice signs each input with the respective private keys
105
- // signInput and signInputAsync are better
106
- // (They take the input index explicitly as the first arg)
107
- signer1.signAllInputs(alice1.keys[0]);
108
- signer2.signAllInputs(alice2.keys[0]);
109
- // If your signer object's sign method returns a promise, use the following
110
- // await signer2.signAllInputsAsync(alice2.keys[0])
111
- // encode to send back to combiner (signer 1 and 2 are not near each other)
112
- const s1text = signer1.toBase64();
113
- const s2text = signer2.toBase64();
114
- const final1 = bitcoin.Psbt.fromBase64(s1text);
115
- const final2 = bitcoin.Psbt.fromBase64(s2text);
116
- // final1.combine(final2) would give the exact same result
117
- psbt.combine(final1, final2);
118
- // Finalizer wants to check all signatures are valid before finalizing.
119
- // If the finalizer wants to check for specific pubkeys, the second arg
120
- // can be passed. See the first multisig example below.
121
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator), true);
122
- assert.strictEqual(psbt.validateSignaturesOfInput(1, validator), true);
123
- // This step it new. Since we separate the signing operation and
124
- // the creation of the scriptSig and witness stack, we are able to
125
- psbt.finalizeAllInputs();
126
- // build and broadcast our RegTest network
127
- await _regtest_1.regtestUtils.broadcast(psbt.extractTransaction().toHex());
128
- // to build and broadcast to the actual Bitcoin network, see https://github.com/bitcoinjs/bitcoinjs-lib/issues/839
129
- });
130
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction with an OP_RETURN output', async () => {
131
- const alice1 = createPayment('p2pkh');
132
- const inputData1 = await getInputData(2e5, alice1.payment, false, 'noredeem');
133
- const data = Buffer.from('bitcoinjs-lib', 'utf8');
134
- const embed = bitcoin.payments.embed({ data: [data] });
135
- const psbt = new bitcoin.Psbt({ network: regtest })
136
- .addInput(inputData1)
137
- .addOutput({
138
- script: embed.output,
139
- value: 1000,
140
- })
141
- .addOutput({
142
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
143
- value: 1e5,
144
- })
145
- .signInput(0, alice1.keys[0]);
146
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator), true);
147
- psbt.finalizeAllInputs();
148
- // build and broadcast to the RegTest network
149
- await _regtest_1.regtestUtils.broadcast(psbt.extractTransaction().toHex());
150
- });
151
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2MS(2 of 4)) (multisig) input', async () => {
152
- const multisig = createPayment('p2sh-p2ms(2 of 4)');
153
- const inputData1 = await getInputData(2e4, multisig.payment, false, 'p2sh');
154
- {
155
- const { hash, index, nonWitnessUtxo, redeemScript, // NEW: P2SH needs to give redeemScript when adding an input.
156
- } = inputData1;
157
- assert.deepStrictEqual({ hash, index, nonWitnessUtxo, redeemScript }, inputData1);
158
- }
159
- const psbt = new bitcoin.Psbt({ network: regtest })
160
- .addInput(inputData1)
161
- .addOutput({
162
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
163
- value: 1e4,
164
- })
165
- .signInput(0, multisig.keys[0])
166
- .signInput(0, multisig.keys[2]);
167
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator), true);
168
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator, multisig.keys[0].publicKey), true);
169
- assert.throws(() => {
170
- psbt.validateSignaturesOfInput(0, validator, multisig.keys[3].publicKey);
171
- }, new RegExp('No signatures for this pubkey'));
172
- psbt.finalizeAllInputs();
173
- const tx = psbt.extractTransaction();
174
- // build and broadcast to the Bitcoin RegTest network
175
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
176
- await _regtest_1.regtestUtils.verify({
177
- txId: tx.getId(),
178
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
179
- vout: 0,
180
- value: 1e4,
181
- });
182
- });
183
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WPKH) input', async () => {
184
- const p2sh = createPayment('p2sh-p2wpkh');
185
- const inputData = await getInputData(5e4, p2sh.payment, true, 'p2sh');
186
- const inputData2 = await getInputData(5e4, p2sh.payment, true, 'p2sh');
187
- {
188
- const { hash, index, witnessUtxo, // NEW: this is an object of the output being spent { script: Buffer; value: Satoshis; }
189
- redeemScript, } = inputData;
190
- assert.deepStrictEqual({ hash, index, witnessUtxo, redeemScript }, inputData);
191
- }
192
- const keyPair = p2sh.keys[0];
193
- const outputData = {
194
- script: p2sh.payment.output,
195
- value: 2e4,
196
- };
197
- const outputData2 = {
198
- script: p2sh.payment.output,
199
- value: 7e4,
200
- };
201
- const tx = new bitcoin.Psbt()
202
- .addInputs([inputData, inputData2])
203
- .addOutputs([outputData, outputData2])
204
- .signAllInputs(keyPair)
205
- .finalizeAllInputs()
206
- .extractTransaction();
207
- // build and broadcast to the Bitcoin RegTest network
208
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
209
- await _regtest_1.regtestUtils.verify({
210
- txId: tx.getId(),
211
- address: p2sh.payment.address,
212
- vout: 0,
213
- value: 2e4,
214
- });
215
- });
216
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WPKH) input with nonWitnessUtxo', async () => {
217
- // For learning purposes, ignore this test.
218
- // REPEATING ABOVE BUT WITH nonWitnessUtxo by passing false to getInputData
219
- const p2sh = createPayment('p2sh-p2wpkh');
220
- const inputData = await getInputData(5e4, p2sh.payment, false, 'p2sh');
221
- const inputData2 = await getInputData(5e4, p2sh.payment, false, 'p2sh');
222
- const keyPair = p2sh.keys[0];
223
- const outputData = {
224
- script: p2sh.payment.output,
225
- value: 2e4,
226
- };
227
- const outputData2 = {
228
- script: p2sh.payment.output,
229
- value: 7e4,
230
- };
231
- const tx = new bitcoin.Psbt()
232
- .addInputs([inputData, inputData2])
233
- .addOutputs([outputData, outputData2])
234
- .signAllInputs(keyPair)
235
- .finalizeAllInputs()
236
- .extractTransaction();
237
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
238
- await _regtest_1.regtestUtils.verify({
239
- txId: tx.getId(),
240
- address: p2sh.payment.address,
241
- vout: 0,
242
- value: 2e4,
243
- });
244
- });
245
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input', async () => {
246
- // the only thing that changes is you don't give a redeemscript for input data
247
- const p2wpkh = createPayment('p2wpkh');
248
- const inputData = await getInputData(5e4, p2wpkh.payment, true, 'noredeem');
249
- {
250
- const { hash, index, witnessUtxo } = inputData;
251
- assert.deepStrictEqual({ hash, index, witnessUtxo }, inputData);
252
- }
253
- const psbt = new bitcoin.Psbt({ network: regtest })
254
- .addInput(inputData)
255
- .addOutput({
256
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
257
- value: 2e4,
258
- })
259
- .signInput(0, p2wpkh.keys[0]);
260
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator), true);
261
- psbt.finalizeAllInputs();
262
- const tx = psbt.extractTransaction();
263
- // build and broadcast to the Bitcoin RegTest network
264
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
265
- await _regtest_1.regtestUtils.verify({
266
- txId: tx.getId(),
267
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
268
- vout: 0,
269
- value: 2e4,
270
- });
271
- });
272
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input with nonWitnessUtxo', async () => {
273
- // For learning purposes, ignore this test.
274
- // REPEATING ABOVE BUT WITH nonWitnessUtxo by passing false to getInputData
275
- const p2wpkh = createPayment('p2wpkh');
276
- const inputData = await getInputData(5e4, p2wpkh.payment, false, 'noredeem');
277
- const psbt = new bitcoin.Psbt({ network: regtest })
278
- .addInput(inputData)
279
- .addOutput({
280
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
281
- value: 2e4,
282
- })
283
- .signInput(0, p2wpkh.keys[0]);
284
- psbt.finalizeAllInputs();
285
- const tx = psbt.extractTransaction();
286
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
287
- await _regtest_1.regtestUtils.verify({
288
- txId: tx.getId(),
289
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
290
- vout: 0,
291
- value: 2e4,
292
- });
293
- });
294
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a P2WSH(P2PK) input', async () => {
295
- const p2wsh = createPayment('p2wsh-p2pk');
296
- const inputData = await getInputData(5e4, p2wsh.payment, true, 'p2wsh');
297
- {
298
- const { hash, index, witnessUtxo, witnessScript, // NEW: A Buffer of the witnessScript
299
- } = inputData;
300
- assert.deepStrictEqual({ hash, index, witnessUtxo, witnessScript }, inputData);
301
- }
302
- const psbt = new bitcoin.Psbt({ network: regtest })
303
- .addInput(inputData)
304
- .addOutput({
305
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
306
- value: 2e4,
307
- })
308
- .signInput(0, p2wsh.keys[0]);
309
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator), true);
310
- psbt.finalizeAllInputs();
311
- const tx = psbt.extractTransaction();
312
- // build and broadcast to the Bitcoin RegTest network
313
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
314
- await _regtest_1.regtestUtils.verify({
315
- txId: tx.getId(),
316
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
317
- vout: 0,
318
- value: 2e4,
319
- });
320
- });
321
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a P2WSH(P2PK) input with nonWitnessUtxo', async () => {
322
- // For learning purposes, ignore this test.
323
- // REPEATING ABOVE BUT WITH nonWitnessUtxo by passing false to getInputData
324
- const p2wsh = createPayment('p2wsh-p2pk');
325
- const inputData = await getInputData(5e4, p2wsh.payment, false, 'p2wsh');
326
- const psbt = new bitcoin.Psbt({ network: regtest })
327
- .addInput(inputData)
328
- .addOutput({
329
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
330
- value: 2e4,
331
- })
332
- .signInput(0, p2wsh.keys[0]);
333
- psbt.finalizeAllInputs();
334
- const tx = psbt.extractTransaction();
335
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
336
- await _regtest_1.regtestUtils.verify({
337
- txId: tx.getId(),
338
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
339
- vout: 0,
340
- value: 2e4,
341
- });
342
- });
343
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a ' +
344
- 'P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input', async () => {
345
- const p2sh = createPayment('p2sh-p2wsh-p2ms(3 of 4)');
346
- const inputData = await getInputData(5e4, p2sh.payment, true, 'p2sh-p2wsh');
347
- {
348
- const { hash, index, witnessUtxo, redeemScript, witnessScript, } = inputData;
349
- assert.deepStrictEqual({ hash, index, witnessUtxo, redeemScript, witnessScript }, inputData);
350
- }
351
- const psbt = new bitcoin.Psbt({ network: regtest })
352
- .addInput(inputData)
353
- .addOutput({
354
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
355
- value: 2e4,
356
- })
357
- .signInput(0, p2sh.keys[0])
358
- .signInput(0, p2sh.keys[2])
359
- .signInput(0, p2sh.keys[3]);
360
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator), true);
361
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator, p2sh.keys[3].publicKey), true);
362
- assert.throws(() => {
363
- psbt.validateSignaturesOfInput(0, validator, p2sh.keys[1].publicKey);
364
- }, new RegExp('No signatures for this pubkey'));
365
- psbt.finalizeAllInputs();
366
- const tx = psbt.extractTransaction();
367
- // build and broadcast to the Bitcoin RegTest network
368
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
369
- await _regtest_1.regtestUtils.verify({
370
- txId: tx.getId(),
371
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
372
- vout: 0,
373
- value: 2e4,
374
- });
375
- });
376
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a ' +
377
- 'P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input with nonWitnessUtxo', async () => {
378
- // For learning purposes, ignore this test.
379
- // REPEATING ABOVE BUT WITH nonWitnessUtxo by passing false to getInputData
380
- const p2sh = createPayment('p2sh-p2wsh-p2ms(3 of 4)');
381
- const inputData = await getInputData(5e4, p2sh.payment, false, 'p2sh-p2wsh');
382
- const psbt = new bitcoin.Psbt({ network: regtest })
383
- .addInput(inputData)
384
- .addOutput({
385
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
386
- value: 2e4,
387
- })
388
- .signInput(0, p2sh.keys[0])
389
- .signInput(0, p2sh.keys[2])
390
- .signInput(0, p2sh.keys[3]);
391
- psbt.finalizeAllInputs();
392
- const tx = psbt.extractTransaction();
393
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
394
- await _regtest_1.regtestUtils.verify({
395
- txId: tx.getId(),
396
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
397
- vout: 0,
398
- value: 2e4,
399
- });
400
- });
401
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a ' +
402
- 'P2SH(P2MS(2 of 2)) input with nonWitnessUtxo', async () => {
403
- const myKey = ECPair.makeRandom({ network: regtest });
404
- const myKeys = [
405
- myKey,
406
- ECPair.fromPrivateKey(myKey.privateKey, { network: regtest }),
407
- ];
408
- const p2sh = createPayment('p2sh-p2ms(2 of 2)', myKeys);
409
- const inputData = await getInputData(5e4, p2sh.payment, false, 'p2sh');
410
- const psbt = new bitcoin.Psbt({ network: regtest })
411
- .addInput(inputData)
412
- .addOutput({
413
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
414
- value: 2e4,
415
- })
416
- .signInput(0, p2sh.keys[0]);
417
- psbt.finalizeAllInputs();
418
- const tx = psbt.extractTransaction();
419
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
420
- await _regtest_1.regtestUtils.verify({
421
- txId: tx.getId(),
422
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
423
- vout: 0,
424
- value: 2e4,
425
- });
426
- });
427
- (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input using HD', async () => {
428
- const hdRoot = bip32.fromSeed(rng(64));
429
- const masterFingerprint = hdRoot.fingerprint;
430
- const path = "m/84'/0'/0'/0/0";
431
- const childNode = hdRoot.derivePath(path);
432
- const pubkey = childNode.publicKey;
433
- // This information should be added to your input via updateInput
434
- // You can add multiple bip32Derivation objects for multisig, but
435
- // each must have a unique pubkey.
436
- //
437
- // This is useful because as long as you store the masterFingerprint on
438
- // the PSBT Creator's server, you can have the PSBT Creator do the heavy
439
- // lifting with derivation from your m/84'/0'/0' xpub, (deriving only 0/0 )
440
- // and your signer just needs to pass in an HDSigner interface (ie. bip32 library)
441
- const updateData = {
442
- bip32Derivation: [
443
- {
444
- masterFingerprint,
445
- path,
446
- pubkey,
447
- },
448
- ],
449
- };
450
- const p2wpkh = createPayment('p2wpkh', [childNode]);
451
- const inputData = await getInputData(5e4, p2wpkh.payment, true, 'noredeem');
452
- {
453
- const { hash, index, witnessUtxo } = inputData;
454
- assert.deepStrictEqual({ hash, index, witnessUtxo }, inputData);
455
- }
456
- // You can add extra attributes for updateData into the addInput(s) object(s)
457
- Object.assign(inputData, updateData);
458
- const psbt = new bitcoin.Psbt({ network: regtest })
459
- .addInput(inputData)
460
- // .updateInput(0, updateData) // if you didn't merge the bip32Derivation with inputData
461
- .addOutput({
462
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
463
- value: 2e4,
464
- })
465
- .signInputHD(0, hdRoot); // must sign with root!!!
466
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator), true);
467
- assert.strictEqual(psbt.validateSignaturesOfInput(0, validator, childNode.publicKey), true);
468
- psbt.finalizeAllInputs();
469
- const tx = psbt.extractTransaction();
470
- // build and broadcast to the Bitcoin RegTest network
471
- await _regtest_1.regtestUtils.broadcast(tx.toHex());
472
- await _regtest_1.regtestUtils.verify({
473
- txId: tx.getId(),
474
- address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
475
- vout: 0,
476
- value: 2e4,
477
- });
478
- });
479
- });
480
- function createPayment(_type, myKeys, network) {
481
- network = network || regtest;
482
- const splitType = _type.split('-').reverse();
483
- const isMultisig = splitType[0].slice(0, 4) === 'p2ms';
484
- const keys = myKeys || [];
485
- let m;
486
- if (isMultisig) {
487
- const match = splitType[0].match(/^p2ms\((\d+) of (\d+)\)$/);
488
- m = parseInt(match[1], 10);
489
- let n = parseInt(match[2], 10);
490
- if (keys.length > 0 && keys.length !== n) {
491
- throw new Error('Need n keys for multisig');
492
- }
493
- while (!myKeys && n > 1) {
494
- keys.push(ECPair.makeRandom({ network }));
495
- n--;
496
- }
497
- }
498
- if (!myKeys)
499
- keys.push(ECPair.makeRandom({ network }));
500
- let payment;
501
- splitType.forEach(type => {
502
- if (type.slice(0, 4) === 'p2ms') {
503
- payment = bitcoin.payments.p2ms({
504
- m,
505
- pubkeys: keys
506
- .map(key => key.publicKey)
507
- .sort((a, b) => a.compare(b)),
508
- network,
509
- });
510
- }
511
- else if (['p2sh', 'p2wsh'].indexOf(type) > -1) {
512
- payment = bitcoin.payments[type]({
513
- redeem: payment,
514
- network,
515
- });
516
- }
517
- else {
518
- payment = bitcoin.payments[type]({
519
- pubkey: keys[0].publicKey,
520
- network,
521
- });
522
- }
523
- });
524
- return {
525
- payment,
526
- keys,
527
- };
528
- }
529
- function getWitnessUtxo(out) {
530
- delete out.address;
531
- out.script = Buffer.from(out.script, 'hex');
532
- return out;
533
- }
534
- async function getInputData(amount, payment, isSegwit, redeemType) {
535
- const unspent = await _regtest_1.regtestUtils.faucetComplex(payment.output, amount);
536
- const utx = await _regtest_1.regtestUtils.fetch(unspent.txId);
537
- // for non segwit inputs, you must pass the full transaction buffer
538
- const nonWitnessUtxo = Buffer.from(utx.txHex, 'hex');
539
- // for segwit inputs, you only need the output script and value as an object.
540
- const witnessUtxo = getWitnessUtxo(utx.outs[unspent.vout]);
541
- const mixin = isSegwit ? { witnessUtxo } : { nonWitnessUtxo };
542
- const mixin2 = {};
543
- switch (redeemType) {
544
- case 'p2sh':
545
- mixin2.redeemScript = payment.redeem.output;
546
- break;
547
- case 'p2wsh':
548
- mixin2.witnessScript = payment.redeem.output;
549
- break;
550
- case 'p2sh-p2wsh':
551
- mixin2.witnessScript = payment.redeem.redeem.output;
552
- mixin2.redeemScript = payment.redeem.output;
553
- break;
554
- }
555
- return {
556
- hash: unspent.txId,
557
- index: unspent.vout,
558
- ...mixin,
559
- ...mixin2,
560
- };
561
- }
@@ -1,97 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const assert = require("assert");
4
- const ecc = require("tiny-secp256k1");
5
- const mocha_1 = require("mocha");
6
- const u = require("./payments.utils");
7
- const src_1 = require("../src");
8
- ['embed', 'p2ms', 'p2pk', 'p2pkh', 'p2sh', 'p2wpkh', 'p2wsh', 'p2tr'].forEach(p => {
9
- (0, mocha_1.describe)(p, () => {
10
- beforeEach(() => {
11
- (0, src_1.initEccLib)(p === 'p2tr' ? ecc : undefined);
12
- });
13
- let fn;
14
- const payment = require('../src/payments/' + p);
15
- if (p === 'embed') {
16
- fn = payment.p2data;
17
- }
18
- else {
19
- fn = payment[p];
20
- }
21
- const fixtures = require('./fixtures/' + p);
22
- fixtures.valid.forEach((f) => {
23
- (0, mocha_1.it)(f.description + ' as expected', () => {
24
- const args = u.preform(f.arguments);
25
- const actual = fn(args, f.options);
26
- u.equate(actual, f.expected, f.arguments);
27
- });
28
- (0, mocha_1.it)(f.description + ' as expected (no validation)', () => {
29
- const args = u.preform(f.arguments);
30
- const actual = fn(args, Object.assign({}, f.options, {
31
- validate: false,
32
- }));
33
- u.equate(actual, f.expected, f.arguments);
34
- });
35
- });
36
- fixtures.invalid.forEach((f) => {
37
- (0, mocha_1.it)('throws ' +
38
- f.exception +
39
- (f.description ? 'for ' + f.description : ''), () => {
40
- const args = u.preform(f.arguments);
41
- assert.throws(() => {
42
- fn(args, f.options);
43
- }, new RegExp(f.exception));
44
- });
45
- });
46
- if (p === 'p2sh') {
47
- const p2wsh = require('../src/payments/p2wsh').p2wsh;
48
- const p2pk = require('../src/payments/p2pk').p2pk;
49
- (0, mocha_1.it)('properly assembles nested p2wsh with names', () => {
50
- const actual = fn({
51
- redeem: p2wsh({
52
- redeem: p2pk({
53
- pubkey: Buffer.from('03e15819590382a9dd878f01e2f0cbce541564eb415e43b440472d883ecd283058', 'hex'),
54
- }),
55
- }),
56
- });
57
- assert.strictEqual(actual.address, '3MGbrbye4ttNUXM8WAvBFRKry4fkS9fjuw');
58
- assert.strictEqual(actual.name, 'p2sh-p2wsh-p2pk');
59
- assert.strictEqual(actual.redeem.name, 'p2wsh-p2pk');
60
- assert.strictEqual(actual.redeem.redeem.name, 'p2pk');
61
- });
62
- }
63
- // cross-verify dynamically too
64
- if (!fixtures.dynamic)
65
- return;
66
- const { depends, details } = fixtures.dynamic;
67
- details.forEach((f) => {
68
- const detail = u.preform(f);
69
- const disabled = {};
70
- if (f.disabled)
71
- f.disabled.forEach((k) => {
72
- disabled[k] = true;
73
- });
74
- for (const key in depends) {
75
- if (key in disabled)
76
- continue;
77
- const dependencies = depends[key];
78
- dependencies.forEach((dependency) => {
79
- if (!Array.isArray(dependency))
80
- dependency = [dependency];
81
- const args = {};
82
- dependency.forEach((d) => {
83
- u.from(d, detail, args);
84
- });
85
- const expected = u.from(key, detail);
86
- (0, mocha_1.it)(f.description +
87
- ', ' +
88
- key +
89
- ' derives from ' +
90
- JSON.stringify(dependency), () => {
91
- u.equate(fn(args), expected);
92
- });
93
- });
94
- }
95
- });
96
- });
97
- });