@btc-vision/bitcoin 6.4.2 → 6.4.4

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.
Files changed (54) hide show
  1. package/browser/index.d.ts +1 -1
  2. package/browser/index.js +1 -1
  3. package/browser/payments/embed.d.ts +2 -2
  4. package/browser/payments/index.d.ts +71 -14
  5. package/browser/payments/lazy.d.ts +1 -1
  6. package/browser/payments/p2ms.d.ts +2 -2
  7. package/browser/payments/p2op.d.ts +25 -2
  8. package/browser/payments/p2pk.d.ts +2 -2
  9. package/browser/payments/p2pkh.d.ts +2 -2
  10. package/browser/payments/p2sh.d.ts +2 -2
  11. package/browser/payments/p2tr.d.ts +2 -2
  12. package/browser/payments/p2wpkh.d.ts +2 -2
  13. package/browser/payments/p2wsh.d.ts +2 -2
  14. package/build/address.js +0 -1
  15. package/build/index.d.ts +1 -1
  16. package/build/index.js +1 -0
  17. package/build/payments/embed.d.ts +2 -2
  18. package/build/payments/embed.js +7 -2
  19. package/build/payments/index.d.ts +71 -14
  20. package/build/payments/index.js +13 -0
  21. package/build/payments/lazy.d.ts +1 -1
  22. package/build/payments/p2ms.d.ts +2 -2
  23. package/build/payments/p2ms.js +9 -2
  24. package/build/payments/p2op.d.ts +25 -2
  25. package/build/payments/p2op.js +29 -4
  26. package/build/payments/p2pk.d.ts +2 -2
  27. package/build/payments/p2pk.js +6 -1
  28. package/build/payments/p2pkh.d.ts +2 -2
  29. package/build/payments/p2pkh.js +6 -1
  30. package/build/payments/p2sh.d.ts +2 -2
  31. package/build/payments/p2sh.js +5 -1
  32. package/build/payments/p2tr.d.ts +2 -2
  33. package/build/payments/p2tr.js +6 -2
  34. package/build/payments/p2wpkh.d.ts +2 -2
  35. package/build/payments/p2wpkh.js +5 -1
  36. package/build/payments/p2wsh.d.ts +2 -2
  37. package/build/payments/p2wsh.js +5 -1
  38. package/build/psbt.js +5 -2
  39. package/package.json +1 -1
  40. package/src/address.ts +283 -284
  41. package/src/index.ts +20 -1
  42. package/src/payments/embed.ts +61 -55
  43. package/src/payments/index.ts +172 -68
  44. package/src/payments/lazy.ts +28 -28
  45. package/src/payments/p2ms.ts +11 -5
  46. package/src/payments/p2op.ts +64 -5
  47. package/src/payments/p2pk.ts +93 -85
  48. package/src/payments/p2pkh.ts +214 -210
  49. package/src/payments/p2sh.ts +210 -206
  50. package/src/payments/p2tr.ts +9 -4
  51. package/src/payments/p2wpkh.ts +6 -3
  52. package/src/payments/p2wsh.ts +6 -3
  53. package/src/psbt.ts +10 -7
  54. package/test/payments.spec.ts +2 -2
