ecash-lib 0.1.0-rc2 → 0.1.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 (91) hide show
  1. package/README.md +73 -15
  2. package/dist/ecc.d.ts +6 -2
  3. package/dist/ecc.d.ts.map +1 -1
  4. package/dist/ecc.js +9 -6
  5. package/dist/ecc.js.map +1 -1
  6. package/dist/ffi/ecash_lib_wasm_bg.wasm +0 -0
  7. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
  8. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm.d.ts +16 -0
  9. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
  10. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm.d.ts +16 -0
  11. package/dist/ffi/ecash_lib_wasm_browser.d.ts +90 -0
  12. package/dist/ffi/ecash_lib_wasm_browser.js +340 -0
  13. package/dist/ffi/ecash_lib_wasm_nodejs.d.ts +50 -0
  14. package/dist/ffi/ecash_lib_wasm_nodejs.js +265 -0
  15. package/dist/hash.d.ts +10 -4
  16. package/dist/hash.d.ts.map +1 -1
  17. package/dist/hash.js +20 -4
  18. package/dist/hash.js.map +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +37 -21
  22. package/dist/index.js.map +1 -1
  23. package/dist/indexBrowser.d.ts +3 -0
  24. package/dist/indexBrowser.d.ts.map +1 -0
  25. package/dist/indexBrowser.js +22 -0
  26. package/dist/indexBrowser.js.map +1 -0
  27. package/dist/indexNodeJs.d.ts +3 -0
  28. package/dist/indexNodeJs.d.ts.map +1 -0
  29. package/dist/indexNodeJs.js +22 -0
  30. package/dist/indexNodeJs.js.map +1 -0
  31. package/dist/initBrowser.d.ts +3 -0
  32. package/dist/initBrowser.d.ts.map +1 -0
  33. package/dist/initBrowser.js +44 -0
  34. package/dist/initBrowser.js.map +1 -0
  35. package/dist/initNodeJs.d.ts +3 -0
  36. package/dist/initNodeJs.d.ts.map +1 -0
  37. package/dist/initNodeJs.js +43 -0
  38. package/dist/initNodeJs.js.map +1 -0
  39. package/dist/io/bytes.js +5 -1
  40. package/dist/io/bytes.js.map +1 -1
  41. package/dist/io/hex.js +11 -4
  42. package/dist/io/hex.js.map +1 -1
  43. package/dist/io/int.js +2 -1
  44. package/dist/io/int.js.map +1 -1
  45. package/dist/io/str.d.ts +2 -0
  46. package/dist/io/str.d.ts.map +1 -1
  47. package/dist/io/str.js +11 -1
  48. package/dist/io/str.js.map +1 -1
  49. package/dist/io/varsize.js +7 -2
  50. package/dist/io/varsize.js.map +1 -1
  51. package/dist/io/writer.js +2 -1
  52. package/dist/io/writer.js.map +1 -1
  53. package/dist/io/writerbytes.js +5 -1
  54. package/dist/io/writerbytes.js.map +1 -1
  55. package/dist/io/writerlength.js +5 -1
  56. package/dist/io/writerlength.js.map +1 -1
  57. package/dist/op.js +23 -16
  58. package/dist/op.js.map +1 -1
  59. package/dist/opcode.js +126 -121
  60. package/dist/opcode.js.map +1 -1
  61. package/dist/script.d.ts +1 -0
  62. package/dist/script.d.ts.map +1 -1
  63. package/dist/script.js +34 -25
  64. package/dist/script.js.map +1 -1
  65. package/dist/sigHashType.js +23 -19
  66. package/dist/sigHashType.js.map +1 -1
  67. package/dist/test/testRunner.d.ts +1 -1
  68. package/dist/test/testRunner.d.ts.map +1 -1
  69. package/dist/test/testRunner.js +51 -26
  70. package/dist/test/testRunner.js.map +1 -1
  71. package/dist/token/alp.js +43 -36
  72. package/dist/token/alp.js.map +1 -1
  73. package/dist/token/common.js +8 -5
  74. package/dist/token/common.js.map +1 -1
  75. package/dist/token/empp.js +13 -9
  76. package/dist/token/empp.js.map +1 -1
  77. package/dist/token/slp.js +61 -53
  78. package/dist/token/slp.js.map +1 -1
  79. package/dist/tx.d.ts +2 -0
  80. package/dist/tx.d.ts.map +1 -1
  81. package/dist/tx.js +39 -21
  82. package/dist/tx.js.map +1 -1
  83. package/dist/txBuilder.js +33 -25
  84. package/dist/txBuilder.js.map +1 -1
  85. package/dist/unsignedTx.js +34 -29
  86. package/dist/unsignedTx.js.map +1 -1
  87. package/package.json +3 -3
  88. package/tsconfig.json +1 -2
  89. package/tests/alp.test.ts +0 -383
  90. package/tests/slp.test.ts +0 -1124
  91. package/tests/txBuilder.test.ts +0 -562
