@caravan/psbt 1.0.1 → 1.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.
- package/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-lint.log +19 -14
- package/.turbo/turbo-test.log +44 -44
- package/CHANGELOG.md +6 -0
- package/README.md +71 -16
- package/dist/index.d.mts +67 -12
- package/dist/index.d.ts +67 -12
- package/dist/index.js +162 -13
- package/dist/index.mjs +162 -13
- package/package.json +1 -1
- package/src/psbtv2/psbtv2.test.ts +150 -1
- package/src/psbtv2/psbtv2.ts +268 -22
package/dist/index.js
CHANGED
|
@@ -235,7 +235,10 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
235
235
|
* Globals Getters/Setters
|
|
236
236
|
*/
|
|
237
237
|
get PSBT_GLOBAL_XPUB() {
|
|
238
|
-
return getNonUniqueKeyTypeValues(
|
|
238
|
+
return getNonUniqueKeyTypeValues(
|
|
239
|
+
this.globalMap,
|
|
240
|
+
"01" /* PSBT_GLOBAL_XPUB */
|
|
241
|
+
);
|
|
239
242
|
}
|
|
240
243
|
get PSBT_GLOBAL_TX_VERSION() {
|
|
241
244
|
const val = this.globalMap.get("02" /* PSBT_GLOBAL_TX_VERSION */);
|
|
@@ -409,16 +412,28 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
409
412
|
);
|
|
410
413
|
}
|
|
411
414
|
get PSBT_IN_RIPEMD160() {
|
|
412
|
-
return getNonUniqueKeyTypeValues(
|
|
415
|
+
return getNonUniqueKeyTypeValues(
|
|
416
|
+
this.inputMaps,
|
|
417
|
+
"0a" /* PSBT_IN_RIPEMD160 */
|
|
418
|
+
);
|
|
413
419
|
}
|
|
414
420
|
get PSBT_IN_SHA256() {
|
|
415
|
-
return getNonUniqueKeyTypeValues(
|
|
421
|
+
return getNonUniqueKeyTypeValues(
|
|
422
|
+
this.inputMaps,
|
|
423
|
+
"0b" /* PSBT_IN_SHA256 */
|
|
424
|
+
);
|
|
416
425
|
}
|
|
417
426
|
get PSBT_IN_HASH160() {
|
|
418
|
-
return getNonUniqueKeyTypeValues(
|
|
427
|
+
return getNonUniqueKeyTypeValues(
|
|
428
|
+
this.inputMaps,
|
|
429
|
+
"0c" /* PSBT_IN_HASH160 */
|
|
430
|
+
);
|
|
419
431
|
}
|
|
420
432
|
get PSBT_IN_HASH256() {
|
|
421
|
-
return getNonUniqueKeyTypeValues(
|
|
433
|
+
return getNonUniqueKeyTypeValues(
|
|
434
|
+
this.inputMaps,
|
|
435
|
+
"0d" /* PSBT_IN_HASH256 */
|
|
436
|
+
);
|
|
422
437
|
}
|
|
423
438
|
get PSBT_IN_PREVIOUS_TXID() {
|
|
424
439
|
const indices = [];
|
|
@@ -570,6 +585,106 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
570
585
|
"fc" /* PSBT_OUT_PROPRIETARY */
|
|
571
586
|
);
|
|
572
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* Operator Role Validation Getters
|
|
590
|
+
*/
|
|
591
|
+
/**
|
|
592
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Constructor
|
|
593
|
+
* role.
|
|
594
|
+
*
|
|
595
|
+
* This check assumes that the Creator used this class's constructor method to
|
|
596
|
+
* initialize the PsbtV2 without passing a psbt (constructor defaults were
|
|
597
|
+
* set).
|
|
598
|
+
*/
|
|
599
|
+
get isReadyForConstructor() {
|
|
600
|
+
if (this.PSBT_GLOBAL_FALLBACK_LOCKTIME === null) {
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
if (!this.isModifiable(["INPUTS" /* INPUTS */]) && !this.isModifiable(["OUTPUTS" /* OUTPUTS */])) {
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
return true;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Updater
|
|
610
|
+
* role.
|
|
611
|
+
*
|
|
612
|
+
* Before signatures are added, but after an input is added, a PsbtV2 is
|
|
613
|
+
* likely to be ready for Constructor, ready for Updater, and ready for Signer
|
|
614
|
+
* simultaneously.
|
|
615
|
+
*
|
|
616
|
+
* According to BIP370, the Updater can modify the sequence number, but it is
|
|
617
|
+
* unclear if the Updater retains permissions provided in psbtv0 (BIP174). It
|
|
618
|
+
* is likely not the case that the Updater has the same permissions as
|
|
619
|
+
* previously because it seems to now be the realm of the Constructor to add
|
|
620
|
+
* inputs and outputs.
|
|
621
|
+
*/
|
|
622
|
+
get isReadyForUpdater() {
|
|
623
|
+
if (this.PSBT_GLOBAL_INPUT_COUNT === 0) {
|
|
624
|
+
return false;
|
|
625
|
+
}
|
|
626
|
+
if (!this.isModifiable(["INPUTS" /* INPUTS */])) {
|
|
627
|
+
return false;
|
|
628
|
+
}
|
|
629
|
+
return true;
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Signer role.
|
|
633
|
+
*/
|
|
634
|
+
get isReadyForSigner() {
|
|
635
|
+
if (this.PSBT_GLOBAL_INPUT_COUNT === 0) {
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
if (this.isReadyForTransactionExtractor) {
|
|
639
|
+
return false;
|
|
640
|
+
}
|
|
641
|
+
return true;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Combiner
|
|
645
|
+
* role.
|
|
646
|
+
*/
|
|
647
|
+
get isReadyForCombiner() {
|
|
648
|
+
return this.isReadyForConstructor || this.isReadyForUpdater || this.isReadyForSigner;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Unimplemented. Returns false.
|
|
652
|
+
*/
|
|
653
|
+
get isReadyForInputFinalizer() {
|
|
654
|
+
console.warn(
|
|
655
|
+
"PsbtV2.isReadyForInputFinalizer has been called, however, this getter is unimplemented and shouldn't be used."
|
|
656
|
+
);
|
|
657
|
+
return false;
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Transaction
|
|
661
|
+
* Extractor role.
|
|
662
|
+
*
|
|
663
|
+
* If all the inputs have been finalized, then the psbt is ready for the
|
|
664
|
+
* Transaction Extractor. According to BIP 174, it's the responsibility of the
|
|
665
|
+
* Input Finalizer to add scriptSigs or scriptWitnesses and then remove other
|
|
666
|
+
* details besides the UTXO. This getter checks that the Input Finalizer has
|
|
667
|
+
* finished its job.
|
|
668
|
+
*/
|
|
669
|
+
get isReadyForTransactionExtractor() {
|
|
670
|
+
for (let i = 0; i < this.PSBT_GLOBAL_INPUT_COUNT; i++) {
|
|
671
|
+
if (!this.PSBT_IN_FINAL_SCRIPTSIG[i] && !this.PSBT_IN_FINAL_SCRIPTWITNESS[i]) {
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
if (this.PSBT_IN_FINAL_SCRIPTSIG[i] && !this.PSBT_IN_NON_WITNESS_UTXO[i] || this.PSBT_IN_FINAL_SCRIPTWITNESS[i] && !this.PSBT_IN_WITNESS_UTXO[i]) {
|
|
675
|
+
return false;
|
|
676
|
+
}
|
|
677
|
+
if (
|
|
678
|
+
// Strings
|
|
679
|
+
this.PSBT_IN_REDEEM_SCRIPT[i] || this.PSBT_IN_WITNESS_SCRIPT[i] || this.PSBT_IN_POR_COMMITMENT[i] || this.PSBT_IN_TAP_KEY_SIG[i] || this.PSBT_IN_TAP_INTERNAL_KEY[i] || this.PSBT_IN_TAP_MERKLE_ROOT[i] || // Numbers
|
|
680
|
+
this.PSBT_IN_SIGHASH_TYPE[i] !== null || this.PSBT_IN_SEQUENCE[i] !== null || this.PSBT_IN_REQUIRED_TIME_LOCKTIME[i] !== null || this.PSBT_IN_REQUIRED_HEIGHT_LOCKTIME[i] !== null || // Arrays of non-unique keytype values
|
|
681
|
+
this.PSBT_IN_PARTIAL_SIG[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_BIP32_DERIVATION[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_RIPEMD160[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_SHA256[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_HASH160[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_HASH256[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_TAP_SCRIPT_SIG[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_TAP_LEAF_SCRIPT[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_TAP_BIP32_DERIVATION[i].filter((el) => el !== null).length > 0
|
|
682
|
+
) {
|
|
683
|
+
return false;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
return true;
|
|
687
|
+
}
|
|
573
688
|
/**
|
|
574
689
|
* Other Getters/Setters
|
|
575
690
|
*/
|
|
@@ -615,6 +730,10 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
615
730
|
this.PSBT_GLOBAL_INPUT_COUNT = 0;
|
|
616
731
|
this.PSBT_GLOBAL_OUTPUT_COUNT = 0;
|
|
617
732
|
this.PSBT_GLOBAL_FALLBACK_LOCKTIME = 0;
|
|
733
|
+
this.PSBT_GLOBAL_TX_MODIFIABLE = [
|
|
734
|
+
"INPUTS" /* INPUTS */,
|
|
735
|
+
"OUTPUTS" /* OUTPUTS */
|
|
736
|
+
];
|
|
618
737
|
}
|
|
619
738
|
/**
|
|
620
739
|
* Checks initial construction of any valid PsbtV2. It is called when a psbt
|
|
@@ -672,6 +791,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
672
791
|
* defined for PsbtV2.
|
|
673
792
|
*/
|
|
674
793
|
dangerouslySetGlobalTxVersion1() {
|
|
794
|
+
if (!this.isReadyForConstructor) {
|
|
795
|
+
throw Error(
|
|
796
|
+
"The PsbtV2 is not ready for a Constructor. The PSBT_GLOBAL_TX_VERSION should not be forced to version 1."
|
|
797
|
+
);
|
|
798
|
+
}
|
|
675
799
|
console.warn("Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!");
|
|
676
800
|
const bw = new import_bufio3.BufferWriter();
|
|
677
801
|
bw.writeI32(1);
|
|
@@ -700,6 +824,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
700
824
|
witnessScript,
|
|
701
825
|
bip32Derivation
|
|
702
826
|
}) {
|
|
827
|
+
if (!this.isReadyForConstructor) {
|
|
828
|
+
throw Error(
|
|
829
|
+
"The PsbtV2 is not ready for a Constructor. Inputs cannot be added."
|
|
830
|
+
);
|
|
831
|
+
}
|
|
703
832
|
if (!this.isModifiable(["INPUTS" /* INPUTS */])) {
|
|
704
833
|
throw Error(
|
|
705
834
|
"PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE inputs cannot be modified."
|
|
@@ -753,6 +882,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
753
882
|
witnessScript,
|
|
754
883
|
bip32Derivation
|
|
755
884
|
}) {
|
|
885
|
+
if (!this.isReadyForConstructor) {
|
|
886
|
+
throw Error(
|
|
887
|
+
"The PsbtV2 is not ready for a Constructor. Outputs cannot be added."
|
|
888
|
+
);
|
|
889
|
+
}
|
|
756
890
|
if (!this.isModifiable(["OUTPUTS" /* OUTPUTS */])) {
|
|
757
891
|
throw Error(
|
|
758
892
|
"PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE outputs cannot be modified."
|
|
@@ -792,6 +926,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
792
926
|
* Removes an input-map from inputMaps.
|
|
793
927
|
*/
|
|
794
928
|
deleteInput(index) {
|
|
929
|
+
if (!this.isReadyForConstructor) {
|
|
930
|
+
throw Error(
|
|
931
|
+
"The PsbtV2 is not ready for a Constructor. Inputs cannot be removed."
|
|
932
|
+
);
|
|
933
|
+
}
|
|
795
934
|
if (!this.isModifiable(["INPUTS" /* INPUTS */])) {
|
|
796
935
|
throw Error(
|
|
797
936
|
"PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE inputs cannot be modified."
|
|
@@ -805,6 +944,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
805
944
|
* Removes an output-map from outputMaps.
|
|
806
945
|
*/
|
|
807
946
|
deleteOutput(index) {
|
|
947
|
+
if (!this.isReadyForConstructor) {
|
|
948
|
+
throw Error(
|
|
949
|
+
"The PsbtV2 is not ready for a Constructor. Outputs cannot be removed."
|
|
950
|
+
);
|
|
951
|
+
}
|
|
808
952
|
if (!this.isModifiable(["OUTPUTS" /* OUTPUTS */])) {
|
|
809
953
|
throw Error(
|
|
810
954
|
"PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE outputs cannot be modified."
|
|
@@ -818,7 +962,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
818
962
|
this.PSBT_GLOBAL_OUTPUT_COUNT = this.outputMaps.length;
|
|
819
963
|
}
|
|
820
964
|
/**
|
|
821
|
-
* Checks that provided flags are present in PSBT_GLOBAL_TX_MODIFIABLE.
|
|
965
|
+
* Checks that all provided flags are present in PSBT_GLOBAL_TX_MODIFIABLE.
|
|
822
966
|
*/
|
|
823
967
|
isModifiable(flags) {
|
|
824
968
|
for (const flag of flags) {
|
|
@@ -842,6 +986,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
842
986
|
* https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#signer
|
|
843
987
|
*/
|
|
844
988
|
addPartialSig(inputIndex, pubkey, sig) {
|
|
989
|
+
if (!this.isReadyForSigner) {
|
|
990
|
+
throw Error(
|
|
991
|
+
"The PsbtV2 is not ready for a Signer. Partial sigs cannot be added."
|
|
992
|
+
);
|
|
993
|
+
}
|
|
845
994
|
if (!this.inputMaps[inputIndex]) {
|
|
846
995
|
throw Error(`PsbtV2 has no input at ${inputIndex}`);
|
|
847
996
|
}
|
|
@@ -920,17 +1069,17 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
920
1069
|
this.PSBT_GLOBAL_TX_MODIFIABLE = modifiable;
|
|
921
1070
|
}
|
|
922
1071
|
/**
|
|
923
|
-
* Attempts to return a PsbtV2 by converting from a PsbtV0 string or Buffer
|
|
1072
|
+
* Attempts to return a PsbtV2 by converting from a PsbtV0 string or Buffer.
|
|
1073
|
+
*
|
|
1074
|
+
* This method first starts with a fresh PsbtV2 having just been created. It
|
|
1075
|
+
* then takes the PsbtV2 through its operator saga through the Signer role. In
|
|
1076
|
+
* this sense validation for each operator role will be performed.
|
|
924
1077
|
*/
|
|
925
1078
|
static FromV0(psbt, allowTxnVersion1 = false) {
|
|
926
1079
|
const psbtv0Buf = bufferize(psbt);
|
|
927
1080
|
const psbtv0 = import_bitcoinjs_lib2.Psbt.fromBuffer(psbtv0Buf);
|
|
928
1081
|
const psbtv0GlobalMap = psbtv0.data.globalMap;
|
|
929
1082
|
const psbtv2 = new _PsbtV2();
|
|
930
|
-
psbtv2.PSBT_GLOBAL_TX_MODIFIABLE = [
|
|
931
|
-
"INPUTS" /* INPUTS */,
|
|
932
|
-
"OUTPUTS" /* OUTPUTS */
|
|
933
|
-
];
|
|
934
1083
|
const txVersion = psbtv0.data.getTransaction().readInt32LE(0);
|
|
935
1084
|
if (txVersion === 1 && allowTxnVersion1) {
|
|
936
1085
|
psbtv2.dangerouslySetGlobalTxVersion1();
|
|
@@ -944,7 +1093,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
944
1093
|
globalXpub.path
|
|
945
1094
|
);
|
|
946
1095
|
}
|
|
947
|
-
|
|
1096
|
+
const txInputs = [];
|
|
948
1097
|
for (const [index, txInput] of psbtv0.txInputs.entries()) {
|
|
949
1098
|
txInputs[index] = txInput;
|
|
950
1099
|
}
|
|
@@ -964,7 +1113,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
964
1113
|
bip32Derivation: input.bip32Derivation
|
|
965
1114
|
});
|
|
966
1115
|
}
|
|
967
|
-
|
|
1116
|
+
const txOutputs = [];
|
|
968
1117
|
for (const [index, txOutput] of psbtv0.txOutputs.entries()) {
|
|
969
1118
|
txOutputs[index] = txOutput;
|
|
970
1119
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -216,7 +216,10 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
216
216
|
* Globals Getters/Setters
|
|
217
217
|
*/
|
|
218
218
|
get PSBT_GLOBAL_XPUB() {
|
|
219
|
-
return getNonUniqueKeyTypeValues(
|
|
219
|
+
return getNonUniqueKeyTypeValues(
|
|
220
|
+
this.globalMap,
|
|
221
|
+
"01" /* PSBT_GLOBAL_XPUB */
|
|
222
|
+
);
|
|
220
223
|
}
|
|
221
224
|
get PSBT_GLOBAL_TX_VERSION() {
|
|
222
225
|
const val = this.globalMap.get("02" /* PSBT_GLOBAL_TX_VERSION */);
|
|
@@ -390,16 +393,28 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
390
393
|
);
|
|
391
394
|
}
|
|
392
395
|
get PSBT_IN_RIPEMD160() {
|
|
393
|
-
return getNonUniqueKeyTypeValues(
|
|
396
|
+
return getNonUniqueKeyTypeValues(
|
|
397
|
+
this.inputMaps,
|
|
398
|
+
"0a" /* PSBT_IN_RIPEMD160 */
|
|
399
|
+
);
|
|
394
400
|
}
|
|
395
401
|
get PSBT_IN_SHA256() {
|
|
396
|
-
return getNonUniqueKeyTypeValues(
|
|
402
|
+
return getNonUniqueKeyTypeValues(
|
|
403
|
+
this.inputMaps,
|
|
404
|
+
"0b" /* PSBT_IN_SHA256 */
|
|
405
|
+
);
|
|
397
406
|
}
|
|
398
407
|
get PSBT_IN_HASH160() {
|
|
399
|
-
return getNonUniqueKeyTypeValues(
|
|
408
|
+
return getNonUniqueKeyTypeValues(
|
|
409
|
+
this.inputMaps,
|
|
410
|
+
"0c" /* PSBT_IN_HASH160 */
|
|
411
|
+
);
|
|
400
412
|
}
|
|
401
413
|
get PSBT_IN_HASH256() {
|
|
402
|
-
return getNonUniqueKeyTypeValues(
|
|
414
|
+
return getNonUniqueKeyTypeValues(
|
|
415
|
+
this.inputMaps,
|
|
416
|
+
"0d" /* PSBT_IN_HASH256 */
|
|
417
|
+
);
|
|
403
418
|
}
|
|
404
419
|
get PSBT_IN_PREVIOUS_TXID() {
|
|
405
420
|
const indices = [];
|
|
@@ -551,6 +566,106 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
551
566
|
"fc" /* PSBT_OUT_PROPRIETARY */
|
|
552
567
|
);
|
|
553
568
|
}
|
|
569
|
+
/**
|
|
570
|
+
* Operator Role Validation Getters
|
|
571
|
+
*/
|
|
572
|
+
/**
|
|
573
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Constructor
|
|
574
|
+
* role.
|
|
575
|
+
*
|
|
576
|
+
* This check assumes that the Creator used this class's constructor method to
|
|
577
|
+
* initialize the PsbtV2 without passing a psbt (constructor defaults were
|
|
578
|
+
* set).
|
|
579
|
+
*/
|
|
580
|
+
get isReadyForConstructor() {
|
|
581
|
+
if (this.PSBT_GLOBAL_FALLBACK_LOCKTIME === null) {
|
|
582
|
+
return false;
|
|
583
|
+
}
|
|
584
|
+
if (!this.isModifiable(["INPUTS" /* INPUTS */]) && !this.isModifiable(["OUTPUTS" /* OUTPUTS */])) {
|
|
585
|
+
return false;
|
|
586
|
+
}
|
|
587
|
+
return true;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Updater
|
|
591
|
+
* role.
|
|
592
|
+
*
|
|
593
|
+
* Before signatures are added, but after an input is added, a PsbtV2 is
|
|
594
|
+
* likely to be ready for Constructor, ready for Updater, and ready for Signer
|
|
595
|
+
* simultaneously.
|
|
596
|
+
*
|
|
597
|
+
* According to BIP370, the Updater can modify the sequence number, but it is
|
|
598
|
+
* unclear if the Updater retains permissions provided in psbtv0 (BIP174). It
|
|
599
|
+
* is likely not the case that the Updater has the same permissions as
|
|
600
|
+
* previously because it seems to now be the realm of the Constructor to add
|
|
601
|
+
* inputs and outputs.
|
|
602
|
+
*/
|
|
603
|
+
get isReadyForUpdater() {
|
|
604
|
+
if (this.PSBT_GLOBAL_INPUT_COUNT === 0) {
|
|
605
|
+
return false;
|
|
606
|
+
}
|
|
607
|
+
if (!this.isModifiable(["INPUTS" /* INPUTS */])) {
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
return true;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Signer role.
|
|
614
|
+
*/
|
|
615
|
+
get isReadyForSigner() {
|
|
616
|
+
if (this.PSBT_GLOBAL_INPUT_COUNT === 0) {
|
|
617
|
+
return false;
|
|
618
|
+
}
|
|
619
|
+
if (this.isReadyForTransactionExtractor) {
|
|
620
|
+
return false;
|
|
621
|
+
}
|
|
622
|
+
return true;
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Combiner
|
|
626
|
+
* role.
|
|
627
|
+
*/
|
|
628
|
+
get isReadyForCombiner() {
|
|
629
|
+
return this.isReadyForConstructor || this.isReadyForUpdater || this.isReadyForSigner;
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Unimplemented. Returns false.
|
|
633
|
+
*/
|
|
634
|
+
get isReadyForInputFinalizer() {
|
|
635
|
+
console.warn(
|
|
636
|
+
"PsbtV2.isReadyForInputFinalizer has been called, however, this getter is unimplemented and shouldn't be used."
|
|
637
|
+
);
|
|
638
|
+
return false;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Returns true if the PsbtV2 is ready for an operator taking the Transaction
|
|
642
|
+
* Extractor role.
|
|
643
|
+
*
|
|
644
|
+
* If all the inputs have been finalized, then the psbt is ready for the
|
|
645
|
+
* Transaction Extractor. According to BIP 174, it's the responsibility of the
|
|
646
|
+
* Input Finalizer to add scriptSigs or scriptWitnesses and then remove other
|
|
647
|
+
* details besides the UTXO. This getter checks that the Input Finalizer has
|
|
648
|
+
* finished its job.
|
|
649
|
+
*/
|
|
650
|
+
get isReadyForTransactionExtractor() {
|
|
651
|
+
for (let i = 0; i < this.PSBT_GLOBAL_INPUT_COUNT; i++) {
|
|
652
|
+
if (!this.PSBT_IN_FINAL_SCRIPTSIG[i] && !this.PSBT_IN_FINAL_SCRIPTWITNESS[i]) {
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
if (this.PSBT_IN_FINAL_SCRIPTSIG[i] && !this.PSBT_IN_NON_WITNESS_UTXO[i] || this.PSBT_IN_FINAL_SCRIPTWITNESS[i] && !this.PSBT_IN_WITNESS_UTXO[i]) {
|
|
656
|
+
return false;
|
|
657
|
+
}
|
|
658
|
+
if (
|
|
659
|
+
// Strings
|
|
660
|
+
this.PSBT_IN_REDEEM_SCRIPT[i] || this.PSBT_IN_WITNESS_SCRIPT[i] || this.PSBT_IN_POR_COMMITMENT[i] || this.PSBT_IN_TAP_KEY_SIG[i] || this.PSBT_IN_TAP_INTERNAL_KEY[i] || this.PSBT_IN_TAP_MERKLE_ROOT[i] || // Numbers
|
|
661
|
+
this.PSBT_IN_SIGHASH_TYPE[i] !== null || this.PSBT_IN_SEQUENCE[i] !== null || this.PSBT_IN_REQUIRED_TIME_LOCKTIME[i] !== null || this.PSBT_IN_REQUIRED_HEIGHT_LOCKTIME[i] !== null || // Arrays of non-unique keytype values
|
|
662
|
+
this.PSBT_IN_PARTIAL_SIG[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_BIP32_DERIVATION[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_RIPEMD160[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_SHA256[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_HASH160[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_HASH256[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_TAP_SCRIPT_SIG[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_TAP_LEAF_SCRIPT[i].filter((el) => el !== null).length > 0 || this.PSBT_IN_TAP_BIP32_DERIVATION[i].filter((el) => el !== null).length > 0
|
|
663
|
+
) {
|
|
664
|
+
return false;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return true;
|
|
668
|
+
}
|
|
554
669
|
/**
|
|
555
670
|
* Other Getters/Setters
|
|
556
671
|
*/
|
|
@@ -596,6 +711,10 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
596
711
|
this.PSBT_GLOBAL_INPUT_COUNT = 0;
|
|
597
712
|
this.PSBT_GLOBAL_OUTPUT_COUNT = 0;
|
|
598
713
|
this.PSBT_GLOBAL_FALLBACK_LOCKTIME = 0;
|
|
714
|
+
this.PSBT_GLOBAL_TX_MODIFIABLE = [
|
|
715
|
+
"INPUTS" /* INPUTS */,
|
|
716
|
+
"OUTPUTS" /* OUTPUTS */
|
|
717
|
+
];
|
|
599
718
|
}
|
|
600
719
|
/**
|
|
601
720
|
* Checks initial construction of any valid PsbtV2. It is called when a psbt
|
|
@@ -653,6 +772,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
653
772
|
* defined for PsbtV2.
|
|
654
773
|
*/
|
|
655
774
|
dangerouslySetGlobalTxVersion1() {
|
|
775
|
+
if (!this.isReadyForConstructor) {
|
|
776
|
+
throw Error(
|
|
777
|
+
"The PsbtV2 is not ready for a Constructor. The PSBT_GLOBAL_TX_VERSION should not be forced to version 1."
|
|
778
|
+
);
|
|
779
|
+
}
|
|
656
780
|
console.warn("Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!");
|
|
657
781
|
const bw = new BufferWriter3();
|
|
658
782
|
bw.writeI32(1);
|
|
@@ -681,6 +805,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
681
805
|
witnessScript,
|
|
682
806
|
bip32Derivation
|
|
683
807
|
}) {
|
|
808
|
+
if (!this.isReadyForConstructor) {
|
|
809
|
+
throw Error(
|
|
810
|
+
"The PsbtV2 is not ready for a Constructor. Inputs cannot be added."
|
|
811
|
+
);
|
|
812
|
+
}
|
|
684
813
|
if (!this.isModifiable(["INPUTS" /* INPUTS */])) {
|
|
685
814
|
throw Error(
|
|
686
815
|
"PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE inputs cannot be modified."
|
|
@@ -734,6 +863,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
734
863
|
witnessScript,
|
|
735
864
|
bip32Derivation
|
|
736
865
|
}) {
|
|
866
|
+
if (!this.isReadyForConstructor) {
|
|
867
|
+
throw Error(
|
|
868
|
+
"The PsbtV2 is not ready for a Constructor. Outputs cannot be added."
|
|
869
|
+
);
|
|
870
|
+
}
|
|
737
871
|
if (!this.isModifiable(["OUTPUTS" /* OUTPUTS */])) {
|
|
738
872
|
throw Error(
|
|
739
873
|
"PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE outputs cannot be modified."
|
|
@@ -773,6 +907,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
773
907
|
* Removes an input-map from inputMaps.
|
|
774
908
|
*/
|
|
775
909
|
deleteInput(index) {
|
|
910
|
+
if (!this.isReadyForConstructor) {
|
|
911
|
+
throw Error(
|
|
912
|
+
"The PsbtV2 is not ready for a Constructor. Inputs cannot be removed."
|
|
913
|
+
);
|
|
914
|
+
}
|
|
776
915
|
if (!this.isModifiable(["INPUTS" /* INPUTS */])) {
|
|
777
916
|
throw Error(
|
|
778
917
|
"PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE inputs cannot be modified."
|
|
@@ -786,6 +925,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
786
925
|
* Removes an output-map from outputMaps.
|
|
787
926
|
*/
|
|
788
927
|
deleteOutput(index) {
|
|
928
|
+
if (!this.isReadyForConstructor) {
|
|
929
|
+
throw Error(
|
|
930
|
+
"The PsbtV2 is not ready for a Constructor. Outputs cannot be removed."
|
|
931
|
+
);
|
|
932
|
+
}
|
|
789
933
|
if (!this.isModifiable(["OUTPUTS" /* OUTPUTS */])) {
|
|
790
934
|
throw Error(
|
|
791
935
|
"PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE outputs cannot be modified."
|
|
@@ -799,7 +943,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
799
943
|
this.PSBT_GLOBAL_OUTPUT_COUNT = this.outputMaps.length;
|
|
800
944
|
}
|
|
801
945
|
/**
|
|
802
|
-
* Checks that provided flags are present in PSBT_GLOBAL_TX_MODIFIABLE.
|
|
946
|
+
* Checks that all provided flags are present in PSBT_GLOBAL_TX_MODIFIABLE.
|
|
803
947
|
*/
|
|
804
948
|
isModifiable(flags) {
|
|
805
949
|
for (const flag of flags) {
|
|
@@ -823,6 +967,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
823
967
|
* https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#signer
|
|
824
968
|
*/
|
|
825
969
|
addPartialSig(inputIndex, pubkey, sig) {
|
|
970
|
+
if (!this.isReadyForSigner) {
|
|
971
|
+
throw Error(
|
|
972
|
+
"The PsbtV2 is not ready for a Signer. Partial sigs cannot be added."
|
|
973
|
+
);
|
|
974
|
+
}
|
|
826
975
|
if (!this.inputMaps[inputIndex]) {
|
|
827
976
|
throw Error(`PsbtV2 has no input at ${inputIndex}`);
|
|
828
977
|
}
|
|
@@ -901,17 +1050,17 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
901
1050
|
this.PSBT_GLOBAL_TX_MODIFIABLE = modifiable;
|
|
902
1051
|
}
|
|
903
1052
|
/**
|
|
904
|
-
* Attempts to return a PsbtV2 by converting from a PsbtV0 string or Buffer
|
|
1053
|
+
* Attempts to return a PsbtV2 by converting from a PsbtV0 string or Buffer.
|
|
1054
|
+
*
|
|
1055
|
+
* This method first starts with a fresh PsbtV2 having just been created. It
|
|
1056
|
+
* then takes the PsbtV2 through its operator saga through the Signer role. In
|
|
1057
|
+
* this sense validation for each operator role will be performed.
|
|
905
1058
|
*/
|
|
906
1059
|
static FromV0(psbt, allowTxnVersion1 = false) {
|
|
907
1060
|
const psbtv0Buf = bufferize(psbt);
|
|
908
1061
|
const psbtv0 = Psbt2.fromBuffer(psbtv0Buf);
|
|
909
1062
|
const psbtv0GlobalMap = psbtv0.data.globalMap;
|
|
910
1063
|
const psbtv2 = new _PsbtV2();
|
|
911
|
-
psbtv2.PSBT_GLOBAL_TX_MODIFIABLE = [
|
|
912
|
-
"INPUTS" /* INPUTS */,
|
|
913
|
-
"OUTPUTS" /* OUTPUTS */
|
|
914
|
-
];
|
|
915
1064
|
const txVersion = psbtv0.data.getTransaction().readInt32LE(0);
|
|
916
1065
|
if (txVersion === 1 && allowTxnVersion1) {
|
|
917
1066
|
psbtv2.dangerouslySetGlobalTxVersion1();
|
|
@@ -925,7 +1074,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
925
1074
|
globalXpub.path
|
|
926
1075
|
);
|
|
927
1076
|
}
|
|
928
|
-
|
|
1077
|
+
const txInputs = [];
|
|
929
1078
|
for (const [index, txInput] of psbtv0.txInputs.entries()) {
|
|
930
1079
|
txInputs[index] = txInput;
|
|
931
1080
|
}
|
|
@@ -945,7 +1094,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
945
1094
|
bip32Derivation: input.bip32Derivation
|
|
946
1095
|
});
|
|
947
1096
|
}
|
|
948
|
-
|
|
1097
|
+
const txOutputs = [];
|
|
949
1098
|
for (const [index, txOutput] of psbtv0.txOutputs.entries()) {
|
|
950
1099
|
txOutputs[index] = txOutput;
|
|
951
1100
|
}
|