@btc-vision/bitcoin 6.3.0 → 6.3.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btc-vision/bitcoin",
3
- "version": "6.3.0",
3
+ "version": "6.3.1",
4
4
  "description": "Client-side Bitcoin JavaScript library",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
package/src/networks.d.ts CHANGED
@@ -27,3 +27,57 @@ export declare const regtest: Network;
27
27
  * Represents the testnet network configuration.
28
28
  */
29
29
  export declare const testnet: Network;
30
+ /**
31
+ * Represents the Dogecoin mainnet configuration.
32
+ *
33
+ * Prefixes from:
34
+ * - P2PKH: 0x1e (30 decimal) - addresses start with 'D'
35
+ * - P2SH: 0x16 (22 decimal) - addresses often start with '9' or 'A'
36
+ * - WIF: 0x9e (158 decimal)
37
+ * - BIP32:
38
+ * - public: 0x02facafd
39
+ * - private: 0x02fac398
40
+ * Message prefix:
41
+ * - Dogecoin uses "\x19Dogecoin Signed Message:\n"
42
+ */
43
+ export declare const dogecoin: Network;
44
+ /**
45
+ * Represents the Dogecoin testnet configuration.
46
+ *
47
+ * Prefixes from Dogecoin testnet chainparams:
48
+ * - P2PKH: 0x71 (113 decimal)
49
+ * - P2SH: 0xc4 (196 decimal)
50
+ * - WIF: 0xf1 (241 decimal)
51
+ * - BIP32:
52
+ * - public: 0x0432a9a8
53
+ * - private: 0x0432a243
54
+ * Message prefix:
55
+ * - Same as mainnet: "\x19Dogecoin Signed Message:\n"
56
+ */
57
+ export declare const dogecoinTestnet: Network;
58
+ /**
59
+ * Litecoin mainnet configuration.
60
+ */
61
+ export declare const litecoin: Network;
62
+ /**
63
+ * Litecoin testnet configuration.
64
+ */
65
+ export declare const litecoinTestnet: Network;
66
+ /**
67
+ * Bitcoin Cash mainnet configuration (legacy).
68
+ * Note: Bitcoin Cash uses Cashaddr starting with 'q' or 'p',
69
+ * but we retain the legacy prefixes for compatibility.
70
+ */
71
+ export declare const bitcoinCash: Network;
72
+ /**
73
+ * Bitcoin Cash testnet configuration (legacy).
74
+ */
75
+ export declare const bitcoinCashTestnet: Network;
76
+ /**
77
+ * Dash mainnet configuration.
78
+ */
79
+ export declare const dash: Network;
80
+ /**
81
+ * Dash testnet configuration.
82
+ */
83
+ export declare const dashTestnet: Network;
package/src/networks.js CHANGED
@@ -2,7 +2,18 @@
2
2
  // https://en.bitcoin.it/wiki/List_of_address_prefixes
3
3
  // Dogecoin BIP32 is a proposed standard: https://bitcointalk.org/index.php?topic=409731
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
- exports.testnet = exports.regtest = exports.bitcoin = void 0;
5
+ exports.dashTestnet =
6
+ exports.dash =
7
+ exports.bitcoinCashTestnet =
8
+ exports.bitcoinCash =
9
+ exports.litecoinTestnet =
10
+ exports.litecoin =
11
+ exports.dogecoinTestnet =
12
+ exports.dogecoin =
13
+ exports.testnet =
14
+ exports.regtest =
15
+ exports.bitcoin =
16
+ void 0;
6
17
  /**
7
18
  * Represents the Bitcoin network configuration.
8
19
  */
@@ -69,3 +80,141 @@ exports.testnet = {
69
80
  scriptHash: 0xc4,
70
81
  wif: 0xef,
71
82
  };