@@ -1,562 +0,0 @@
1
- // Copyright (c) 2024 The Bitcoin developers
2
- // Distributed under the MIT software license, see the accompanying
3
- // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
-
5
- import { expect } from 'chai';
6
-
7
- import { ChronikClientNode } from 'chronik-client';
8
-
9
- import {
10
- ALL_ANYONECANPAY_BIP143,
11
- ALL_BIP143,
12
- Ecc,
13
- NONE_ANYONECANPAY_BIP143,
14
- NONE_BIP143,
15
- OP_CHECKSIG,
16
- OP_CHECKSIGVERIFY,
17
- OP_CODESEPARATOR,
18
- OP_REVERSEBYTES,
19
- P2PKHSignatory,
20
- P2PKSignatory,
21
- SINGLE_ANYONECANPAY_BIP143,
22
- SINGLE_BIP143,
23
- Script,
24
- TxBuilder,
25
- UnsignedTxInput,
26
- flagSignature,
27
- fromHex,
28
- initWasm,
29
- pushBytesOp,
30
- sha256d,
31
- shaRmd160,
32
- toHex,
33
- } from '../src/index.js';
34
- import { TestRunner } from '../src/test/testRunner.js';
35
-
36
- const NUM_COINS = 500;
37
- const COIN_VALUE = 100000;
38
-
39
- const SIG_HASH_TYPES = [
40
- ALL_BIP143,
41
- ALL_ANYONECANPAY_BIP143,
42
- NONE_BIP143,
43
- NONE_ANYONECANPAY_BIP143,
44
- SINGLE_BIP143,
45
- SINGLE_ANYONECANPAY_BIP143,
46
- ];
47
-
48
- describe('TxBuilder', () => {
49
- let runner: TestRunner;
50
- let chronik: ChronikClientNode;
51
- let ecc: Ecc;
52
-
53
- before(async () => {
54
- runner = await TestRunner.setup();
55
- chronik = runner.chronik;
56
- ecc = runner.ecc;
57
- await initWasm();
58
- await runner.setupCoins(NUM_COINS, COIN_VALUE);
59
- });
60
-
61
- after(() => {
62
- runner.stop();
63
- });
64
-
65
- it('TxBuilder P2PKH Wallet', async () => {
66
- // Setup simple single-address P2PKH wallet
67
- const sk = fromHex(
68
- '112233445566778899001122334455667788990011223344556677889900aabb',
69
- );
70
- const pk = ecc.derivePubkey(sk);
71
- const pkh = shaRmd160(pk);
72
- const p2pkh = Script.p2pkh(pkh);
73
-
74
- // Recipient script
75
- const recipientPkh = fromHex(
76
- '0123456789012345678901234567890123456789',
77
- );
78
- const recipientScript = Script.p2pkh(recipientPkh);
79
-
80
- // Send some UTXOs to the wallet
81
- await runner.sendToScript(90000, p2pkh);
82
- await runner.sendToScript(90000, p2pkh);
83
-
84
- const utxos = await chronik.script('p2pkh', toHex(pkh)).utxos();
85
- expect(utxos.utxos.length).to.equal(2);
86
-
87
- const txBuild = new TxBuilder({
88
- // Use all UTXOs of the wallet as input
89
- inputs: utxos.utxos.map(utxo => ({
90
- input: {
91
- prevOut: utxo.outpoint,
92
- signData: {
93
- value: utxo.value,
94
- outputScript: p2pkh,
95
- },
96
- },
97
- signatory: P2PKHSignatory(sk, pk, ALL_BIP143),
98
- })),
99
- outputs: [
100
- // Recipient using a TxOutput
101
- { value: 120000, script: recipientScript },
102
- // Leftover change back to wallet
103
- p2pkh,
104
- ],
105
- });
106
- const spendTx = txBuild.sign(ecc, 1000, 546);
107
- const txid = (await chronik.broadcastTx(spendTx.ser())).txid;
108
-
109
- // Now have 1 UTXO change in the wallet
110
- const newUtxos = await chronik.script('p2pkh', toHex(pkh)).utxos();
111
- expect(newUtxos.utxos).to.deep.equal([
112
- {
113
- outpoint: {
114
- txid,
115
- outIdx: 1,
116
- },
117
- blockHeight: -1,
118
- isCoinbase: false,
119
- value: 90000 * 2 - 120000 - spendTx.serSize(),
120
- isFinal: false,
121
- },
122
- ]);
123
- });
124
-
125
- it('TxBuilder P2PKH', async () => {
126
- const sk = fromHex(
127
- '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
128
- );
129
- const pk = ecc.derivePubkey(sk);
130
- const pkh = shaRmd160(pk);
131
- const p2pkh = Script.p2pkh(pkh);
132
-
133
- for (const sigHashType of SIG_HASH_TYPES) {
134
- const txid = await runner.sendToScript(90000, p2pkh);
135
- const txBuild = new TxBuilder({
136
- inputs: [
137
- {
138
- input: {
139
- prevOut: {
140
- txid,
141
- outIdx: 0,
142
- },
143
- signData: {
144
- value: 90000,
145
- outputScript: p2pkh,
146
- },
147
- },
148
- signatory: P2PKHSignatory(sk, pk, sigHashType),
149
- },
150
- ],
151
- outputs: [p2pkh],
152
- });
153
- const spendTx = txBuild.sign(ecc, 1000, 546);
154
- await chronik.broadcastTx(spendTx.ser());
155
- }
156
- });
157
-
158
- it('TxBuilder P2PK', async () => {
159
- const sk = fromHex(
160
- '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
161
- );
162
- const pk = ecc.derivePubkey(sk);
163
- const p2pk = Script.fromOps([pushBytesOp(pk), OP_CHECKSIG]);
164
-
165
- for (const sigHashType of SIG_HASH_TYPES) {
166
- const txid = await runner.sendToScript(90000, p2pk);
167
- const txBuild = new TxBuilder({
168
- inputs: [
169
- {
170
- input: {
171
- prevOut: {
172
- txid,
173
- outIdx: 0,
174
- },
175
- signData: {
176
- value: 90000,
177
- outputScript: p2pk,
178
- },
179
- },
180
- signatory: P2PKSignatory(sk, sigHashType),
181
- },
182
- ],
183
- outputs: [p2pk],
184
- });
185
- const spendTx = txBuild.sign(ecc, 1000, 546);
186
- await chronik.broadcastTx(spendTx.ser());
187
- }
188
- });
189
-
190
- it('TxBuilder P2PK ECDSA', async () => {
191
- const sk = fromHex(
192
- '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
193
- );
194
- const pk = ecc.derivePubkey(sk);
195
- const p2pk = Script.fromOps([pushBytesOp(pk), OP_CHECKSIG]);
196
-
197
- for (const sigHashType of SIG_HASH_TYPES) {
198
- const txid = await runner.sendToScript(90000, p2pk);
199
- const txBuild = new TxBuilder({
200
- inputs: [
201
- {
202
- input: {
203
- prevOut: {
204
- txid,
205
- outIdx: 0,
206
- },
207
- sequence: 0x92345678,
208
- signData: {
209
- value: 90000,
210
- outputScript: p2pk,
211
- },
212
- },
213
- signatory: (
214
- ecc: Ecc,
215
- input: UnsignedTxInput,
216
- ): Script => {
217
- const preimage = input.sigHashPreimage(sigHashType);
218
- const sighash = sha256d(preimage.bytes);
219
- const sig = flagSignature(
220
- ecc.ecdsaSign(sk, sighash),
221
- sigHashType,
222
- );
223
- return Script.fromOps([pushBytesOp(sig)]);
224
- },
225
- },
226
- ],
227
- outputs: [p2pk],
228
- });
229
- const spendTx = txBuild.sign(ecc, 1000, 546);
230
- await chronik.broadcastTx(spendTx.ser());
231
- }
232
- });
233
-
234
- it('TxBuilder P2SH with reversed signature OP_CHECKSIG', async () => {
235
- const sk = fromHex(
236
- '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
237
- );
238
- const pk = ecc.derivePubkey(sk);
239
- const redeemScript = Script.fromOps([
240
- OP_REVERSEBYTES,
241
- pushBytesOp(pk),
242
- OP_CHECKSIG,
243
- ]);
244
- const p2sh = Script.p2sh(shaRmd160(redeemScript.bytecode));
245
-
246
- for (const sigHashType of SIG_HASH_TYPES) {
247
- const txid = await runner.sendToScript(90000, p2sh);
248
- const txBuild = new TxBuilder({
249
- inputs: [
250
- {
251
- input: {
252
- prevOut: {
253
- txid,
254
- outIdx: 0,
255
- },
256
- signData: {
257
- value: 90000,
258
- redeemScript,
259
- },
260
- },
261
- signatory: (
262
- ecc: Ecc,
263
- input: UnsignedTxInput,
264
- ): Script => {
265
- const preimage = input.sigHashPreimage(sigHashType);
266
- const sighash = sha256d(preimage.bytes);
267
- const sig = flagSignature(
268
- ecc.schnorrSign(sk, sighash),
269
- sigHashType,
270
- );
271
- sig.reverse();
272
- return Script.fromOps([
273
- pushBytesOp(sig),
274
- pushBytesOp(preimage.redeemScript.bytecode),
275
- ]);
276
- },
277
- },
278
- ],
279
- outputs: [p2sh],
280
- });
281
- const spendTx = txBuild.sign(ecc, 1000, 546);
282
- await chronik.broadcastTx(spendTx.ser());
283
- }
284
- });
285
-
286
- it('TxBuilder OP_CODESEPERATOR', async () => {
287
- const sk1 = fromHex('11'.repeat(32));
288
- const pk1 = ecc.derivePubkey(sk1);
289
- const sk2 = fromHex('22'.repeat(32));
290
- const pk2 = ecc.derivePubkey(sk2);
291
- const sk3 = fromHex('33'.repeat(32));
292
- const pk3 = ecc.derivePubkey(sk3);
293
- const redeemScript = Script.fromOps([
294
- OP_CODESEPARATOR,
295
- pushBytesOp(pk1),
296
- OP_CODESEPARATOR,
297
- OP_CHECKSIGVERIFY,
298
- OP_CODESEPARATOR,
299
- pushBytesOp(pk2),
300
- OP_CHECKSIGVERIFY,
301
- OP_CODESEPARATOR,
302
- pushBytesOp(pk3),
303
- OP_CHECKSIG,
304
- OP_CODESEPARATOR,
305
- ]);
306
- const p2sh = Script.p2sh(shaRmd160(redeemScript.bytecode));
307
-
308
- for (const sigHashType of SIG_HASH_TYPES) {
309
- const txid = await runner.sendToScript(90000, p2sh);
310
- const txBuild = new TxBuilder({
311
- inputs: [
312
- {
313
- input: {
314
- prevOut: {
315
- txid,
316
- outIdx: 0,
317
- },
318
- sequence: 0x98765432,
319
- signData: {
320
- value: 90000,
321
- redeemScript,
322
- },
323
- },
324
- signatory: (
325
- ecc: Ecc,
326
- input: UnsignedTxInput,
327
- ): Script => {
328
- const sks = [sk1, sk2, sk3];
329
- const sigs = [...Array(3).keys()].map(i => {
330
- // Sign with nCodesep = 1, 2, 3
331
- const preimage = input.sigHashPreimage(
332
- sigHashType,
333
- i + 1,
334
- );
335
- return flagSignature(
336
- ecc.schnorrSign(
337
- sks[i],
338
- sha256d(preimage.bytes),
339
- ),
340
- sigHashType,
341
- );
342
- });
343
- return Script.fromOps([
344
- pushBytesOp(sigs[2]),
345
- pushBytesOp(sigs[1]),
346
- pushBytesOp(sigs[0]),
347
- pushBytesOp(redeemScript.bytecode),
348
- ]);
349
- },
350
- },
351
- ],
352
- outputs: [p2sh],
353
- });
354
- const spendTx = txBuild.sign(ecc, 1000, 546);
355
- await chronik.broadcastTx(spendTx.ser());
356
- }
357
- });
358
-
359
- it('TxBuilder leftover calculation', async () => {
360
- const sk1 = fromHex('11'.repeat(32));
361
- const pk1 = ecc.derivePubkey(sk1);
362
- const sk2 = fromHex('22'.repeat(32));
363
- const pk2 = ecc.derivePubkey(sk2);
364
- const redeemScript = Script.fromOps([
365
- pushBytesOp(pk1),
366
- OP_CHECKSIGVERIFY,
367
- pushBytesOp(pk2),
368
- OP_CHECKSIG,
369
- ]);
370
- const p2sh = Script.p2sh(shaRmd160(redeemScript.bytecode));
371
- const txid = await runner.sendToScript(90000, p2sh);
372
- const txBuild = new TxBuilder({
373
- inputs: [
374
- {
375
- input: {
376
- prevOut: {
377
- txid,
378
- outIdx: 0,
379
- },
380
- signData: {
381
- value: 90000,
382
- redeemScript,
383
- },
384
- },
385
- signatory: (ecc: Ecc, input: UnsignedTxInput): Script => {
386
- const sks = [sk1, sk2];
387
- const sigs = [...Array(2).keys()].map(i => {
388
- const preimage = input.sigHashPreimage(ALL_BIP143);
389
- return flagSignature(
390
- ecc.schnorrSign(
391
- sks[i],
392
- sha256d(preimage.bytes),
393
- ),
394
- ALL_BIP143,
395
- );
396
- });
397
- return Script.fromOps([
398
- pushBytesOp(sigs[1]),
399
- pushBytesOp(sigs[0]),
400
- pushBytesOp(redeemScript.bytecode),
401
- ]);
402
- },
403
- },
404
- ],
405
- outputs: [
406
- {
407
- value: 20000,
408
- script: Script.p2pkh(shaRmd160(pk1)),
409
- },
410
- Script.p2pkh(shaRmd160(pk2)),
411
- {
412
- value: 30000,
413
- script: Script.p2pkh(shaRmd160(pk2)),
414
- },
415
- ],
416
- });
417
-
418
- // 0sats/kB (not broadcast)
419
- let spendTx = txBuild.sign(ecc, 0, 546);
420
- expect(spendTx.outputs[1].value).to.equal(40000n);
421
-
422
- // 1ksats/kB
423
- spendTx = txBuild.sign(ecc, 1000, 546);
424
- await chronik.broadcastTx(spendTx.ser());
425
- expect(spendTx.outputs[1].value).to.equal(
426
- BigInt(40000 - spendTx.serSize()),
427
- );
428
-
429
- // 10ksats/kB
430
- txBuild.inputs[0].input.prevOut.txid = await runner.sendToScript(
431
- 90000,
432
- p2sh,
433
- );
434
- spendTx = txBuild.sign(ecc, 10000, 546);
435
- await chronik.broadcastTx(spendTx.ser());
436
- expect(spendTx.outputs[1].value).to.equal(
437
- BigInt(40000 - 10 * spendTx.serSize()),
438
- );
439
-
440
- // 100ksats/kB
441
- txBuild.inputs[0].input.prevOut.txid = await runner.sendToScript(
442
- 90000,
443
- p2sh,
444
- );
445
- spendTx = txBuild.sign(ecc, 100000, 546);
446
- await chronik.broadcastTx(spendTx.ser());
447
- expect(spendTx.outputs[1].value).to.equal(
448
- BigInt(40000 - 100 * spendTx.serSize()),
449
- );
450
-
451
- // 120ksats/kB, deletes leftover output
452
- txBuild.inputs[0].input.prevOut.txid = await runner.sendToScript(
453
- 90000,
454
- p2sh,
455
- );
456
- spendTx = txBuild.sign(ecc, 120000, 546);
457
- await chronik.broadcastTx(spendTx.ser());
458
- expect(spendTx.outputs.length).to.equal(2);
459
-
460
- // 100ksats/kB with a 5000 dust limit deletes leftover too
461
- txBuild.inputs[0].input.prevOut.txid = await runner.sendToScript(
462
- 90000,
463
- p2sh,
464
- );
465
- spendTx = txBuild.sign(ecc, 100000, /*dustLimit=*/ 5000);
466
- await chronik.broadcastTx(spendTx.ser());
467
- expect(spendTx.outputs.length).to.equal(2);
468
-
469
- // 1000ksats/kB does't have sufficient sats even without leftover
470
- txBuild.inputs[0].input.prevOut.txid = await runner.sendToScript(
471
- 90000,
472
- p2sh,
473
- );
474
- expect(() => txBuild.sign(ecc, 1000000, 546)).to.throw(
475
- `Insufficient input value (90000): Can only pay for 40000 fees, ` +
476
- `but ${spendTx.serSize() * 1000} required`,
477
- );
478
- });
479
-
480
- it('TxBuilder leftover with 0xFD outputs', async () => {
481
- const sk = fromHex('11'.repeat(32));
482
- const pk = ecc.derivePubkey(sk);
483
- const pkh = shaRmd160(pk);
484
- const p2pkh = Script.p2pkh(pkh);
485
- const sk2 = fromHex('22'.repeat(32));
486
- const pk2 = ecc.derivePubkey(sk2);
487
- const txBuild = new TxBuilder();
488
- for (let i = 0; i < 2; ++i) {
489
- txBuild.inputs.push({
490
- input: {
491
- prevOut: {
492
- txid: await runner.sendToScript(90000, p2pkh),
493
- outIdx: 0,
494
- },
495
- signData: {
496
- value: 90000,
497
- outputScript: p2pkh,
498
- },
499
- },
500
- signatory: P2PKHSignatory(sk, pk, ALL_BIP143),
501
- });
502
- }
503
- txBuild.outputs.push(Script.p2pkh(shaRmd160(pk2)));
504
- const txSize = 8896;
505
- const extraOutput = {
506
- value: 90000 * 2 - (txSize + 252 * 546),
507
- script: p2pkh,
508
- };
509
- txBuild.outputs.push(extraOutput);
510
- for (let i = 0; i < 251; ++i) {
511
- txBuild.outputs.push({ value: 546, script: p2pkh });
512
- }
513
- expect(txBuild.outputs.length).to.equal(253);
514
- let spendTx = txBuild.sign(ecc, 1000, 546);
515
- expect(spendTx.serSize()).to.equal(txSize);
516
- expect(spendTx.outputs[0].value).to.equal(BigInt(546));
517
-
518
- // If we remove the leftover output from the tx, we also remove 2 extra
519
- // bytes from the VARSIZE of the output, because 253 requires 3 bytes to
520
- // encode and 252 requires just 1 byte to encode.
521
- const p2pkhSize = 8 + 1 + 25;
522
- const smallerSize = txSize - p2pkhSize - 2;
523
- // We can add 2 extra sats for the VARSIZE savings and it's handled fine
524
- extraOutput.value += 546 + p2pkhSize + 2;
525
- spendTx = txBuild.sign(ecc, 1000, 546);
526
- expect(spendTx.serSize()).to.equal(smallerSize);
527
- expect(spendTx.outputs.length).to.equal(252);
528
-
529
- // Adding 1 extra sat -> fails -> showing that the previous tx was exact
530
- extraOutput.value += 1;
531
- expect(() => txBuild.sign(ecc, 1000, 546)).to.throw(
532
- `Insufficient input value (180000): Can only pay for ` +
533
- `${smallerSize - 1} fees, but ${smallerSize} required`,
534
- );
535
- });
536
-
537
- it('TxBuilder leftover failure', async () => {
538
- const txBuild = new TxBuilder({
539
- inputs: [
540
- {
541
- input: {
542
- prevOut: {
543
- txid: new Uint8Array(32),
544
- outIdx: 0,
545
- },
546
- },
547
- },
548
- ],
549
- outputs: [new Script()],
550
- });
551
- expect(() => txBuild.sign(ecc, 1000, 545)).to.throw(
552
- 'Using a leftover output requires setting SignData.value for all inputs',
553
- );
554
- txBuild.inputs[0].input.signData = { value: 1234 };
555
- expect(() => txBuild.sign(ecc, 1000)).to.throw(
556
- 'Using a leftover output requires setting dustLimit',
557
- );
558
- expect(() => txBuild.sign(ecc)).to.throw(
559
- 'Using a leftover output requires setting feePerKb',
560
- );
561
- });
562
- });