@btc-vision/bitcoin 6.3.0

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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +201 -0
  3. package/package.json +95 -0
  4. package/src/address.d.ts +42 -0
  5. package/src/address.js +191 -0
  6. package/src/bip66.d.ts +7 -0
  7. package/src/bip66.js +103 -0
  8. package/src/block.d.ts +30 -0
  9. package/src/block.js +224 -0
  10. package/src/bufferutils.d.ts +54 -0
  11. package/src/bufferutils.js +182 -0
  12. package/src/crypto.d.ts +18 -0
  13. package/src/crypto.js +128 -0
  14. package/src/ecc_lib.d.ts +17 -0
  15. package/src/ecc_lib.js +122 -0
  16. package/src/hooks/AdvancedSignatureManager.d.ts +44 -0
  17. package/src/hooks/AdvancedSignatureManager.js +88 -0
  18. package/src/hooks/HookedSigner.d.ts +4 -0
  19. package/src/hooks/HookedSigner.js +90 -0
  20. package/src/hooks/SignatureManager.d.ts +35 -0
  21. package/src/hooks/SignatureManager.js +72 -0
  22. package/src/index.d.ts +42 -0
  23. package/src/index.js +87 -0
  24. package/src/merkle.d.ts +10 -0
  25. package/src/merkle.js +30 -0
  26. package/src/networks.d.ts +29 -0
  27. package/src/networks.js +71 -0
  28. package/src/ops.d.ts +126 -0
  29. package/src/ops.js +131 -0
  30. package/src/payments/bip341.d.ts +49 -0
  31. package/src/payments/bip341.js +124 -0
  32. package/src/payments/embed.d.ts +9 -0
  33. package/src/payments/embed.js +54 -0
  34. package/src/payments/index.d.ts +48 -0
  35. package/src/payments/index.js +69 -0
  36. package/src/payments/lazy.d.ts +2 -0
  37. package/src/payments/lazy.js +32 -0
  38. package/src/payments/p2ms.d.ts +9 -0
  39. package/src/payments/p2ms.js +158 -0
  40. package/src/payments/p2pk.d.ts +10 -0
  41. package/src/payments/p2pk.js +82 -0
  42. package/src/payments/p2pkh.d.ts +10 -0
  43. package/src/payments/p2pkh.js +143 -0
  44. package/src/payments/p2sh.d.ts +10 -0
  45. package/src/payments/p2sh.js +204 -0
  46. package/src/payments/p2tr.d.ts +10 -0
  47. package/src/payments/p2tr.js +315 -0
  48. package/src/payments/p2wpkh.d.ts +10 -0
  49. package/src/payments/p2wpkh.js +146 -0
  50. package/src/payments/p2wsh.d.ts +10 -0
  51. package/src/payments/p2wsh.js +226 -0
  52. package/src/psbt/bip371.d.ts +42 -0
  53. package/src/psbt/bip371.js +424 -0
  54. package/src/psbt/psbtutils.d.ts +64 -0
  55. package/src/psbt/psbtutils.js +191 -0
  56. package/src/psbt.d.ts +235 -0
  57. package/src/psbt.js +1825 -0
  58. package/src/push_data.d.ts +29 -0
  59. package/src/push_data.js +83 -0
  60. package/src/script.d.ts +42 -0
  61. package/src/script.js +231 -0
  62. package/src/script_number.d.ts +19 -0
  63. package/src/script_number.js +78 -0
  64. package/src/script_signature.d.ts +21 -0
  65. package/src/script_signature.js +79 -0
  66. package/src/transaction.d.ts +60 -0
  67. package/src/transaction.js +571 -0
  68. package/src/types.d.ts +54 -0
  69. package/src/types.js +106 -0
