@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
package/src/types.ts ADDED
@@ -0,0 +1,122 @@
1
+ import { Buffer as NBuffer } from 'buffer';
2
+
3
+ // @ts-ignore
4
+ import * as _typeforce from 'typeforce';
5
+
6
+ export const typeforce = _typeforce.default;
7
+
8
+ const ZERO32 = NBuffer.alloc(32, 0);
9
+ const EC_P = NBuffer.from(
10
+ 'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f',
11
+ 'hex',
12
+ );
13
+
14
+ /**
15
+ * Checks if two arrays of Buffers are equal.
16
+ * @param a - The first array of Buffers.
17
+ * @param b - The second array of Buffers.
18
+ * @returns True if the arrays are equal, false otherwise.
19
+ */
20
+ export function stacksEqual(a: Buffer[], b: Buffer[]): boolean {
21
+ if (a.length !== b.length) return false;
22
+
23
+ return a.every((x, i) => {
24
+ return x.equals(b[i]);
25
+ });
26
+ }
27
+
28
+ /**
29
+ * Checks if the given value is a valid elliptic curve point.
30
+ * @param p - The value to check.
31
+ * @returns True if the value is a valid elliptic curve point, false otherwise.
32
+ */
33
+ export function isPoint(p: Buffer | number | undefined | null): boolean {
34
+ if (!NBuffer.isBuffer(p)) return false;
35
+ if (p.length < 33) return false;
36
+
37
+ const t = p[0]; // First byte = point format indicator
38
+ const x = p.slice(1, 33); // Next 32 bytes = X coordinate
39
+
40
+ // Validate X coordinate
41
+ if (x.compare(ZERO32) === 0) return false; // X cannot be zero
42
+ if (x.compare(EC_P) >= 0) return false; // X must be < P
43
+
44
+ // Check for compressed format (0x02 or 0x03), must be exactly 33 bytes total
45
+ if ((t === 0x02 || t === 0x03) && p.length === 33) {
46
+ return true;
47
+ }
48
+
49
+ // For uncompressed (0x04) or hybrid (0x06 or 0x07) formats, must be 65 bytes total
50
+ if (p.length !== 65) return false;
51
+
52
+ const y = p.slice(33); // Last 32 bytes = Y coordinate
53
+
54
+ // Validate Y coordinate
55
+ if (y.compare(ZERO32) === 0) return false; // Y cannot be zero
56
+ if (y.compare(EC_P) >= 0) return false; // Y must be < P
57
+
58
+ // 0x04 = uncompressed, 0x06/0x07 = hybrid (also 65 bytes, but with Y's parity bit set)
59
+ return t === 0x04 || t === 0x06 || t === 0x07;
60
+ }
61
+
62
+ const SATOSHI_MAX: number = 21 * 1e14;
63
+
64
+ export function Satoshi(value: number): boolean {
65
+ return typeforce.UInt53(value) && value <= SATOSHI_MAX;
66
+ }
67
+
68
+ export interface XOnlyPointAddTweakResult {
69
+ parity: 1 | 0;
70
+ xOnlyPubkey: Uint8Array;
71
+ }
72
+
73
+ export interface Tapleaf {
74
+ output: Buffer;
75
+ version?: number;
76
+ }
77
+
78
+ export const TAPLEAF_VERSION_MASK = 0xfe;
79
+
80
+ export function isTapleaf(o: any): o is Tapleaf {
81
+ if (!o || !('output' in o)) return false;
82
+ if (!NBuffer.isBuffer(o.output)) return false;
83
+ if (o.version !== undefined) return (o.version & TAPLEAF_VERSION_MASK) === o.version;
84
+ return true;
85
+ }
86
+
87
+ /**
88
+ * Binary tree repsenting script path spends for a Taproot input.
89
+ * Each node is either a single Tapleaf, or a pair of Tapleaf | Taptree.
90
+ * The tree has no balancing requirements.
91
+ */
92
+ export type Taptree = [Taptree | Tapleaf, Taptree | Tapleaf] | Tapleaf;
93
+
94
+ export function isTaptree(scriptTree: any): scriptTree is Taptree {
95
+ if (!Array(scriptTree)) return isTapleaf(scriptTree);
96
+ if (scriptTree.length !== 2) return false;
97
+ return scriptTree.every((t: any) => isTaptree(t));
98
+ }
99
+
100
+ export interface TinySecp256k1Interface {
101
+ isXOnlyPoint(p: Uint8Array): boolean;
102
+
103
+ xOnlyPointAddTweak(p: Uint8Array, tweak: Uint8Array): XOnlyPointAddTweakResult | null;
104
+ }
105
+
106
+ export const Buffer256bit = typeforce.BufferN(32);
107
+ export const Hash160bit = typeforce.BufferN(20);
108
+ export const Hash256bit = typeforce.BufferN(32);
109
+ export const Number = typeforce.Number;
110
+ export const Array = typeforce.Array;
111
+ export const Boolean = typeforce.Boolean;
112
+ export const String = typeforce.String;
113
+ export const Buffer = typeforce.Buffer;
114
+ export const Hex = typeforce.Hex;
115
+ export const maybe = typeforce.maybe;
116
+ export const tuple = typeforce.tuple;
117
+ export const UInt8 = typeforce.UInt8;
118
+ export const UInt32 = typeforce.UInt32;
119
+ export const Function = typeforce.Function;
120
+ export const BufferN = typeforce.BufferN;
121
+ export const Null = typeforce.Null;
122
+ export const oneOf = typeforce.oneOf;
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const assert = require("assert");
4
+ const mocha_1 = require("mocha");
5
+ const ecc = require("tiny-secp256k1");
6
+ const baddress = require("../src/address");
7
+ const bscript = require("../src/script");
8
+ const fixtures = require("./fixtures/address.json");
9
+ const src_1 = require("../src");
10
+ const NETWORKS = Object.assign({
11
+ litecoin: {
12
+ messagePrefix: '\x19Litecoin Signed Message:\n',
13
+ bip32: {
14
+ public: 0x019da462,
15
+ private: 0x019d9cfe,
16
+ },
17
+ pubKeyHash: 0x30,
18
+ scriptHash: 0x32,
19
+ wif: 0xb0,
20
+ },
21
+ }, require('../src/networks'));
22
+ (0, mocha_1.describe)('address', () => {
23
+ (0, mocha_1.describe)('fromBase58Check', () => {
24
+ fixtures.standard.forEach(f => {
25
+ if (!f.base58check)
26
+ return;
27
+ (0, mocha_1.it)('decodes ' + f.base58check, () => {
28
+ const decode = baddress.fromBase58Check(f.base58check);
29
+ assert.strictEqual(decode.version, f.version);
30
+ assert.strictEqual(decode.hash.toString('hex'), f.hash);
31
+ });
32
+ });
33
+ fixtures.invalid.fromBase58Check.forEach(f => {
34
+ (0, mocha_1.it)('throws on ' + f.exception, () => {
35
+ assert.throws(() => {
36
+ baddress.fromBase58Check(f.address);
37
+ }, new RegExp(f.address + ' ' + f.exception));
38
+ });
39
+ });
40
+ });
41
+ (0, mocha_1.describe)('fromBech32', () => {
42
+ fixtures.standard.forEach(f => {
43
+ if (!f.bech32)
44
+ return;
45
+ (0, mocha_1.it)('decodes ' + f.bech32, () => {
46
+ const actual = baddress.fromBech32(f.bech32);
47
+ assert.strictEqual(actual.version, f.version);
48
+ assert.strictEqual(actual.prefix, NETWORKS[f.network].bech32);
49
+ assert.strictEqual(actual.data.toString('hex'), f.data);
50
+ });
51
+ });
52
+ fixtures.invalid.bech32.forEach(f => {
53
+ (0, mocha_1.it)('decode fails for ' + f.address + '(' + f.exception + ')', () => {
54
+ assert.throws(() => {
55
+ baddress.fromBech32(f.address);
56
+ }, new RegExp(f.exception));
57
+ });
58
+ });
59
+ });
60
+ (0, mocha_1.describe)('fromOutputScript', () => {
61
+ (0, src_1.initEccLib)(ecc);
62
+ fixtures.standard.forEach(f => {
63
+ (0, mocha_1.it)('encodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', () => {
64
+ const script = bscript.fromASM(f.script);
65
+ const address = baddress.fromOutputScript(script, NETWORKS[f.network]);
66
+ assert.strictEqual(address, f.base58check || f.bech32.toLowerCase());
67
+ });
68
+ });
69
+ fixtures.invalid.fromOutputScript.forEach(f => {
70
+ (0, mocha_1.it)('throws when ' + f.script.slice(0, 30) + '... ' + f.exception, () => {
71
+ const script = bscript.fromASM(f.script);
72
+ assert.throws(() => {
73
+ baddress.fromOutputScript(script, undefined);
74
+ }, new RegExp(f.exception));
75
+ });
76
+ });
77
+ });
78
+ (0, mocha_1.describe)('toBase58Check', () => {
79
+ fixtures.standard.forEach(f => {
80
+ if (!f.base58check)
81
+ return;
82
+ (0, mocha_1.it)('encodes ' + f.hash + ' (' + f.network + ')', () => {
83
+ const address = baddress.toBase58Check(Buffer.from(f.hash, 'hex'), f.version);
84
+ assert.strictEqual(address, f.base58check);
85
+ });
86
+ });
87
+ });
88
+ (0, mocha_1.describe)('toBech32', () => {
89
+ fixtures.bech32.forEach(f => {
90
+ if (!f.address)
91
+ return;
92
+ const data = Buffer.from(f.data, 'hex');
93
+ (0, mocha_1.it)('encode ' + f.address, () => {
94
+ assert.deepStrictEqual(baddress.toBech32(data, f.version, f.prefix), f.address.toLowerCase());
95
+ });
96
+ });
97
+ // TODO: These fixtures (according to TypeScript) have none of the data used below
98
+ fixtures.invalid.bech32.forEach((f) => {
99
+ if (!f.prefix || f.version === undefined || f.data === undefined)
100
+ return;
101
+ (0, mocha_1.it)('encode fails (' + f.exception, () => {
102
+ assert.throws(() => {
103
+ baddress.toBech32(Buffer.from(f.data, 'hex'), f.version, f.prefix);
104
+ }, new RegExp(f.exception));
105
+ });
106
+ });
107
+ });
108
+ (0, mocha_1.describe)('toOutputScript', () => {
109
+ fixtures.standard.forEach(f => {
110
+ (0, mocha_1.it)('decodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', () => {
111
+ const script = baddress.toOutputScript((f.base58check || f.bech32), NETWORKS[f.network]);
112
+ assert.strictEqual(bscript.toASM(script), f.script);
113
+ });
114
+ });
115
+ fixtures.invalid.toOutputScript.forEach(f => {
116
+ (0, mocha_1.it)('throws when ' + (f.exception || f.paymentException), () => {
117
+ const exception = f.paymentException || `${f.address} ${f.exception}`;
118
+ assert.throws(() => {
119
+ baddress.toOutputScript(f.address, f.network);
120
+ }, new RegExp(exception));
121
+ });
122
+ });
123
+ });
124
+ });
@@ -0,0 +1,177 @@
1
+ import * as assert from 'assert';
2
+ import { describe, it } from 'mocha';
3
+ import * as ecc from 'tiny-secp256k1';
4
+ import * as baddress from '../src/address';
5
+ import * as bscript from '../src/script';
6
+ import * as fixtures from './fixtures/address.json';
7
+
8
+ import { initEccLib } from '../src';
9
+
10
+ const NETWORKS = Object.assign(
11
+ {
12
+ litecoin: {
13
+ messagePrefix: '\x19Litecoin Signed Message:\n',
14
+ bip32: {
15
+ public: 0x019da462,
16
+ private: 0x019d9cfe,
17
+ },
18
+ pubKeyHash: 0x30,
19
+ scriptHash: 0x32,
20
+ wif: 0xb0,
21
+ },
22
+ },
23
+ require('../src/networks'),
24
+ );
25
+
26
+ describe('address', () => {
27
+ describe('fromBase58Check', () => {
28
+ fixtures.standard.forEach(f => {
29
+ if (!f.base58check) return;
30
+
31
+ it('decodes ' + f.base58check, () => {
32
+ const decode = baddress.fromBase58Check(f.base58check);
33
+
34
+ assert.strictEqual(decode.version, f.version);
35
+ assert.strictEqual(decode.hash.toString('hex'), f.hash);
36
+ });
37
+ });
38
+
39
+ fixtures.invalid.fromBase58Check.forEach(f => {
40
+ it('throws on ' + f.exception, () => {
41
+ assert.throws(() => {
42
+ baddress.fromBase58Check(f.address);
43
+ }, new RegExp(f.address + ' ' + f.exception));
44
+ });
45
+ });
46
+ });
47
+
48
+ describe('fromBech32', () => {
49
+ fixtures.standard.forEach(f => {
50
+ if (!f.bech32) return;
51
+
52
+ it('decodes ' + f.bech32, () => {
53
+ const actual = baddress.fromBech32(f.bech32);
54
+
55
+ assert.strictEqual(actual.version, f.version);
56
+ assert.strictEqual(actual.prefix, NETWORKS[f.network].bech32);
57
+ assert.strictEqual(actual.data.toString('hex'), f.data);
58
+ });
59
+ });
60
+
61
+ fixtures.invalid.bech32.forEach(f => {
62
+ it(
63
+ 'decode fails for ' + f.address + '(' + f.exception + ')',
64
+ () => {
65
+ assert.throws(() => {
66
+ baddress.fromBech32(f.address);
67
+ }, new RegExp(f.exception));
68
+ },
69
+ );
70
+ });
71
+ });
72
+
73
+ describe('fromOutputScript', () => {
74
+ initEccLib(ecc);
75
+ fixtures.standard.forEach(f => {
76
+ it(
77
+ 'encodes ' + f.script.slice(0, 30) + '... (' + f.network + ')',
78
+ () => {
79
+ const script = bscript.fromASM(f.script);
80
+ const address = baddress.fromOutputScript(
81
+ script,
82
+ NETWORKS[f.network],
83
+ );
84
+
85
+ assert.strictEqual(
86
+ address,
87
+ f.base58check || f.bech32!.toLowerCase(),
88
+ );
89
+ },
90
+ );
91
+ });
92
+
93
+ fixtures.invalid.fromOutputScript.forEach(f => {
94
+ it(
95
+ 'throws when ' + f.script.slice(0, 30) + '... ' + f.exception,
96
+ () => {
97
+ const script = bscript.fromASM(f.script);
98
+
99
+ assert.throws(() => {
100
+ baddress.fromOutputScript(script, undefined);
101
+ }, new RegExp(f.exception));
102
+ },
103
+ );
104
+ });
105
+ });
106
+
107
+ describe('toBase58Check', () => {
108
+ fixtures.standard.forEach(f => {
109
+ if (!f.base58check) return;
110
+
111
+ it('encodes ' + f.hash + ' (' + f.network + ')', () => {
112
+ const address = baddress.toBase58Check(
113
+ Buffer.from(f.hash, 'hex'),
114
+ f.version,
115
+ );
116
+
117
+ assert.strictEqual(address, f.base58check);
118
+ });
119
+ });
120
+ });
121
+
122
+ describe('toBech32', () => {
123
+ fixtures.bech32.forEach(f => {
124
+ if (!f.address) return;
125
+ const data = Buffer.from(f.data, 'hex');
126
+
127
+ it('encode ' + f.address, () => {
128
+ assert.deepStrictEqual(
129
+ baddress.toBech32(data, f.version, f.prefix),
130
+ f.address.toLowerCase(),
131
+ );
132
+ });
133
+ });
134
+
135
+ // TODO: These fixtures (according to TypeScript) have none of the data used below
136
+ fixtures.invalid.bech32.forEach((f: any) => {
137
+ if (!f.prefix || f.version === undefined || f.data === undefined)
138
+ return;
139
+
140
+ it('encode fails (' + f.exception, () => {
141
+ assert.throws(() => {
142
+ baddress.toBech32(
143
+ Buffer.from(f.data, 'hex'),
144
+ f.version,
145
+ f.prefix,
146
+ );
147
+ }, new RegExp(f.exception));
148
+ });
149
+ });
150
+ });
151
+
152
+ describe('toOutputScript', () => {
153
+ fixtures.standard.forEach(f => {
154
+ it(
155
+ 'decodes ' + f.script.slice(0, 30) + '... (' + f.network + ')',
156
+ () => {
157
+ const script = baddress.toOutputScript(
158
+ (f.base58check || f.bech32)!,
159
+ NETWORKS[f.network],
160
+ );
161
+
162
+ assert.strictEqual(bscript.toASM(script), f.script);
163
+ },
164
+ );
165
+ });
166
+
167
+ fixtures.invalid.toOutputScript.forEach(f => {
168
+ it('throws when ' + (f.exception || f.paymentException), () => {
169
+ const exception =
170
+ f.paymentException || `${f.address} ${f.exception}`;
171
+ assert.throws(() => {
172
+ baddress.toOutputScript(f.address, f.network as any);
173
+ }, new RegExp(exception));
174
+ });
175
+ });
176
+ });
177
+ });
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const assert = require("assert");
4
+ const base58 = require("bs58");
5
+ const mocha_1 = require("mocha");
6
+ const bitcoin = require("..");
7
+ const base58EncodeDecode = require("./fixtures/core/base58_encode_decode.json");
8
+ const base58KeysInvalid = require("./fixtures/core/base58_keys_invalid.json");
9
+ const base58KeysValid = require("./fixtures/core/base58_keys_valid.json");
10
+ const blocksValid = require("./fixtures/core/blocks.json");
11
+ const sigCanonical = require("./fixtures/core/sig_canonical.json");
12
+ const sigNoncanonical = require("./fixtures/core/sig_noncanonical.json");
13
+ const sigHash = require("./fixtures/core/sighash.json");
14
+ const txValid = require("./fixtures/core/tx_valid.json");
15
+ (0, mocha_1.describe)('Bitcoin-core', () => {
16
+ // base58EncodeDecode
17
+ (0, mocha_1.describe)('base58', () => {
18
+ base58EncodeDecode.forEach(f => {
19
+ const fhex = f[0];
20
+ const fb58 = f[1];
21
+ (0, mocha_1.it)('can decode ' + fb58, () => {
22
+ const buffer = base58.decode(fb58);
23
+ const actual = buffer.toString('hex');
24
+ assert.strictEqual(actual, fhex);
25
+ });
26
+ (0, mocha_1.it)('can encode ' + fhex, () => {
27
+ const buffer = Buffer.from(fhex, 'hex');
28
+ const actual = base58.encode(buffer);
29
+ assert.strictEqual(actual, fb58);
30
+ });
31
+ });
32
+ });
33
+ // base58KeysValid
34
+ (0, mocha_1.describe)('address.toBase58Check', () => {
35
+ const typeMap = {
36
+ pubkey: 'pubKeyHash',
37
+ script: 'scriptHash',
38
+ };
39
+ base58KeysValid.forEach(f => {
40
+ const expected = f[0];
41
+ const hash = Buffer.from(f[1], 'hex');
42
+ const params = f[2];
43
+ if (params.isPrivkey)
44
+ return;
45
+ const network = params.isTestnet
46
+ ? bitcoin.networks.testnet
47
+ : bitcoin.networks.bitcoin;
48
+ const version = network[typeMap[params.addrType]];
49
+ (0, mocha_1.it)('can export ' + expected, () => {
50
+ assert.strictEqual(bitcoin.address.toBase58Check(hash, version), expected);
51
+ });
52
+ });
53
+ });
54
+ // base58KeysInvalid
55
+ (0, mocha_1.describe)('address.fromBase58Check', () => {
56
+ const allowedNetworks = [
57
+ bitcoin.networks.bitcoin.pubKeyHash,
58
+ bitcoin.networks.bitcoin.scriptHash,
59
+ bitcoin.networks.testnet.pubKeyHash,
60
+ bitcoin.networks.testnet.scriptHash,
61
+ ];
62
+ base58KeysInvalid.forEach(f => {
63
+ const strng = f[0];
64
+ (0, mocha_1.it)('throws on ' + strng, () => {
65
+ assert.throws(() => {
66
+ const address = bitcoin.address.fromBase58Check(strng);
67
+ assert.notStrictEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network');
68
+ }, /(Invalid (checksum|network))|(too (short|long))/);
69
+ });
70
+ });
71
+ });
72
+ (0, mocha_1.describe)('Block.fromHex', () => {
73
+ blocksValid.forEach(f => {
74
+ (0, mocha_1.it)('can parse ' + f.id, () => {
75
+ const block = bitcoin.Block.fromHex(f.hex);
76
+ assert.strictEqual(block.getId(), f.id);
77
+ assert.strictEqual(block.transactions.length, f.transactions);
78
+ });
79
+ });
80
+ });
81
+ // txValid
82
+ (0, mocha_1.describe)('Transaction.fromHex', () => {
83
+ txValid.forEach(f => {
84
+ // Objects that are only a single string are ignored
85
+ if (f.length === 1)
86
+ return;
87
+ const inputs = f[0];
88
+ const fhex = f[1];
89
+ // const verifyFlags = f[2] // TODO: do we need to test this?
90
+ (0, mocha_1.it)('can decode ' + fhex, () => {
91
+ const transaction = bitcoin.Transaction.fromHex(fhex);
92
+ transaction.ins.forEach((txIn, i) => {
93
+ const input = inputs[i];
94
+ // reverse because test data is reversed
95
+ const prevOutHash = Buffer.from(input[0], 'hex').reverse();
96
+ const prevOutIndex = input[1];
97
+ assert.deepStrictEqual(txIn.hash, prevOutHash);
98
+ // we read UInt32, not Int32
99
+ assert.strictEqual(txIn.index & 0xffffffff, prevOutIndex);
100
+ });
101
+ });
102
+ });
103
+ });
104
+ // sighash
105
+ (0, mocha_1.describe)('Transaction', () => {
106
+ sigHash.forEach(f => {
107
+ // Objects that are only a single string are ignored
108
+ if (f.length === 1)
109
+ return;
110
+ const txHex = f[0];
111
+ const scriptHex = f[1];
112
+ const inIndex = f[2];
113
+ const hashType = f[3];
114
+ const expectedHash = f[4];
115
+ const hashTypes = [];
116
+ if ((hashType & 0x1f) === bitcoin.Transaction.SIGHASH_NONE)
117
+ hashTypes.push('SIGHASH_NONE');
118
+ else if ((hashType & 0x1f) === bitcoin.Transaction.SIGHASH_SINGLE)
119
+ hashTypes.push('SIGHASH_SINGLE');
120
+ else
121
+ hashTypes.push('SIGHASH_ALL');
122
+ if (hashType & bitcoin.Transaction.SIGHASH_ANYONECANPAY)
123
+ hashTypes.push('SIGHASH_ANYONECANPAY');
124
+ const hashTypeName = hashTypes.join(' | ');
125
+ (0, mocha_1.it)('should hash ' +
126
+ txHex.slice(0, 40) +
127
+ '... (' +
128
+ hashTypeName +
129
+ ')', () => {
130
+ const transaction = bitcoin.Transaction.fromHex(txHex);
131
+ assert.strictEqual(transaction.toHex(), txHex);
132
+ const script = Buffer.from(scriptHex, 'hex');
133
+ const scriptChunks = bitcoin.script.decompile(script);
134
+ assert.strictEqual(bitcoin.script.compile(scriptChunks).toString('hex'), scriptHex);
135
+ const hash = transaction.hashForSignature(inIndex, script, hashType);
136
+ // reverse because test data is reversed
137
+ assert.strictEqual(hash.reverse().toString('hex'), expectedHash);
138
+ assert.doesNotThrow(() => transaction.hashForWitnessV0(inIndex, script, 0,
139
+ // convert to UInt32
140
+ hashType < 0 ? 0x100000000 + hashType : hashType));
141
+ });
142
+ });
143
+ });
144
+ (0, mocha_1.describe)('script.signature.decode', () => {
145
+ sigCanonical.forEach(hex => {
146
+ const buffer = Buffer.from(hex, 'hex');
147
+ (0, mocha_1.it)('can parse ' + hex, () => {
148
+ const parsed = bitcoin.script.signature.decode(buffer);
149
+ const actual = bitcoin.script.signature.encode(parsed.signature, parsed.hashType);
150
+ assert.strictEqual(actual.toString('hex'), hex);
151
+ });
152
+ });
153
+ sigNoncanonical.forEach((hex, i) => {
154
+ if (i === 0)
155
+ return;
156
+ if (i % 2 !== 0)
157
+ return;
158
+ const description = sigNoncanonical[i - 1].slice(0, -1);
159
+ const buffer = Buffer.from(hex, 'hex');
160
+ (0, mocha_1.it)('throws on ' + description, () => {
161
+ const reg = new RegExp('Expected DER (integer|sequence)|(R|S) value (excessively ' +
162
+ 'padded|is negative)|(R|S|DER sequence) length is (zero|too ' +
163
+ 'short|too long|invalid)|Invalid hashType');
164
+ assert.throws(() => {
165
+ bitcoin.script.signature.decode(buffer);
166
+ }, reg);
167
+ });
168
+ });
169
+ });
170
+ });