@@ -1,206 +1,210 @@
1
- import * as bs58check from 'bs58check';
2
- import * as bcrypto from '../crypto.js';
3
- import { bitcoin as BITCOIN_NETWORK } from '../networks.js';
4
- import * as bscript from '../script.js';
5
- import { stacksEqual, typeforce as typef } from '../types.js';
6
- import { Payment, PaymentFunction, PaymentOpts, Stack, StackFunction } from './index.js';
7
- import * as lazy from './lazy.js';
8
-
9
- const OPS = bscript.OPS;
10
-
11
- // input: [redeemScriptSig ...] {redeemScript}
12
- // witness: <?>
13
- // output: OP_HASH160 {hash160(redeemScript)} OP_EQUAL
14
- /**
15
- * Creates a Pay-to-Script-Hash (P2SH) payment object.
16
- *
17
- * @param a - The payment object containing the necessary data.
18
- * @param opts - Optional payment options.
19
- * @returns The P2SH payment object.
20
- * @throws {TypeError} If the required data is not provided or if the data is invalid.
21
- */
22
- export function p2sh(a: Payment, opts?: PaymentOpts): Payment {
23
- if (!a.address && !a.hash && !a.output && !a.redeem && !a.input) {
24
- throw new TypeError('Not enough data');
25
- }
26
- opts = Object.assign({ validate: true }, opts || {});
27
-
28
- typef(
29
- {
30
- network: typef.maybe(typef.Object),
31
-
32
- address: typef.maybe(typef.String),
33
- hash: typef.maybe(typef.BufferN(20)),
34
- output: typef.maybe(typef.BufferN(23)),
35
-
36
- redeem: typef.maybe({
37
- network: typef.maybe(typef.Object),
38
- output: typef.maybe(typef.Buffer),
39
- input: typef.maybe(typef.Buffer),
40
- witness: typef.maybe(typef.arrayOf(typef.Buffer)),
41
- }),
42
- input: typef.maybe(typef.Buffer),
43
- witness: typef.maybe(typef.arrayOf(typef.Buffer)),
44
- },
45
- a,
46
- );
47
-
48
- let network = a.network;
49
- if (!network) {
50
- network = (a.redeem && a.redeem.network) || BITCOIN_NETWORK;
51
- }
52
-
53
- const o: Payment = { network };
54
-
55
- const _address = lazy.value(() => {
56
- const payload = Buffer.from(bs58check.default.decode(a.address!));
57
- const version = payload.readUInt8(0);
58
- const hash = payload.slice(1);
59
- return { version, hash };
60
- });
61
- const _chunks = lazy.value(() => {
62
- return bscript.decompile(a.input!);
63
- }) as StackFunction;
64
- const _redeem = lazy.value((): Payment => {
65
- const chunks = _chunks();
66
- const lastChunk = chunks[chunks.length - 1];
67
- return {
68
- network,
69
- output: lastChunk === OPS.OP_FALSE ? Buffer.from([]) : (lastChunk as Buffer),
70
- input: bscript.compile(chunks.slice(0, -1)),
71
- witness: a.witness || [],
72
- };
73
- }) as PaymentFunction;
74
-
75
- // output dependents
76
- lazy.prop(o, 'address', () => {
77
- if (!o.hash) return;
78
-
79
- const payload = Buffer.allocUnsafe(21);
80
- payload.writeUInt8(o.network!.scriptHash, 0);
81
- o.hash.copy(payload, 1);
82
- return bs58check.default.encode(payload);
83
- });
84
- lazy.prop(o, 'hash', () => {
85
- // in order of least effort
86
- if (a.output) return a.output.slice(2, 22);
87
- if (a.address) return _address().hash;
88
- if (o.redeem && o.redeem.output) return bcrypto.hash160(o.redeem.output);
89
- });
90
- lazy.prop(o, 'output', () => {
91
- if (!o.hash) return;
92
- return bscript.compile([OPS.OP_HASH160, o.hash, OPS.OP_EQUAL]);
93
- });
94
-
95
- // input dependents
96
- lazy.prop(o, 'redeem', () => {
97
- if (!a.input) return;
98
- return _redeem();
99
- });
100
- lazy.prop(o, 'input', () => {
101
- if (!a.redeem || !a.redeem.input || !a.redeem.output) return;
102
- return bscript.compile(
103
- ([] as Stack).concat(bscript.decompile(a.redeem.input) as Stack, a.redeem.output),
104
- );
105
- });
106
- lazy.prop(o, 'witness', () => {
107
- if (o.redeem && o.redeem.witness) return o.redeem.witness;
108
- if (o.input) return [];
109
- });
110
- lazy.prop(o, 'name', () => {
111
- const nameParts = ['p2sh'];
112
- if (o.redeem !== undefined && o.redeem.name !== undefined) nameParts.push(o.redeem.name!);
113
- return nameParts.join('-');
114
- });
115
-
116
- if (opts.validate) {
117
- let hash: Buffer = Buffer.from([]);
118
- if (a.address) {
119
- if (_address().version !== network.scriptHash)
120
- throw new TypeError('Invalid version or Network mismatch');
121
- if (_address().hash.length !== 20) throw new TypeError('Invalid address');
122
- hash = _address().hash;
123
- }
124
-
125
- if (a.hash) {
126
- if (hash.length > 0 && !hash.equals(a.hash)) throw new TypeError('Hash mismatch');
127
- else hash = a.hash;
128
- }
129
-
130
- if (a.output) {
131
- if (
132
- a.output.length !== 23 ||
133
- a.output[0] !== OPS.OP_HASH160 ||
134
- a.output[1] !== 0x14 ||
135
- a.output[22] !== OPS.OP_EQUAL
136
- )
137
- throw new TypeError('Output is invalid');
138
-
139
- const hash2 = a.output.slice(2, 22);
140
- if (hash.length > 0 && !hash.equals(hash2)) throw new TypeError('Hash mismatch');
141
- else hash = hash2;
142
- }
143
-
144
- // inlined to prevent 'no-inner-declarations' failing
145
- const checkRedeem = (redeem: Payment): void => {
146
- // is the redeem output empty/invalid?
147
- if (redeem.output) {
148
- const decompile = bscript.decompile(redeem.output);
149
- if (!decompile || decompile.length < 1)
150
- throw new TypeError('Redeem.output too short');
151
- if (redeem.output.byteLength > 520)
152
- throw new TypeError('Redeem.output unspendable if larger than 520 bytes');
153
- if (bscript.countNonPushOnlyOPs(decompile) > 201)
154
- throw new TypeError(
155
- 'Redeem.output unspendable with more than 201 non-push ops',
156
- );
157
-
158
- // match hash against other sources
159
- const hash2 = bcrypto.hash160(redeem.output);
160
- if (hash.length > 0 && !hash.equals(hash2)) throw new TypeError('Hash mismatch');
161
- else hash = hash2;
162
- }
163
-
164
- if (redeem.input) {
165
- const hasInput = redeem.input.length > 0;
166
- const hasWitness = redeem.witness && redeem.witness.length > 0;
167
- if (!hasInput && !hasWitness) throw new TypeError('Empty input');
168
- if (hasInput && hasWitness) throw new TypeError('Input and witness provided');
169
- if (hasInput) {
170
- const richunks = bscript.decompile(redeem.input) as Stack;
171
- if (!bscript.isPushOnly(richunks))
172
- throw new TypeError('Non push-only scriptSig');
173
- }
174
- }
175
- };
176
-
177
- if (a.input) {
178
- const chunks = _chunks();
179
- if (!chunks || chunks.length < 1) throw new TypeError('Input too short');
180
- if (!Buffer.isBuffer(_redeem().output)) throw new TypeError('Input is invalid');
181
-
182
- checkRedeem(_redeem());
183
- }
184
-
185
- if (a.redeem) {
186
- if (a.redeem.network && a.redeem.network !== network)
187
- throw new TypeError('Network mismatch');
188
- if (a.input) {
189
- const redeem = _redeem();
190
- if (a.redeem.output && !a.redeem.output.equals(redeem.output!))
191
- throw new TypeError('Redeem.output mismatch');
192
- if (a.redeem.input && !a.redeem.input.equals(redeem.input!))
193
- throw new TypeError('Redeem.input mismatch');
194
- }
195
-
196
- checkRedeem(a.redeem);
197
- }
198
-
199
- if (a.witness) {
200
- if (a.redeem && a.redeem.witness && !stacksEqual(a.redeem.witness, a.witness))
201
- throw new TypeError('Witness and redeem.witness mismatch');
202
- }
203
- }
204
-
205
- return Object.assign(o, a);
206
- }
1
+ import * as bs58check from 'bs58check';
2
+ import * as bcrypto from '../crypto.js';
3
+ import { bitcoin as BITCOIN_NETWORK } from '../networks.js';
4
+ import * as bscript from '../script.js';
5
+ import { stacksEqual, typeforce as typef } from '../types.js';
6
+ import { P2SHPayment, Payment, PaymentOpts, PaymentType, ScriptRedeem, Stack, StackFunction } from './index.js';
7
+ import * as lazy from './lazy.js';
8
+
9
+ const OPS = bscript.OPS;
10
+
11
+ // input: [redeemScriptSig ...] {redeemScript}
12
+ // witness: <?>
13
+ // output: OP_HASH160 {hash160(redeemScript)} OP_EQUAL
14
+ /**
15
+ * Creates a Pay-to-Script-Hash (P2SH) payment object.
16
+ *
17
+ * @param a - The payment object containing the necessary data.
18
+ * @param opts - Optional payment options.
19
+ * @returns The P2SH payment object.
20
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
21
+ */
22
+ export function p2sh(a: Omit<P2SHPayment, 'name'>, opts?: PaymentOpts): P2SHPayment {
23
+ if (!a.address && !a.hash && !a.output && !a.redeem && !a.input) {
24
+ throw new TypeError('Not enough data');
25
+ }
26
+ opts = Object.assign({ validate: true }, opts || {});
27
+
28
+ typef(
29
+ {
30
+ network: typef.maybe(typef.Object),
31
+
32
+ address: typef.maybe(typef.String),
33
+ hash: typef.maybe(typef.BufferN(20)),
34
+ output: typef.maybe(typef.BufferN(23)),
35
+
36
+ redeem: typef.maybe({
37
+ network: typef.maybe(typef.Object),
38
+ output: typef.maybe(typef.Buffer),
39
+ input: typef.maybe(typef.Buffer),
40
+ witness: typef.maybe(typef.arrayOf(typef.Buffer)),
41
+ }),
42
+ input: typef.maybe(typef.Buffer),
43
+ witness: typef.maybe(typef.arrayOf(typef.Buffer)),
44
+ },
45
+ a,
46
+ );
47
+
48
+ let network = a.network;
49
+ if (!network) {
50
+ network = (a.redeem && a.redeem.network) || BITCOIN_NETWORK;
51
+ }
52
+
53
+ const o: P2SHPayment = {
54
+ network,
55
+ name: PaymentType.P2SH
56
+ };
57
+
58
+ const _address = lazy.value(() => {
59
+ const payload = Buffer.from(bs58check.default.decode(a.address!));
60
+ const version = payload.readUInt8(0);
61
+ const hash = payload.slice(1);
62
+ return { version, hash };
63
+ });
64
+ const _chunks = lazy.value(() => {
65
+ return bscript.decompile(a.input!);
66
+ }) as StackFunction;
67
+
68
+ const _redeem = lazy.value((): ScriptRedeem => {
69
+ const chunks = _chunks();
70
+ const lastChunk = chunks[chunks.length - 1];
71
+ return {
72
+ network,
73
+ output: lastChunk === OPS.OP_FALSE ? Buffer.from([]) : (lastChunk as Buffer),
74
+ input: bscript.compile(chunks.slice(0, -1)),
75
+ witness: a.witness || [],
76
+ };
77
+ });
78
+
79
+ // output dependents
80
+ lazy.prop(o, 'address', () => {
81
+ if (!o.hash) return;
82
+
83
+ const payload = Buffer.allocUnsafe(21);
84
+ payload.writeUInt8(o.network!.scriptHash, 0);
85
+ o.hash.copy(payload, 1);
86
+ return bs58check.default.encode(payload);
87
+ });
88
+ lazy.prop(o, 'hash', () => {
89
+ // in order of least effort
90
+ if (a.output) return a.output.slice(2, 22);
91
+ if (a.address) return _address().hash;
92
+ if (o.redeem && o.redeem.output) return bcrypto.hash160(o.redeem.output);
93
+ });
94
+ lazy.prop(o, 'output', () => {
95
+ if (!o.hash) return;
96
+ return bscript.compile([OPS.OP_HASH160, o.hash, OPS.OP_EQUAL]);
97
+ });
98
+
99
+ // input dependents
100
+ lazy.prop(o, 'redeem', () => {
101
+ if (!a.input) return;
102
+ return _redeem();
103
+ });
104
+ lazy.prop(o, 'input', () => {
105
+ if (!a.redeem || !a.redeem.input || !a.redeem.output) return;
106
+ return bscript.compile(
107
+ ([] as Stack).concat(bscript.decompile(a.redeem.input) as Stack, a.redeem.output),
108
+ );
109
+ });
110
+ lazy.prop(o, 'witness', () => {
111
+ if (o.redeem && o.redeem.witness) return o.redeem.witness;
112
+ if (o.input) return [];
113
+ });
114
+ lazy.prop(o, 'name', () => {
115
+ const nameParts = ['p2sh'];
116
+ if (o.redeem !== undefined && o.redeem.name !== undefined) nameParts.push(o.redeem.name!);
117
+ return nameParts.join('-');
118
+ });
119
+
120
+ if (opts.validate) {
121
+ let hash: Buffer = Buffer.from([]);
122
+ if (a.address) {
123
+ if (_address().version !== network.scriptHash)
124
+ throw new TypeError('Invalid version or Network mismatch');
125
+ if (_address().hash.length !== 20) throw new TypeError('Invalid address');
126
+ hash = _address().hash;
127
+ }
128
+
129
+ if (a.hash) {
130
+ if (hash.length > 0 && !hash.equals(a.hash)) throw new TypeError('Hash mismatch');
131
+ else hash = a.hash;
132
+ }
133
+
134
+ if (a.output) {
135
+ if (
136
+ a.output.length !== 23 ||
137
+ a.output[0] !== OPS.OP_HASH160 ||
138
+ a.output[1] !== 0x14 ||
139
+ a.output[22] !== OPS.OP_EQUAL
140
+ )
141
+ throw new TypeError('Output is invalid');
142
+
143
+ const hash2 = a.output.slice(2, 22);
144
+ if (hash.length > 0 && !hash.equals(hash2)) throw new TypeError('Hash mismatch');
145
+ else hash = hash2;
146
+ }
147
+
148
+ // inlined to prevent 'no-inner-declarations' failing
149
+ const checkRedeem = (redeem: Payment): void => {
150
+ // is the redeem output empty/invalid?
151
+ if (redeem.output) {
152
+ const decompile = bscript.decompile(redeem.output);
153
+ if (!decompile || decompile.length < 1)
154
+ throw new TypeError('Redeem.output too short');
155
+ if (redeem.output.byteLength > 520)
156
+ throw new TypeError('Redeem.output unspendable if larger than 520 bytes');
157
+ if (bscript.countNonPushOnlyOPs(decompile) > 201)
158
+ throw new TypeError(
159
+ 'Redeem.output unspendable with more than 201 non-push ops',
160
+ );
161
+
162
+ // match hash against other sources
163
+ const hash2 = bcrypto.hash160(redeem.output);
164
+ if (hash.length > 0 && !hash.equals(hash2)) throw new TypeError('Hash mismatch');
165
+ else hash = hash2;
166
+ }
167
+
168
+ if (redeem.input) {
169
+ const hasInput = redeem.input.length > 0;
170
+ const hasWitness = redeem.witness && redeem.witness.length > 0;
171
+ if (!hasInput && !hasWitness) throw new TypeError('Empty input');
172
+ if (hasInput && hasWitness) throw new TypeError('Input and witness provided');
173
+ if (hasInput) {
174
+ const richunks = bscript.decompile(redeem.input) as Stack;
175
+ if (!bscript.isPushOnly(richunks))
176
+ throw new TypeError('Non push-only scriptSig');
177
+ }
178
+ }
179
+ };
180
+
181
+ if (a.input) {
182
+ const chunks = _chunks();
183
+ if (!chunks || chunks.length < 1) throw new TypeError('Input too short');
184
+ if (!Buffer.isBuffer(_redeem().output)) throw new TypeError('Input is invalid');
185
+
186
+ checkRedeem(_redeem());
187
+ }
188
+
189
+ if (a.redeem) {
190
+ if (a.redeem.network && a.redeem.network !== network)
191
+ throw new TypeError('Network mismatch');
192
+ if (a.input) {
193
+ const redeem = _redeem();
194
+ if (a.redeem.output && !a.redeem.output.equals(redeem.output!))
195
+ throw new TypeError('Redeem.output mismatch');
196
+ if (a.redeem.input && !a.redeem.input.equals(redeem.input!))
197
+ throw new TypeError('Redeem.input mismatch');
198
+ }
199
+
200
+ checkRedeem(a.redeem);
201
+ }
202
+
203
+ if (a.witness) {
204
+ if (a.redeem && a.redeem.witness && !stacksEqual(a.redeem.witness, a.witness))
205
+ throw new TypeError('Witness and redeem.witness mismatch');
206
+ }
207
+ }
208
+
209
+ return Object.assign(o, a);
210
+ }
@@ -13,7 +13,7 @@ import {
13
13
  toHashTree,
14
14
  tweakKey,
15
15
  } from './bip341.js';
