@btc-vision/bitcoin 6.3.0 → 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 (260) 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 -235
  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.ts +235 -0
  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} +195 -178
  144. package/src/psbt/psbtutils.ts +299 -0
  145. package/src/{psbt.js → psbt.ts} +1048 -699
  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 -29
  240. package/src/networks.js +0 -71
  241. package/src/payments/bip341.d.ts +0 -49
  242. package/src/payments/bip341.js +0 -124
  243. package/src/payments/embed.d.ts +0 -9
  244. package/src/payments/embed.js +0 -54
  245. package/src/payments/index.js +0 -69
  246. package/src/payments/p2ms.d.ts +0 -9
  247. package/src/payments/p2pk.d.ts +0 -10
  248. package/src/payments/p2pkh.d.ts +0 -10
  249. package/src/payments/p2sh.d.ts +0 -10
  250. package/src/payments/p2tr.d.ts +0 -10
  251. package/src/payments/p2wpkh.d.ts +0 -10
  252. package/src/payments/p2wsh.d.ts +0 -10
  253. package/src/psbt/bip371.d.ts +0 -42
  254. package/src/psbt/psbtutils.d.ts +0 -64
  255. package/src/psbt/psbtutils.js +0 -191
  256. package/src/push_data.d.ts +0 -29
  257. package/src/script.d.ts +0 -42
  258. package/src/script_number.d.ts +0 -19
  259. package/src/script_signature.d.ts +0 -21
  260. package/src/types.js +0 -106
