@btc-vision/bitcoin 6.3.1 → 6.3.2

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 (259) hide show
  1. package/.babelrc +4 -0
  2. package/.gitattributes +2 -0
  3. package/.nyc_output/6368a5b2-daa5-4821-8ed0-b742d6fc7eab.json +1 -0
  4. package/.nyc_output/processinfo/6368a5b2-daa5-4821-8ed0-b742d6fc7eab.json +1 -0
  5. package/.nyc_output/processinfo/index.json +1 -0
  6. package/.prettierrc.json +12 -0
  7. package/CHANGELOG.md +403 -0
  8. package/CONTRIBUTING.md +83 -0
  9. package/browser/address.d.ts +16 -0
  10. package/{src → browser}/bip66.d.ts +6 -7
  11. package/{src → browser}/block.d.ts +29 -30
  12. package/{src → browser}/bufferutils.d.ts +34 -54
  13. package/browser/crypto/crypto.d.ts +1 -0
  14. package/{src → browser}/crypto.d.ts +13 -18
  15. package/browser/ecc_lib.d.ts +3 -0
  16. package/browser/hooks/AdvancedSignatureManager.d.ts +16 -0
  17. package/{src → browser}/hooks/HookedSigner.d.ts +4 -4
  18. package/browser/hooks/SignatureManager.d.ts +13 -0
  19. package/browser/index.d.ts +58 -0
  20. package/browser/index.js +2 -0
  21. package/browser/index.js.LICENSE.txt +14 -0
  22. package/browser/merkle.d.ts +1 -0
  23. package/browser/networks.d.ts +23 -0
  24. package/{src → browser}/ops.d.ts +126 -126
  25. package/browser/payments/bip341.d.ts +23 -0
  26. package/browser/payments/embed.d.ts +2 -0
  27. package/browser/payments/index.d.ts +41 -0
  28. package/{src → browser}/payments/lazy.d.ts +2 -2
  29. package/browser/payments/p2ms.d.ts +2 -0
  30. package/browser/payments/p2pk.d.ts +2 -0
  31. package/browser/payments/p2pkh.d.ts +2 -0
  32. package/browser/payments/p2sh.d.ts +2 -0
  33. package/browser/payments/p2tr.d.ts +2 -0
  34. package/browser/payments/p2wpkh.d.ts +2 -0
  35. package/browser/payments/p2wsh.d.ts +2 -0
  36. package/browser/psbt/bip371.d.ts +16 -0
  37. package/browser/psbt/psbtutils.d.ts +26 -0
  38. package/{src → browser}/psbt.d.ts +167 -238
  39. package/browser/push_data.d.ts +7 -0
  40. package/browser/script.d.ts +17 -0
  41. package/browser/script_number.d.ts +2 -0
  42. package/browser/script_signature.d.ts +7 -0
  43. package/{src → browser}/transaction.d.ts +48 -60
  44. package/{src → browser}/types.d.ts +37 -54
  45. package/build/address.d.ts +16 -0
  46. package/build/address.js +148 -0
  47. package/build/bip66.d.ts +6 -0
  48. package/build/bip66.js +99 -0
  49. package/build/block.d.ts +29 -0
  50. package/build/block.js +181 -0
  51. package/build/bufferutils.d.ts +34 -0
  52. package/build/bufferutils.js +141 -0
  53. package/build/crypto/crypto.d.ts +1 -0
  54. package/build/crypto/crypto.js +1 -0
  55. package/build/crypto.d.ts +13 -0
  56. package/build/crypto.js +87 -0
  57. package/build/ecc_lib.d.ts +3 -0
  58. package/build/ecc_lib.js +61 -0
  59. package/build/hooks/AdvancedSignatureManager.d.ts +16 -0
  60. package/build/hooks/AdvancedSignatureManager.js +52 -0
  61. package/build/hooks/HookedSigner.d.ts +4 -0
  62. package/build/hooks/HookedSigner.js +64 -0
  63. package/build/hooks/SignatureManager.d.ts +13 -0
  64. package/build/hooks/SignatureManager.js +45 -0
  65. package/build/index.d.ts +58 -0
  66. package/build/index.js +32 -0
  67. package/build/merkle.d.ts +1 -0
  68. package/build/merkle.js +19 -0
  69. package/build/networks.d.ts +23 -0
  70. package/build/networks.js +121 -0
  71. package/build/ops.d.ts +126 -0
  72. package/{src → build}/ops.js +127 -131
  73. package/build/payments/bip341.d.ts +23 -0
  74. package/build/payments/bip341.js +82 -0
  75. package/build/payments/embed.d.ts +2 -0
  76. package/build/payments/embed.js +39 -0
  77. package/build/payments/index.d.ts +41 -0
  78. package/build/payments/index.js +10 -0
  79. package/build/payments/lazy.d.ts +2 -0
  80. package/{src → build}/payments/lazy.js +28 -32
  81. package/build/payments/p2ms.d.ts +2 -0
  82. package/{src → build}/payments/p2ms.js +128 -158
  83. package/build/payments/p2pk.d.ts +2 -0
  84. package/build/payments/p2pk.js +68 -0
  85. package/build/payments/p2pkh.d.ts +2 -0
  86. package/build/payments/p2pkh.js +135 -0
  87. package/build/payments/p2sh.d.ts +2 -0
  88. package/build/payments/p2sh.js +175 -0
  89. package/build/payments/p2tr.d.ts +2 -0
  90. package/build/payments/p2tr.js +254 -0
  91. package/build/payments/p2wpkh.d.ts +2 -0
  92. package/build/payments/p2wpkh.js +130 -0
  93. package/build/payments/p2wsh.d.ts +2 -0
  94. package/build/payments/p2wsh.js +180 -0
  95. package/build/psbt/bip371.d.ts +16 -0
  96. package/build/psbt/bip371.js +246 -0
  97. package/build/psbt/psbtutils.d.ts +26 -0
  98. package/build/psbt/psbtutils.js +170 -0
  99. package/build/psbt.d.ts +167 -0
  100. package/build/psbt.js +1305 -0
  101. package/build/push_data.d.ts +7 -0
  102. package/build/push_data.js +57 -0
  103. package/build/script.d.ts +17 -0
  104. package/build/script.js +167 -0
  105. package/build/script_number.d.ts +2 -0
  106. package/build/script_number.js +49 -0
  107. package/build/script_signature.d.ts +7 -0
  108. package/build/script_signature.js +49 -0
  109. package/build/transaction.d.ts +48 -0
  110. package/build/transaction.js +445 -0
  111. package/build/types.d.ts +37 -0
  112. package/build/types.js +73 -0
  113. package/cjs/package.json +3 -0
  114. package/eslint.config.js +56 -0
  115. package/gulpfile.js +42 -0
  116. package/package.json +105 -50
  117. package/src/{address.js → address.ts} +93 -73
  118. package/src/{bip66.js → bip66.ts} +23 -19
  119. package/src/{block.js → block.ts} +114 -105
  120. package/src/{bufferutils.js → bufferutils.ts} +65 -67
  121. package/src/crypto/crypto-browser.js +75 -0
  122. package/src/crypto/crypto.ts +1 -0
  123. package/src/crypto.ts +108 -0
  124. package/src/{ecc_lib.js → ecc_lib.ts} +25 -53
  125. package/src/hooks/{AdvancedSignatureManager.js → AdvancedSignatureManager.ts} +34 -18
  126. package/src/hooks/HookedSigner.ts +108 -0
  127. package/src/hooks/{SignatureManager.js → SignatureManager.ts} +26 -14
  128. package/src/index.ts +86 -0
  129. package/src/{merkle.js → merkle.ts} +8 -7
  130. package/src/{networks.js → networks.ts} +44 -29
  131. package/src/ops.ts +282 -0
  132. package/src/payments/bip341.ts +140 -0
  133. package/src/payments/embed.ts +55 -0
  134. package/src/payments/{index.d.ts → index.ts} +20 -10
  135. package/src/payments/lazy.ts +28 -0
  136. package/src/payments/p2ms.ts +150 -0
  137. package/src/payments/{p2pk.js → p2pk.ts} +32 -29
  138. package/src/payments/{p2pkh.js → p2pkh.ts} +53 -47
  139. package/src/payments/{p2sh.js → p2sh.ts} +72 -71
  140. package/src/payments/{p2tr.js → p2tr.ts} +114 -125
  141. package/src/payments/{p2wpkh.js → p2wpkh.ts} +51 -56
  142. package/src/payments/{p2wsh.js → p2wsh.ts} +69 -81
  143. package/src/psbt/{bip371.js → bip371.ts} +191 -174
  144. package/src/psbt/psbtutils.ts +299 -0
  145. package/src/{psbt.js → psbt.ts} +1025 -679
  146. package/src/{push_data.js → push_data.ts} +35 -21
  147. package/src/{script.js → script.ts} +93 -77
  148. package/src/{script_number.js → script_number.ts} +15 -21
  149. package/src/{script_signature.js → script_signature.ts} +26 -14
  150. package/src/{transaction.js → transaction.ts} +247 -167
  151. package/src/types.ts +122 -0
  152. package/test/address.spec.js +124 -0
  153. package/test/address.spec.ts +177 -0
  154. package/test/bitcoin.core.spec.js +170 -0
  155. package/test/bitcoin.core.spec.ts +234 -0
  156. package/test/block.spec.js +141 -0
  157. package/test/block.spec.ts +194 -0
  158. package/test/bufferutils.spec.js +427 -0
  159. package/test/bufferutils.spec.ts +513 -0
  160. package/test/crypto.spec.js +41 -0
  161. package/test/crypto.spec.ts +55 -0
  162. package/test/fixtures/address.json +329 -0
  163. package/test/fixtures/block.json +148 -0
  164. package/test/fixtures/bufferutils.json +102 -0
  165. package/test/fixtures/core/README.md +26 -0
  166. package/test/fixtures/core/base58_encode_decode.json +50 -0
  167. package/test/fixtures/core/base58_keys_invalid.json +152 -0
  168. package/test/fixtures/core/base58_keys_valid.json +452 -0
  169. package/test/fixtures/core/blocks.json +27 -0
  170. package/test/fixtures/core/sig_canonical.json +7 -0
  171. package/test/fixtures/core/sig_noncanonical.json +33 -0
  172. package/test/fixtures/core/sighash.json +3505 -0
  173. package/test/fixtures/core/tx_valid.json +2023 -0
  174. package/test/fixtures/crypto.json +43 -0
  175. package/test/fixtures/ecdsa.json +217 -0
  176. package/test/fixtures/ecpair.json +141 -0
  177. package/test/fixtures/embed.json +108 -0
  178. package/test/fixtures/p2ms.json +434 -0
  179. package/test/fixtures/p2pk.json +179 -0
  180. package/test/fixtures/p2pkh.json +276 -0
  181. package/test/fixtures/p2sh.json +508 -0
  182. package/test/fixtures/p2tr.json +1198 -0
  183. package/test/fixtures/p2wpkh.json +290 -0
  184. package/test/fixtures/p2wsh.json +489 -0
  185. package/test/fixtures/psbt.json +924 -0
  186. package/test/fixtures/script.json +465 -0
  187. package/test/fixtures/script_number.json +225 -0
  188. package/test/fixtures/signature.json +140 -0
  189. package/test/fixtures/transaction.json +916 -0
  190. package/test/integration/_regtest.js +7 -0
  191. package/test/integration/_regtest.ts +6 -0
  192. package/test/integration/addresses.spec.js +116 -0
  193. package/test/integration/addresses.spec.ts +154 -0
  194. package/test/integration/bip32.spec.js +85 -0
  195. package/test/integration/bip32.spec.ts +151 -0
  196. package/test/integration/blocks.spec.js +26 -0
  197. package/test/integration/blocks.spec.ts +28 -0
  198. package/test/integration/cltv.spec.js +199 -0
  199. package/test/integration/cltv.spec.ts +283 -0
  200. package/test/integration/csv.spec.js +362 -0
  201. package/test/integration/csv.spec.ts +527 -0
  202. package/test/integration/payments.spec.js +98 -0
  203. package/test/integration/payments.spec.ts +135 -0
  204. package/test/integration/taproot.spec.js +532 -0
  205. package/test/integration/taproot.spec.ts +707 -0
  206. package/test/integration/transactions.spec.js +561 -0
  207. package/test/integration/transactions.spec.ts +769 -0
  208. package/test/payments.spec.js +97 -0
  209. package/test/payments.spec.ts +125 -0
  210. package/test/payments.utils.js +190 -0
  211. package/test/payments.utils.ts +208 -0
  212. package/test/psbt.spec.js +1044 -0
  213. package/test/psbt.spec.ts +1414 -0
  214. package/test/script.spec.js +151 -0
  215. package/test/script.spec.ts +210 -0
  216. package/test/script_number.spec.js +24 -0
  217. package/test/script_number.spec.ts +29 -0
  218. package/test/script_signature.spec.js +52 -0
  219. package/test/script_signature.spec.ts +66 -0
  220. package/test/transaction.spec.js +269 -0
  221. package/test/transaction.spec.ts +387 -0
  222. package/test/ts-node-register.js +5 -0
  223. package/test/tsconfig.json +45 -0
  224. package/test/types.spec.js +46 -0
  225. package/test/types.spec.ts +58 -0
  226. package/tsconfig.base.json +27 -0
  227. package/tsconfig.json +19 -0
  228. package/tsconfig.webpack.json +18 -0
  229. package/webpack.config.js +79 -0
  230. package/src/address.d.ts +0 -42
  231. package/src/crypto.js +0 -128
  232. package/src/ecc_lib.d.ts +0 -17
  233. package/src/hooks/AdvancedSignatureManager.d.ts +0 -44
  234. package/src/hooks/HookedSigner.js +0 -90
  235. package/src/hooks/SignatureManager.d.ts +0 -35
  236. package/src/index.d.ts +0 -42
  237. package/src/index.js +0 -87
  238. package/src/merkle.d.ts +0 -10
  239. package/src/networks.d.ts +0 -83
  240. package/src/payments/bip341.d.ts +0 -49
  241. package/src/payments/bip341.js +0 -124
  242. package/src/payments/embed.d.ts +0 -9
  243. package/src/payments/embed.js +0 -54
  244. package/src/payments/index.js +0 -69
  245. package/src/payments/p2ms.d.ts +0 -9
  246. package/src/payments/p2pk.d.ts +0 -10
  247. package/src/payments/p2pkh.d.ts +0 -10
  248. package/src/payments/p2sh.d.ts +0 -10
  249. package/src/payments/p2tr.d.ts +0 -10
  250. package/src/payments/p2wpkh.d.ts +0 -10
  251. package/src/payments/p2wsh.d.ts +0 -10
  252. package/src/psbt/bip371.d.ts +0 -42
  253. package/src/psbt/psbtutils.d.ts +0 -64
  254. package/src/psbt/psbtutils.js +0 -191
  255. package/src/push_data.d.ts +0 -29
  256. package/src/script.d.ts +0 -42
  257. package/src/script_number.d.ts +0 -19
  258. package/src/script_signature.d.ts +0 -21
  259. package/src/types.js +0 -106
