@caravan/psbt 1.0.0 → 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/dist/index.js CHANGED
@@ -38,9 +38,8 @@ module.exports = __toCommonJS(src_exports);
38
38
  // ../../node_modules/esbuild-plugin-polyfill-node/polyfills/buffer.js
39
39
  var import_buffer = require("buffer");
40
40
 
41
- // src/psbtv2.ts
41
+ // src/psbtv2/functions.ts
42
42
  var import_bufio = require("bufio");
43
- var import_bitcoinjs_lib2 = require("bitcoinjs-lib");
44
43
  var import_bitcoin3 = require("@caravan/bitcoin");
45
44
 
46
45
  // src/psbt.ts
@@ -51,10 +50,12 @@ var import_bitcoin2 = require("@caravan/bitcoin");
51
50
  var import_bignumber = __toESM(require("bignumber.js"));
52
51
  var PSBT_MAGIC_BYTES = import_buffer.Buffer.from([112, 115, 98, 116, 255]);
53
52
 
54
- // src/psbtv2.ts
53
+ // src/psbtv2/values.ts
55
54
  var PSBT_MAP_SEPARATOR = import_buffer.Buffer.from([0]);
56
55
  var BIP_32_NODE_REGEX = /(\/[0-9]+'?)/gi;
57
56
  var BIP_32_HARDENING_OFFSET = 2147483648;
57
+
58
+ // src/psbtv2/functions.ts
58
59
  function bufferize(psbt) {
59
60
  if (import_buffer.Buffer.isBuffer(psbt)) {
60
61
  return psbt;
@@ -131,8 +132,23 @@ function serializeMap(map, bw) {
131
132
  });
132
133
  bw.writeBytes(PSBT_MAP_SEPARATOR);
133
134
  }
135
+ function getPsbtVersionNumber(psbt) {
136
+ const map = /* @__PURE__ */ new Map();
137
+ const buf = bufferize(psbt);
138
+ const br = new import_bufio.BufferReader(buf.slice(import_bitcoin3.PSBT_MAGIC_BYTES.length));
139
+ readAndSetKeyPairs(map, br);
140
+ return map.get("fb" /* PSBT_GLOBAL_VERSION */)?.readUInt32LE(0) || 0;
141
+ }
142
+
143
+ // src/psbtv2/psbtv2.ts
144
+ var import_bufio3 = require("bufio");
145
+ var import_bitcoinjs_lib2 = require("bitcoinjs-lib");
146
+
147
+ // src/psbtv2/psbtv2maps.ts
148
+ var import_bufio2 = require("bufio");
134
149
  var PsbtV2Maps = class {
135
- // These maps directly correspond to the maps defined in BIP0174
150
+ // These maps directly correspond to the maps defined in BIP0174 and extended
151
+ // in BIP0370
136
152
  globalMap = /* @__PURE__ */ new Map();
137
153
  inputMaps = [];
138
154
  outputMaps = [];
@@ -141,7 +157,7 @@ var PsbtV2Maps = class {
141
157
  return;
142
158
  }
143
159
  const buf = bufferize(psbt);
144
- const br = new import_bufio.BufferReader(buf);
160
+ const br = new import_bufio2.BufferReader(buf);
145
161
  if (!br.readBytes(PSBT_MAGIC_BYTES.length, true).equals(PSBT_MAGIC_BYTES)) {
146
162
  throw Error("PsbtV2 magic bytes are incorrect.");
147
163
  }
@@ -165,9 +181,11 @@ var PsbtV2Maps = class {
165
181
  this.outputMaps.push(map);
166
182
  }
167
183
  }
168
- // Return the current state of the psbt as a string in the specified format.
184
+ /**
185
+ * Return the current state of the psbt as a string in the specified format.
186
+ */
169
187
  serialize(format = "base64") {
170
- let bw = new import_bufio.BufferWriter();
188
+ const bw = new import_bufio2.BufferWriter();
171
189
  bw.writeBytes(PSBT_MAGIC_BYTES);
172
190
  serializeMap(this.globalMap, bw);
173
191
  for (const map of this.inputMaps) {
@@ -178,12 +196,15 @@ var PsbtV2Maps = class {
178
196
  }
179
197
  return bw.render().toString(format);
180
198
  }
181
- // NOTE: This set of copy methods is made available to
182
- // achieve parity with the PSBT api required by ledger-bitcoin
183
- // for creating merklized PSBTs. HOWEVER, it is not recommended
184
- // to use this when avoidable as copying maps bypasses the validation
185
- // defined in the constructor, so it could create a psbtv2 in an invalid psbt status.
186
- // PsbtV2.serialize is preferable whenever possible.
199
+ /**
200
+ * Copies the maps in this PsbtV2 object to another PsbtV2 object.
201
+ *
202
+ * NOTE: This copy method is made available to achieve parity with the PSBT
203
+ * api required by `ledger-bitcoin` for creating merklized PSBTs. HOWEVER, it
204
+ * is not recommended to use this when avoidable as copying maps bypasses the
205
+ * validation defined in the constructor, so it could create a psbtv2 in an
206
+ * invalid psbt state. PsbtV2.serialize is preferable whenever possible.
207
+ */
187
208
  copy(to) {
188
209
  this.copyMap(this.globalMap, to.globalMap);
189
210
  this.copyMaps(this.inputMaps, to.inputMaps);
@@ -196,11 +217,12 @@ var PsbtV2Maps = class {
196
217
  to[index] = to_index;
197
218
  });
198
219
  }
199
- // eslint-disable-next-line class-methods-use-this
200
220
  copyMap(from, to) {
201
221
  from.forEach((v, k) => to.set(k, import_buffer.Buffer.from(v)));
202
222
  }
203
223
  };