package/src/bip66.js ADDED
@@ -0,0 +1,103 @@
1
+ 'use strict';
2
+ // Reference https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki
3
+ // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
4
+ // NOTE: SIGHASH byte ignored AND restricted, truncate before use
5
+ Object.defineProperty(exports, '__esModule', { value: true });
6
+ exports.encode = exports.decode = exports.check = void 0;
7
+ function check(buffer) {
8
+ if (buffer.length < 8) return false;
9
+ if (buffer.length > 72) return false;
10
+ if (buffer[0] !== 0x30) return false;
11
+ if (buffer[1] !== buffer.length - 2) return false;
12
+ if (buffer[2] !== 0x02) return false;
13
+ const lenR = buffer[3];
14
+ if (lenR === 0) return false;
15
+ if (5 + lenR >= buffer.length) return false;
16
+ if (buffer[4 + lenR] !== 0x02) return false;
17
+ const lenS = buffer[5 + lenR];
18
+ if (lenS === 0) return false;
19
+ if (6 + lenR + lenS !== buffer.length) return false;
20
+ if (buffer[4] & 0x80) return false;
21
+ if (lenR > 1 && buffer[4] === 0x00 && !(buffer[5] & 0x80)) return false;
22
+ if (buffer[lenR + 6] & 0x80) return false;
23
+ if (lenS > 1 && buffer[lenR + 6] === 0x00 && !(buffer[lenR + 7] & 0x80))
24
+ return false;
25
+ return true;
26
+ }
27
+ exports.check = check;
28
+ function decode(buffer) {
29
+ if (buffer.length < 8) throw new Error('DER sequence length is too short');
30
+ if (buffer.length > 72) throw new Error('DER sequence length is too long');
31
+ if (buffer[0] !== 0x30) throw new Error('Expected DER sequence');
32
+ if (buffer[1] !== buffer.length - 2)
33
+ throw new Error('DER sequence length is invalid');
34
+ if (buffer[2] !== 0x02) throw new Error('Expected DER integer');
35
+ const lenR = buffer[3];
36
+ if (lenR === 0) throw new Error('R length is zero');
37
+ if (5 + lenR >= buffer.length) throw new Error('R length is too long');
38
+ if (buffer[4 + lenR] !== 0x02) throw new Error('Expected DER integer (2)');
39
+ const lenS = buffer[5 + lenR];
40
+ if (lenS === 0) throw new Error('S length is zero');
41
+ if (6 + lenR + lenS !== buffer.length)
42
+ throw new Error('S length is invalid');
43
+ if (buffer[4] & 0x80) throw new Error('R value is negative');
44
+ if (lenR > 1 && buffer[4] === 0x00 && !(buffer[5] & 0x80))
45
+ throw new Error('R value excessively padded');
46
+ if (buffer[lenR + 6] & 0x80) throw new Error('S value is negative');
47
+ if (lenS > 1 && buffer[lenR + 6] === 0x00 && !(buffer[lenR + 7] & 0x80))
48
+ throw new Error('S value excessively padded');
49
+ // non-BIP66 - extract R, S values
50
+ return {
51
+ r: buffer.slice(4, 4 + lenR),
52
+ s: buffer.slice(6 + lenR),
53
+ };
54
+ }
55
+ exports.decode = decode;
56
+ /*
57
+ * Expects r and s to be positive DER integers.
58
+ *
59
+ * The DER format uses the most significant bit as a sign bit (& 0x80).
60
+ * If the significant bit is set AND the integer is positive, a 0x00 is prepended.
61
+ *
62
+ * Examples:
63
+ *
64
+ * 0 => 0x00
65
+ * 1 => 0x01
66
+ * -1 => 0xff
67
+ * 127 => 0x7f
68
+ * -127 => 0x81
69
+ * 128 => 0x0080
70
+ * -128 => 0x80
71
+ * 255 => 0x00ff
72
+ * -255 => 0xff01
73
+ * 16300 => 0x3fac
74
+ * -16300 => 0xc054
75
+ * 62300 => 0x00f35c
76
+ * -62300 => 0xff0ca4
77
+ */
78
+ function encode(r, s) {
79
+ const lenR = r.length;
80
+ const lenS = s.length;
81
+ if (lenR === 0) throw new Error('R length is zero');
82
+ if (lenS === 0) throw new Error('S length is zero');
83
+ if (lenR > 33) throw new Error('R length is too long');
84
+ if (lenS > 33) throw new Error('S length is too long');
85
+ if (r[0] & 0x80) throw new Error('R value is negative');
86
+ if (s[0] & 0x80) throw new Error('S value is negative');
87
+ if (lenR > 1 && r[0] === 0x00 && !(r[1] & 0x80))
88
+ throw new Error('R value excessively padded');
89
+ if (lenS > 1 && s[0] === 0x00 && !(s[1] & 0x80))
90
+ throw new Error('S value excessively padded');
91
+ const signature = Buffer.allocUnsafe(6 + lenR + lenS);
92
+ // 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
93
+ signature[0] = 0x30;
94
+ signature[1] = signature.length - 2;
95
+ signature[2] = 0x02;
96
+ signature[3] = r.length;
97
+ r.copy(signature, 4);
98
+ signature[4 + lenR] = 0x02;
99
+ signature[5 + lenR] = s.length;
100
+ s.copy(signature, 6 + lenR);
101
+ return signature;
102
+ }
103
+ exports.encode = encode;
package/src/block.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ /// <reference types="node" />
2
+ import { Transaction } from './transaction';
3
+ export declare class Block {
4
+ version: number;
5
+ prevHash?: Buffer;
6
+ merkleRoot?: Buffer;
7
+ timestamp: number;
8
+ witnessCommit?: Buffer;
9
+ bits: number;
10
+ nonce: number;
11
+ transactions?: Transaction[];
12
+ static fromBuffer(buffer: Buffer): Block;
13
+ static fromHex(hex: string): Block;
14
+ static calculateTarget(bits: number): Buffer;
15
+ static calculateMerkleRoot(transactions: Transaction[], forWitness?: boolean): Buffer;
16
+ getWitnessCommit(): Buffer | null;
17
+ hasWitnessCommit(): boolean;
18
+ hasWitness(): boolean;
19
+ weight(): number;
20
+ byteLength(headersOnly?: boolean, allowWitness?: boolean): number;
21
+ getHash(): Buffer;
22
+ getId(): string;
23
+ getUTCDate(): Date;
24
+ toBuffer(headersOnly?: boolean): Buffer;
25
+ toHex(headersOnly?: boolean): string;
26
+ checkTxRoots(): boolean;
27
+ checkProofOfWork(): boolean;
28
+ private __checkMerkleRoot;
29
+ private __checkWitnessCommit;
30
+ }
package/src/block.js ADDED
@@ -0,0 +1,224 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, '__esModule', { value: true });
3
+ exports.Block = void 0;
4
+ const bufferutils_1 = require('./bufferutils');
5
+ const bcrypto = require('./crypto');
6
+ const merkle_1 = require('./merkle');
7
+ const transaction_1 = require('./transaction');
8
+ const types = require('./types');
9
+ const { typeforce } = types;
10
+ const errorMerkleNoTxes = new TypeError(
11
+ 'Cannot compute merkle root for zero transactions',
12
+ );
13
+ const errorWitnessNotSegwit = new TypeError(
14
+ 'Cannot compute witness commit for non-segwit block',
15
+ );
16
+ class Block {
17
+ version = 1;
18
+ prevHash = undefined;
19
+ merkleRoot = undefined;
20
+ timestamp = 0;
21
+ witnessCommit = undefined;
22
+ bits = 0;
23
+ nonce = 0;
24
+ transactions = undefined;
25
+ static fromBuffer(buffer) {
26
+ if (buffer.length < 80)
27
+ throw new Error('Buffer too small (< 80 bytes)');
28
+ const bufferReader = new bufferutils_1.BufferReader(buffer);
29
+ const block = new Block();
30
+ block.version = bufferReader.readInt32();
31
+ block.prevHash = bufferReader.readSlice(32);
32
+ block.merkleRoot = bufferReader.readSlice(32);
33
+ block.timestamp = bufferReader.readUInt32();
34
+ block.bits = bufferReader.readUInt32();
35
+ block.nonce = bufferReader.readUInt32();
36
+ if (buffer.length === 80) return block;
37
+ const readTransaction = () => {
38
+ const tx = transaction_1.Transaction.fromBuffer(
39
+ bufferReader.buffer.slice(bufferReader.offset),
40
+ true,
41
+ );
42
+ bufferReader.offset += tx.byteLength();
43
+ return tx;
44
+ };
45
+ const nTransactions = bufferReader.readVarInt();
46
+ block.transactions = [];
47
+ for (let i = 0; i < nTransactions; ++i) {
48
+ const tx = readTransaction();
49
+ block.transactions.push(tx);
50
+ }
51
+ const witnessCommit = block.getWitnessCommit();
52
+ // This Block contains a witness commit
53
+ if (witnessCommit) block.witnessCommit = witnessCommit;
54
+ return block;
55
+ }
56
+ static fromHex(hex) {
57
+ return Block.fromBuffer(Buffer.from(hex, 'hex'));
58
+ }
59
+ static calculateTarget(bits) {
60
+ const exponent = ((bits & 0xff000000) >> 24) - 3;
61
+ const mantissa = bits & 0x007fffff;
62
+ const target = Buffer.alloc(32, 0);
63
+ target.writeUIntBE(mantissa, 29 - exponent, 3);
64
+ return target;
65
+ }
66
+ static calculateMerkleRoot(transactions, forWitness) {
67
+ typeforce([{ getHash: types.Function }], transactions);
68
+ if (transactions.length === 0) throw errorMerkleNoTxes;
69
+ if (forWitness && !txesHaveWitnessCommit(transactions))
70
+ throw errorWitnessNotSegwit;
71
+ const hashes = transactions.map(transaction =>
72
+ transaction.getHash(forWitness),
73
+ );
74
+ const rootHash = (0, merkle_1.fastMerkleRoot)(hashes, bcrypto.hash256);
75
+ return forWitness
76
+ ? bcrypto.hash256(
77
+ Buffer.concat([rootHash, transactions[0].ins[0].witness[0]]),
78
+ )
79
+ : rootHash;
80
+ }
81
+ getWitnessCommit() {
82
+ if (!txesHaveWitnessCommit(this.transactions)) return null;
83
+ // The merkle root for the witness data is in an OP_RETURN output.
84
+ // There is no rule for the index of the output, so use filter to find it.
85
+ // The root is prepended with 0xaa21a9ed so check for 0x6a24aa21a9ed
86
+ // If multiple commits are found, the output with highest index is assumed.
87
+ const witnessCommits = this.transactions[0].outs
88
+ .filter(out =>
89
+ out.script
90
+ .slice(0, 6)
91
+ .equals(Buffer.from('6a24aa21a9ed', 'hex')),
92
+ )
93
+ .map(out => out.script.slice(6, 38));
94
+ if (witnessCommits.length === 0) return null;
95
+ // Use the commit with the highest output (should only be one though)
96
+ const result = witnessCommits[witnessCommits.length - 1];
97
+ if (!(result instanceof Buffer && result.length === 32)) return null;
98
+ return result;
99
+ }
100
+ hasWitnessCommit() {
101
+ if (
102
+ this.witnessCommit instanceof Buffer &&
103
+ this.witnessCommit.length === 32
104
+ )
105
+ return true;
106
+ if (this.getWitnessCommit() !== null) return true;
107
+ return false;
108
+ }
109
+ hasWitness() {
110
+ return anyTxHasWitness(this.transactions);
111
+ }
112
+ weight() {
113
+ const base = this.byteLength(false, false);
114
+ const total = this.byteLength(false, true);
115
+ return base * 3 + total;
116
+ }
117
+ byteLength(headersOnly, allowWitness = true) {
118
+ if (headersOnly || !this.transactions) return 80;
119
+ return (
120
+ 80 +
121
+ bufferutils_1.varuint.encodingLength(this.transactions.length) +
122
+ this.transactions.reduce(
123
+ (a, x) => a + x.byteLength(allowWitness),
124
+ 0,
125
+ )
126
+ );
127
+ }
128
+ getHash() {
129
+ return bcrypto.hash256(this.toBuffer(true));
130
+ }
131
+ getId() {
132
+ return (0, bufferutils_1.reverseBuffer)(this.getHash()).toString('hex');
133
+ }
134
+ getUTCDate() {
135
+ const date = new Date(0); // epoch
136
+ date.setUTCSeconds(this.timestamp);
137
+ return date;
138
+ }
139
+ // TODO: buffer, offset compatibility
140
+ toBuffer(headersOnly) {
141
+ const buffer = Buffer.allocUnsafe(this.byteLength(headersOnly));
142
+ const bufferWriter = new bufferutils_1.BufferWriter(buffer);
143
+ bufferWriter.writeInt32(this.version);
144
+ bufferWriter.writeSlice(this.prevHash);
145
+ bufferWriter.writeSlice(this.merkleRoot);
146
+ bufferWriter.writeUInt32(this.timestamp);
147
+ bufferWriter.writeUInt32(this.bits);
148
+ bufferWriter.writeUInt32(this.nonce);
149
+ if (headersOnly || !this.transactions) return buffer;
150
+ bufferutils_1.varuint.encode(
151
+ this.transactions.length,
152
+ buffer,
153
+ bufferWriter.offset,
154
+ );
155
+ bufferWriter.offset += bufferutils_1.varuint.encode.bytes;
156
+ this.transactions.forEach(tx => {
157
+ const txSize = tx.byteLength(); // TODO: extract from toBuffer?
158
+ tx.toBuffer(buffer, bufferWriter.offset);
159
+ bufferWriter.offset += txSize;
160
+ });
161
+ return buffer;
162
+ }
163
+ toHex(headersOnly) {
164
+ return this.toBuffer(headersOnly).toString('hex');
165
+ }
166
+ checkTxRoots() {
167
+ // If the Block has segwit transactions but no witness commit,
168
+ // there's no way it can be valid, so fail the check.
169
+ const hasWitnessCommit = this.hasWitnessCommit();
170
+ if (!hasWitnessCommit && this.hasWitness()) return false;
171
+ return (
172
+ this.__checkMerkleRoot() &&
173
+ (hasWitnessCommit ? this.__checkWitnessCommit() : true)
174
+ );
175
+ }
176
+ checkProofOfWork() {
177
+ const hash = (0, bufferutils_1.reverseBuffer)(this.getHash());
178
+ const target = Block.calculateTarget(this.bits);
179
+ return hash.compare(target) <= 0;
180
+ }
181
+ __checkMerkleRoot() {
182
+ if (!this.transactions) throw errorMerkleNoTxes;
183
+ const actualMerkleRoot = Block.calculateMerkleRoot(this.transactions);
184
+ return this.merkleRoot.compare(actualMerkleRoot) === 0;
185
+ }
186
+ __checkWitnessCommit() {
187
+ if (!this.transactions) throw errorMerkleNoTxes;
188
+ if (!this.hasWitnessCommit()) throw errorWitnessNotSegwit;
189
+ const actualWitnessCommit = Block.calculateMerkleRoot(
190
+ this.transactions,
191
+ true,
192
+ );
193
+ return this.witnessCommit.compare(actualWitnessCommit) === 0;
194
+ }
195
+ }
196
+ exports.Block = Block;
197
+ function txesHaveWitnessCommit(transactions) {
198
+ return (
199
+ transactions instanceof Array &&
200
+ transactions[0] &&
201
+ transactions[0].ins &&
202
+ transactions[0].ins instanceof Array &&
203
+ transactions[0].ins[0] &&
204
+ transactions[0].ins[0].witness &&
205
+ transactions[0].ins[0].witness instanceof Array &&
206
+ transactions[0].ins[0].witness.length > 0
207
+ );
208
+ }
209
+ function anyTxHasWitness(transactions) {
210
+ return (
211
+ transactions instanceof Array &&
212
+ transactions.some(
213
+ tx =>
214
+ typeof tx === 'object' &&
215
+ tx.ins instanceof Array &&
216
+ tx.ins.some(
217
+ input =>
218
+ typeof input === 'object' &&
219
+ input.witness instanceof Array &&
220
+ input.witness.length > 0,
221
+ ),
222
+ )
223
+ );
224
+ }
@@ -0,0 +1,54 @@
1
+ /// <reference types="node" />
2
+ import * as varuint from 'varuint-bitcoin';
3
+ export { varuint };
4
+ export declare function readUInt64LE(buffer: Buffer, offset: number): number;
5
+ /**
6
+ * Writes a 64-bit unsigned integer in little-endian format to the specified buffer at the given offset.
7
+ *
8
+ * @param buffer - The buffer to write the value to.
9
+ * @param value - The 64-bit unsigned integer value to write.
10
+ * @param offset - The offset in the buffer where the value should be written.
11
+ * @returns The new offset after writing the value.
12
+ */
13
+ export declare function writeUInt64LE(buffer: Buffer, value: number, offset: number): number;
14
+ /**
15
+ * Reverses the order of bytes in a buffer.
16
+ * @param buffer - The buffer to reverse.
17
+ * @returns A new buffer with the bytes reversed.
18
+ */
19
+ export declare function reverseBuffer(buffer: Buffer): Buffer;
20
+ export declare function cloneBuffer(buffer: Buffer): Buffer;
21
+ /**
22
+ * Helper class for serialization of bitcoin data types into a pre-allocated buffer.
23
+ */
24
+ export declare class BufferWriter {
25
+ buffer: Buffer;
26
+ offset: number;
27
+ constructor(buffer: Buffer, offset?: number);
28
+ static withCapacity(size: number): BufferWriter;
29
+ writeUInt8(i: number): void;
30
+ writeInt32(i: number): void;
31
+ writeUInt32(i: number): void;
32
+ writeUInt64(i: number): void;
33
+ writeVarInt(i: number): void;
34
+ writeSlice(slice: Buffer): void;
35
+ writeVarSlice(slice: Buffer): void;
36
+ writeVector(vector: Buffer[]): void;
37
+ end(): Buffer;
38
+ }
39
+ /**
40
+ * Helper class for reading of bitcoin data types from a buffer.
41
+ */
42
+ export declare class BufferReader {
43
+ buffer: Buffer;
44
+ offset: number;
45
+ constructor(buffer: Buffer, offset?: number);
46
+ readUInt8(): number;
47
+ readInt32(): number;
48
+ readUInt32(): number;
49
+ readUInt64(): number;
50
+ readVarInt(): number;
51
+ readSlice(n: number): Buffer;
52
+ readVarSlice(): Buffer;
53
+ readVector(): Buffer[];
54
+ }
@@ -0,0 +1,182 @@
1
+ 'use strict';
2
+ Object.defineProperty(exports, '__esModule', { value: true });
3
+ exports.BufferReader =
4
+ exports.BufferWriter =
5
+ exports.cloneBuffer =
6
+ exports.reverseBuffer =
7
+ exports.writeUInt64LE =
8
+ exports.readUInt64LE =
9
+ exports.varuint =
10
+ void 0;
11
+ const types = require('./types');
12
+ const varuint = require('varuint-bitcoin');
13
+ exports.varuint = varuint;
14
+ const { typeforce } = types;
15
+ // https://github.com/feross/buffer/blob/master/index.js#L1127
16
+ function verifuint(value, max) {
17
+ if (typeof value !== 'number')
18
+ throw new Error('cannot write a non-number as a number');
19
+ if (value < 0)
20
+ throw new Error(
21
+ 'specified a negative value for writing an unsigned value',
22
+ );
23
+ if (value > max) throw new Error('RangeError: value out of range');
24
+ if (Math.floor(value) !== value)
25
+ throw new Error('value has a fractional component');
26
+ }
27
+ function readUInt64LE(buffer, offset) {
28
+ const a = buffer.readUInt32LE(offset);
29
+ let b = buffer.readUInt32LE(offset + 4);
30
+ b *= 0x100000000;
31
+ verifuint(b + a, 0x001fffffffffffff);
32
+ return b + a;
33
+ }
34
+ exports.readUInt64LE = readUInt64LE;
35
+ /**
36
+ * Writes a 64-bit unsigned integer in little-endian format to the specified buffer at the given offset.
37
+ *
38
+ * @param buffer - The buffer to write the value to.
39
+ * @param value - The 64-bit unsigned integer value to write.
40
+ * @param offset - The offset in the buffer where the value should be written.
41
+ * @returns The new offset after writing the value.
42
+ */
43
+ function writeUInt64LE(buffer, value, offset) {
44
+ verifuint(value, 0x001fffffffffffff);
45
+ buffer.writeInt32LE(value & -1, offset);
46
+ buffer.writeUInt32LE(Math.floor(value / 0x100000000), offset + 4);
47
+ return offset + 8;
48
+ }
49
+ exports.writeUInt64LE = writeUInt64LE;
50
+ /**
51
+ * Reverses the order of bytes in a buffer.
52
+ * @param buffer - The buffer to reverse.
53
+ * @returns A new buffer with the bytes reversed.
54
+ */
55
+ function reverseBuffer(buffer) {
56
+ if (buffer.length < 1) return buffer;
57
+ let j = buffer.length - 1;
58
+ let tmp = 0;
59
+ for (let i = 0; i < buffer.length / 2; i++) {
60
+ tmp = buffer[i];
61
+ buffer[i] = buffer[j];
62
+ buffer[j] = tmp;
63
+ j--;
64
+ }
65
+ return buffer;
66
+ }
67
+ exports.reverseBuffer = reverseBuffer;
68
+ function cloneBuffer(buffer) {
69
+ const clone = Buffer.allocUnsafe(buffer.length);
70
+ buffer.copy(clone);
71
+ return clone;
72
+ }
73
+ exports.cloneBuffer = cloneBuffer;
74
+ /**
75
+ * Helper class for serialization of bitcoin data types into a pre-allocated buffer.
76
+ */
77
+ class BufferWriter {
78
+ buffer;
79
+ offset;
80
+ constructor(buffer, offset = 0) {
81
+ this.buffer = buffer;
82
+ this.offset = offset;
83
+ typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]);
84
+ }
85
+ static withCapacity(size) {
86
+ return new BufferWriter(Buffer.alloc(size));
87
+ }
88
+ writeUInt8(i) {
89
+ this.offset = this.buffer.writeUInt8(i, this.offset);
90
+ }
91
+ writeInt32(i) {
92
+ this.offset = this.buffer.writeInt32LE(i, this.offset);
93
+ }
94
+ writeUInt32(i) {
95
+ this.offset = this.buffer.writeUInt32LE(i, this.offset);
96
+ }
97
+ writeUInt64(i) {
98
+ this.offset = writeUInt64LE(this.buffer, i, this.offset);
99
+ }
100
+ writeVarInt(i) {
101
+ varuint.encode(i, this.buffer, this.offset);
102
+ this.offset += varuint.encode.bytes;
103
+ }
104
+ writeSlice(slice) {
105
+ if (this.buffer.length < this.offset + slice.length) {
106
+ throw new Error('Cannot write slice out of bounds');
107
+ }
108
+ this.offset += slice.copy(this.buffer, this.offset);
109
+ }
110
+ writeVarSlice(slice) {
111
+ this.writeVarInt(slice.length);
112
+ this.writeSlice(slice);
113
+ }
114
+ writeVector(vector) {
115
+ this.writeVarInt(vector.length);
116
+ vector.forEach(buf => this.writeVarSlice(buf));
117
+ }
118
+ end() {
119
+ if (this.buffer.length === this.offset) {
120
+ return this.buffer;
121
+ }
122
+ throw new Error(
123
+ `buffer size ${this.buffer.length}, offset ${this.offset}`,
124
+ );
125
+ }
126
+ }
127
+ exports.BufferWriter = BufferWriter;
128
+ /**
129
+ * Helper class for reading of bitcoin data types from a buffer.
130
+ */
131
+ class BufferReader {
132
+ buffer;
133
+ offset;
134
+ constructor(buffer, offset = 0) {
135
+ this.buffer = buffer;
136
+ this.offset = offset;
137
+ typeforce(types.tuple(types.Buffer, types.UInt32), [buffer, offset]);
138
+ }
139
+ readUInt8() {
140
+ const result = this.buffer.readUInt8(this.offset);
141
+ this.offset++;
142
+ return result;
143
+ }
144
+ readInt32() {
145
+ const result = this.buffer.readInt32LE(this.offset);
146
+ this.offset += 4;
147
+ return result;
148
+ }
149
+ readUInt32() {
150
+ const result = this.buffer.readUInt32LE(this.offset);
151
+ this.offset += 4;
152
+ return result;
153
+ }
154
+ readUInt64() {
155
+ const result = readUInt64LE(this.buffer, this.offset);
156
+ this.offset += 8;
157
+ return result;
158
+ }
159
+ readVarInt() {
160
+ const vi = varuint.decode(this.buffer, this.offset);
161
+ this.offset += varuint.decode.bytes;
162
+ return vi;
163
+ }
164
+ readSlice(n) {
165
+ if (this.buffer.length < this.offset + n) {
166
+ throw new Error('Cannot read slice out of bounds');
167
+ }
168
+ const result = this.buffer.slice(this.offset, this.offset + n);
169
+ this.offset += n;
170
+ return result;
171
+ }
172
+ readVarSlice() {
173
+ return this.readSlice(this.readVarInt());
174
+ }
175
+ readVector() {
176
+ const count = this.readVarInt();
177
+ const vector = [];
178
+ for (let i = 0; i < count; i++) vector.push(this.readVarSlice());
179
+ return vector;
180
+ }
181
+ }
182
+ exports.BufferReader = BufferReader;
@@ -0,0 +1,18 @@
1
+ /// <reference types="node" />
2
+ export declare function ripemd160(buffer: Buffer): Buffer;
3
+ export declare function sha1(buffer: Buffer): Buffer;
4
+ export declare function sha256(buffer: Buffer): Buffer;
5
+ export declare function hash160(buffer: Buffer): Buffer;
6
+ export declare function hash256(buffer: Buffer): Buffer;
7
+ export declare const TAGS: readonly ["BIP0340/challenge", "BIP0340/aux", "BIP0340/nonce", "TapLeaf", "TapBranch", "TapSighash", "TapTweak", "KeyAgg list", "KeyAgg coefficient"];
8
+ export type TaggedHashPrefix = typeof TAGS[number];
9
+ type TaggedHashPrefixes = {
10
+ [key in TaggedHashPrefix]: Buffer;
11
+ };
12
+ /** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */
13
+ /**
14
+ * Defines the tagged hash prefixes used in the crypto module.
15
+ */
16
+ export declare const TAGGED_HASH_PREFIXES: TaggedHashPrefixes;
17
+ export declare function taggedHash(prefix: TaggedHashPrefix, data: Buffer): Buffer;
18
+ export {};