@@ -1,18 +1,25 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', { value: true });
3
- exports.p2tr = void 0;
4
- const buffer_1 = require('buffer');
5
- const networks_1 = require('../networks');
6
- const bscript = require('../script');
7
- const types_1 = require('../types');
8
- const ecc_lib_1 = require('../ecc_lib');
9
- const bip341_1 = require('./bip341');
10
- const lazy = require('./lazy');
11
- const bech32_1 = require('bech32');
12
- const address_1 = require('../address');
1
+ import { bech32m } from 'bech32';
2
+ import { Buffer as NBuffer } from 'buffer';
3
+ import { fromBech32 } from '../address.js';
4
+ import { getEccLib } from '../ecc_lib.js';
5
+ import { bitcoin as BITCOIN_NETWORK } from '../networks.js';
6
+ import * as bscript from '../script.js';
7
+ import { isTaptree, stacksEqual, TAPLEAF_VERSION_MASK, typeforce as typef } from '../types.js';
8
+ import {
9
+ findScriptPath,
10
+ LEAF_VERSION_TAPSCRIPT,
11
+ rootHashFromPath,
12
+ tapleafHash,
13
+ toHashTree,
14
+ tweakKey,
15
+ } from './bip341.js';
16
+ import { Payment, PaymentOpts } from './index.js';
17
+ import * as lazy from './lazy.js';
18
+
13
19
  const OPS = bscript.OPS;
