@btc-vision/transaction 1.1.16 → 1.1.17
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/_version.d.ts +1 -1
- package/browser/index.js +1 -1
- package/browser/keypair/Address.d.ts +2 -0
- package/browser/signer/SignerUtils.d.ts +6 -0
- package/browser/transaction/shared/TweakedTransaction.d.ts +5 -6
- package/browser/utxo/interfaces/IUTXO.d.ts +1 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/keypair/Address.d.ts +2 -0
- package/build/keypair/Address.js +9 -0
- package/build/signer/SignerUtils.d.ts +6 -0
- package/build/signer/SignerUtils.js +56 -0
- package/build/transaction/browser/extensions/UnisatSigner.js +5 -32
- package/build/transaction/browser/extensions/XverseSigner.js +5 -48
- package/build/transaction/builders/FundingTransaction.js +6 -1
- package/build/transaction/builders/TransactionBuilder.js +3 -1
- package/build/transaction/shared/TweakedTransaction.d.ts +5 -6
- package/build/transaction/shared/TweakedTransaction.js +121 -91
- package/build/utils/BitcoinUtils.js +4 -4
- package/build/utxo/OPNetLimitedProvider.js +1 -0
- package/build/utxo/interfaces/IUTXO.d.ts +1 -0
- package/package.json +2 -5
- package/src/_version.ts +1 -1
- package/src/keypair/Address.ts +15 -0
- package/src/signer/SignerUtils.ts +78 -0
- package/src/transaction/TransactionFactory.ts +0 -253
- package/src/transaction/browser/extensions/UnisatSigner.ts +4 -40
- package/src/transaction/browser/extensions/XverseSigner.ts +9 -68
- package/src/transaction/builders/FundingTransaction.ts +7 -2
- package/src/transaction/builders/TransactionBuilder.ts +3 -1
- package/src/transaction/shared/TweakedTransaction.ts +224 -77
- package/src/utils/BitcoinUtils.ts +4 -4
- package/src/utxo/OPNetLimitedProvider.ts +1 -0
- package/src/utxo/interfaces/IUTXO.ts +2 -0
|
@@ -20,11 +20,23 @@ import { ECPairInterface } from 'ecpair';
|
|
|
20
20
|
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
21
21
|
import { UTXO } from '../../utxo/interfaces/IUTXO.js';
|
|
22
22
|
import { TapLeafScript } from '../interfaces/Tap.js';
|
|
23
|
-
import { AddressTypes, AddressVerificator } from '../../keypair/AddressVerificator.js';
|
|
24
23
|
import { ChainId } from '../../network/ChainId.js';
|
|
25
24
|
import { varuint } from '@btc-vision/bitcoin/src/bufferutils.js';
|
|
26
|
-
import * as bscript from '@btc-vision/bitcoin/src/script.js';
|
|
27
25
|
import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
|
|
26
|
+
import {
|
|
27
|
+
canSignNonTaprootInput,
|
|
28
|
+
isTaprootInput,
|
|
29
|
+
pubkeyInScript,
|
|
30
|
+
} from '../../signer/SignerUtils.js';
|
|
31
|
+
import {
|
|
32
|
+
isP2MS,
|
|
33
|
+
isP2PK,
|
|
34
|
+
isP2PKH,
|
|
35
|
+
isP2SHScript,
|
|
36
|
+
isP2TR,
|
|
37
|
+
isP2WPKH,
|
|
38
|
+
isP2WSHScript,
|
|
39
|
+
} from '@btc-vision/bitcoin/src/psbt/psbtutils.js';
|
|
28
40
|
|
|
29
41
|
export interface ITweakedTransactionData {
|
|
30
42
|
readonly signer: Signer | ECPairInterface | UnisatSigner;
|
|
@@ -370,6 +382,7 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
370
382
|
* @param {number} i - The index of the input
|
|
371
383
|
* @param {Signer} signer - The signer to use
|
|
372
384
|
* @param {boolean} [reverse=false] - Should the input be signed in reverse
|
|
385
|
+
* @param {boolean} [errored=false] - Was there an error
|
|
373
386
|
* @protected
|
|
374
387
|
*/
|
|
375
388
|
protected async signInput(
|
|
@@ -378,38 +391,48 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
378
391
|
i: number,
|
|
379
392
|
signer: Signer | ECPairInterface,
|
|
380
393
|
reverse: boolean = false,
|
|
394
|
+
errored: boolean = false,
|
|
381
395
|
): Promise<void> {
|
|
382
396
|
const publicKey = signer.publicKey;
|
|
383
|
-
let isTaproot = this.isTaprootInput(input);
|
|
384
397
|
|
|
398
|
+
let isTaproot = isTaprootInput(input);
|
|
385
399
|
if (reverse) {
|
|
386
400
|
isTaproot = !isTaproot;
|
|
387
401
|
}
|
|
388
402
|
|
|
389
403
|
let signed: boolean = false;
|
|
390
|
-
|
|
404
|
+
let didError: boolean = false;
|
|
391
405
|
if (isTaproot) {
|
|
392
406
|
try {
|
|
393
407
|
await this.attemptSignTaproot(transaction, input, i, signer, publicKey);
|
|
394
408
|
signed = true;
|
|
395
409
|
} catch (e) {
|
|
396
|
-
this.error(
|
|
410
|
+
this.error(
|
|
411
|
+
`Failed to sign Taproot script path input ${i} (reverse: ${reverse}): ${(e as Error).message}`,
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
didError = true;
|
|
397
415
|
}
|
|
398
416
|
} else {
|
|
399
417
|
// Non-Taproot input
|
|
400
|
-
if (!reverse ?
|
|
418
|
+
if (!reverse ? canSignNonTaprootInput(input, publicKey) : true) {
|
|
401
419
|
try {
|
|
402
420
|
await this.signNonTaprootInput(signer, transaction, i);
|
|
403
421
|
signed = true;
|
|
404
422
|
} catch (e) {
|
|
405
|
-
this.error(`Failed to sign non-Taproot input ${i}: ${e}`);
|
|
423
|
+
this.error(`Failed to sign non-Taproot input ${i}: ${(e as Error).stack}`);
|
|
424
|
+
didError = true;
|
|
406
425
|
}
|
|
407
426
|
}
|
|
408
427
|
}
|
|
409
428
|
|
|
410
429
|
if (!signed) {
|
|
430
|
+
if (didError && errored) {
|
|
431
|
+
throw new Error(`Failed to sign input ${i} with the provided signer.`);
|
|
432
|
+
}
|
|
433
|
+
|
|
411
434
|
try {
|
|
412
|
-
await this.signInput(transaction, input, i, signer, true);
|
|
435
|
+
await this.signInput(transaction, input, i, signer, true, didError);
|
|
413
436
|
} catch {
|
|
414
437
|
throw new Error(`Cannot sign input ${i} with the provided signer.`);
|
|
415
438
|
}
|
|
@@ -585,14 +608,202 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
585
608
|
return;
|
|
586
609
|
}
|
|
587
610
|
|
|
611
|
+
protected generateP2SHP2PKHRedeemScript(inputAddr: string):
|
|
612
|
+
| {
|
|
613
|
+
redeemScript: Buffer;
|
|
614
|
+
outputScript: Buffer;
|
|
615
|
+
}
|
|
616
|
+
| undefined {
|
|
617
|
+
const pubkey = Buffer.isBuffer(this.signer.publicKey)
|
|
618
|
+
? this.signer.publicKey
|
|
619
|
+
: Buffer.from(this.signer.publicKey, 'hex');
|
|
620
|
+
|
|
621
|
+
const w = payments.p2wpkh({
|
|
622
|
+
pubkey: pubkey,
|
|
623
|
+
network: this.network,
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
const p = payments.p2sh({
|
|
627
|
+
redeem: w,
|
|
628
|
+
network: this.network,
|
|
629
|
+
});
|
|
630
|
+
|
|
631
|
+
const address = p.address;
|
|
632
|
+
const redeemScript = p.redeem?.output;
|
|
633
|
+
if (!redeemScript) {
|
|
634
|
+
throw new Error('Failed to generate P2SH-P2WPKH redeem script');
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
if (address === inputAddr && p.redeem && p.redeem.output && p.output) {
|
|
638
|
+
return {
|
|
639
|
+
redeemScript: p.redeem.output,
|
|
640
|
+
outputScript: p.output,
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
|
|
588
647
|
/**
|
|
589
|
-
* Generate the PSBT input extended
|
|
648
|
+
* Generate the PSBT input extended, supporting various script types
|
|
590
649
|
* @param {UTXO} utxo The UTXO
|
|
591
650
|
* @param {number} i The index of the input
|
|
592
651
|
* @protected
|
|
593
652
|
* @returns {PsbtInputExtended} The PSBT input extended
|
|
594
653
|
*/
|
|
595
654
|
protected generatePsbtInputExtended(utxo: UTXO, i: number): PsbtInputExtended {
|
|
655
|
+
const script = Buffer.from(utxo.scriptPubKey.hex, 'hex');
|
|
656
|
+
|
|
657
|
+
const input: PsbtInputExtended = {
|
|
658
|
+
hash: utxo.transactionId,
|
|
659
|
+
index: utxo.outputIndex,
|
|
660
|
+
sequence: this.sequence,
|
|
661
|
+
witnessUtxo: {
|
|
662
|
+
value: Number(utxo.value),
|
|
663
|
+
script,
|
|
664
|
+
},
|
|
665
|
+
};
|
|
666
|
+
|
|
667
|
+
// Handle P2PKH (Legacy)
|
|
668
|
+
if (isP2PKH(script)) {
|
|
669
|
+
// Legacy input requires nonWitnessUtxo
|
|
670
|
+
if (utxo.nonWitnessUtxo) {
|
|
671
|
+
//delete input.witnessUtxo;
|
|
672
|
+
input.nonWitnessUtxo = Buffer.isBuffer(utxo.nonWitnessUtxo)
|
|
673
|
+
? utxo.nonWitnessUtxo
|
|
674
|
+
: Buffer.from(utxo.nonWitnessUtxo, 'hex');
|
|
675
|
+
} else {
|
|
676
|
+
throw new Error('Missing nonWitnessUtxo for P2PKH UTXO');
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Handle P2WPKH (SegWit)
|
|
681
|
+
else if (isP2WPKH(script)) {
|
|
682
|
+
// No redeemScript required for pure P2WPKH
|
|
683
|
+
// witnessUtxo is enough, no nonWitnessUtxo needed.
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// Handle P2WSH (SegWit)
|
|
687
|
+
else if (isP2WSHScript(script)) {
|
|
688
|
+
// P2WSH requires a witnessScript
|
|
689
|
+
if (!utxo.witnessScript) {
|
|
690
|
+
// Can't just invent a witnessScript out of thin air. If not provided, it's an error.
|
|
691
|
+
throw new Error('Missing witnessScript for P2WSH UTXO');
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
input.witnessScript = Buffer.isBuffer(utxo.witnessScript)
|
|
695
|
+
? utxo.witnessScript
|
|
696
|
+
: Buffer.from(utxo.witnessScript, 'hex');
|
|
697
|
+
|
|
698
|
+
// No nonWitnessUtxo needed for segwit
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Handle P2SH (Can be legacy or wrapping segwit)
|
|
702
|
+
else if (isP2SHScript(script)) {
|
|
703
|
+
// Redeem script is required for P2SH
|
|
704
|
+
let redeemScriptBuf: Buffer | undefined;
|
|
705
|
+
|
|
706
|
+
if (utxo.redeemScript) {
|
|
707
|
+
redeemScriptBuf = Buffer.isBuffer(utxo.redeemScript)
|
|
708
|
+
? utxo.redeemScript
|
|
709
|
+
: Buffer.from(utxo.redeemScript, 'hex');
|
|
710
|
+
} else {
|
|
711
|
+
// Attempt to generate a redeem script if missing
|
|
712
|
+
if (!utxo.scriptPubKey.address) {
|
|
713
|
+
throw new Error(
|
|
714
|
+
'Missing redeemScript and no address to regenerate it for P2SH UTXO',
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
const legacyScripts = this.generateP2SHP2PKHRedeemScript(utxo.scriptPubKey.address);
|
|
719
|
+
if (!legacyScripts) {
|
|
720
|
+
throw new Error('Missing redeemScript for P2SH UTXO and unable to regenerate');
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
redeemScriptBuf = legacyScripts.redeemScript;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
input.redeemScript = redeemScriptBuf;
|
|
727
|
+
|
|
728
|
+
// Check if redeemScript is wrapping segwit (like P2SH-P2WPKH or P2SH-P2WSH)
|
|
729
|
+
const payment = payments.p2sh({ redeem: { output: input.redeemScript } });
|
|
730
|
+
if (!payment.redeem) {
|
|
731
|
+
throw new Error('Failed to extract redeem script from P2SH UTXO');
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
const redeemOutput = payment.redeem.output;
|
|
735
|
+
if (!redeemOutput) {
|
|
736
|
+
throw new Error('Failed to extract redeem output from P2SH UTXO');
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
if (utxo.nonWitnessUtxo) {
|
|
740
|
+
input.nonWitnessUtxo = Buffer.isBuffer(utxo.nonWitnessUtxo)
|
|
741
|
+
? utxo.nonWitnessUtxo
|
|
742
|
+
: Buffer.from(utxo.nonWitnessUtxo, 'hex');
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
if (isP2WPKH(redeemOutput)) {
|
|
746
|
+
// P2SH-P2WPKH
|
|
747
|
+
// Use witnessUtxo + redeemScript
|
|
748
|
+
delete input.nonWitnessUtxo; // ensure we do NOT have nonWitnessUtxo
|
|
749
|
+
// witnessScript is not needed
|
|
750
|
+
} else if (isP2WSHScript(redeemOutput)) {
|
|
751
|
+
// P2SH-P2WSH
|
|
752
|
+
// Use witnessUtxo + redeemScript + witnessScript
|
|
753
|
+
delete input.nonWitnessUtxo; // ensure we do NOT have nonWitnessUtxo
|
|
754
|
+
if (!input.witnessScript) {
|
|
755
|
+
throw new Error('Missing witnessScript for P2SH-P2WSH UTXO');
|
|
756
|
+
}
|
|
757
|
+
} else {
|
|
758
|
+
// Legacy P2SH
|
|
759
|
+
// Use nonWitnessUtxo
|
|
760
|
+
delete input.witnessUtxo; // ensure we do NOT have witnessUtxo
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// Handle P2TR (Taproot)
|
|
765
|
+
else if (isP2TR(script)) {
|
|
766
|
+
// Taproot inputs do not require nonWitnessUtxo, witnessUtxo is sufficient.
|
|
767
|
+
|
|
768
|
+
// If there's a configured sighash type
|
|
769
|
+
if (this.sighashTypes) {
|
|
770
|
+
const inputSign = TweakedTransaction.calculateSignHash(this.sighashTypes);
|
|
771
|
+
if (inputSign) input.sighashType = inputSign;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// Taproot internal key
|
|
775
|
+
this.tweakSigner();
|
|
776
|
+
input.tapInternalKey = this.internalPubKeyToXOnly();
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
// Handle P2PK (legacy) or P2MS (bare multisig)
|
|
780
|
+
else if (isP2PK(script) || isP2MS(script)) {
|
|
781
|
+
// These are legacy scripts, need nonWitnessUtxo
|
|
782
|
+
if (utxo.nonWitnessUtxo) {
|
|
783
|
+
input.nonWitnessUtxo = Buffer.isBuffer(utxo.nonWitnessUtxo)
|
|
784
|
+
? utxo.nonWitnessUtxo
|
|
785
|
+
: Buffer.from(utxo.nonWitnessUtxo, 'hex');
|
|
786
|
+
} else {
|
|
787
|
+
throw new Error('Missing nonWitnessUtxo for P2PK or P2MS UTXO');
|
|
788
|
+
}
|
|
789
|
+
} else {
|
|
790
|
+
this.error(`Unknown or unsupported script type for output: ${utxo.scriptPubKey.hex}`);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// TapLeafScript if available
|
|
794
|
+
if (this.tapLeafScript) {
|
|
795
|
+
input.tapLeafScript = [this.tapLeafScript];
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
// If the first input and we have a global nonWitnessUtxo not yet set
|
|
799
|
+
if (i === 0 && this.nonWitnessUtxo) {
|
|
800
|
+
input.nonWitnessUtxo = this.nonWitnessUtxo;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
return input;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/*protected generatePsbtInputExtended(utxo: UTXO, i: number): PsbtInputExtended {
|
|
596
807
|
const input: PsbtInputExtended = {
|
|
597
808
|
hash: utxo.transactionId,
|
|
598
809
|
index: utxo.outputIndex,
|
|
@@ -655,10 +866,6 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
655
866
|
if (inputSign) input.sighashType = inputSign;
|
|
656
867
|
}
|
|
657
868
|
|
|
658
|
-
if (this.tapLeafScript) {
|
|
659
|
-
input.tapLeafScript = [this.tapLeafScript];
|
|
660
|
-
}
|
|
661
|
-
|
|
662
869
|
if (i === 0 && this.nonWitnessUtxo) {
|
|
663
870
|
input.nonWitnessUtxo = this.nonWitnessUtxo;
|
|
664
871
|
}
|
|
@@ -673,8 +880,10 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
673
880
|
input.tapInternalKey = this.internalPubKeyToXOnly();
|
|
674
881
|
}
|
|
675
882
|
|
|
883
|
+
console.log(input);
|
|
884
|
+
|
|
676
885
|
return input;
|
|
677
|
-
}
|
|
886
|
+
}*/
|
|
678
887
|
|
|
679
888
|
protected customFinalizerP2SH = (
|
|
680
889
|
inputIndex: number,
|
|
@@ -747,7 +956,7 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
747
956
|
if (input.tapLeafScript && input.tapLeafScript.length > 0) {
|
|
748
957
|
// Check if the signer's public key is involved in any tapLeafScript
|
|
749
958
|
for (const tapLeafScript of input.tapLeafScript) {
|
|
750
|
-
if (
|
|
959
|
+
if (pubkeyInScript(publicKey, tapLeafScript.script)) {
|
|
751
960
|
// The public key is in the script; it's a script spend
|
|
752
961
|
return true;
|
|
753
962
|
}
|
|
@@ -756,68 +965,6 @@ export abstract class TweakedTransaction extends Logger {
|
|
|
756
965
|
return false;
|
|
757
966
|
}
|
|
758
967
|
|
|
759
|
-
// Helper method to determine if an input is Taproot
|
|
760
|
-
private isTaprootInput(input: PsbtInput): boolean {
|
|
761
|
-
if (input.tapInternalKey || input.tapKeySig || input.tapScriptSig || input.tapLeafScript) {
|
|
762
|
-
return true;
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
if (input.witnessUtxo) {
|
|
766
|
-
const script = input.witnessUtxo.script;
|
|
767
|
-
// Check if the script is a P2TR output (OP_1 [32-byte key])
|
|
768
|
-
return script.length === 34 && script[0] === opcodes.OP_1 && script[1] === 0x20;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
return false;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
// Check if the signer can sign the non-Taproot input
|
|
775
|
-
private canSignNonTaprootInput(input: PsbtInput, publicKey: Buffer): boolean {
|
|
776
|
-
const script = this.getInputRelevantScript(input);
|
|
777
|
-
if (script) {
|
|
778
|
-
return this.pubkeyInScript(publicKey, script);
|
|
779
|
-
}
|
|
780
|
-
return false;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
// Helper method to extract the relevant script from the input
|
|
784
|
-
private getInputRelevantScript(input: PsbtInput): Buffer | null {
|
|
785
|
-
if (input.redeemScript) {
|
|
786
|
-
return input.redeemScript;
|
|
787
|
-
}
|
|
788
|
-
if (input.witnessScript) {
|
|
789
|
-
return input.witnessScript;
|
|
790
|
-
}
|
|
791
|
-
if (input.witnessUtxo) {
|
|
792
|
-
return input.witnessUtxo.script;
|
|
793
|
-
}
|
|
794
|
-
if (input.nonWitnessUtxo) {
|
|
795
|
-
// Additional logic can be added to extract script from nonWitnessUtxo
|
|
796
|
-
return null;
|
|
797
|
-
}
|
|
798
|
-
return null;
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
// Helper method to check if a public key is in a script
|
|
802
|
-
private pubkeyInScript(pubkey: Buffer, script: Buffer): boolean {
|
|
803
|
-
return this.pubkeyPositionInScript(pubkey, script) !== -1;
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
private pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number {
|
|
807
|
-
const pubkeyHash = bitCrypto.hash160(pubkey);
|
|
808
|
-
const pubkeyXOnly = toXOnly(pubkey);
|
|
809
|
-
|
|
810
|
-
const decompiled = bscript.decompile(script);
|
|
811
|
-
if (decompiled === null) throw new Error('Unknown script error');
|
|
812
|
-
|
|
813
|
-
return decompiled.findIndex((element) => {
|
|
814
|
-
if (typeof element === 'number') return false;
|
|
815
|
-
return (
|
|
816
|
-
element.equals(pubkey) || element.equals(pubkeyHash) || element.equals(pubkeyXOnly)
|
|
817
|
-
);
|
|
818
|
-
});
|
|
819
|
-
}
|
|
820
|
-
|
|
821
968
|
private async signTaprootInput(
|
|
822
969
|
signer: Signer | ECPairInterface,
|
|
823
970
|
transaction: Psbt,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Utility class for Bitcoin related functions
|
|
@@ -34,16 +34,16 @@ export class BitcoinUtils {
|
|
|
34
34
|
window.crypto.getRandomValues(array);
|
|
35
35
|
|
|
36
36
|
return Buffer.from(array);
|
|
37
|
-
} else if (crypto && typeof crypto.getRandomValues === 'function') {
|
|
37
|
+
} else if (globalThis.crypto && typeof globalThis.crypto.getRandomValues === 'function') {
|
|
38
38
|
const array = new Uint8Array(length);
|
|
39
|
-
crypto.getRandomValues(array);
|
|
39
|
+
globalThis.crypto.getRandomValues(array);
|
|
40
40
|
|
|
41
41
|
return Buffer.from(array);
|
|
42
42
|
} else {
|
|
43
43
|
console.log(
|
|
44
44
|
`No secure random number generator available. Please upgrade your environment.`,
|
|
45
45
|
globalThis.window.crypto,
|
|
46
|
-
crypto,
|
|
46
|
+
globalThis.crypto,
|
|
47
47
|
);
|
|
48
48
|
throw new Error(
|
|
49
49
|
'No secure random number generator available. Please upgrade your environment.',
|
|
@@ -5,6 +5,7 @@ export interface UTXO {
|
|
|
5
5
|
readonly outputIndex: number;
|
|
6
6
|
readonly value: bigint;
|
|
7
7
|
readonly scriptPubKey: ScriptPubKey;
|
|
8
|
+
|
|
8
9
|
redeemScript?: string | Buffer;
|
|
9
10
|
witnessScript?: string | Buffer;
|
|
10
11
|
nonWitnessUtxo?: string | Buffer;
|
|
@@ -31,4 +32,5 @@ export interface RawUTXOResponse {
|
|
|
31
32
|
readonly outputIndex: number;
|
|
32
33
|
readonly value: string;
|
|
33
34
|
readonly scriptPubKey: ScriptPubKey;
|
|
35
|
+
readonly raw: string;
|
|
34
36
|
}
|