224
+
225
+ // src/psbtv2/psbtv2.ts
204
226
  var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
205
227
  constructor(psbt) {
206
228
  super(psbt);
@@ -213,7 +235,10 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
213
235
  * Globals Getters/Setters
214
236
  */
215
237
  get PSBT_GLOBAL_XPUB() {
216
- return getNonUniqueKeyTypeValues(this.globalMap, "01" /* PSBT_GLOBAL_XPUB */);
238
+ return getNonUniqueKeyTypeValues(
239
+ this.globalMap,
240
+ "01" /* PSBT_GLOBAL_XPUB */
241
+ );
217
242
  }
218
243
  get PSBT_GLOBAL_TX_VERSION() {
219
244
  const val = this.globalMap.get("02" /* PSBT_GLOBAL_TX_VERSION */);
@@ -228,7 +253,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
228
253
  `PsbtV2 cannot have a global tx version less than 2. Version ${version} specified.`
229
254
  );
230
255
  }
231
- const bw = new import_bufio.BufferWriter();
256
+ const bw = new import_bufio3.BufferWriter();
232
257
  bw.writeI32(version);
233
258
  this.globalMap.set("02" /* PSBT_GLOBAL_TX_VERSION */, bw.render());
234
259
  }
@@ -239,7 +264,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
239
264
  if (locktime === null) {
240
265
  this.globalMap.delete("03" /* PSBT_GLOBAL_FALLBACK_LOCKTIME */);
241
266
  } else {
242
- const bw = new import_bufio.BufferWriter();
267
+ const bw = new import_bufio3.BufferWriter();
243
268
  bw.writeI32(locktime);
244
269
  this.globalMap.set("03" /* PSBT_GLOBAL_FALLBACK_LOCKTIME */, bw.render());
245
270
  }
@@ -252,7 +277,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
252
277
  return val.readUInt8(0);
253
278
  }
254
279
  set PSBT_GLOBAL_INPUT_COUNT(count) {
255
- const bw = new import_bufio.BufferWriter();
280
+ const bw = new import_bufio3.BufferWriter();
256
281
  bw.writeU8(count);
257
282
  this.globalMap.set("04" /* PSBT_GLOBAL_INPUT_COUNT */, bw.render());
258
283
  }
@@ -264,7 +289,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
264
289
  return val.readUInt8(0);
265
290
  }
266
291
  set PSBT_GLOBAL_OUTPUT_COUNT(count) {
267
- const bw = new import_bufio.BufferWriter();
292
+ const bw = new import_bufio3.BufferWriter();
268
293
  bw.writeU8(count);
269
294
  this.globalMap.set("05" /* PSBT_GLOBAL_OUTPUT_COUNT */, bw.render());
270
295
  }
