@caravan/psbt 1.4.3 → 1.6.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.d.ts +59 -0
- package/dist/index.js +81 -6
- package/dist/index.mjs +82 -6
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -209,6 +209,65 @@ declare class PsbtV2 extends PsbtV2Maps {
|
|
|
209
209
|
* validate the current state of the psbt.
|
|
210
210
|
*/
|
|
211
211
|
private validate;
|
|
212
|
+
/**
|
|
213
|
+
* Sets the sequence number for a specific input in the transaction.
|
|
214
|
+
*
|
|
215
|
+
* This private helper method is crucial for implementing RBF and other
|
|
216
|
+
* sequence-based transaction features. It writes the provided sequence
|
|
217
|
+
* number as a 32-bit little-endian unsigned integer and stores it in the
|
|
218
|
+
* appropriate input's map using the PSBT_IN_SEQUENCE key.
|
|
219
|
+
*
|
|
220
|
+
* The sequence number has multiple uses in Bitcoin transactions:
|
|
221
|
+
* 1. Signaling RBF (values < 0xfffffffe)
|
|
222
|
+
* 2. Enabling nLockTime (values < 0xffffffff)
|
|
223
|
+
* 3. Relative timelock with BIP68 (if bit 31 is not set)
|
|
224
|
+
*
|
|
225
|
+
* According to BIP125 (Opt-in Full Replace-by-Fee Signaling):
|
|
226
|
+
*
|
|
227
|
+
* - For a transaction to be considered opt-in RBF, it must have at least
|
|
228
|
+
* one input with a sequence number < 0xfffffffe.
|
|
229
|
+
* - The recommended sequence for RBF is 0xffffffff-2 (0xfffffffd).
|
|
230
|
+
*
|
|
231
|
+
* Sequence number meanings:
|
|
232
|
+
* - = 0xffffffff: Then the transaction is final no matter the nLockTime.
|
|
233
|
+
* - < 0xfffffffe: Transaction signals for RBF.
|
|
234
|
+
* - < 0xefffffff : Then the transaction signals BIP68 relative locktime.
|
|
235
|
+
*
|
|
236
|
+
* For using nLocktime along with Opt-in RBF, the sequence value
|
|
237
|
+
* should be between 0xf0000000 and 0xfffffffd.
|
|
238
|
+
*
|
|
239
|
+
* Care should be taken when setting sequence numbers to ensure the desired
|
|
240
|
+
* transaction properties are correctly signaled. Improper use can lead to
|
|
241
|
+
* unexpected transaction behavior or rejection by the network.
|
|
242
|
+
*
|
|
243
|
+
* References:
|
|
244
|
+
* - BIP125: Opt-in Full Replace-by-Fee Signaling
|
|
245
|
+
* https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki
|
|
246
|
+
* - BIP68: Relative lock-time using consensus-enforced sequence numbers
|
|
247
|
+
* https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
|
|
248
|
+
*/
|
|
249
|
+
setInputSequence(inputIndex: number, sequence: number): void;
|
|
250
|
+
/**
|
|
251
|
+
* Checks if the transaction signals Replace-by-Fee (RBF).
|
|
252
|
+
*
|
|
253
|
+
* This method determines whether the transaction is eligible for RBF by
|
|
254
|
+
* examining the sequence numbers of all inputs. As per BIP125, a transaction
|
|
255
|
+
* is considered to have opted in to RBF if it contains at least one input
|
|
256
|
+
* with a sequence number less than (0xffffffff - 1).
|
|
257
|
+
*
|
|
258
|
+
* Return value:
|
|
259
|
+
* - true: If any input has a sequence number < 0xfffffffe, indicating RBF.
|
|
260
|
+
* - false: If all inputs have sequence numbers >= 0xfffffffe, indicating no RBF.
|
|
261
|
+
*
|
|
262
|
+
* This method is useful for wallets, block explorers, or any service that
|
|
263
|
+
* needs to determine if a transaction can potentially be replaced before
|
|
264
|
+
* confirmation.
|
|
265
|
+
*
|
|
266
|
+
* References:
|
|
267
|
+
* - BIP125: Opt-in Full Replace-by-Fee Signaling
|
|
268
|
+
* https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki
|
|
269
|
+
*/
|
|
270
|
+
get isRBFSignaled(): boolean;
|
|
212
271
|
/**
|
|
213
272
|
* This method is provided for compatibility issues and probably shouldn't be
|
|
214
273
|
* used since a PsbtV2 with PSBT_GLOBAL_TX_VERSION = 1 is BIP0370
|
package/dist/index.js
CHANGED
|
@@ -789,6 +789,81 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
789
789
|
}
|
|
790
790
|
}
|
|
791
791
|
}
|
|
792
|
+
/**
|
|
793
|
+
* Sets the sequence number for a specific input in the transaction.
|
|
794
|
+
*
|
|
795
|
+
* This private helper method is crucial for implementing RBF and other
|
|
796
|
+
* sequence-based transaction features. It writes the provided sequence
|
|
797
|
+
* number as a 32-bit little-endian unsigned integer and stores it in the
|
|
798
|
+
* appropriate input's map using the PSBT_IN_SEQUENCE key.
|
|
799
|
+
*
|
|
800
|
+
* The sequence number has multiple uses in Bitcoin transactions:
|
|
801
|
+
* 1. Signaling RBF (values < 0xfffffffe)
|
|
802
|
+
* 2. Enabling nLockTime (values < 0xffffffff)
|
|
803
|
+
* 3. Relative timelock with BIP68 (if bit 31 is not set)
|
|
804
|
+
*
|
|
805
|
+
* According to BIP125 (Opt-in Full Replace-by-Fee Signaling):
|
|
806
|
+
*
|
|
807
|
+
* - For a transaction to be considered opt-in RBF, it must have at least
|
|
808
|
+
* one input with a sequence number < 0xfffffffe.
|
|
809
|
+
* - The recommended sequence for RBF is 0xffffffff-2 (0xfffffffd).
|
|
810
|
+
*
|
|
811
|
+
* Sequence number meanings:
|
|
812
|
+
* - = 0xffffffff: Then the transaction is final no matter the nLockTime.
|
|
813
|
+
* - < 0xfffffffe: Transaction signals for RBF.
|
|
814
|
+
* - < 0xefffffff : Then the transaction signals BIP68 relative locktime.
|
|
815
|
+
*
|
|
816
|
+
* For using nLocktime along with Opt-in RBF, the sequence value
|
|
817
|
+
* should be between 0xf0000000 and 0xfffffffd.
|
|
818
|
+
*
|
|
819
|
+
* Care should be taken when setting sequence numbers to ensure the desired
|
|
820
|
+
* transaction properties are correctly signaled. Improper use can lead to
|
|
821
|
+
* unexpected transaction behavior or rejection by the network.
|
|
822
|
+
*
|
|
823
|
+
* References:
|
|
824
|
+
* - BIP125: Opt-in Full Replace-by-Fee Signaling
|
|
825
|
+
* https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki
|
|
826
|
+
* - BIP68: Relative lock-time using consensus-enforced sequence numbers
|
|
827
|
+
* https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
|
|
828
|
+
*/
|
|
829
|
+
setInputSequence(inputIndex, sequence) {
|
|
830
|
+
if (!this.isReadyForUpdater) {
|
|
831
|
+
throw new Error(
|
|
832
|
+
"PSBT is not ready for the Updater role. Sequence cannot be changed."
|
|
833
|
+
);
|
|
834
|
+
}
|
|
835
|
+
if (inputIndex < 0 || inputIndex >= this.PSBT_GLOBAL_INPUT_COUNT) {
|
|
836
|
+
throw new Error(`Input at index ${inputIndex} does not exist.`);
|
|
837
|
+
}
|
|
838
|
+
const bw = new import_bufio3.BufferWriter();
|
|
839
|
+
bw.writeU32(sequence);
|
|
840
|
+
this.inputMaps[inputIndex].set("10" /* PSBT_IN_SEQUENCE */, bw.render());
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Checks if the transaction signals Replace-by-Fee (RBF).
|
|
844
|
+
*
|
|
845
|
+
* This method determines whether the transaction is eligible for RBF by
|
|
846
|
+
* examining the sequence numbers of all inputs. As per BIP125, a transaction
|
|
847
|
+
* is considered to have opted in to RBF if it contains at least one input
|
|
848
|
+
* with a sequence number less than (0xffffffff - 1).
|
|
849
|
+
*
|
|
850
|
+
* Return value:
|
|
851
|
+
* - true: If any input has a sequence number < 0xfffffffe, indicating RBF.
|
|
852
|
+
* - false: If all inputs have sequence numbers >= 0xfffffffe, indicating no RBF.
|
|
853
|
+
*
|
|
854
|
+
* This method is useful for wallets, block explorers, or any service that
|
|
855
|
+
* needs to determine if a transaction can potentially be replaced before
|
|
856
|
+
* confirmation.
|
|
857
|
+
*
|
|
858
|
+
* References:
|
|
859
|
+
* - BIP125: Opt-in Full Replace-by-Fee Signaling
|
|
860
|
+
* https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki
|
|
861
|
+
*/
|
|
862
|
+
get isRBFSignaled() {
|
|
863
|
+
return this.PSBT_IN_SEQUENCE.some(
|
|
864
|
+
(seq) => seq !== null && seq < 4294967294
|
|
865
|
+
);
|
|
866
|
+
}
|
|
792
867
|
/**
|
|
793
868
|
* This method is provided for compatibility issues and probably shouldn't be
|
|
794
869
|
* used since a PsbtV2 with PSBT_GLOBAL_TX_VERSION = 1 is BIP0370
|
|
@@ -93949,11 +94024,6 @@ var getHashForSignature = (psbt, inputIndex, inputAmount, sigHashFlag = import_b
|
|
|
93949
94024
|
throw new Error("No redeem or witness script found for input.");
|
|
93950
94025
|
};
|
|
93951
94026
|
function translatePSBT(network, addressType, psbt, signingKeyDetails) {
|
|
93952
|
-
if (addressType !== import_bitcoin4.P2SH) {
|
|
93953
|
-
throw new Error(
|
|
93954
|
-
"Unsupported addressType -- only P2SH is supported right now"
|
|
93955
|
-
);
|
|
93956
|
-
}
|
|
93957
94027
|
const localPSBT = autoLoadPSBT(psbt, { network: (0, import_bitcoin4.networkData)(network) });
|
|
93958
94028
|
if (localPSBT === null)
|
|
93959
94029
|
return null;
|
|
@@ -93976,12 +94046,17 @@ function translatePSBT(network, addressType, psbt, signingKeyDetails) {
|
|
|
93976
94046
|
function getUnchainedInputsFromPSBT(network, addressType, psbt) {
|
|
93977
94047
|
return psbt.txInputs.map((input, index) => {
|
|
93978
94048
|
const dataInput = psbt.data.inputs[index];
|
|
94049
|
+
const spendingScript = dataInput.witnessScript || dataInput.redeemScript;
|
|
94050
|
+
if (!dataInput?.nonWitnessUtxo && addressType === import_bitcoin4.P2WSH) {
|
|
94051
|
+
throw new Error(`Non-witness UTXO now required for P2WSH
|
|
94052
|
+
inputs to protect against large fee attack`);
|
|
94053
|
+
}
|
|
93979
94054
|
const fundingTxHex = dataInput.nonWitnessUtxo.toString("hex");
|
|
93980
94055
|
const fundingTx = import_bitcoinjs_lib_v63.Transaction.fromHex(fundingTxHex);
|
|
93981
94056
|
const multisig = (0, import_bitcoin4.generateMultisigFromHex)(
|
|
93982
94057
|
network,
|
|
93983
94058
|
addressType,
|
|
93984
|
-
|
|
94059
|
+
spendingScript.toString("hex")
|
|
93985
94060
|
);
|
|
93986
94061
|
return {
|
|
93987
94062
|
amountSats: fundingTx.outs[input.index].value,
|
package/dist/index.mjs
CHANGED
|
@@ -748,6 +748,81 @@ var PsbtV2 = class _PsbtV2 extends PsbtV2Maps {
|
|
|
748
748
|
}
|
|
749
749
|
}
|
|
750
750
|
}
|
|
751
|
+
/**
|
|
752
|
+
* Sets the sequence number for a specific input in the transaction.
|
|
753
|
+
*
|
|
754
|
+
* This private helper method is crucial for implementing RBF and other
|
|
755
|
+
* sequence-based transaction features. It writes the provided sequence
|
|
756
|
+
* number as a 32-bit little-endian unsigned integer and stores it in the
|
|
757
|
+
* appropriate input's map using the PSBT_IN_SEQUENCE key.
|
|
758
|
+
*
|
|
759
|
+
* The sequence number has multiple uses in Bitcoin transactions:
|
|
760
|
+
* 1. Signaling RBF (values < 0xfffffffe)
|
|
761
|
+
* 2. Enabling nLockTime (values < 0xffffffff)
|
|
762
|
+
* 3. Relative timelock with BIP68 (if bit 31 is not set)
|
|
763
|
+
*
|
|
764
|
+
* According to BIP125 (Opt-in Full Replace-by-Fee Signaling):
|
|
765
|
+
*
|
|
766
|
+
* - For a transaction to be considered opt-in RBF, it must have at least
|
|
767
|
+
* one input with a sequence number < 0xfffffffe.
|
|
768
|
+
* - The recommended sequence for RBF is 0xffffffff-2 (0xfffffffd).
|
|
769
|
+
*
|
|
770
|
+
* Sequence number meanings:
|
|
771
|
+
* - = 0xffffffff: Then the transaction is final no matter the nLockTime.
|
|
772
|
+
* - < 0xfffffffe: Transaction signals for RBF.
|
|
773
|
+
* - < 0xefffffff : Then the transaction signals BIP68 relative locktime.
|
|
774
|
+
*
|
|
775
|
+
* For using nLocktime along with Opt-in RBF, the sequence value
|
|
776
|
+
* should be between 0xf0000000 and 0xfffffffd.
|
|
777
|
+
*
|
|
778
|
+
* Care should be taken when setting sequence numbers to ensure the desired
|
|
779
|
+
* transaction properties are correctly signaled. Improper use can lead to
|
|
780
|
+
* unexpected transaction behavior or rejection by the network.
|
|
781
|
+
*
|
|
782
|
+
* References:
|
|
783
|
+
* - BIP125: Opt-in Full Replace-by-Fee Signaling
|
|
784
|
+
* https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki
|
|
785
|
+
* - BIP68: Relative lock-time using consensus-enforced sequence numbers
|
|
786
|
+
* https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
|
|
787
|
+
*/
|
|
788
|
+
setInputSequence(inputIndex, sequence) {
|
|
789
|
+
if (!this.isReadyForUpdater) {
|
|
790
|
+
throw new Error(
|
|
791
|
+
"PSBT is not ready for the Updater role. Sequence cannot be changed."
|
|
792
|
+
);
|
|
793
|
+
}
|
|
794
|
+
if (inputIndex < 0 || inputIndex >= this.PSBT_GLOBAL_INPUT_COUNT) {
|
|
795
|
+
throw new Error(`Input at index ${inputIndex} does not exist.`);
|
|
796
|
+
}
|
|
797
|
+
const bw = new BufferWriter3();
|
|
798
|
+
bw.writeU32(sequence);
|
|
799
|
+
this.inputMaps[inputIndex].set("10" /* PSBT_IN_SEQUENCE */, bw.render());
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Checks if the transaction signals Replace-by-Fee (RBF).
|
|
803
|
+
*
|
|
804
|
+
* This method determines whether the transaction is eligible for RBF by
|
|
805
|
+
* examining the sequence numbers of all inputs. As per BIP125, a transaction
|
|
806
|
+
* is considered to have opted in to RBF if it contains at least one input
|
|
807
|
+
* with a sequence number less than (0xffffffff - 1).
|
|
808
|
+
*
|
|
809
|
+
* Return value:
|
|
810
|
+
* - true: If any input has a sequence number < 0xfffffffe, indicating RBF.
|
|
811
|
+
* - false: If all inputs have sequence numbers >= 0xfffffffe, indicating no RBF.
|
|
812
|
+
*
|
|
813
|
+
* This method is useful for wallets, block explorers, or any service that
|
|
814
|
+
* needs to determine if a transaction can potentially be replaced before
|
|
815
|
+
* confirmation.
|
|
816
|
+
*
|
|
817
|
+
* References:
|
|
818
|
+
* - BIP125: Opt-in Full Replace-by-Fee Signaling
|
|
819
|
+
* https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki
|
|
820
|
+
*/
|
|
821
|
+
get isRBFSignaled() {
|
|
822
|
+
return this.PSBT_IN_SEQUENCE.some(
|
|
823
|
+
(seq) => seq !== null && seq < 4294967294
|
|
824
|
+
);
|
|
825
|
+
}
|
|
751
826
|
/**
|
|
752
827
|
* This method is provided for compatibility issues and probably shouldn't be
|
|
753
828
|
* used since a PsbtV2 with PSBT_GLOBAL_TX_VERSION = 1 is BIP0370
|
|
@@ -1166,6 +1241,7 @@ import {
|
|
|
1166
1241
|
multisigSignatureBuffer,
|
|
1167
1242
|
networkData,
|
|
1168
1243
|
P2SH as P2SH2,
|
|
1244
|
+
P2WSH as P2WSH2,
|
|
1169
1245
|
signatureNoSighashType
|
|
1170
1246
|
} from "@caravan/bitcoin";
|
|
1171
1247
|
import { Psbt as Psbt3, Transaction } from "bitcoinjs-lib-v6";
|
|
@@ -93927,11 +94003,6 @@ var getHashForSignature = (psbt, inputIndex, inputAmount, sigHashFlag = Transact
|
|
|
93927
94003
|
throw new Error("No redeem or witness script found for input.");
|
|
93928
94004
|
};
|
|
93929
94005
|
function translatePSBT(network, addressType, psbt, signingKeyDetails) {
|
|
93930
|
-
if (addressType !== P2SH2) {
|
|
93931
|
-
throw new Error(
|
|
93932
|
-
"Unsupported addressType -- only P2SH is supported right now"
|
|
93933
|
-
);
|
|
93934
|
-
}
|
|
93935
94006
|
const localPSBT = autoLoadPSBT(psbt, { network: networkData(network) });
|
|
93936
94007
|
if (localPSBT === null)
|
|
93937
94008
|
return null;
|
|
@@ -93954,12 +94025,17 @@ function translatePSBT(network, addressType, psbt, signingKeyDetails) {
|
|
|
93954
94025
|
function getUnchainedInputsFromPSBT(network, addressType, psbt) {
|
|
93955
94026
|
return psbt.txInputs.map((input, index) => {
|
|
93956
94027
|
const dataInput = psbt.data.inputs[index];
|
|
94028
|
+
const spendingScript = dataInput.witnessScript || dataInput.redeemScript;
|
|
94029
|
+
if (!dataInput?.nonWitnessUtxo && addressType === P2WSH2) {
|
|
94030
|
+
throw new Error(`Non-witness UTXO now required for P2WSH
|
|
94031
|
+
inputs to protect against large fee attack`);
|
|
94032
|
+
}
|
|
93957
94033
|
const fundingTxHex = dataInput.nonWitnessUtxo.toString("hex");
|
|
93958
94034
|
const fundingTx = Transaction.fromHex(fundingTxHex);
|
|
93959
94035
|
const multisig = generateMultisigFromHex(
|
|
93960
94036
|
network,
|
|
93961
94037
|
addressType,
|
|
93962
|
-
|
|
94038
|
+
spendingScript.toString("hex")
|
|
93963
94039
|
);
|
|
93964
94040
|
return {
|
|
93965
94041
|
amountSats: fundingTx.outs[input.index].value,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caravan/psbt",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "typescript library for working with PSBTs",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"author": "unchained capital",
|
|
52
52
|
"license": "ISC",
|
|
53
53
|
"devDependencies": {
|
|
54
|
+
"@caravan/bip32": "*",
|
|
54
55
|
"@caravan/eslint-config": "*",
|
|
55
56
|
"@caravan/multisig": "*",
|
|
56
57
|
"@caravan/typescript-config": "*",
|