83
+ /**
84
+ * Represents the Dogecoin mainnet configuration.
85
+ *
86
+ * Prefixes from:
87
+ * - P2PKH: 0x1e (30 decimal) - addresses start with 'D'
88
+ * - P2SH: 0x16 (22 decimal) - addresses often start with '9' or 'A'
89
+ * - WIF: 0x9e (158 decimal)
90
+ * - BIP32:
91
+ * - public: 0x02facafd
92
+ * - private: 0x02fac398
93
+ * Message prefix:
94
+ * - Dogecoin uses "\x19Dogecoin Signed Message:\n"
95
+ */
96
+ exports.dogecoin = {
97
+ messagePrefix: '\x19Dogecoin Signed Message:\n',
98
+ bech32: '',
99
+ bip32: {
100
+ public: 0x02facafd,
101
+ private: 0x02fac398,
102
+ },
103
+ pubKeyHash: 0x1e,
104
+ scriptHash: 0x16,
105
+ wif: 0x9e,
106
+ };
107
+ /**
108
+ * Represents the Dogecoin testnet configuration.
109
+ *
110
+ * Prefixes from Dogecoin testnet chainparams:
111
+ * - P2PKH: 0x71 (113 decimal)
112
+ * - P2SH: 0xc4 (196 decimal)
113
+ * - WIF: 0xf1 (241 decimal)
114
+ * - BIP32:
115
+ * - public: 0x0432a9a8
116
+ * - private: 0x0432a243
117
+ * Message prefix:
118
+ * - Same as mainnet: "\x19Dogecoin Signed Message:\n"
119
+ */
120
+ exports.dogecoinTestnet = {
121
+ messagePrefix: '\x19Dogecoin Signed Message:\n',
122
+ bech32: '',
123
+ bip32: {
124
+ public: 0x0432a9a8,
125
+ private: 0x0432a243,
126
+ },
127
+ pubKeyHash: 0x71,
128
+ scriptHash: 0xc4,
129
+ wif: 0xf1,
130
+ };
131
+ /**
132
+ * Litecoin mainnet configuration.
133
+ */
134
+ exports.litecoin = {
135
+ messagePrefix: '\x19Litecoin Signed Message:\n',
136
+ bech32: 'ltc',
137
+ bip32: {
138
+ public: 0x019da462,
139
+ private: 0x019d9cfe,
140
+ },
141
+ pubKeyHash: 0x30,
142
+ scriptHash: 0x32,
143
+ wif: 0xb0,
144
+ };
145
+ /**
146
+ * Litecoin testnet configuration.
147
+ */
148
+ exports.litecoinTestnet = {
149
+ messagePrefix: '\x19Litecoin Signed Message:\n',
150
+ bech32: 'tltc',
151
+ bip32: {
152
+ public: 0x0436ef7d,
153
+ private: 0x0436f6e1,
154
+ },
155
+ pubKeyHash: 0x6f,
156
+ scriptHash: 0x3a,
157
+ wif: 0xef,
158
+ };
159
+ /**
160
+ * Bitcoin Cash mainnet configuration (legacy).
161
+ * Note: Bitcoin Cash uses Cashaddr starting with 'q' or 'p',
162
+ * but we retain the legacy prefixes for compatibility.
163
+ */
164
+ exports.bitcoinCash = {
165
+ messagePrefix: '\x18Bitcoin Signed Message:\n',
166
+ // Cashaddr prefix differs from bech32 for general usage, but we can set it similarly.
167
+ // Actual cashaddr prefix is "bitcoincash", but this field is for bech32 which BCH doesn't fully use for segwit (it doesn't have segwit).
168
+ bech32: 'bitcoincash',
169
+ bip32: {
170
+ public: 0x0488b21e,
171
+ private: 0x0488ade4,
172
+ },
173
+ pubKeyHash: 0x00,
174
+ scriptHash: 0x05,
175
+ wif: 0x80,
176
+ };
177
+ /**
178
+ * Bitcoin Cash testnet configuration (legacy).
179
+ */
180
+ exports.bitcoinCashTestnet = {
181
+ messagePrefix: '\x18Bitcoin Signed Message:\n',
182
+ bech32: 'bchtest',
183
+ bip32: {
184
+ public: 0x043587cf,
185
+ private: 0x04358394,
186
+ },
187
+ pubKeyHash: 0x6f,
188
+ scriptHash: 0xc4,
189
+ wif: 0xef,
190
+ };
191
+ /**
192
+ * Dash mainnet configuration.
193
+ */
194
+ exports.dash = {
195
+ // Historically Dash used DarkCoin message prefix, and most implementations use this:
196
+ // As of Dash Core 0.17, this has not changed in code.
197
+ messagePrefix: '\x19DarkCoin Signed Message:\n',
198
+ bech32: '',
199
+ bip32: {
200
+ public: 0x02fe52cc,
201
+ private: 0x02fe52f8,
202
+ },
203
+ pubKeyHash: 0x4c,
204
+ scriptHash: 0x10,
205
+ wif: 0xcc,
206
+ };
207
+ /**
208
+ * Dash testnet configuration.
209
+ */
210
+ exports.dashTestnet = {
211
+ messagePrefix: '\x19DarkCoin Signed Message:\n',
212
+ bech32: '',
213
+ bip32: {
214
+ public: 0x3a8061a0,
215
+ private: 0x3a805837,
216
+ },
217
+ pubKeyHash: 0x8c,
218
+ scriptHash: 0x13,
219
+ wif: 0xef,
220
+ };
@@ -39,4 +39,4 @@ export declare function tapTreeToList(tree: Taptree): TapLeaf[];
39
39
  */