@@ -293,7 +318,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
293
318
  if (modifiable.includes("SIGHASH_SINGLE" /* SIGHASH_SINGLE */)) {
294
319
  val |= 4;
295
320
  }
296
- const br = new import_bufio.BufferWriter();
321
+ const br = new import_bufio3.BufferWriter();
297
322
  br.writeU8(val);
298
323
  this.globalMap.set("06" /* PSBT_GLOBAL_TX_MODIFIABLE */, br.render());
299
324
  }
@@ -313,7 +338,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
313
338
  );
314
339
  workingVersion = 2;
315
340
  }
316
- const bw = new import_bufio.BufferWriter();
341
+ const bw = new import_bufio3.BufferWriter();
317
342
  bw.writeU32(workingVersion);
318
343
  this.globalMap.set("fb" /* PSBT_GLOBAL_VERSION */, bw.render());
319
344
  }
@@ -387,16 +412,28 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
387
412
  );
388
413
  }
389
414
  get PSBT_IN_RIPEMD160() {
390
- return getNonUniqueKeyTypeValues(this.inputMaps, "0a" /* PSBT_IN_RIPEMD160 */);
415
+ return getNonUniqueKeyTypeValues(
416
+ this.inputMaps,
417
+ "0a" /* PSBT_IN_RIPEMD160 */
418
+ );
391
419
  }
392
420
  get PSBT_IN_SHA256() {
393
- return getNonUniqueKeyTypeValues(this.inputMaps, "0b" /* PSBT_IN_SHA256 */);
421
+ return getNonUniqueKeyTypeValues(
422
+ this.inputMaps,
423
+ "0b" /* PSBT_IN_SHA256 */
424
+ );
394
425
  }
395
426
  get PSBT_IN_HASH160() {
396
- return getNonUniqueKeyTypeValues(this.inputMaps, "0c" /* PSBT_IN_HASH160 */);
427
+ return getNonUniqueKeyTypeValues(
428
+ this.inputMaps,
429
+ "0c" /* PSBT_IN_HASH160 */
430
+ );
397
431
  }
398
432
  get PSBT_IN_HASH256() {
399
- return getNonUniqueKeyTypeValues(this.inputMaps, "0d" /* PSBT_IN_HASH256 */);
433
+ return getNonUniqueKeyTypeValues(
434
+ this.inputMaps,
435
+ "0d" /* PSBT_IN_HASH256 */
436
+ );
400
437
  }
401
438
  get PSBT_IN_PREVIOUS_TXID() {
402
439
  const indices = [];
@@ -508,7 +545,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
508
545
  if (!value) {
509
546
  throw Error("PSBT_OUT_AMOUNT not set for an output");
510
547
  }
511
- const br = new import_bufio.BufferReader(value);
548
+ const br = new import_bufio3.BufferReader(value);
512
549
  indices.push(br.readBigI64(value));
513
550
  }
514
551
  return indices;
@@ -548,9 +585,113 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
548
585
  "fc" /* PSBT_OUT_PROPRIETARY */
549
586
  );
550
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
+ }
551
688
  /**
552
689
  * Other Getters/Setters
553
690
  */