16
- import { Payment, PaymentOpts } from './index.js';
16
+ import { P2TRPayment, PaymentOpts, PaymentType } from './index.js';
17
17
  import * as lazy from './lazy.js';
18
18
 
19
19
  const OPS = bscript.OPS;
@@ -28,7 +28,7 @@ const ANNEX_PREFIX = 0x50;
28
28
  * @returns The P2TR payment object.
29
29
  * @throws {TypeError} If the provided data is invalid or insufficient.
30
30
  */
31
- export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
31
+ export function p2tr(a: Omit<P2TRPayment, 'name'>, opts?: PaymentOpts): P2TRPayment {
32
32
  if (
33
33
  !a.address &&
34
34
  !a.output &&
@@ -82,7 +82,10 @@ export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
82
82
  });
83
83
 
84
84
  const network = a.network || BITCOIN_NETWORK;
85
- const o: Payment = { name: 'p2tr', network };
85
+ const o: P2TRPayment = {
86
+ name: PaymentType.P2TR,
87
+ network,
88
+ };
86
89
 
87
90
  lazy.prop(o, 'address', () => {
88
91
  if (!o.pubkey) return;
@@ -95,6 +98,7 @@ export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
95
98
  lazy.prop(o, 'hash', () => {
96
99
  const hashTree = _hashTree();
97
100
  if (hashTree) return hashTree.hash;
101
+
98
102
  const w = _witness();
99
103
  if (w && w.length > 1) {
100
104
  const controlBlock = w[w.length - 1];
@@ -106,7 +110,8 @@ export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
106
110
  });
107
111
  return rootHashFromPath(controlBlock, leafHash);
108
112
  }
109
- return null;
113
+
114
+ return undefined;
110
115
  });