@@ -0,0 +1,362 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const assert = require("assert");
4
+ const ecpair_1 = require("ecpair");
5
+ const ecc = require("tiny-secp256k1");
6
+ const mocha_1 = require("mocha");
7
+ const bitcoin = require("../..");
8
+ const _regtest_1 = require("./_regtest");
9
+ const ECPair = (0, ecpair_1.default)(ecc);
10
+ const regtest = _regtest_1.regtestUtils.network;
11
+ const bip68 = require('bip68');
12
+ const varuint = require('varuint-bitcoin');
13
+ function toOutputScript(address) {
14
+ return bitcoin.address.toOutputScript(address, regtest);
15
+ }
16
+ function idToHash(txid) {
17
+ return Buffer.from(txid, 'hex').reverse();
18
+ }
19
+ const alice = ECPair.fromWIF('cScfkGjbzzoeewVWmU2hYPUHeVGJRDdFt7WhmrVVGkxpmPP8BHWe', regtest);
20
+ const bob = ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsLwjHXA9x', regtest);
21
+ const charles = ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsMSb4Ubnf', regtest);
22
+ const dave = ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsMwS4pqnx', regtest);
23
+ (0, mocha_1.describe)('bitcoinjs-lib (transactions w/ CSV)', () => {
24
+ // force update MTP
25
+ (0, mocha_1.before)(async () => {
26
+ await _regtest_1.regtestUtils.mine(11);
27
+ });
28
+ const hashType = bitcoin.Transaction.SIGHASH_ALL;
29
+ // IF MTP (from when confirmed) > seconds, _alice can redeem
30
+ function csvCheckSigOutput(_alice, _bob, sequence) {
31
+ return bitcoin.script.fromASM(`
32
+ OP_IF
33
+ ${bitcoin.script.number.encode(sequence).toString('hex')}
34
+ OP_CHECKSEQUENCEVERIFY
35
+ OP_DROP
36
+ OP_ELSE
37
+ ${_bob.publicKey.toString('hex')}
38
+ OP_CHECKSIGVERIFY
39
+ OP_ENDIF
40
+ ${_alice.publicKey.toString('hex')}
41
+ OP_CHECKSIG
42
+ `
43
+ .trim()
44
+ .replace(/\s+/g, ' '));
45
+ }
46
+ // 2 of 3 multisig of _bob, _charles, _dave,
47
+ // but after sequence1 time, _alice can allow the multisig to become 1 of 3.
48
+ // but after sequence2 time, _alice can sign for the output all by themself.
49
+ // Ref: https://github.com/bitcoinbook/bitcoinbook/blob/f8b883dcd4e3d1b9adf40fed59b7e898fbd9241f/ch07.asciidoc#complex-script-example
50
+ // Note: bitcoinjs-lib will not offer specific support for problems with
51
+ // advanced script usages such as below. Use at your own risk.
52
+ function complexCsvOutput(_alice, _bob, _charles, _dave, sequence1, sequence2) {
53
+ return bitcoin.script.fromASM(`
54
+ OP_IF
55
+ OP_IF
56
+ OP_2
57
+ OP_ELSE
58
+ ${bitcoin.script.number.encode(sequence1).toString('hex')}
59
+ OP_CHECKSEQUENCEVERIFY
60
+ OP_DROP
61
+ ${_alice.publicKey.toString('hex')}
62
+ OP_CHECKSIGVERIFY
63
+ OP_1
64
+ OP_ENDIF
65
+ ${_bob.publicKey.toString('hex')}
66
+ ${_charles.publicKey.toString('hex')}
67
+ ${_dave.publicKey.toString('hex')}
68
+ OP_3
69
+ OP_CHECKMULTISIG
70
+ OP_ELSE
71
+ ${bitcoin.script.number.encode(sequence2).toString('hex')}
72
+ OP_CHECKSEQUENCEVERIFY
73
+ OP_DROP
74
+ ${_alice.publicKey.toString('hex')}
75
+ OP_CHECKSIG
76
+ OP_ENDIF
77
+ `
78
+ .trim()
79
+ .replace(/\s+/g, ' '));
80
+ }
81
+ // expiry will pass, {Alice's signature} OP_TRUE
82
+ (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction where Alice can redeem ' +
83
+ 'the output after the expiry (in the future) (simple CHECKSEQUENCEVERIFY)', async () => {
84
+ // 5 blocks from now
85
+ const sequence = bip68.encode({ blocks: 5 });
86
+ const p2sh = bitcoin.payments.p2sh({
87
+ redeem: {
88
+ output: csvCheckSigOutput(alice, bob, sequence),
89
+ },
90
+ network: regtest,
91
+ });
92
+ // fund the P2SH(CSV) address
93
+ const unspent = await _regtest_1.regtestUtils.faucet(p2sh.address, 1e5);
94
+ const utx = await _regtest_1.regtestUtils.fetch(unspent.txId);
95
+ // for non segwit inputs, you must pass the full transaction buffer
96
+ const nonWitnessUtxo = Buffer.from(utx.txHex, 'hex');
97
+ // This is an example of using the finalizeInput second parameter to
98
+ // define how you finalize the inputs, allowing for any type of script.
99
+ const tx = new bitcoin.Psbt({ network: regtest })
100
+ .setVersion(2)
101
+ .addInput({
102
+ hash: unspent.txId,
103
+ index: unspent.vout,
104
+ sequence,
105
+ redeemScript: p2sh.redeem.output,
106
+ nonWitnessUtxo,
107
+ })
108
+ .addOutput({
109
+ address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
110
+ value: 7e4,
111
+ })
112
+ .signInput(0, alice)
113
+ .finalizeInput(0, csvGetFinalScripts) // See csvGetFinalScripts below
114
+ .extractTransaction();
115
+ // TODO: test that it failures _prior_ to expiry, unfortunately, race conditions when run concurrently
116
+ // ...
117
+ // into the future!
118
+ await _regtest_1.regtestUtils.mine(10);
119
+ await _regtest_1.regtestUtils.broadcast(tx.toHex());
120
+ await _regtest_1.regtestUtils.verify({
121
+ txId: tx.getId(),
122
+ address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
123
+ vout: 0,
124
+ value: 7e4,
125
+ });
126
+ });
127
+ // expiry in the future, {Alice's signature} OP_TRUE
128
+ (0, mocha_1.it)('can create (but fail to broadcast via 3PBP) a Transaction where Alice ' +
129
+ 'attempts to redeem before the expiry (simple CHECKSEQUENCEVERIFY)', async () => {
130
+ // two hours after confirmation
131
+ const sequence = bip68.encode({ seconds: 7168 });
132
+ const p2sh = bitcoin.payments.p2sh({
133
+ network: regtest,
134
+ redeem: {
135
+ output: csvCheckSigOutput(alice, bob, sequence),
136
+ },
137
+ });
138
+ // fund the P2SH(CSV) address
139
+ const unspent = await _regtest_1.regtestUtils.faucet(p2sh.address, 2e4);
140
+ const tx = new bitcoin.Transaction();
141
+ tx.version = 2;
142
+ tx.addInput(idToHash(unspent.txId), unspent.vout, sequence);
143
+ tx.addOutput(toOutputScript(_regtest_1.regtestUtils.RANDOM_ADDRESS), 1e4);
144
+ // {Alice's signature} OP_TRUE
145
+ const signatureHash = tx.hashForSignature(0, p2sh.redeem.output, hashType);
146
+ const redeemScriptSig = bitcoin.payments.p2sh({
147
+ network: regtest,
148
+ redeem: {
149
+ network: regtest,
150
+ output: p2sh.redeem.output,
151
+ input: bitcoin.script.compile([
152
+ bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
153
+ bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
154
+ bitcoin.opcodes.OP_TRUE,
155
+ ]),
156
+ },
157
+ }).input;
158
+ tx.setInputScript(0, redeemScriptSig);
159
+ await _regtest_1.regtestUtils.broadcast(tx.toHex()).catch(err => {
160
+ assert.throws(() => {
161
+ if (err)
162
+ throw err;
163
+ }, /Error: non-BIP68-final/);
164
+ });
165
+ });
166
+ // Check first combination of complex CSV, 2 of 3
167
+ (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction where Bob and Charles ' +
168
+ 'can send (complex CHECKSEQUENCEVERIFY)', async () => {
169
+ // 2 blocks from now
170
+ const sequence1 = bip68.encode({ blocks: 2 });
171
+ // 5 blocks from now
172
+ const sequence2 = bip68.encode({ blocks: 5 });
173
+ const p2sh = bitcoin.payments.p2sh({
174
+ redeem: {
175
+ output: complexCsvOutput(alice, bob, charles, dave, sequence1, sequence2),
176
+ },
177
+ network: regtest,
178
+ });
179
+ // fund the P2SH(CCSV) address
180
+ const unspent = await _regtest_1.regtestUtils.faucet(p2sh.address, 1e5);
181
+ const tx = new bitcoin.Transaction();
182
+ tx.version = 2;
183
+ tx.addInput(idToHash(unspent.txId), unspent.vout);
184
+ tx.addOutput(toOutputScript(_regtest_1.regtestUtils.RANDOM_ADDRESS), 7e4);
185
+ // OP_0 {Bob sig} {Charles sig} OP_TRUE OP_TRUE
186
+ const signatureHash = tx.hashForSignature(0, p2sh.redeem.output, hashType);
187
+ const redeemScriptSig = bitcoin.payments.p2sh({
188
+ network: regtest,
189
+ redeem: {
190
+ network: regtest,
191
+ output: p2sh.redeem.output,
192
+ input: bitcoin.script.compile([
193
+ bitcoin.opcodes.OP_0,
194
+ bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
195
+ bitcoin.script.signature.encode(charles.sign(signatureHash), hashType),
196
+ bitcoin.opcodes.OP_TRUE,
197
+ bitcoin.opcodes.OP_TRUE,
198
+ ]),
199
+ },
200
+ }).input;
201
+ tx.setInputScript(0, redeemScriptSig);
202
+ await _regtest_1.regtestUtils.broadcast(tx.toHex());
203
+ await _regtest_1.regtestUtils.verify({
204
+ txId: tx.getId(),
205
+ address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
206
+ vout: 0,
207
+ value: 7e4,
208
+ });
209
+ });
210
+ // Check first combination of complex CSV, mediator + 1 of 3 after 2 blocks
211
+ (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction where Alice (mediator) ' +
212
+ 'and Bob can send after 2 blocks (complex CHECKSEQUENCEVERIFY)', async () => {
213
+ // 2 blocks from now
214
+ const sequence1 = bip68.encode({ blocks: 2 });
215
+ // 5 blocks from now
216
+ const sequence2 = bip68.encode({ blocks: 5 });
217
+ const p2sh = bitcoin.payments.p2sh({
218
+ redeem: {
219
+ output: complexCsvOutput(alice, bob, charles, dave, sequence1, sequence2),
220
+ },
221
+ network: regtest,
222
+ });
223
+ // fund the P2SH(CCSV) address
224
+ const unspent = await _regtest_1.regtestUtils.faucet(p2sh.address, 1e5);
225
+ const tx = new bitcoin.Transaction();
226
+ tx.version = 2;
227
+ tx.addInput(idToHash(unspent.txId), unspent.vout, sequence1); // Set sequence1 for input
228
+ tx.addOutput(toOutputScript(_regtest_1.regtestUtils.RANDOM_ADDRESS), 7e4);
229
+ // OP_0 {Bob sig} {Alice mediator sig} OP_FALSE OP_TRUE
230
+ const signatureHash = tx.hashForSignature(0, p2sh.redeem.output, hashType);
231
+ const redeemScriptSig = bitcoin.payments.p2sh({
232
+ network: regtest,
233
+ redeem: {
234
+ network: regtest,
235
+ output: p2sh.redeem.output,
236
+ input: bitcoin.script.compile([
237
+ bitcoin.opcodes.OP_0,
238
+ bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
239
+ bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
240
+ bitcoin.opcodes.OP_0,
241
+ bitcoin.opcodes.OP_TRUE,
242
+ ]),
243
+ },
244
+ }).input;
245
+ tx.setInputScript(0, redeemScriptSig);
246
+ // Wait 2 blocks
247
+ await _regtest_1.regtestUtils.mine(2);
248
+ await _regtest_1.regtestUtils.broadcast(tx.toHex());
249
+ await _regtest_1.regtestUtils.verify({
250
+ txId: tx.getId(),
251
+ address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
252
+ vout: 0,
253
+ value: 7e4,
254
+ });
255
+ });
256
+ // Check first combination of complex CSV, mediator after 5 blocks
257
+ (0, mocha_1.it)('can create (and broadcast via 3PBP) a Transaction where Alice (mediator) ' +
258
+ 'can send after 5 blocks (complex CHECKSEQUENCEVERIFY)', async () => {
259
+ // 2 blocks from now
260
+ const sequence1 = bip68.encode({ blocks: 2 });
261
+ // 5 blocks from now
262
+ const sequence2 = bip68.encode({ blocks: 5 });
263
+ const p2sh = bitcoin.payments.p2sh({
264
+ redeem: {
265
+ output: complexCsvOutput(alice, bob, charles, dave, sequence1, sequence2),
266
+ },
267
+ network: regtest,
268
+ });
269
+ // fund the P2SH(CCSV) address
270
+ const unspent = await _regtest_1.regtestUtils.faucet(p2sh.address, 1e5);
271
+ const tx = new bitcoin.Transaction();
272
+ tx.version = 2;
273
+ tx.addInput(idToHash(unspent.txId), unspent.vout, sequence2); // Set sequence2 for input
274
+ tx.addOutput(toOutputScript(_regtest_1.regtestUtils.RANDOM_ADDRESS), 7e4);
275
+ // {Alice mediator sig} OP_FALSE
276
+ const signatureHash = tx.hashForSignature(0, p2sh.redeem.output, hashType);
277
+ const redeemScriptSig = bitcoin.payments.p2sh({
278
+ network: regtest,
279
+ redeem: {
280
+ network: regtest,
281
+ output: p2sh.redeem.output,
282
+ input: bitcoin.script.compile([
283
+ bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
284
+ bitcoin.opcodes.OP_0,
285
+ ]),
286
+ },
287
+ }).input;
288
+ tx.setInputScript(0, redeemScriptSig);
289
+ // Wait 5 blocks
290
+ await _regtest_1.regtestUtils.mine(5);
291
+ await _regtest_1.regtestUtils.broadcast(tx.toHex());
292
+ await _regtest_1.regtestUtils.verify({
293
+ txId: tx.getId(),
294
+ address: _regtest_1.regtestUtils.RANDOM_ADDRESS,
295
+ vout: 0,
296
+ value: 7e4,
297
+ });
298
+ });
299
+ });
300
+ // This function is used to finalize a CSV transaction using PSBT.
301
+ // See first test above.
302
+ function csvGetFinalScripts(inputIndex, input, script, isSegwit, isP2SH, isP2WSH) {
303
+ // Step 1: Check to make sure the meaningful script matches what you expect.
304
+ const decompiled = bitcoin.script.decompile(script);
305
+ // Checking if first OP is OP_IF... should do better check in production!
306
+ // You may even want to check the public keys in the script against a
307
+ // whitelist depending on the circumstances!!!
308
+ // You also want to check the contents of the input to see if you have enough
309
+ // info to actually construct the scriptSig and Witnesses.
310
+ if (!decompiled || decompiled[0] !== bitcoin.opcodes.OP_IF) {
311
+ throw new Error(`Can not finalize input #${inputIndex}`);
312
+ }
313
+ // Step 2: Create final scripts
314
+ let payment = {
315
+ network: regtest,
316
+ output: script,
317
+ // This logic should be more strict and make sure the pubkeys in the
318
+ // meaningful script are the ones signing in the PSBT etc.
319
+ input: bitcoin.script.compile([
320
+ input.partialSig[0].signature,
321
+ bitcoin.opcodes.OP_TRUE,
322
+ ]),
323
+ };
324
+ if (isP2WSH && isSegwit)
325
+ payment = bitcoin.payments.p2wsh({
326
+ network: regtest,
327
+ redeem: payment,
328
+ });
329
+ if (isP2SH)
330
+ payment = bitcoin.payments.p2sh({
331
+ network: regtest,
332
+ redeem: payment,
333
+ });
334
+ function witnessStackToScriptWitness(witness) {
335
+ let buffer = Buffer.allocUnsafe(0);
336
+ function writeSlice(slice) {
337
+ buffer = Buffer.concat([buffer, Buffer.from(slice)]);
338
+ }
339
+ function writeVarInt(i) {
340
+ const currentLen = buffer.length;
341
+ const varintLen = varuint.encodingLength(i);
342
+ buffer = Buffer.concat([buffer, Buffer.allocUnsafe(varintLen)]);
343
+ varuint.encode(i, buffer, currentLen);
344
+ }
345
+ function writeVarSlice(slice) {
346
+ writeVarInt(slice.length);
347
+ writeSlice(slice);
348
+ }
349
+ function writeVector(vector) {
350
+ writeVarInt(vector.length);
351
+ vector.forEach(writeVarSlice);
352
+ }
353
+ writeVector(witness);
354
+ return buffer;
355
+ }
356
+ return {
357
+ finalScriptSig: payment.input,
358
+ finalScriptWitness: payment.witness && payment.witness.length > 0
359
+ ? witnessStackToScriptWitness(payment.witness)
360
+ : undefined,
361
+ };
362
+ }