691
+ /**
692
+ * Returns the `nLockTime` field for the psbt as if it were a bitcoin
693
+ * transaction.
694
+ */
554
695
  get nLockTime() {
555
696
  const inputCount = this.PSBT_GLOBAL_INPUT_COUNT;
556
697
  const heightLocks = this.PSBT_IN_REQUIRED_HEIGHT_LOCKTIME;
@@ -579,20 +720,27 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
579
720
  /**
580
721
  * Creator/Constructor Methods
581
722
  */
582
- // This method ensures that global fields have initial values required by a
583
- // PsbtV2 Creator. It is called by the constructor if constructed without a
584
- // psbt.
723
+ /**
724
+ * Ensures that global fields have initial values required by a PsbtV2
725
+ * Creator. It is called by the constructor if constructed without a psbt.
726
+ */
585
727
  create() {
586
728
  this.PSBT_GLOBAL_VERSION = 2;
587
729
  this.PSBT_GLOBAL_TX_VERSION = 2;
588
730
  this.PSBT_GLOBAL_INPUT_COUNT = 0;
589
731
  this.PSBT_GLOBAL_OUTPUT_COUNT = 0;
590
732
  this.PSBT_GLOBAL_FALLBACK_LOCKTIME = 0;
733
+ this.PSBT_GLOBAL_TX_MODIFIABLE = [
734
+ "INPUTS" /* INPUTS */,
735
+ "OUTPUTS" /* OUTPUTS */
736
+ ];
591
737
  }
592
- // This method should check initial construction of any valid PsbtV2. It is
593
- // called when a psbt is passed to the constructor or when a new psbt is being
594
- // created. If constructed with a psbt, this method acts outside of the
595
- // Creator role to validate the current state of the psbt.
738
+ /**
739
+ * Checks initial construction of any valid PsbtV2. It is called when a psbt
740
+ * is passed to the constructor or when a new psbt is being created. If
741
+ * constructed with a psbt, this method acts outside of the Creator role to
742
+ * validate the current state of the psbt.
743
+ */
596
744
  validate() {
597
745
  if (this.PSBT_GLOBAL_VERSION < 2) {
598
746
  throw Error("PsbtV2 has a version field set less than 2");
@@ -631,25 +779,32 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
631
779
  }
632
780
  }
633
781
  }
634
- // This method is provided for compatibility issues and probably shouldn't be
635
- // used since a PsbtV2 with PSBT_GLOBAL_TX_VERSION = 1 is BIP0370
636
- // non-compliant. No guarantees can be made here that a serialized PsbtV2
637
- // which used this method will be compatible with outside consumers.
638
- //
639
- // One may wish to instance this class from a partially signed
640
- // PSBTv0 with a txn version 1 by using the static PsbtV2.FromV0. This method
641
- // provides a way to override validation logic for the txn version and roles
642
- // lifecycle defined for PsbtV2.
782
+ /**
783
+ * This method is provided for compatibility issues and probably shouldn't be
784
+ * used since a PsbtV2 with PSBT_GLOBAL_TX_VERSION = 1 is BIP0370
785
+ * non-compliant. No guarantees can be made here that a serialized PsbtV2
786
+ * which used this method will be compatible with outside consumers.
787
+ *
788
+ * One may wish to instance this class from a partially signed PSBTv0 with a
789
+ * txn version 1 by using the static PsbtV2.FromV0. This method provides a way
790
+ * to override validation logic for the txn version and roles lifecycle
791
+ * defined for PsbtV2.
792
+ */
643
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
+ }
644
799
  console.warn("Dangerously setting PsbtV2.PSBT_GLOBAL_TX_VERSION to 1!");
645
- const bw = new import_bufio.BufferWriter();
800
+ const bw = new import_bufio3.BufferWriter();
646
801
  bw.writeI32(1);
647
802
  this.globalMap.set("02" /* PSBT_GLOBAL_TX_VERSION */, bw.render());
648
803
  }
649
- // Is this a Creator/Constructor role action, or something else. BIPs don't
804
+ // Is this a Creator/Constructor role action, or something else? BIPs don't
650
805
  // define it well.