40
40
  export declare function tapTreeFromList(leaves?: TapLeaf[]): Taptree;
41
41
  export declare function checkTaprootInputForSigs(input: PsbtInput, action: string): boolean;
42
- export declare function getTapKeySigFromWithness(finalScriptWitness?: Buffer): Buffer | undefined;
42
+ export declare function getTapKeySigFromWitness(finalScriptWitness?: Buffer): Buffer | undefined;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, '__esModule', { value: true });
3
- exports.getTapKeySigFromWithness =
3
+ exports.getTapKeySigFromWitness =
4
4
  exports.checkTaprootInputForSigs =
5
5
  exports.tapTreeFromList =
6
6
  exports.tapTreeToList =
@@ -165,7 +165,7 @@ function tapTreeFromList(leaves = []) {
165
165
  output: leaves[0].script,
166
166
  version: leaves[0].leafVersion,
167
167
  };
168
- return instertLeavesInTree(leaves);
168
+ return insertLeavesInTree(leaves);
169
169
  }
170
170
  exports.tapTreeFromList = tapTreeFromList;
171
171
  function checkTaprootInputForSigs(input, action) {
@@ -192,20 +192,20 @@ function extractTaprootSigs(input) {
192
192
  if (input.tapScriptSig)
193
193
  sigs.push(...input.tapScriptSig.map(s => s.signature));
194
194
  if (!sigs.length) {
195
- const finalTapKeySig = getTapKeySigFromWithness(
195
+ const finalTapKeySig = getTapKeySigFromWitness(
196
196
  input.finalScriptWitness,
197
197
  );
198
198
  if (finalTapKeySig) sigs.push(finalTapKeySig);
199
199
  }
200
200
  return sigs;
201
201
  }
202
- function getTapKeySigFromWithness(finalScriptWitness) {
202
+ function getTapKeySigFromWitness(finalScriptWitness) {
203
203
  if (!finalScriptWitness) return;
204
204
  const witness = finalScriptWitness.slice(2);
205
205
  // todo: add schnorr signature validation
206
206
  if (witness.length === 64 || witness.length === 65) return witness;
207
207
  }
208
- exports.getTapKeySigFromWithness = getTapKeySigFromWithness;
208
+ exports.getTapKeySigFromWitness = getTapKeySigFromWitness;
209
209
  function _tapTreeToList(tree, leaves = [], depth = 0) {
210
210
  if (depth > bip341_1.MAX_TAPTREE_DEPTH)
211
211
  throw new Error('Max taptree depth exceeded.');
@@ -222,15 +222,15 @@ function _tapTreeToList(tree, leaves = [], depth = 0) {
222
222
  if (tree[1]) _tapTreeToList(tree[1], leaves, depth + 1);
223
223
  return leaves;
224
224
  }
225
- function instertLeavesInTree(leaves) {
225
+ function insertLeavesInTree(leaves) {
226
226
  let tree;
227
227
  for (const leaf of leaves) {
228
- tree = instertLeafInTree(leaf, tree);
228
+ tree = insertLeafInTree(leaf, tree);
229
229
  if (!tree) throw new Error(`No room left to insert tapleaf in tree`);
230
230
  }
231
231
  return tree;
232
232
  }
233
- function instertLeafInTree(leaf, tree, depth = 0) {
233
+ function insertLeafInTree(leaf, tree, depth = 0) {
234
234
  if (depth > bip341_1.MAX_TAPTREE_DEPTH)
235
235
  throw new Error('Max taptree depth exceeded.');
236
236
  if (leaf.depth === depth) {
@@ -242,9 +242,9 @@ function instertLeafInTree(leaf, tree, depth = 0) {
242
242
  return;
243
243
  }
244
244
  if ((0, types_1.isTapleaf)(tree)) return;
245
- const leftSide = instertLeafInTree(leaf, tree && tree[0], depth + 1);
245
+ const leftSide = insertLeafInTree(leaf, tree && tree[0], depth + 1);
246
246
  if (leftSide) return [leftSide, tree && tree[1]];
247
- const rightSide = instertLeafInTree(leaf, tree && tree[1], depth + 1);
247
+ const rightSide = insertLeafInTree(leaf, tree && tree[1], depth + 1);
248
248
  if (rightSide) return [tree && tree[0], rightSide];
249
249
  }
250
250
  function checkMixedTaprootAndNonTaprootInputFields(
package/src/psbt.d.ts CHANGED
@@ -123,6 +123,10 @@ export declare class Psbt {
123
123
  addUnknownKeyValToInput(inputIndex: number, keyVal: KeyValue): this;
124
124
  addUnknownKeyValToOutput(outputIndex: number, keyVal: KeyValue): this;
125
125
  clearFinalizedInput(inputIndex: number): this;
126
+ checkTaprootHashesForSig(inputIndex: number, input: PsbtInput, keyPair: Signer | SignerAlternative | SignerAsync | BIP32Interface | ECPairInterface, tapLeafHashToSign?: Buffer, allowedSighashTypes?: number[]): {
127
+ hash: Buffer;
128
+ leafHash?: Buffer;
129
+ }[];
126
130
  private _finalizeInput;
127
131
  private _finalizeTaprootInput;
128
132
  private _validateSignaturesOfInput;
@@ -131,7 +135,6 @@ export declare class Psbt {
131
135
  private _signTaprootInput;
132
136
  private _signInputAsync;
133
137
  private _signTaprootInputAsync;
134
- private checkTaprootHashesForSig;
135
138
  }
136
139
  export interface PsbtOptsOptional {
137
140
  network?: Network;
package/src/psbt.js CHANGED
@@ -541,8 +541,9 @@ class Psbt {
541
541
  });
542
542
  }
543
543
  signInput(inputIndex, keyPair, sighashTypes) {
544
- if (!keyPair || !keyPair.publicKey)
544
+ if (!keyPair || !keyPair.publicKey) {
545
545
  throw new Error('Need Signer to sign input');
546
+ }
546
547
  const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
547
548
  if ((0, bip371_1.isTaprootInput)(input)) {
548
549
  return this._signTaprootInput(
@@ -556,10 +557,11 @@ class Psbt {
556
557
  return this._signInput(inputIndex, keyPair, sighashTypes);
557
558
  }
558
559
  signTaprootInput(inputIndex, keyPair, tapLeafHashToSign, sighashTypes) {
559
- if (!keyPair || !keyPair.publicKey)
560
+ if (!keyPair || !keyPair.publicKey) {
560
561
  throw new Error('Need Signer to sign input');
562
+ }
561
563
  const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
562
- if ((0, bip371_1.isTaprootInput)(input))
564
+ if ((0, bip371_1.isTaprootInput)(input)) {
563
565
  return this._signTaprootInput(
564
566
  inputIndex,
565
567
  input,
@@ -567,6 +569,7 @@ class Psbt {
567
569
  tapLeafHashToSign,
568
570
  sighashTypes,
569
571
  );
572
+ }
570
573
  throw new Error(`Input #${inputIndex} is not of type Taproot.`);
571
574
  }
572
575
  signInputAsync(inputIndex, keyPair, sighashTypes) {
@@ -667,6 +670,34 @@ class Psbt {
667
670
  this.data.clearFinalizedInput(inputIndex);
668
671
  return this;
669
672
  }
673
+ checkTaprootHashesForSig(
674
+ inputIndex,
675
+ input,
676
+ keyPair,
677
+ tapLeafHashToSign,
678
+ allowedSighashTypes,
679
+ ) {
680
+ if (typeof keyPair.signSchnorr !== 'function')
681
+ throw new Error(
682
+ `Need Schnorr Signer to sign taproot input #${inputIndex}.`,
683
+ );
684
+ const hashesForSig = getTaprootHashesForSig(
685
+ inputIndex,
686
+ input,
687
+ this.data.inputs,
688
+ keyPair.publicKey,
689
+ this.__CACHE,
690
+ tapLeafHashToSign,
691
+ allowedSighashTypes,
692
+ );
693
+ if (!hashesForSig || !hashesForSig.length)
694
+ throw new Error(
695
+ `Can not sign for input #${inputIndex} with the key ${keyPair.publicKey.toString(
696
+ 'hex',
697
+ )}`,
698
+ );
699
+ return hashesForSig;
700
+ }
670
701
  _finalizeInput(inputIndex, input, finalScriptsFunc = getFinalScripts) {
671
702
  const { script, isP2SH, isP2WSH, isSegwit } = getScriptFromInput(
672
703
  inputIndex,
@@ -701,7 +732,7 @@ class Psbt {
701
732
  ) {
702
733
  if (!input.witnessUtxo)
703
734
  throw new Error(
704
- `Cannot finalize input #${inputIndex}. Missing withness utxo.`,
735
+ `Cannot finalize input #${inputIndex}. Missing witness utxo.`,
705
736
  );
706
737
  // Check key spend first. Increased privacy and reduced block space.
707
738
  if (input.tapKeySig) {
@@ -955,34 +986,6 @@ class Psbt {
955
986
  this.data.updateInput(inputIndex, v);
956
987
  }
957
988
  }
958
- checkTaprootHashesForSig(
959
- inputIndex,
960
- input,
961
- keyPair,
962
- tapLeafHashToSign,
963
- allowedSighashTypes,
964
- ) {
965
- if (typeof keyPair.signSchnorr !== 'function')
966
- throw new Error(
967
- `Need Schnorr Signer to sign taproot input #${inputIndex}.`,
968
- );
969
- const hashesForSig = getTaprootHashesForSig(
970
- inputIndex,
971
- input,
972
- this.data.inputs,
973
- keyPair.publicKey,
974
- this.__CACHE,
975
- tapLeafHashToSign,
976
- allowedSighashTypes,
977
- );
978
- if (!hashesForSig || !hashesForSig.length)
979
- throw new Error(
980
- `Can not sign for input #${inputIndex} with the key ${keyPair.publicKey.toString(
981
- 'hex',
982
- )}`,
983
- );
984
- return hashesForSig;
985
- }
986
989
  }
987
990
  exports.Psbt = Psbt;
988
991
  /**