@btc-vision/bitcoin 6.5.1 → 6.5.2
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/browser/chunks/crypto-0PweVewC.js +2033 -0
- package/browser/chunks/{payments-BE4vwHhV.js → payments-CgasufRS.js} +410 -408
- package/browser/chunks/psbt-BIwOrKer.js +4096 -0
- package/browser/chunks/{script-COWGdiOo.js → script-CROJPzz_.js} +96 -96
- package/browser/chunks/{transaction-BiXwH2v4.js → transaction-DchBu35N.js} +158 -147
- package/browser/chunks/{utils-BKmkTzNZ.js → utils-CO5kmxe9.js} +225 -223
- package/browser/crypto.d.ts +1 -1
- package/browser/hooks/HookedSigner.d.ts +1 -1
- package/browser/index.d.ts +23 -1
- package/browser/index.js +6 -6
- package/browser/payments/index.d.ts +2 -2
- package/browser/payments/lazy.d.ts +1 -1
- package/browser/psbt/bip371.d.ts +5 -1
- package/browser/psbt.d.ts +1 -1
- package/browser/typeforce.d.ts +38 -0
- package/browser/types.d.ts +22 -20
- package/build/address.js +2 -2
- package/build/bip66.js +2 -2
- package/build/block.js +2 -2
- package/build/crypto.d.ts +1 -1
- package/build/crypto.js +2 -3
- package/build/hooks/HookedSigner.d.ts +1 -1
- package/build/index.d.ts +23 -1
- package/build/payments/bip341.js +1 -1
- package/build/payments/index.d.ts +2 -2
- package/build/payments/lazy.d.ts +1 -1
- package/build/payments/p2op.js +3 -3
- package/build/payments/p2pk.js +1 -1
- package/build/payments/p2pkh.js +3 -3
- package/build/payments/p2sh.js +3 -3
- package/build/payments/p2tr.js +9 -5
- package/build/payments/p2wpkh.js +3 -3
- package/build/payments/p2wsh.js +2 -2
- package/build/psbt/bip371.d.ts +5 -1
- package/build/psbt/bip371.js +10 -7
- package/build/psbt/psbtutils.js +5 -4
- package/build/psbt.d.ts +1 -1
- package/build/psbt.js +78 -45
- package/build/script.js +2 -2
- package/build/script_signature.js +7 -7
- package/build/transaction.js +22 -10
- package/build/tsconfig.tsbuildinfo +1 -0
- package/build/types.d.ts +22 -20
- package/build/types.js +10 -9
- package/package.json +30 -59
- package/src/address.ts +2 -2
- package/src/bip66.ts +2 -2
- package/src/block.ts +8 -5
- package/src/crypto.ts +3 -4
- package/src/ecc_lib.ts +1 -1
- package/src/hooks/HookedSigner.ts +1 -1
- package/src/index.ts +34 -12
- package/src/payments/bip341.ts +1 -1
- package/src/payments/embed.ts +1 -2
- package/src/payments/index.ts +4 -4
- package/src/payments/lazy.ts +3 -3
- package/src/payments/p2op.ts +4 -3
- package/src/payments/p2pk.ts +1 -1
- package/src/payments/p2pkh.ts +3 -3
- package/src/payments/p2sh.ts +13 -5
- package/src/payments/p2tr.ts +8 -9
- package/src/payments/p2wpkh.ts +3 -3
- package/src/payments/p2wsh.ts +4 -4
- package/src/psbt/bip371.ts +22 -13
- package/src/psbt/psbtutils.ts +8 -5
- package/src/psbt.ts +127 -80
- package/src/script.ts +4 -4
- package/src/script_signature.ts +7 -7
- package/src/transaction.ts +31 -18
- package/src/typeforce.d.ts +38 -0
- package/src/types.ts +34 -29
- package/test/address.spec.ts +12 -4
- package/test/bitcoin.core.spec.ts +1 -1
- package/test/block.spec.ts +1 -1
- package/test/bufferutils.spec.ts +1 -1
- package/test/crypto.spec.ts +3 -2
- package/test/fixtures/address.json +1 -1
- package/test/integration/addresses.spec.ts +1 -1
- package/test/integration/bip32.spec.ts +2 -2
- package/test/integration/blocks.spec.ts +1 -1
- package/test/integration/cltv.spec.ts +3 -3
- package/test/integration/csv.spec.ts +3 -3
- package/test/integration/payments.spec.ts +1 -1
- package/test/integration/taproot.spec.ts +8 -7
- package/test/integration/transactions.spec.ts +2 -2
- package/test/payments.spec.ts +4 -3
- package/test/psbt.spec.ts +106 -74
- package/test/script.spec.ts +73 -7
- package/test/script_number.spec.ts +1 -1
- package/test/script_signature.spec.ts +1 -1
- package/test/transaction.spec.ts +1 -1
- package/test/tsconfig.json +1 -1
- package/test/types.spec.ts +1 -1
- package/vitest.config.ts +16 -0
- package/.babelrc +0 -13
- package/.mocharc.json +0 -13
- package/browser/chunks/crypto-C6FlKKmp.js +0 -2006
- package/browser/chunks/psbt-Dlosf9CT.js +0 -3853
- package/cjs/package.json +0 -3
- package/gulpfile.js +0 -42
- package/src/crypto/crypto-browser.js +0 -75
- package/test/ts-node-register.js +0 -7
- package/webpack.config.js +0 -79
package/build/psbt/psbtutils.js
CHANGED
|
@@ -18,7 +18,7 @@ function isPaymentFactory(payment) {
|
|
|
18
18
|
payment({ output: script });
|
|
19
19
|
return true;
|
|
20
20
|
}
|
|
21
|
-
catch
|
|
21
|
+
catch {
|
|
22
22
|
return false;
|
|
23
23
|
}
|
|
24
24
|
};
|
|
@@ -170,14 +170,15 @@ export function signatureBlocksAction(signature, signatureDecodeFn, action) {
|
|
|
170
170
|
return whitelist.indexOf(action) === -1;
|
|
171
171
|
}
|
|
172
172
|
function extractPartialSigs(input) {
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
const { partialSig } = input;
|
|
174
|
+
let pSigs;
|
|
175
|
+
if (!partialSig || partialSig.length === 0) {
|
|
175
176
|
if (!input.finalScriptSig && !input.finalScriptWitness)
|
|
176
177
|
return [];
|
|
177
178
|
pSigs = getPsigsFromInputFinalScripts(input);
|
|
178
179
|
}
|
|
179
180
|
else {
|
|
180
|
-
pSigs =
|
|
181
|
+
pSigs = partialSig;
|
|
181
182
|
}
|
|
182
183
|
return pSigs.map((p) => p.signature);
|
|
183
184
|
}
|
package/build/psbt.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Psbt as PsbtBase } from 'bip174';
|
|
2
2
|
import { KeyValue, PartialSig, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate } from 'bip174/src/lib/interfaces.js';
|
|
3
|
-
import { BIP32Interface } from 'bip32';
|
|
3
|
+
import { BIP32Interface } from '@btc-vision/bip32';
|
|
4
4
|
import { ECPairInterface } from 'ecpair';
|
|
5
5
|
import { Network } from './networks.js';
|
|
6
6
|
import { Transaction } from './transaction.js';
|
package/build/psbt.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Psbt as PsbtBase } from 'bip174';
|
|
2
2
|
import * as varuint from 'bip174/src/lib/converter/varint.js';
|
|
3
|
+
const varuintDecode = varuint.decode;
|
|
3
4
|
import { checkForInput, checkForOutput } from 'bip174/src/lib/utils.js';
|
|
4
5
|
import { fromOutputScript, isUnknownSegwitVersion, toOutputScript } from './address.js';
|
|
5
6
|
import { cloneBuffer, reverseBuffer } from './bufferutils.js';
|
|
@@ -94,7 +95,8 @@ export class Psbt {
|
|
|
94
95
|
return this;
|
|
95
96
|
}
|
|
96
97
|
clone() {
|
|
97
|
-
|
|
98
|
+
const clonedOpts = JSON.parse(JSON.stringify(this.opts));
|
|
99
|
+
return Psbt.fromBuffer(this.data.toBuffer(), clonedOpts);
|
|
98
100
|
}
|
|
99
101
|
setMaximumFeeRate(satoshiPerByte) {
|
|
100
102
|
check32Bit(satoshiPerByte);
|
|
@@ -164,16 +166,18 @@ export class Psbt {
|
|
|
164
166
|
return this;
|
|
165
167
|
}
|
|
166
168
|
addOutput(outputData) {
|
|
169
|
+
const hasAddress = 'address' in outputData;
|
|
170
|
+
const hasScript = 'script' in outputData;
|
|
167
171
|
if (arguments.length > 1 ||
|
|
168
172
|
!outputData ||
|
|
169
173
|
outputData.value === undefined ||
|
|
170
|
-
(
|
|
174
|
+
(!hasAddress && !hasScript)) {
|
|
171
175
|
throw new Error(`Invalid arguments for Psbt.addOutput. ` +
|
|
172
176
|
`Requires single object with at least [script or address] and [value]`);
|
|
173
177
|
}
|
|
174
178
|
checkInputsForPartialSig(this.data.inputs, 'addOutput');
|
|
175
|
-
|
|
176
|
-
|
|
179
|
+
if (hasAddress) {
|
|
180
|
+
const { address } = outputData;
|
|
177
181
|
const { network } = this.opts;
|
|
178
182
|
const script = toOutputScript(address, network);
|
|
179
183
|
outputData = Object.assign({}, outputData, { script });
|
|
@@ -255,7 +259,7 @@ export class Psbt {
|
|
|
255
259
|
validateSignaturesOfAllInputs(validator) {
|
|
256
260
|
checkForInput(this.data.inputs, 0);
|
|
257
261
|
const results = range(this.data.inputs.length).map((idx) => this.validateSignaturesOfInput(idx, validator));
|
|
258
|
-
return results.reduce((final, res) => res
|
|
262
|
+
return results.reduce((final, res) => res && final, true);
|
|
259
263
|
}
|
|
260
264
|
validateSignaturesOfInput(inputIndex, validator, pubkey) {
|
|
261
265
|
const input = this.data.inputs[inputIndex];
|
|
@@ -277,7 +281,7 @@ export class Psbt {
|
|
|
277
281
|
results.push(false);
|
|
278
282
|
}
|
|
279
283
|
}
|
|
280
|
-
if (results.every((v) => v
|
|
284
|
+
if (results.every((v) => !v)) {
|
|
281
285
|
throw new Error('No inputs were signed');
|
|
282
286
|
}
|
|
283
287
|
return this;
|
|
@@ -297,7 +301,7 @@ export class Psbt {
|
|
|
297
301
|
}));
|
|
298
302
|
}
|
|
299
303
|
return Promise.all(promises).then(() => {
|
|
300
|
-
if (results.every((v) => v
|
|
304
|
+
if (results.every((v) => !v)) {
|
|
301
305
|
return reject(new Error('No inputs were signed'));
|
|
302
306
|
}
|
|
303
307
|
resolve();
|
|
@@ -339,7 +343,7 @@ export class Psbt {
|
|
|
339
343
|
results.push(false);
|
|
340
344
|
}
|
|
341
345
|
}
|
|
342
|
-
if (results.every((v) => v
|
|
346
|
+
if (results.every((v) => !v)) {
|
|
343
347
|
throw new Error('No inputs were signed');
|
|
344
348
|
}
|
|
345
349
|
return this;
|
|
@@ -358,7 +362,7 @@ export class Psbt {
|
|
|
358
362
|
}));
|
|
359
363
|
}
|
|
360
364
|
return Promise.all(promises).then(() => {
|
|
361
|
-
if (results.every((v) => v
|
|
365
|
+
if (results.every((v) => !v)) {
|
|
362
366
|
return reject(new Error('No inputs were signed'));
|
|
363
367
|
}
|
|
364
368
|
resolve();
|
|
@@ -456,9 +460,12 @@ export class Psbt {
|
|
|
456
460
|
checkTaprootHashesForSig(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes) {
|
|
457
461
|
if (typeof keyPair.signSchnorr !== 'function')
|
|
458
462
|
throw new Error(`Need Schnorr Signer to sign taproot input #${inputIndex}.`);
|
|
459
|
-
const
|
|
463
|
+
const pubkey = Buffer.isBuffer(keyPair.publicKey)
|
|
464
|
+
? keyPair.publicKey
|
|
465
|
+
: Buffer.from(keyPair.publicKey);
|
|
466
|
+
const hashesForSig = getTaprootHashesForSig(inputIndex, input, this.data.inputs, pubkey, this.__CACHE, tapLeafHashToSign, allowedSighashTypes);
|
|
460
467
|
if (!hashesForSig || !hashesForSig.length)
|
|
461
|
-
throw new Error(`Can not sign for input #${inputIndex} with the key ${
|
|
468
|
+
throw new Error(`Can not sign for input #${inputIndex} with the key ${pubkey.toString('hex')}`);
|
|
462
469
|
return hashesForSig;
|
|
463
470
|
}
|
|
464
471
|
_finalizeInput(inputIndex, input, finalScriptsFunc = getFinalScripts, canRunChecks = true) {
|
|
@@ -484,6 +491,8 @@ export class Psbt {
|
|
|
484
491
|
output: input.witnessUtxo.script,
|
|
485
492
|
signature: input.tapKeySig,
|
|
486
493
|
});
|
|
494
|
+
if (!payment.witness)
|
|
495
|
+
throw new Error('Cannot finalize taproot key spend');
|
|
487
496
|
const finalScriptWitness = witnessStackToScriptWitness(payment.witness);
|
|
488
497
|
this.data.updateInput(inputIndex, { finalScriptWitness });
|
|
489
498
|
}
|
|
@@ -510,7 +519,7 @@ export class Psbt {
|
|
|
510
519
|
let sighashCache;
|
|
511
520
|
for (const pSig of mySigs) {
|
|
512
521
|
const sig = bscript.signature.decode(pSig.signature);
|
|
513
|
-
const { hash, script } = sighashCache !== sig.hashType
|
|
522
|
+
const { hash, script } = sighashCache !== sig.hashType || !hashCache || !scriptCache
|
|
514
523
|
? getHashForSig(inputIndex, Object.assign({}, input, {
|
|
515
524
|
sighashType: sig.hashType,
|
|
516
525
|
}), this.__CACHE, true)
|
|
@@ -521,7 +530,7 @@ export class Psbt {
|
|
|
521
530
|
checkScriptForPubkey(pSig.pubkey, script, 'verify');
|
|
522
531
|
results.push(validator(pSig.pubkey, hash, sig.signature));
|
|
523
532
|
}
|
|
524
|
-
return results.every((res) => res
|
|
533
|
+
return results.every((res) => res);
|
|
525
534
|
}
|
|
526
535
|
validateSignaturesOfTaprootInput(inputIndex, validator, pubkey) {
|
|
527
536
|
const input = this.data.inputs[inputIndex];
|
|
@@ -559,26 +568,35 @@ export class Psbt {
|
|
|
559
568
|
return validationResultCount > 0;
|
|
560
569
|
}
|
|
561
570
|
_signInput(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
|
|
562
|
-
const
|
|
571
|
+
const pubkey = Buffer.isBuffer(keyPair.publicKey)
|
|
572
|
+
? keyPair.publicKey
|
|
573
|
+
: Buffer.from(keyPair.publicKey);
|
|
574
|
+
const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.__CACHE, sighashTypes);
|
|
575
|
+
const sig = keyPair.sign(hash);
|
|
563
576
|
const partialSig = [
|
|
564
577
|
{
|
|
565
|
-
pubkey
|
|
566
|
-
signature: bscript.signature.encode(
|
|
578
|
+
pubkey,
|
|
579
|
+
signature: bscript.signature.encode(Buffer.isBuffer(sig) ? sig : Buffer.from(sig), sighashType),
|
|
567
580
|
},
|
|
568
581
|
];
|
|
569
582
|
this.data.updateInput(inputIndex, { partialSig });
|
|
570
583
|
return this;
|
|
571
584
|
}
|
|
572
585
|
_signTaprootInput(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes = [Transaction.SIGHASH_DEFAULT]) {
|
|
586
|
+
const pubkey = Buffer.isBuffer(keyPair.publicKey)
|
|
587
|
+
? keyPair.publicKey
|
|
588
|
+
: Buffer.from(keyPair.publicKey);
|
|
573
589
|
const hashesForSig = this.checkTaprootHashesForSig(inputIndex, input, keyPair, tapLeafHashToSign, allowedSighashTypes);
|
|
590
|
+
const signSchnorr = keyPair.signSchnorr.bind(keyPair);
|
|
591
|
+
const toBuffer = (data) => Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
574
592
|
const tapKeySig = hashesForSig
|
|
575
593
|
.filter((h) => !h.leafHash)
|
|
576
|
-
.map((h) => serializeTaprootSignature(
|
|
594
|
+
.map((h) => serializeTaprootSignature(toBuffer(signSchnorr(h.hash)), input.sighashType))[0];
|
|
577
595
|
const tapScriptSig = hashesForSig
|
|
578
596
|
.filter((h) => !!h.leafHash)
|
|
579
597
|
.map((h) => ({
|
|
580
|
-
pubkey: toXOnly(
|
|
581
|
-
signature: serializeTaprootSignature(
|
|
598
|
+
pubkey: toXOnly(pubkey),
|
|
599
|
+
signature: serializeTaprootSignature(toBuffer(signSchnorr(h.hash)), input.sighashType),
|
|
582
600
|
leafHash: h.leafHash,
|
|
583
601
|
}));
|
|
584
602
|
if (tapKeySig) {
|
|
@@ -590,25 +608,34 @@ export class Psbt {
|
|
|
590
608
|
return this;
|
|
591
609
|
}
|
|
592
610
|
_signInputAsync(inputIndex, keyPair, sighashTypes = [Transaction.SIGHASH_ALL]) {
|
|
593
|
-
const
|
|
611
|
+
const pubkey = Buffer.isBuffer(keyPair.publicKey)
|
|
612
|
+
? keyPair.publicKey
|
|
613
|
+
: Buffer.from(keyPair.publicKey);
|
|
614
|
+
const { hash, sighashType } = getHashAndSighashType(this.data.inputs, inputIndex, pubkey, this.__CACHE, sighashTypes);
|
|
594
615
|
return Promise.resolve(keyPair.sign(hash)).then((signature) => {
|
|
616
|
+
const sig = Buffer.isBuffer(signature) ? signature : Buffer.from(signature);
|
|
595
617
|
const partialSig = [
|
|
596
618
|
{
|
|
597
|
-
pubkey
|
|
598
|
-
signature: bscript.signature.encode(
|
|
619
|
+
pubkey,
|
|
620
|
+
signature: bscript.signature.encode(sig, sighashType),
|
|
599
621
|
},
|
|
600
622
|
];
|
|
601
623
|
this.data.updateInput(inputIndex, { partialSig });
|
|
602
624
|
});
|
|
603
625
|
}
|
|
604
626
|
async _signTaprootInputAsync(inputIndex, input, keyPair, tapLeafHash, sighashTypes = [Transaction.SIGHASH_DEFAULT]) {
|
|
627
|
+
const pubkey = Buffer.isBuffer(keyPair.publicKey)
|
|
628
|
+
? keyPair.publicKey
|
|
629
|
+
: Buffer.from(keyPair.publicKey);
|
|
605
630
|
const hashesForSig = this.checkTaprootHashesForSig(inputIndex, input, keyPair, tapLeafHash, sighashTypes);
|
|
631
|
+
const signSchnorr = keyPair.signSchnorr.bind(keyPair);
|
|
632
|
+
const toBuffer = (data) => Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
606
633
|
const signaturePromises = [];
|
|
607
634
|
const tapKeyHash = hashesForSig.filter((h) => !h.leafHash)[0];
|
|
608
635
|
if (tapKeyHash) {
|
|
609
|
-
const tapKeySigPromise = Promise.resolve(
|
|
636
|
+
const tapKeySigPromise = Promise.resolve(signSchnorr(tapKeyHash.hash)).then((sig) => {
|
|
610
637
|
return {
|
|
611
|
-
tapKeySig: serializeTaprootSignature(sig, input.sighashType),
|
|
638
|
+
tapKeySig: serializeTaprootSignature(toBuffer(sig), input.sighashType),
|
|
612
639
|
};
|
|
613
640
|
});
|
|
614
641
|
signaturePromises.push(tapKeySigPromise);
|
|
@@ -616,11 +643,11 @@ export class Psbt {
|
|
|
616
643
|
const tapScriptHashes = hashesForSig.filter((h) => !!h.leafHash);
|
|
617
644
|
if (tapScriptHashes.length) {
|
|
618
645
|
const tapScriptSigPromises = tapScriptHashes.map(async (tsh) => {
|
|
619
|
-
const signature = await
|
|
646
|
+
const signature = await signSchnorr(tsh.hash);
|
|
620
647
|
const tapScriptSig = [
|
|
621
648
|
{
|
|
622
|
-
pubkey: toXOnly(
|
|
623
|
-
signature: serializeTaprootSignature(signature, input.sighashType),
|
|
649
|
+
pubkey: toXOnly(pubkey),
|
|
650
|
+
signature: serializeTaprootSignature(toBuffer(signature), input.sighashType),
|
|
624
651
|
leafHash: tsh.leafHash,
|
|
625
652
|
},
|
|
626
653
|
];
|
|
@@ -681,11 +708,12 @@ function canFinalize(input, script, scriptType) {
|
|
|
681
708
|
case 'pubkeyhash':
|
|
682
709
|
case 'witnesspubkeyhash':
|
|
683
710
|
return hasSigs(1, input.partialSig);
|
|
684
|
-
case 'multisig':
|
|
711
|
+
case 'multisig': {
|
|
685
712
|
const p2ms = payments.p2ms({
|
|
686
713
|
output: script,
|
|
687
714
|
});
|
|
688
715
|
return hasSigs(p2ms.m, input.partialSig, p2ms.pubkeys);
|
|
716
|
+
}
|
|
689
717
|
case 'nonstandard':
|
|
690
718
|
return true;
|
|
691
719
|
default:
|
|
@@ -693,7 +721,7 @@ function canFinalize(input, script, scriptType) {
|
|
|
693
721
|
}
|
|
694
722
|
}
|
|
695
723
|
function checkCache(cache) {
|
|
696
|
-
if (cache.__UNSAFE_SIGN_NONSEGWIT
|
|
724
|
+
if (cache.__UNSAFE_SIGN_NONSEGWIT) {
|
|
697
725
|
throw new Error('Not BIP174 compliant, can not export');
|
|
698
726
|
}
|
|
699
727
|
}
|
|
@@ -721,9 +749,14 @@ function isFinalized(input) {
|
|
|
721
749
|
}
|
|
722
750
|
function bip32DerivationIsMine(root) {
|
|
723
751
|
return (d) => {
|
|
724
|
-
|
|
752
|
+
const fingerprint = Buffer.isBuffer(root.fingerprint)
|
|
753
|
+
? root.fingerprint
|
|
754
|
+
: Buffer.from(root.fingerprint);
|
|
755
|
+
if (!d.masterFingerprint.equals(fingerprint))
|
|
725
756
|
return false;
|
|
726
|
-
|
|
757
|
+
const derivedPubkey = root.derivePath(d.path).publicKey;
|
|
758
|
+
const pubkey = Buffer.isBuffer(derivedPubkey) ? derivedPubkey : Buffer.from(derivedPubkey);
|
|
759
|
+
if (!pubkey.equals(d.pubkey))
|
|
727
760
|
return false;
|
|
728
761
|
return true;
|
|
729
762
|
};
|
|
@@ -785,7 +818,7 @@ function checkTxForDupeIns(tx, cache) {
|
|
|
785
818
|
});
|
|
786
819
|
}
|
|
787
820
|
function checkTxInputCache(cache, input) {
|
|
788
|
-
const key = reverseBuffer(Buffer.from(input.hash)).toString('hex')
|
|
821
|
+
const key = `${reverseBuffer(Buffer.from(input.hash)).toString('hex')}:${input.index}`;
|
|
789
822
|
if (cache.__TX_IN_CACHE[key])
|
|
790
823
|
throw new Error('Duplicate input detected.');
|
|
791
824
|
cache.__TX_IN_CACHE[key] = 1;
|
|
@@ -819,10 +852,10 @@ function getTxCacheValue(key, name, inputs, c, disableOutputChecks = false) {
|
|
|
819
852
|
tx = c.__TX.clone();
|
|
820
853
|
}
|
|
821
854
|
inputFinalizeGetAmts(inputs, tx, c, mustFinalize, disableOutputChecks);
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
855
|
+
const value = key === '__FEE_RATE' ? c.__FEE_RATE : c.__FEE;
|
|
856
|
+
if (value === undefined)
|
|
857
|
+
throw new Error(`Failed to calculate ${name}`);
|
|
858
|
+
return value;
|
|
826
859
|
}
|
|
827
860
|
export function getFinalScripts(inputIndex, input, script, isSegwit, isP2SH, isP2WSH, canRunChecks = true, solution) {
|
|
828
861
|
const scriptType = classifyScript(script);
|
|
@@ -907,15 +940,15 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
|
|
|
907
940
|
}
|
|
908
941
|
else if (isP2WPKH(meaningfulScript)) {
|
|
909
942
|
const signingScript = payments.p2pkh({
|
|
910
|
-
hash: meaningfulScript.
|
|
943
|
+
hash: meaningfulScript.subarray(2),
|
|
911
944
|
}).output;
|
|
912
945
|
hash = unsignedTx.hashForWitnessV0(inputIndex, signingScript, prevout.value, sighashType);
|
|
913
946
|
}
|
|
914
947
|
else {
|
|
915
|
-
if (input.nonWitnessUtxo === undefined && cache.__UNSAFE_SIGN_NONSEGWIT
|
|
948
|
+
if (input.nonWitnessUtxo === undefined && !cache.__UNSAFE_SIGN_NONSEGWIT)
|
|
916
949
|
throw new Error(`Input #${inputIndex} has witnessUtxo but non-segwit script: ` +
|
|
917
|
-
|
|
918
|
-
if (!forValidate && cache.__UNSAFE_SIGN_NONSEGWIT
|
|
950
|
+
meaningfulScript.toString('hex'));
|
|
951
|
+
if (!forValidate && cache.__UNSAFE_SIGN_NONSEGWIT)
|
|
919
952
|
console.warn('Warning: Signing non-segwit inputs without the full parent transaction ' +
|
|
920
953
|
'means there is a chance that a miner could feed you incorrect information ' +
|
|
921
954
|
"to trick you into paying large fees. This behavior is the same as Psbt's predecessor " +
|
|
@@ -1109,11 +1142,11 @@ function scriptWitnessToWitnessStack(buffer) {
|
|
|
1109
1142
|
let offset = 0;
|
|
1110
1143
|
function readSlice(n) {
|
|
1111
1144
|
offset += n;
|
|
1112
|
-
return buffer.
|
|
1145
|
+
return buffer.subarray(offset - n, offset);
|
|
1113
1146
|
}
|
|
1114
1147
|
function readVarInt() {
|
|
1115
|
-
const vi =
|
|
1116
|
-
offset +=
|
|
1148
|
+
const vi = varuintDecode(buffer, offset);
|
|
1149
|
+
offset += varuintDecode.bytes;
|
|
1117
1150
|
return vi;
|
|
1118
1151
|
}
|
|
1119
1152
|
function readVarSlice() {
|
|
@@ -1265,11 +1298,11 @@ function redeemFromFinalWitnessScript(finalScript) {
|
|
|
1265
1298
|
function compressPubkey(pubkey) {
|
|
1266
1299
|
if (pubkey.length === 65) {
|
|
1267
1300
|
const parity = pubkey[64] & 1;
|
|
1268
|
-
const newKey = pubkey.
|
|
1301
|
+
const newKey = Buffer.from(pubkey.subarray(0, 33));
|
|
1269
1302
|
newKey[0] = 2 | parity;
|
|
1270
1303
|
return newKey;
|
|
1271
1304
|
}
|
|
1272
|
-
return
|
|
1305
|
+
return Buffer.from(pubkey);
|
|
1273
1306
|
}
|
|
1274
1307
|
function isPubkeyLike(buf) {
|
|
1275
1308
|
return buf.length === 33 && bscript.isCanonicalPubKey(buf);
|
package/build/script.js
CHANGED
|
@@ -92,7 +92,7 @@ export function decompile(buffer) {
|
|
|
92
92
|
i += d.size;
|
|
93
93
|
if (i + d.number > buffer.length)
|
|
94
94
|
return null;
|
|
95
|
-
const data = buffer.
|
|
95
|
+
const data = buffer.subarray(i, i + d.number);
|
|
96
96
|
i += d.number;
|
|
97
97
|
const op = asMinimalOP(data);
|
|
98
98
|
if (op !== undefined) {
|
|
@@ -161,7 +161,7 @@ export function isCanonicalScriptSignature(buffer) {
|
|
|
161
161
|
return false;
|
|
162
162
|
if (!isDefinedHashType(buffer[buffer.length - 1]))
|
|
163
163
|
return false;
|
|
164
|
-
return bip66.check(buffer.
|
|
164
|
+
return bip66.check(buffer.subarray(0, -1));
|
|
165
165
|
}
|
|
166
166
|
export const number = scriptNumber;
|
|
167
167
|
export const signature = scriptSignature;
|
|
@@ -9,14 +9,14 @@ function toDER(x) {
|
|
|
9
9
|
++i;
|
|
10
10
|
if (i === x.length)
|
|
11
11
|
return ZERO;
|
|
12
|
-
x = x.
|
|
12
|
+
x = x.subarray(i);
|
|
13
13
|
if (x[0] & 0x80)
|
|
14
14
|
return Buffer.concat([ZERO, x], 1 + x.length);
|
|
15
15
|
return x;
|
|
16
16
|
}
|
|
17
17
|
function fromDER(x) {
|
|
18
18
|
if (x[0] === 0x00)
|
|
19
|
-
x = x.
|
|
19
|
+
x = x.subarray(1);
|
|
20
20
|
const buffer = Buffer.alloc(32, 0);
|
|
21
21
|
const bstart = Math.max(0, 32 - x.length);
|
|
22
22
|
x.copy(buffer, bstart);
|
|
@@ -25,9 +25,9 @@ function fromDER(x) {
|
|
|
25
25
|
export function decode(buffer) {
|
|
26
26
|
const hashType = buffer.readUInt8(buffer.length - 1);
|
|
27
27
|
if (!isDefinedHashType(hashType)) {
|
|
28
|
-
throw new Error(
|
|
28
|
+
throw new Error(`Invalid hashType ${hashType}`);
|
|
29
29
|
}
|
|
30
|
-
const decoded = bip66.decode(buffer.
|
|
30
|
+
const decoded = bip66.decode(buffer.subarray(0, -1));
|
|
31
31
|
const r = fromDER(decoded.r);
|
|
32
32
|
const s = fromDER(decoded.s);
|
|
33
33
|
const signature = Buffer.concat([r, s], 64);
|
|
@@ -39,11 +39,11 @@ export function encode(signature, hashType) {
|
|
|
39
39
|
hashType: types.UInt8,
|
|
40
40
|
}, { signature, hashType });
|
|
41
41
|
if (!isDefinedHashType(hashType)) {
|
|
42
|
-
throw new Error(
|
|
42
|
+
throw new Error(`Invalid hashType ${hashType}`);
|
|
43
43
|
}
|
|
44
44
|
const hashTypeBuffer = Buffer.allocUnsafe(1);
|
|
45
45
|
hashTypeBuffer.writeUInt8(hashType, 0);
|
|
46
|
-
const r = toDER(signature.
|
|
47
|
-
const s = toDER(signature.
|
|
46
|
+
const r = toDER(signature.subarray(0, 32));
|
|
47
|
+
const s = toDER(signature.subarray(32, 64));
|
|
48
48
|
return Buffer.concat([bip66.encode(r, s), hashTypeBuffer]);
|
|
49
49
|
}
|
package/build/transaction.js
CHANGED
|
@@ -25,7 +25,7 @@ const BLANK_OUTPUT = {
|
|
|
25
25
|
valueBuffer: VALUE_UINT64_MAX,
|
|
26
26
|
};
|
|
27
27
|
function isOutput(out) {
|
|
28
|
-
return
|
|
28
|
+
return 'value' in out;
|
|
29
29
|
}
|
|
30
30
|
export class Transaction {
|
|
31
31
|
constructor() {
|
|
@@ -98,7 +98,7 @@ export class Transaction {
|
|
|
98
98
|
return this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0].hash);
|
|
99
99
|
}
|
|
100
100
|
addInput(hash, index, sequence, scriptSig) {
|
|
101
|
-
typeforce(types.tuple(types.Hash256bit, types.UInt32, types.maybe(types.UInt32), types.maybe(types.Buffer)),
|
|
101
|
+
typeforce(types.tuple(types.Hash256bit, types.UInt32, types.maybe(types.UInt32), types.maybe(types.Buffer)), [hash, index, sequence, scriptSig]);
|
|
102
102
|
if (types.Null(sequence)) {
|
|
103
103
|
sequence = Transaction.DEFAULT_SEQUENCE;
|
|
104
104
|
}
|
|
@@ -111,7 +111,7 @@ export class Transaction {
|
|
|
111
111
|
}) - 1);
|
|
112
112
|
}
|
|
113
113
|
addOutput(scriptPubKey, value) {
|
|
114
|
-
typeforce(types.tuple(types.Buffer, types.Satoshi),
|
|
114
|
+
typeforce(types.tuple(types.Buffer, types.Satoshi), [scriptPubKey, value]);
|
|
115
115
|
return (this.outs.push({
|
|
116
116
|
script: scriptPubKey,
|
|
117
117
|
value,
|
|
@@ -169,10 +169,17 @@ export class Transaction {
|
|
|
169
169
|
return newTx;
|
|
170
170
|
}
|
|
171
171
|
hashForSignature(inIndex, prevOutScript, hashType) {
|
|
172
|
-
typeforce(types.tuple(types.UInt32, types.Buffer, types.Number),
|
|
172
|
+
typeforce(types.tuple(types.UInt32, types.Buffer, types.Number), [
|
|
173
|
+
inIndex,
|
|
174
|
+
prevOutScript,
|
|
175
|
+
hashType,
|
|
176
|
+
]);
|
|
173
177
|
if (inIndex >= this.ins.length)
|
|
174
178
|
return ONE;
|
|
175
|
-
const
|
|
179
|
+
const decompiled = bscript.decompile(prevOutScript);
|
|
180
|
+
if (!decompiled)
|
|
181
|
+
throw new Error('Could not decompile prevOutScript');
|
|
182
|
+
const ourScript = bscript.compile(decompiled.filter((x) => {
|
|
176
183
|
return x !== opcodes.OP_CODESEPARATOR;
|
|
177
184
|
}));
|
|
178
185
|
const txTmp = this.clone();
|
|
@@ -213,7 +220,7 @@ export class Transaction {
|
|
|
213
220
|
return bcrypto.hash256(buffer);
|
|
214
221
|
}
|
|
215
222
|
hashForWitnessV1(inIndex, prevOutScripts, values, hashType, leafHash, annex) {
|
|
216
|
-
typeforce(types.tuple(types.UInt32, typeforce.arrayOf(types.Buffer), typeforce.arrayOf(types.Satoshi), types.UInt32),
|
|
223
|
+
typeforce(types.tuple(types.UInt32, typeforce.arrayOf(types.Buffer), typeforce.arrayOf(types.Satoshi), types.UInt32), [inIndex, prevOutScripts, values, hashType]);
|
|
217
224
|
if (values.length !== this.ins.length || prevOutScripts.length !== this.ins.length) {
|
|
218
225
|
throw new Error('Must supply prevout script and value for all inputs');
|
|
219
226
|
}
|
|
@@ -311,7 +318,12 @@ export class Transaction {
|
|
|
311
318
|
return bcrypto.taggedHash('TapSighash', Buffer.concat([Buffer.from([0x00]), sigMsgWriter.end()]));
|
|
312
319
|
}
|
|
313
320
|
hashForWitnessV0(inIndex, prevOutScript, value, hashType) {
|
|
314
|
-
typeforce(types.tuple(types.UInt32, types.Buffer, types.Satoshi, types.UInt32),
|
|
321
|
+
typeforce(types.tuple(types.UInt32, types.Buffer, types.Satoshi, types.UInt32), [
|
|
322
|
+
inIndex,
|
|
323
|
+
prevOutScript,
|
|
324
|
+
value,
|
|
325
|
+
hashType,
|
|
326
|
+
]);
|
|
315
327
|
let tbuffer = Buffer.from([]);
|
|
316
328
|
let bufferWriter;
|
|
317
329
|
let hashOutputs = ZERO;
|
|
@@ -388,11 +400,11 @@ export class Transaction {
|
|
|
388
400
|
return this.toBuffer(undefined, undefined).toString('hex');
|
|
389
401
|
}
|
|
390
402
|
setInputScript(index, scriptSig) {
|
|
391
|
-
typeforce(types.tuple(types.Number, types.Buffer),
|
|
403
|
+
typeforce(types.tuple(types.Number, types.Buffer), [index, scriptSig]);
|
|
392
404
|
this.ins[index].script = scriptSig;
|
|
393
405
|
}
|
|
394
406
|
setWitness(index, witness) {
|
|
395
|
-
typeforce(types.tuple(types.Number, [types.Buffer]),
|
|
407
|
+
typeforce(types.tuple(types.Number, [types.Buffer]), [index, witness]);
|
|
396
408
|
this.ins[index].witness = witness;
|
|
397
409
|
}
|
|
398
410
|
__toBuffer(buffer, initialOffset, _ALLOW_WITNESS = false) {
|
|
@@ -429,7 +441,7 @@ export class Transaction {
|
|
|
429
441
|
}
|
|
430
442
|
bufferWriter.writeUInt32(this.locktime);
|
|
431
443
|
if (initialOffset !== undefined)
|
|
432
|
-
return buffer.
|
|
444
|
+
return buffer.subarray(initialOffset, bufferWriter.offset);
|
|
433
445
|
return buffer;
|
|
434
446
|
}
|
|
435
447
|
}
|