14
20
  const TAPROOT_WITNESS_VERSION = 0x01;
15
21
  const ANNEX_PREFIX = 0x50;
22
+
16
23
  /**
17
24
  * Creates a Pay-to-Taproot (P2TR) payment object.
18
25
  *
@@ -21,7 +28,7 @@ const ANNEX_PREFIX = 0x50;
21
28
  * @returns The P2TR payment object.
22
29
  * @throws {TypeError} If the provided data is invalid or insufficient.
23
30
  */
24
- function p2tr(a, opts) {
31
+ export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
25
32
  if (
26
33
  !a.address &&
27
34
  !a.output &&
@@ -30,81 +37,74 @@ function p2tr(a, opts) {
30
37
  !(a.witness && a.witness.length > 1)
31
38
  )
32
39
  throw new TypeError('Not enough data');
40
+
33
41
  opts = Object.assign({ validate: true }, opts || {});
34
- (0, types_1.typeforce)(
42
+
43
+ typef(
35
44
  {
36
- address: types_1.typeforce.maybe(types_1.typeforce.String),
37
- input: types_1.typeforce.maybe(types_1.typeforce.BufferN(0)),
38
- network: types_1.typeforce.maybe(types_1.typeforce.Object),
39
- output: types_1.typeforce.maybe(types_1.typeforce.BufferN(34)),
40
- internalPubkey: types_1.typeforce.maybe(
41
- types_1.typeforce.BufferN(32),
42
- ),
43
- hash: types_1.typeforce.maybe(types_1.typeforce.BufferN(32)),
44
- pubkey: types_1.typeforce.maybe(types_1.typeforce.BufferN(32)),
45
- signature: types_1.typeforce.maybe(
46
- types_1.typeforce.anyOf(
47
- types_1.typeforce.BufferN(64),
48
- types_1.typeforce.BufferN(65),
49
- ),
50
- ),
51
- witness: types_1.typeforce.maybe(
52
- types_1.typeforce.arrayOf(types_1.typeforce.Buffer),
53
- ),
54
- scriptTree: types_1.typeforce.maybe(types_1.isTaptree),
55
- redeem: types_1.typeforce.maybe({
56
- output: types_1.typeforce.maybe(types_1.typeforce.Buffer),
57
- redeemVersion: types_1.typeforce.maybe(
58
- types_1.typeforce.Number,
59
- ),
60
- witness: types_1.typeforce.maybe(
61
- types_1.typeforce.arrayOf(types_1.typeforce.Buffer),
62
- ),
45
+ address: typef.maybe(typef.String),
46
+ input: typef.maybe(typef.BufferN(0)),
47
+ network: typef.maybe(typef.Object),
48
+ output: typef.maybe(typef.BufferN(34)),
49
+ internalPubkey: typef.maybe(typef.BufferN(32)),
50
+ hash: typef.maybe(typef.BufferN(32)), // merkle root hash, the tweak
51
+ pubkey: typef.maybe(typef.BufferN(32)), // tweaked with `hash` from `internalPubkey`
52
+ signature: typef.maybe(typef.anyOf(typef.BufferN(64), typef.BufferN(65))),
53
+ witness: typef.maybe(typef.arrayOf(typef.Buffer)),
54
+ scriptTree: typef.maybe(isTaptree),
55
+ redeem: typef.maybe({
56
+ output: typef.maybe(typef.Buffer), // tapleaf script
57
+ redeemVersion: typef.maybe(typef.Number), // tapleaf version
58
+ witness: typef.maybe(typef.arrayOf(typef.Buffer)),
63
59
  }),
64
- redeemVersion: types_1.typeforce.maybe(types_1.typeforce.Number),
60
+ redeemVersion: typef.maybe(typef.Number),
65
61
  },
66
62
  a,
67
63
  );
64
+
68
65
  const _address = lazy.value(() => {
69
- return (0, address_1.fromBech32)(a.address);
66
+ return fromBech32(a.address!);
70
67
  });
68
+
71
69
  // remove annex if present, ignored by taproot
72
70
  const _witness = lazy.value(() => {
73
71
  if (!a.witness || !a.witness.length) return;
74
- if (
75
- a.witness.length >= 2 &&
76
- a.witness[a.witness.length - 1][0] === ANNEX_PREFIX
77
- ) {
72
+ if (a.witness.length >= 2 && a.witness[a.witness.length - 1][0] === ANNEX_PREFIX) {
78
73
  return a.witness.slice(0, -1);
79
74
  }
80
75
  return a.witness.slice();
81
76
  });
77
+
82
78
  const _hashTree = lazy.value(() => {
83
- if (a.scriptTree) return (0, bip341_1.toHashTree)(a.scriptTree);
79
+ if (a.scriptTree) return toHashTree(a.scriptTree);
84
80
  if (a.hash) return { hash: a.hash };
85
81
  return;
86
82
  });
87
- const network = a.network || networks_1.bitcoin;
88
- const o = { name: 'p2tr', network };
83
+
84
+ const network = a.network || BITCOIN_NETWORK;
85
+ const o: Payment = { name: 'p2tr', network };
86
+
89
87
  lazy.prop(o, 'address', () => {
90
88
  if (!o.pubkey) return;
91
- const words = bech32_1.bech32m.toWords(o.pubkey);
89
+
90
+ const words = bech32m.toWords(o.pubkey);
92
91
  words.unshift(TAPROOT_WITNESS_VERSION);
93
- return bech32_1.bech32m.encode(network.bech32, words);
92
+ return bech32m.encode(network.bech32, words);
94
93
  });
94
+
95
95
  lazy.prop(o, 'hash', () => {
96
96
  const hashTree = _hashTree();
97
97
  if (hashTree) return hashTree.hash;
98
98
  const w = _witness();
99
99
  if (w && w.length > 1) {
100
100
  const controlBlock = w[w.length - 1];
101
- const leafVersion = controlBlock[0] & types_1.TAPLEAF_VERSION_MASK;
101
+ const leafVersion = controlBlock[0] & TAPLEAF_VERSION_MASK;
102
102
  const script = w[w.length - 2];
103
- const leafHash = (0, bip341_1.tapleafHash)({
103
+ const leafHash = tapleafHash({
104
104
  output: script,
105
105
  version: leafVersion,
106
106
  });
107
- return (0, bip341_1.rootHashFromPath)(controlBlock, leafHash);
107
+ return rootHashFromPath(controlBlock, leafHash);
108
108
  }
109
109
  return null;
110
110
  });
@@ -114,23 +114,20 @@ function p2tr(a, opts) {
114
114
  });
115
115
  lazy.prop(o, 'redeemVersion', () => {
116
116
  if (a.redeemVersion) return a.redeemVersion;
117
- if (
118
- a.redeem &&
119
- a.redeem.redeemVersion !== undefined &&
120
- a.redeem.redeemVersion !== null
121
- ) {
117
+ if (a.redeem && a.redeem.redeemVersion !== undefined && a.redeem.redeemVersion !== null) {
122
118
  return a.redeem.redeemVersion;
123
119
  }
124
- return bip341_1.LEAF_VERSION_TAPSCRIPT;
120
+
121
+ return LEAF_VERSION_TAPSCRIPT;
125
122
  });
126
123
  lazy.prop(o, 'redeem', () => {
127
124
  const witness = _witness(); // witness without annex
128
125
  if (!witness || witness.length < 2) return;
126
+
129
127
  return {
130
128
  output: witness[witness.length - 2],
131
129
  witness: witness.slice(0, -2),
132
- redeemVersion:
133
- witness[witness.length - 1][0] & types_1.TAPLEAF_VERSION_MASK,
130
+ redeemVersion: witness[witness.length - 1][0] & TAPLEAF_VERSION_MASK,
134
131
  };
135
132
  });
136
133
  lazy.prop(o, 'pubkey', () => {
@@ -138,15 +135,14 @@ function p2tr(a, opts) {
138
135
  if (a.output) return a.output.slice(2);
139
136
  if (a.address) return _address().data;
140
137
  if (o.internalPubkey) {
141
- const tweakedKey = (0, bip341_1.tweakKey)(o.internalPubkey, o.hash);
138
+ const tweakedKey = tweakKey(o.internalPubkey, o.hash);
142
139
  if (tweakedKey) return tweakedKey.x;
143
140
  }
144
141
  });
145
142
  lazy.prop(o, 'internalPubkey', () => {
146
143
  if (a.internalPubkey) return a.internalPubkey;
147
144
  const witness = _witness();
148
- if (witness && witness.length > 1)
149
- return witness[witness.length - 1].slice(1, 33);
145
+ if (witness && witness.length > 1) return witness[witness.length - 1].slice(1, 33);
150
146
  });
151
147
  lazy.prop(o, 'signature', () => {
152
148
  if (a.signature) return a.signature;
@@ -154,109 +150,105 @@ function p2tr(a, opts) {
154
150
  if (!witness || witness.length !== 1) return;
155
151
  return witness[0];
156
152
  });
153
+
157
154
  lazy.prop(o, 'witness', () => {
158
155
  if (a.witness) return a.witness;
159
156
  const hashTree = _hashTree();
160
157
  if (hashTree && a.redeem && a.redeem.output && a.internalPubkey) {
161
- const leafHash = (0, bip341_1.tapleafHash)({
158
+ const leafHash = tapleafHash({
162
159
  output: a.redeem.output,
163
160
  version: o.redeemVersion,
164
161
  });
165
- const path = (0, bip341_1.findScriptPath)(hashTree, leafHash);
162
+ const path = findScriptPath(hashTree, leafHash);
166
163
  if (!path) return;
167
- const outputKey = (0, bip341_1.tweakKey)(
168
- a.internalPubkey,
169
- hashTree.hash,
170
- );
164
+ const outputKey = tweakKey(a.internalPubkey, hashTree.hash);
171
165
  if (!outputKey) return;
172
- const controlBock = buffer_1.Buffer.concat(
173
- [
174
- buffer_1.Buffer.from([o.redeemVersion | outputKey.parity]),
175
- a.internalPubkey,
176
- ].concat(path),
166
+ const controlBock = NBuffer.concat(
167
+ [NBuffer.from([o.redeemVersion! | outputKey.parity]), a.internalPubkey].concat(
168
+ path,
169
+ ),
177
170
  );
178
171
  return [a.redeem.output, controlBock];
179
172
  }
180
173
  if (a.signature) return [a.signature];
181
174
  });
175
+
182
176
  // extended validation
183
177
  if (opts.validate) {
184
- let pubkey = buffer_1.Buffer.from([]);
178
+ let pubkey: Buffer = NBuffer.from([]);
185
179
  if (a.address) {
186
180
  if (network && network.bech32 !== _address().prefix)
187
181
  throw new TypeError('Invalid prefix or Network mismatch');
188
182
  if (_address().version !== TAPROOT_WITNESS_VERSION)
189
183
  throw new TypeError('Invalid address version');
190
- if (_address().data.length !== 32)
191
- throw new TypeError('Invalid address data');
184
+ if (_address().data.length !== 32) throw new TypeError('Invalid address data');
192
185
  pubkey = _address().data;
193
186
  }
187
+
194
188
  if (a.pubkey) {
195
189
  if (pubkey.length > 0 && !pubkey.equals(a.pubkey))
196
190
  throw new TypeError('Pubkey mismatch');
197
191
  else pubkey = a.pubkey;
198
192
  }
193
+
199
194
  if (a.output) {
200
- if (
201
- a.output.length !== 34 ||
202
- a.output[0] !== OPS.OP_1 ||
203
- a.output[1] !== 0x20
204
- )
195
+ if (a.output.length !== 34 || a.output[0] !== OPS.OP_1 || a.output[1] !== 0x20)
205
196
  throw new TypeError('Output is invalid');
206
197
  if (pubkey.length > 0 && !pubkey.equals(a.output.slice(2)))
207
198
  throw new TypeError('Pubkey mismatch');
208
199
  else pubkey = a.output.slice(2);
209
200
  }
201
+
210
202
  if (a.internalPubkey) {
211
- const tweakedKey = (0, bip341_1.tweakKey)(a.internalPubkey, o.hash);
212
- if (pubkey.length > 0 && !pubkey.equals(tweakedKey.x))
203
+ const tweakedKey = tweakKey(a.internalPubkey, o.hash);
204
+ if (pubkey.length > 0 && !pubkey.equals(tweakedKey!.x))
213
205
  throw new TypeError('Pubkey mismatch');
214
- else pubkey = tweakedKey.x;
206
+ else pubkey = tweakedKey!.x;
215
207
  }
208
+
216
209
  /*if (pubkey && pubkey.length) {
217
210
  if (!getEccLib().isXOnlyPoint(pubkey))
218
211
  throw new TypeError('Invalid pubkey for p2tr');
219
212
  }*/
213
+
220
214
  const hashTree = _hashTree();
215
+
221
216
  if (a.hash && hashTree) {
222
- if (!a.hash.equals(hashTree.hash))
223
- throw new TypeError('Hash mismatch');
217
+ if (!a.hash.equals(hashTree.hash)) throw new TypeError('Hash mismatch');
224
218
  }
219
+
225
220
  if (a.redeem && a.redeem.output && hashTree) {
226
- const leafHash = (0, bip341_1.tapleafHash)({
221
+ const leafHash = tapleafHash({
227
222
  output: a.redeem.output,
228
223
  version: o.redeemVersion,
229
224
  });
230
- if (!(0, bip341_1.findScriptPath)(hashTree, leafHash))
225
+ if (!findScriptPath(hashTree, leafHash))
231
226
  throw new TypeError('Redeem script not in tree');
232
227
  }
228
+
233
229
  const witness = _witness();
230
+
234
231
  // compare the provided redeem data with the one computed from witness
235
232
  if (a.redeem && o.redeem) {
236
233
  if (a.redeem.redeemVersion) {
237
234
  if (a.redeem.redeemVersion !== o.redeem.redeemVersion)
238
- throw new TypeError(
239
- 'Redeem.redeemVersion and witness mismatch',
240
- );
235
+ throw new TypeError('Redeem.redeemVersion and witness mismatch');
241
236
  }
237
+
242
238
  if (a.redeem.output) {
243
- if (bscript.decompile(a.redeem.output).length === 0)
239
+ if (bscript.decompile(a.redeem.output)!.length === 0)
244
240
  throw new TypeError('Redeem.output is invalid');
241
+
245
242
  // output redeem is constructed from the witness
246
243
  if (o.redeem.output && !a.redeem.output.equals(o.redeem.output))
247
244
  throw new TypeError('Redeem.output and witness mismatch');
248
245
  }
249
246
  if (a.redeem.witness) {
250
- if (
251
- o.redeem.witness &&
252
- !(0, types_1.stacksEqual)(
253
- a.redeem.witness,
254
- o.redeem.witness,
255
- )
256
- )
247
+ if (o.redeem.witness && !stacksEqual(a.redeem.witness, o.redeem.witness))
257
248
  throw new TypeError('Redeem.witness and witness mismatch');
258
249
  }
259
250
  }
251
+
260
252
  if (witness && witness.length) {
261
253
  if (witness.length === 1) {
262
254
  // key spending
@@ -269,47 +261,44 @@ function p2tr(a, opts) {
269
261
  throw new TypeError(
270
262
  `The control-block length is too small. Got ${controlBlock.length}, expected min 33.`,
271
263
  );
264
+
272
265
  if ((controlBlock.length - 33) % 32 !== 0)
273
266
  throw new TypeError(
274
267
  `The control-block length of ${controlBlock.length} is incorrect!`,
275
268
  );
269
+
276
270
  const m = (controlBlock.length - 33) / 32;
277
271
  if (m > 128)
278
- throw new TypeError(
279
- `The script path is too long. Got ${m}, expected max 128.`,
280
- );
272
+ throw new TypeError(`The script path is too long. Got ${m}, expected max 128.`);
273
+
281
274
  const internalPubkey = controlBlock.slice(1, 33);
282
- if (
283
- a.internalPubkey &&
284
- !a.internalPubkey.equals(internalPubkey)
285
- )
275
+ if (a.internalPubkey && !a.internalPubkey.equals(internalPubkey))
286
276
  throw new TypeError('Internal pubkey mismatch');
287
- if (!(0, ecc_lib_1.getEccLib)().isXOnlyPoint(internalPubkey))
288
- throw new TypeError(
289
- 'Invalid internalPubkey for p2tr witness',
290
- );
291
- const leafVersion =
292
- controlBlock[0] & types_1.TAPLEAF_VERSION_MASK;
277
+
278
+ if (!getEccLib().isXOnlyPoint(internalPubkey))
279
+ throw new TypeError('Invalid internalPubkey for p2tr witness');
280
+
281
+ const leafVersion = controlBlock[0] & TAPLEAF_VERSION_MASK;
293
282
  const script = witness[witness.length - 2];
294
- const leafHash = (0, bip341_1.tapleafHash)({
283
+
284
+ const leafHash = tapleafHash({
295
285
  output: script,
296
286
  version: leafVersion,
297
287
  });
298
- const hash = (0, bip341_1.rootHashFromPath)(
299
- controlBlock,
300
- leafHash,
301
- );
302
- const outputKey = (0, bip341_1.tweakKey)(internalPubkey, hash);
288
+ const hash = rootHashFromPath(controlBlock, leafHash);
289
+
290
+ const outputKey = tweakKey(internalPubkey, hash);
303
291
  if (!outputKey)
304
292
  // todo: needs test data
305
293
  throw new TypeError('Invalid outputKey for p2tr witness');
294
+
306
295
  if (pubkey.length && !pubkey.equals(outputKey.x))
307
296
  throw new TypeError('Pubkey mismatch for p2tr witness');
308
- if (outputKey.parity !== (controlBlock[0] & 1))
309
- throw new Error('Incorrect parity');
297
+
298
+ if (outputKey.parity !== (controlBlock[0] & 1)) throw new Error('Incorrect parity');
310
299
  }
311
300
  }
312
301
  }
302
+
313
303
  return Object.assign(o, a);
314
304
  }
315
- exports.p2tr = p2tr;
@@ -1,14 +1,15 @@
1
- 'use strict';
2
- Object.defineProperty(exports, '__esModule', { value: true });
3
- exports.p2wpkh = void 0;
4
- const bcrypto = require('../crypto');
5
- const networks_1 = require('../networks');
6
- const bscript = require('../script');
7
- const types_1 = require('../types');
8
- const lazy = require('./lazy');
9
- const bech32_1 = require('bech32');
1
+ import { bech32 } from 'bech32';
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 { isPoint, typeforce as typef } from '../types.js';
6
+ import { Payment, PaymentOpts } from './index.js';
7
+ import * as lazy from './lazy.js';
8
+
10
9
  const OPS = bscript.OPS;
10
+
11
11
  const EMPTY_BUFFER = Buffer.alloc(0);
12
+
12
13
  // witness: {signature} {pubKey}
13
14
  // input: <>
14
15
  // output: OP_0 {pubKeyHash}
@@ -20,49 +21,50 @@ const EMPTY_BUFFER = Buffer.alloc(0);
20
21
  * @returns The p2wpkh payment object.
21
22
  * @throws {TypeError} If the required data is missing or invalid.
22
23
  */
23
- function p2wpkh(a, opts) {
24
+ export function p2wpkh(a: Payment, opts?: PaymentOpts): Payment {
24
25
  if (!a.address && !a.hash && !a.output && !a.pubkey && !a.witness)
25
26
  throw new TypeError('Not enough data');
26
27
  opts = Object.assign({ validate: true }, opts || {});
27
- (0, types_1.typeforce)(
28
+
29
+ typef(
28
30
  {
29
- address: types_1.typeforce.maybe(types_1.typeforce.String),
30
- hash: types_1.typeforce.maybe(types_1.typeforce.BufferN(20)),
31
- input: types_1.typeforce.maybe(types_1.typeforce.BufferN(0)),
32
- network: types_1.typeforce.maybe(types_1.typeforce.Object),
33
- output: types_1.typeforce.maybe(types_1.typeforce.BufferN(22)),
34
- pubkey: types_1.typeforce.maybe(types_1.isPoint),
35
- signature: types_1.typeforce.maybe(
36
- bscript.isCanonicalScriptSignature,
37
- ),
38
- witness: types_1.typeforce.maybe(
39
- types_1.typeforce.arrayOf(types_1.typeforce.Buffer),
40
- ),
31
+ address: typef.maybe(typef.String),
32
+ hash: typef.maybe(typef.BufferN(20)),
33
+ input: typef.maybe(typef.BufferN(0)),
34
+ network: typef.maybe(typef.Object),
35
+ output: typef.maybe(typef.BufferN(22)),
36
+ pubkey: typef.maybe(isPoint),
37
+ signature: typef.maybe(bscript.isCanonicalScriptSignature),
38
+ witness: typef.maybe(typef.arrayOf(typef.Buffer)),
41
39
  },
42
40
  a,
43
41
  );
42
+
44
43
  const _address = lazy.value(() => {
45
- const result = bech32_1.bech32.decode(a.address);
44
+ const result = bech32.decode(a.address!);
46
45
  const version = result.words.shift();
47
- const data = bech32_1.bech32.fromWords(result.words);
46
+ const data = bech32.fromWords(result.words);
48
47
  return {
49
48
  version,
50
49
  prefix: result.prefix,
51
50
  data: Buffer.from(data),
52
51
  };
53
52
  });
54
- const network = a.network || networks_1.bitcoin;
55
- const o = { name: 'p2wpkh', network };
53
+
54
+ const network = a.network || BITCOIN_NETWORK;
55
+ const o: Payment = { name: 'p2wpkh', network };
56
+
56
57
  lazy.prop(o, 'address', () => {
57
58
  if (!o.hash) return;
58
- const words = bech32_1.bech32.toWords(o.hash);
59
+
60
+ const words = bech32.toWords(o.hash);
59
61
  words.unshift(0x00);
60
- return bech32_1.bech32.encode(network.bech32, words);
62
+ return bech32.encode(network.bech32, words);
61
63
  });
62
64
  lazy.prop(o, 'hash', () => {
63
65
  if (a.output) return a.output.slice(2, 22);
64
66
  if (a.address) return _address().data;
65
- if (a.pubkey || o.pubkey) return bcrypto.hash160(a.pubkey || o.pubkey);
67
+ if (a.pubkey || o.pubkey) return bcrypto.hash160(a.pubkey! || o.pubkey!);
66
68
  });
67
69
  lazy.prop(o, 'output', () => {
68
70
  if (!o.hash) return;
@@ -86,61 +88,54 @@ function p2wpkh(a, opts) {
86
88
  if (!a.signature) return;
87
89
  return [a.signature, a.pubkey];
88
90
  });
91
+
89
92
  // extended validation
90
93
  if (opts.validate) {
91
- let hash = Buffer.from([]);
94
+ let hash: Buffer = Buffer.from([]);
92
95
  if (a.address) {
93
96
  if (network && network.bech32 !== _address().prefix)
94
97
  throw new TypeError('Invalid prefix or Network mismatch');
95
- if (_address().version !== 0x00)
96
- throw new TypeError('Invalid address version');
97
- if (_address().data.length !== 20)
98
- throw new TypeError('Invalid address data');
98
+ if (_address().version !== 0x00) throw new TypeError('Invalid address version');
99
+ if (_address().data.length !== 20) throw new TypeError('Invalid address data');
99
100
  hash = _address().data;
100
101
  }
102
+
101
103
  if (a.hash) {
102
- if (hash.length > 0 && !hash.equals(a.hash))
103
- throw new TypeError('Hash mismatch');
104
+ if (hash.length > 0 && !hash.equals(a.hash)) throw new TypeError('Hash mismatch');
104
105
  else hash = a.hash;
105
106
  }
107
+
106
108
  if (a.output) {
107
- if (
108
- a.output.length !== 22 ||
109
- a.output[0] !== OPS.OP_0 ||
110
- a.output[1] !== 0x14
111
- )
109
+ if (a.output.length !== 22 || a.output[0] !== OPS.OP_0 || a.output[1] !== 0x14)
112
110
  throw new TypeError('Output is invalid');
113
111
  if (hash.length > 0 && !hash.equals(a.output.slice(2)))
114
112
  throw new TypeError('Hash mismatch');
115
113
  else hash = a.output.slice(2);
116
114
  }
115
+
117
116
  if (a.pubkey) {
118
117
  const pkh = bcrypto.hash160(a.pubkey);
119
- if (hash.length > 0 && !hash.equals(pkh))
120
- throw new TypeError('Hash mismatch');
118
+ if (hash.length > 0 && !hash.equals(pkh)) throw new TypeError('Hash mismatch');
121
119
  else hash = pkh;
122
- if (!(0, types_1.isPoint)(a.pubkey) || a.pubkey.length !== 33)
120
+ if (!isPoint(a.pubkey) || a.pubkey.length !== 33)
123
121
  throw new TypeError('Invalid pubkey for p2wpkh');
124
122
  }
123
+
125
124
  if (a.witness) {
126
- if (a.witness.length !== 2)
127
- throw new TypeError('Witness is invalid');
125
+ if (a.witness.length !== 2) throw new TypeError('Witness is invalid');
128
126
  if (!bscript.isCanonicalScriptSignature(a.witness[0]))
129
127
  throw new TypeError('Witness has invalid signature');
130
- if (
131
- !(0, types_1.isPoint)(a.witness[1]) ||
132
- a.witness[1].length !== 33
133
- )
128
+ if (!isPoint(a.witness[1]) || a.witness[1].length !== 33)
134
129
  throw new TypeError('Witness has invalid pubkey');
130
+
135
131
  if (a.signature && !a.signature.equals(a.witness[0]))
136
132
  throw new TypeError('Signature mismatch');
137
- if (a.pubkey && !a.pubkey.equals(a.witness[1]))
138
- throw new TypeError('Pubkey mismatch');
133
+ if (a.pubkey && !a.pubkey.equals(a.witness[1])) throw new TypeError('Pubkey mismatch');
134
+
139
135
  const pkh = bcrypto.hash160(a.witness[1]);
140
- if (hash.length > 0 && !hash.equals(pkh))
141
- throw new TypeError('Hash mismatch');
136
+ if (hash.length > 0 && !hash.equals(pkh)) throw new TypeError('Hash mismatch');
142
137
  }
143
138
  }
139
+
144
140
  return Object.assign(o, a);
145
141
  }
146
- exports.p2wpkh = p2wpkh;