111
116
  lazy.prop(o, 'output', () => {
112
117
  if (!o.pubkey) return;
@@ -3,7 +3,7 @@ import * as bcrypto from '../crypto.js';
3
3
  import { bitcoin as BITCOIN_NETWORK } from '../networks.js';
4
4
  import * as bscript from '../script.js';
5
5
  import { isPoint, typeforce as typef } from '../types.js';
6
- import { Payment, PaymentOpts } from './index.js';
6
+ import { P2WPKHPayment, PaymentOpts, PaymentType } from './index.js';
7
7
  import * as lazy from './lazy.js';
8
8
 
9
9
  const OPS = bscript.OPS;
@@ -21,7 +21,7 @@ const EMPTY_BUFFER = Buffer.alloc(0);
21
21
  * @returns The p2wpkh payment object.
22
22
  * @throws {TypeError} If the required data is missing or invalid.
23
23
  */
24
- export function p2wpkh(a: Payment, opts?: PaymentOpts): Payment {
24
+ export function p2wpkh(a: Omit<P2WPKHPayment, 'name'>, opts?: PaymentOpts): P2WPKHPayment {
25
25
  if (!a.address && !a.hash && !a.output && !a.pubkey && !a.witness)
26
26
  throw new TypeError('Not enough data');
27
27
  opts = Object.assign({ validate: true }, opts || {});
@@ -52,7 +52,10 @@ export function p2wpkh(a: Payment, opts?: PaymentOpts): Payment {
52
52
  });
53
53
 
54
54
  const network = a.network || BITCOIN_NETWORK;
55
- const o: Payment = { name: 'p2wpkh', network };
55
+ const o: P2WPKHPayment = {
56
+ name: PaymentType.P2WPKH,
57
+ network
58
+ };
56
59
 
57
60
  lazy.prop(o, 'address', () => {
58
61
  if (!o.hash) return;
@@ -3,7 +3,7 @@ import * as bcrypto from '../crypto.js';
3
3
  import { bitcoin as BITCOIN_NETWORK } from '../networks.js';
4
4
  import * as bscript from '../script.js';
5
5
  import { isPoint, stacksEqual, typeforce as typef } from '../types.js';
6
- import { Payment, PaymentOpts, StackElement, StackFunction } from './index.js';
6
+ import { P2WSHPayment, PaymentOpts, PaymentType, StackElement, StackFunction } from './index.js';
7
7
  import * as lazy from './lazy.js';
8
8
 
9
9
  const OPS = bscript.OPS;
@@ -29,7 +29,7 @@ function chunkHasUncompressedPubkey(chunk: StackElement): boolean {
29
29
  * @returns The P2WSH payment object.
30
30
  * @throws {TypeError} If the required data is missing or invalid.
31
31
  */
32
- export function p2wsh(a: Payment, opts?: PaymentOpts): Payment {
32
+ export function p2wsh(a: Omit<P2WSHPayment, 'name'>, opts?: PaymentOpts): P2WSHPayment {
33
33
  if (!a.address && !a.hash && !a.output && !a.redeem && !a.witness)
34
34
  throw new TypeError('Not enough data');
35
35
  opts = Object.assign({ validate: true }, opts || {});
@@ -73,7 +73,10 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment {
73
73
  network = (a.redeem && a.redeem.network) || BITCOIN_NETWORK;
74
74
  }
75
75
 
76
- const o: Payment = { network };
76
+ const o: P2WSHPayment = {
77
+ network,
78
+ name: PaymentType.P2WSH
79
+ };
77
80
 
78
81
  lazy.prop(o, 'address', () => {
79
82
  if (!o.hash) return;
package/src/psbt.ts CHANGED
@@ -20,10 +20,10 @@ import { BIP32Interface } from 'bip32';
20
20
  import { ECPairInterface } from 'ecpair';
21
21
  import { fromOutputScript, toOutputScript } from './address.js';
22
22
  import { cloneBuffer, reverseBuffer } from './bufferutils.js';
23
- import { payments } from './index.js';
23
+ import { P2WSHPayment, payments } from './index.js';
24
24
  import { bitcoin as btcNetwork, Network } from './networks.js';
25
25
  import { tapleafHash } from './payments/bip341.js';
26
- import { Payment, PaymentOpts } from './payments/index.js';
26
+ import { P2SHPayment, Payment, PaymentOpts } from './payments/index.js';
27
27
  import {
28
28
  checkTaprootInputFields,
29
29
  checkTaprootInputForSigs,
@@ -1284,7 +1284,9 @@ function canFinalize(input: PsbtInput, script: Buffer, scriptType: string): bool
1284
1284
  case 'witnesspubkeyhash':
1285
1285
  return hasSigs(1, input.partialSig);
1286
1286
  case 'multisig':
1287
- const p2ms = payments.p2ms({ output: script });
1287
+ const p2ms = payments.p2ms({
1288
+ output: script,
1289
+ });
1288
1290
  return hasSigs(p2ms.m!, input.partialSig, p2ms.pubkeys);
1289
1291
  case 'nonstandard':
1290
1292
  return true;
@@ -1412,7 +1414,7 @@ function scriptCheckerFactory(
1412
1414
  ): void => {
1413
1415
  const redeemScriptOutput = payment({
1414
1416
  redeem: { output: redeemScript },
1415
- }).output as Buffer;
1417
+ } as P2SHPayment).output as Buffer;
1416
1418
 
1417
1419
  if (!scriptPubKey.equals(redeemScriptOutput)) {
1418
1420
  throw new Error(
@@ -1512,8 +1514,8 @@ export function prepareFinalScripts(
1512
1514
 
1513
1515
  // Wow, the payments API is very handy
1514
1516
  const payment: payments.Payment = getPayment(script, scriptType, partialSig);
1515
- const p2wsh = !isP2WSH ? null : payments.p2wsh({ redeem: payment });
1516
- const p2sh = !isP2SH ? null : payments.p2sh({ redeem: p2wsh || payment });
1517
+ const p2wsh = !isP2WSH ? null : payments.p2wsh({ redeem: payment } as P2WSHPayment);
1518
+ const p2sh = !isP2SH ? null : payments.p2sh({ redeem: p2wsh || payment } as P2SHPayment);
1517
1519
 
1518
1520
  if (isSegwit) {
1519
1521
  if (p2wsh) {
@@ -1769,13 +1771,14 @@ function getPayment(
1769
1771
  ): payments.Payment {
1770
1772
  let payment: payments.Payment;
1771
1773
  switch (scriptType) {
1772
- case 'multisig':
1774
+ case 'multisig': {
1773
1775
  const sigs = getSortedSigs(script, partialSig);
1774
1776
  payment = payments.p2ms({
1775
1777
  output: script,
1776
1778
  signatures: sigs,
1777
1779
  });
1778
1780
  break;
1781
+ }
1779
1782
  case 'pubkey':
1780
1783
  payment = payments.p2pk({
1781
1784
  output: script,
@@ -4,7 +4,7 @@ import { describe, it } from 'mocha';
4
4
  import { initEccLib, PaymentCreator } from '../src/index.js';
5
5
  import * as u from './payments.utils.js';
6
6
  import fs from 'node:fs';
7
- import { p2pk, p2wsh } from '../src/payments/index.js';
7
+ import { p2pk, P2SHPayment, p2wsh } from '../src/payments/index.js';
8
8
 
9
9
  const require = async (name: string) => {
10
10
  const mod = await import(name);
@@ -68,7 +68,7 @@ const require = async (name: string) => {
68
68
  ),
69
69
  }),
70
70
  }),
71
- });
71
+ } as P2SHPayment);
72
72
  assert.strictEqual(actual.address, '3MGbrbye4ttNUXM8WAvBFRKry4fkS9fjuw');
73
73
  assert.strictEqual(actual.name, 'p2sh-p2wsh-p2pk');
74
74
  assert.strictEqual(actual.redeem!.name, 'p2wsh-p2pk');