651
806
  addGlobalXpub(xpub, fingerprint, path) {
652
- const bw = new import_bufio.BufferWriter();
807
+ const bw = new import_bufio3.BufferWriter();
653
808
  bw.writeBytes(import_buffer.Buffer.from("01" /* PSBT_GLOBAL_XPUB */, "hex"));
654
809
  bw.writeBytes(xpub);
655
810
  const key = bw.render().toString("hex");
@@ -669,13 +824,18 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
669
824
  witnessScript,
670
825
  bip32Derivation
671
826
  }) {
827
+ if (!this.isReadyForConstructor) {
828
+ throw Error(
829
+ "The PsbtV2 is not ready for a Constructor. Inputs cannot be added."
830
+ );
831
+ }
672
832
  if (!this.isModifiable(["INPUTS" /* INPUTS */])) {
673
833
  throw Error(
674
834
  "PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE inputs cannot be modified."
675
835
  );
676
836
  }
677
837
  const map = /* @__PURE__ */ new Map();
678
- const bw = new import_bufio.BufferWriter();
838
+ const bw = new import_bufio3.BufferWriter();
679
839
  const prevTxIdBuf = bufferize(previousTxId);
680
840
  bw.writeBytes(prevTxIdBuf);
681
841
  map.set("0e" /* PSBT_IN_PREVIOUS_TXID */, bw.render());
@@ -722,13 +882,18 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
722
882
  witnessScript,
723
883
  bip32Derivation
724
884
  }) {
885
+ if (!this.isReadyForConstructor) {
886
+ throw Error(
887
+ "The PsbtV2 is not ready for a Constructor. Outputs cannot be added."
888
+ );
889
+ }
725
890
  if (!this.isModifiable(["OUTPUTS" /* OUTPUTS */])) {
726
891
  throw Error(
727
892
  "PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE outputs cannot be modified."
728
893
  );
729
894
  }
730
895
  const map = /* @__PURE__ */ new Map();
731
- const bw = new import_bufio.BufferWriter();
896
+ const bw = new import_bufio3.BufferWriter();
732
897
  bw.writeI64(amount);
733
898
  map.set("03" /* PSBT_OUT_AMOUNT */, bw.render());
734
899
  bw.writeBytes(script);
@@ -757,8 +922,15 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
757
922
  /**
758
923
  * Updater/Signer Methods
759
924
  */
760
- // Removes an input-map from inputMaps
925
+ /**
926
+ * Removes an input-map from inputMaps.
927
+ */
761
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
+ }
762
934
  if (!this.isModifiable(["INPUTS" /* INPUTS */])) {
763
935
  throw Error(
764
936
  "PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE inputs cannot be modified."
@@ -768,8 +940,15 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
768
940
  this.inputMaps = newInputs;
769
941
  this.PSBT_GLOBAL_INPUT_COUNT = this.inputMaps.length;
770
942
  }
771
- // Removes an output-map from outputMaps
943
+ /**
944
+ * Removes an output-map from outputMaps.
945
+ */
772
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
+ }
773
952
  if (!this.isModifiable(["OUTPUTS" /* OUTPUTS */])) {
774
953
  throw Error(
775
954
  "PsbtV2.PSBT_GLOBAL_TX_MODIFIABLE outputs cannot be modified."
@@ -782,7 +961,9 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
782
961
  this.outputMaps = newOutputs;
783
962
  this.PSBT_GLOBAL_OUTPUT_COUNT = this.outputMaps.length;
784
963
  }
785
- // Checks that provided flags are present in PSBT_GLOBAL_TX_MODIFIABLE.
964
+ /**
965
+ * Checks that all provided flags are present in PSBT_GLOBAL_TX_MODIFIABLE.
966
+ */
786
967
  isModifiable(flags) {
787
968
  for (const flag of flags) {
788
969
  if (!this.PSBT_GLOBAL_TX_MODIFIABLE.includes(flag)) {
@@ -791,13 +972,25 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
791
972
  }
792
973
  return true;
793
974
  }
794
- // The Signer, when it creates a signature, must add the partial sig keypair
795
- // to the psbt for the input which it is signing. In the case that a
796
- // particular signer does not, this method can be used to add a signature to
797
- // the psbt. This method assumes the Signer did the validation outlined in
798
- // BIP0174 before creating a signature.
799
- // https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#signer
975
+ /**
976
+ * Adds a signature for an input. Validates that the input is mapped and does
977
+ * not already have a signature for the pubkey. Also validates for sighash.
978
+ * Other validation is incomplete. Also validates for required args in case
979
+ * typescript is not being used to call the method.
980
+ *
981
+ * The Signer, when it creates a signature, must add the partial sig keypair
982
+ * to the psbt for the input which it is signing. In the case that a
983
+ * particular signer does not, this method can be used to add a signature to
984
+ * the psbt. This method assumes the Signer did the validation outlined in
985
+ * BIP0174 before creating a signature.
986
+ * https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#signer
987
+ */
800
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
+ }
801
994
  if (!this.inputMaps[inputIndex]) {
802
995
  throw Error(`PsbtV2 has no input at ${inputIndex}`);
803
996
  }
@@ -822,7 +1015,11 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
822
1015
  this.PSBT_GLOBAL_TX_MODIFIABLE = modBackup;
823
1016
  }
824
1017
  }
825
- // Removes all sigs for an input unless a pubkey is specified.
1018
+ /**
1019
+ * Removes all sigs for an input unless a pubkey is specified. Validates that
1020
+ * the input exists. When providing a pubkey, this validates that a sig for
1021
+ * the pubkey exists.
1022
+ */
826
1023
  removePartialSig(inputIndex, pubkey) {
827
1024
  const input = this.inputMaps[inputIndex];
828
1025
  if (!input) {
@@ -846,11 +1043,12 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
846
1043
  }
847
1044
  }
848
1045
  }
849
- // Used to ensure the PSBT is in the proper state when adding a partial sig
850
- // keypair.
851
- // https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#signer
1046
+ /**
1047
+ * Ensures the PSBT is in the proper state when adding a partial sig keypair.
1048
+ * https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#signer
1049
+ */
852
1050
  handleSighashType(sig) {
853
- const br = new import_bufio.BufferReader(sig.slice(-1));
1051
+ const br = new import_bufio3.BufferReader(sig.slice(-1));
854
1052
  let sighashVal = br.readU8();
855
1053
  let modifiable = this.PSBT_GLOBAL_TX_MODIFIABLE;
856
1054
  if (!(sighashVal & 128 /* SIGHASH_ANYONECANPAY */)) {
@@ -870,16 +1068,18 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
870
1068
  }
871
1069
  this.PSBT_GLOBAL_TX_MODIFIABLE = modifiable;
872
1070
  }
873
- // Attempt to return a PsbtV2 by converting from a PsbtV0 string or Buffer
1071
+ /**
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.
1077
+ */
874
1078
  static FromV0(psbt, allowTxnVersion1 = false) {
875
1079
  const psbtv0Buf = bufferize(psbt);
876
1080
  const psbtv0 = import_bitcoinjs_lib2.Psbt.fromBuffer(psbtv0Buf);
877
1081
  const psbtv0GlobalMap = psbtv0.data.globalMap;
878
1082
  const psbtv2 = new _PsbtV2();
879
- psbtv2.PSBT_GLOBAL_TX_MODIFIABLE = [
880
- "INPUTS" /* INPUTS */,
881
- "OUTPUTS" /* OUTPUTS */
882
- ];
883
1083
  const txVersion = psbtv0.data.getTransaction().readInt32LE(0);
884
1084
  if (txVersion === 1 && allowTxnVersion1) {
885
1085
  psbtv2.dangerouslySetGlobalTxVersion1();
@@ -893,7 +1093,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
893
1093
  globalXpub.path
894
1094
  );
895
1095
  }
896
- let txInputs = [];
1096
+ const txInputs = [];
897
1097
  for (const [index, txInput] of psbtv0.txInputs.entries()) {
898
1098
  txInputs[index] = txInput;
899
1099
  }
@@ -913,7 +1113,7 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
913
1113
  bip32Derivation: input.bip32Derivation
914
1114
  });
915
1115
  }
916
- let txOutputs = [];
1116
+ const txOutputs = [];
917
1117
  for (const [index, txOutput] of psbtv0.txOutputs.entries()) {
918
1118
  txOutputs[index] = txOutput;
919
1119
  }
@@ -935,13 +1135,6 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
935
1135
  return psbtv2;
936
1136
  }
937
1137
  };
938
- function getPsbtVersionNumber(psbt) {
939
- const map = /* @__PURE__ */ new Map();
940
- const buf = bufferize(psbt);
941
- const br = new import_bufio.BufferReader(buf.slice(PSBT_MAGIC_BYTES.length));
942
- readAndSetKeyPairs(map, br);
943
- return map.get("fb" /* PSBT_GLOBAL_VERSION */)?.readUInt32LE(0) || 0;
944
- }
945
1138
  // Annotate the CommonJS export names for ESM import in node:
946
1139
  0 && (module.exports = {
947
1140
  PsbtV2,