@btc-vision/bitcoin 7.0.0-beta.0 → 7.0.0-beta.1
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.
- package/README.md +112 -13
- package/benchmark-compare/BENCHMARK.md +74 -59
- package/benchmark-compare/compare.bench.ts +249 -96
- package/benchmark-compare/harness.ts +23 -25
- package/benchmark-compare/package.json +1 -0
- package/browser/address.d.ts +4 -4
- package/browser/address.d.ts.map +1 -1
- package/browser/chunks/{psbt-parallel-B-dfm5GZ.js → psbt-parallel-jZ6QcCnM.js} +3128 -2731
- package/browser/index.d.ts +1 -1
- package/browser/index.d.ts.map +1 -1
- package/browser/index.js +603 -585
- package/browser/io/base58check.d.ts +1 -25
- package/browser/io/base58check.d.ts.map +1 -1
- package/browser/io/base64.d.ts.map +1 -1
- package/browser/networks.d.ts +1 -0
- package/browser/networks.d.ts.map +1 -1
- package/browser/payments/bip341.d.ts +17 -0
- package/browser/payments/bip341.d.ts.map +1 -1
- package/browser/payments/index.d.ts +3 -2
- package/browser/payments/index.d.ts.map +1 -1
- package/browser/payments/p2mr.d.ts +169 -0
- package/browser/payments/p2mr.d.ts.map +1 -0
- package/browser/payments/types.d.ts +11 -1
- package/browser/payments/types.d.ts.map +1 -1
- package/browser/psbt/bip371.d.ts +30 -0
- package/browser/psbt/bip371.d.ts.map +1 -1
- package/browser/psbt/psbtutils.d.ts +1 -0
- package/browser/psbt/psbtutils.d.ts.map +1 -1
- package/browser/psbt.d.ts.map +1 -1
- package/browser/workers/index.js +9 -9
- package/build/address.d.ts +4 -4
- package/build/address.d.ts.map +1 -1
- package/build/address.js +11 -1
- package/build/address.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js.map +1 -1
- package/build/io/base58check.d.ts +1 -25
- package/build/io/base58check.d.ts.map +1 -1
- package/build/io/base58check.js +1 -31
- package/build/io/base58check.js.map +1 -1
- package/build/io/base64.d.ts.map +1 -1
- package/build/io/base64.js +3 -0
- package/build/io/base64.js.map +1 -1
- package/build/networks.d.ts +1 -0
- package/build/networks.d.ts.map +1 -1
- package/build/networks.js +12 -0
- package/build/networks.js.map +1 -1
- package/build/payments/bip341.d.ts +17 -0
- package/build/payments/bip341.d.ts.map +1 -1
- package/build/payments/bip341.js +32 -1
- package/build/payments/bip341.js.map +1 -1
- package/build/payments/index.d.ts +3 -2
- package/build/payments/index.d.ts.map +1 -1
- package/build/payments/index.js +2 -1
- package/build/payments/index.js.map +1 -1
- package/build/payments/p2mr.d.ts +178 -0
- package/build/payments/p2mr.d.ts.map +1 -0
- package/build/payments/p2mr.js +555 -0
- package/build/payments/p2mr.js.map +1 -0
- package/build/payments/types.d.ts +11 -1
- package/build/payments/types.d.ts.map +1 -1
- package/build/payments/types.js +1 -0
- package/build/payments/types.js.map +1 -1
- package/build/psbt/bip371.d.ts +30 -0
- package/build/psbt/bip371.d.ts.map +1 -1
- package/build/psbt/bip371.js +80 -15
- package/build/psbt/bip371.js.map +1 -1
- package/build/psbt/psbtutils.d.ts +1 -0
- package/build/psbt/psbtutils.d.ts.map +1 -1
- package/build/psbt/psbtutils.js +2 -0
- package/build/psbt/psbtutils.js.map +1 -1
- package/build/psbt.d.ts.map +1 -1
- package/build/psbt.js +3 -2
- package/build/psbt.js.map +1 -1
- package/build/pubkey.js +1 -1
- package/build/pubkey.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/documentation/README.md +122 -0
- package/documentation/address.md +820 -0
- package/documentation/block.md +679 -0
- package/documentation/crypto.md +461 -0
- package/documentation/ecc.md +584 -0
- package/documentation/errors.md +656 -0
- package/documentation/io.md +942 -0
- package/documentation/networks.md +625 -0
- package/documentation/p2mr.md +380 -0
- package/documentation/payments.md +1485 -0
- package/documentation/psbt.md +1400 -0
- package/documentation/script.md +730 -0
- package/documentation/taproot.md +670 -0
- package/documentation/transaction.md +943 -0
- package/documentation/types.md +587 -0
- package/documentation/workers.md +1007 -0
- package/eslint.config.js +3 -0
- package/package.json +17 -14
- package/src/address.ts +22 -10
- package/src/index.ts +1 -0
- package/src/io/base58check.ts +1 -35
- package/src/io/base64.ts +5 -0
- package/src/networks.ts +13 -0
- package/src/payments/bip341.ts +36 -1
- package/src/payments/index.ts +4 -0
- package/src/payments/p2mr.ts +660 -0
- package/src/payments/types.ts +12 -0
- package/src/psbt/bip371.ts +84 -13
- package/src/psbt/psbtutils.ts +2 -0
- package/src/psbt.ts +4 -2
- package/src/pubkey.ts +1 -1
- package/test/bitcoin.core.spec.ts +1 -1
- package/test/fixtures/p2mr.json +270 -0
- package/test/integration/taproot.spec.ts +7 -3
- package/test/opnetTestnet.spec.ts +302 -0
- package/test/payments.spec.ts +3 -1
- package/test/psbt.spec.ts +297 -2
- package/test/tsconfig.json +2 -2
|
@@ -0,0 +1,942 @@
|
|
|
1
|
+
# I/O Utilities
|
|
2
|
+
|
|
3
|
+
High-performance binary I/O module providing encoding, decoding, buffer manipulation, and stateful binary reading/writing with zero-allocation operations through reused DataView instances.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
| Category | Functions / Classes |
|
|
8
|
+
|----------|-------------------|
|
|
9
|
+
| Hex encoding | `toHex()`, `fromHex()`, `isHex()` |
|
|
10
|
+
| Base64 encoding | `fromBase64()`, `toBase64()` |
|
|
11
|
+
| Base58Check encoding | `base58check.encode()`, `base58check.decode()`, `base58check.decodeUnsafe()` |
|
|
12
|
+
| Buffer utilities | `concat()`, `equals()`, `compare()`, `isZero()`, `clone()`, `reverse()`, `reverseCopy()`, `alloc()`, `xor()` |
|
|
13
|
+
| UTF-8 utilities | `fromUtf8()`, `toUtf8()` |
|
|
14
|
+
| Variable-length integers | `varuint.encode()`, `varuint.decode()`, `varuint.encodingLength()` |
|
|
15
|
+
| Binary reading | `BinaryReader` class |
|
|
16
|
+
| Binary writing | `BinaryWriter`, `GrowableBinaryWriter` classes |
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
Most I/O utilities (hex, base64, buffer utilities, UTF-8, varuint) are re-exported from the main entry point. However, `base58check`, `BinaryReader`, `BinaryWriter`, and `GrowableBinaryWriter` are only available from the `@btc-vision/bitcoin/io` subpath.
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// These are available from the main entry point:
|
|
26
|
+
import {
|
|
27
|
+
// Hex
|
|
28
|
+
toHex, fromHex, isHex,
|
|
29
|
+
// Base64
|
|
30
|
+
fromBase64, toBase64,
|
|
31
|
+
// Buffer utilities
|
|
32
|
+
concat, equals, compare, isZero, clone, reverse, reverseCopy, alloc, xor,
|
|
33
|
+
// UTF-8
|
|
34
|
+
fromUtf8, toUtf8,
|
|
35
|
+
// Variable-length integers
|
|
36
|
+
varuint,
|
|
37
|
+
} from '@btc-vision/bitcoin';
|
|
38
|
+
|
|
39
|
+
// These are only available from the io subpath:
|
|
40
|
+
import {
|
|
41
|
+
base58check,
|
|
42
|
+
BinaryReader, BinaryWriter, GrowableBinaryWriter,
|
|
43
|
+
} from '@btc-vision/bitcoin/io';
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
> **Note:** `@btc-vision/bs58check` (the underlying Base58Check implementation) is listed under `devDependencies`, not `dependencies`. If your project uses `base58check` directly, ensure that `@btc-vision/bs58check` is installed in your own project's dependencies.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Hex Encoding
|
|
51
|
+
|
|
52
|
+
Optimized hex encoding and decoding using pre-computed lookup tables for O(1) per-byte conversion. Zero dependencies.
|
|
53
|
+
|
|
54
|
+
### toHex
|
|
55
|
+
|
|
56
|
+
Converts a `Uint8Array` to a lowercase hex string.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
function toHex(bytes: Uint8Array): string;
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { toHex } from '@btc-vision/bitcoin';
|
|
64
|
+
|
|
65
|
+
const bytes = new Uint8Array([0xde, 0xad, 0xbe, 0xef]);
|
|
66
|
+
const hex = toHex(bytes);
|
|
67
|
+
console.log(hex); // 'deadbeef'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### fromHex
|
|
71
|
+
|
|
72
|
+
Converts a hex string to a `Uint8Array`. Accepts hex strings with or without `0x` prefix. Case-insensitive.
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
function fromHex(hex: string): Uint8Array;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
| Parameter | Type | Description |
|
|
79
|
+
|-----------|------|-------------|
|
|
80
|
+
| `hex` | `string` | Hex string to convert (with or without `0x` prefix) |
|
|
81
|
+
|
|
82
|
+
| Throws | Condition |
|
|
83
|
+
|--------|-----------|
|
|
84
|
+
| `TypeError` | Hex string has odd length |
|
|
85
|
+
| `TypeError` | Hex string contains invalid characters |
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { fromHex, toHex } from '@btc-vision/bitcoin';
|
|
89
|
+
|
|
90
|
+
const bytes = fromHex('deadbeef');
|
|
91
|
+
console.log(bytes); // Uint8Array [222, 173, 190, 239]
|
|
92
|
+
|
|
93
|
+
// Works with 0x prefix
|
|
94
|
+
const bytes2 = fromHex('0xCAFEBABE');
|
|
95
|
+
console.log(toHex(bytes2)); // 'cafebabe'
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### isHex
|
|
99
|
+
|
|
100
|
+
Checks if a string is valid hexadecimal. Validates even length and valid hex characters. Accepts optional `0x` prefix.
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
function isHex(value: string): boolean;
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { isHex } from '@btc-vision/bitcoin';
|
|
108
|
+
|
|
109
|
+
isHex('deadbeef'); // true
|
|
110
|
+
isHex('0xdeadbeef'); // true
|
|
111
|
+
isHex('DEADBEEF'); // true
|
|
112
|
+
isHex('deadbee'); // false (odd length)
|
|
113
|
+
isHex('deadbeeg'); // false (invalid char 'g')
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Base64 Encoding
|
|
119
|
+
|
|
120
|
+
Base64 encoding and decoding using the native `atob()`/`btoa()` functions available in both browser and service worker contexts.
|
|
121
|
+
|
|
122
|
+
### fromBase64
|
|
123
|
+
|
|
124
|
+
Decodes a base64 string to a `Uint8Array`.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
function fromBase64(base64: string): Uint8Array;
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { fromBase64, toHex } from '@btc-vision/bitcoin';
|
|
132
|
+
|
|
133
|
+
const bytes = fromBase64('3q2+7w==');
|
|
134
|
+
console.log(toHex(bytes)); // 'deadbeef'
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### toBase64
|
|
138
|
+
|
|
139
|
+
Encodes a `Uint8Array` into a base64 string.
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
function toBase64(bytes: Uint8Array): string;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { toBase64, fromHex } from '@btc-vision/bitcoin';
|
|
147
|
+
|
|
148
|
+
const bytes = fromHex('deadbeef');
|
|
149
|
+
const encoded = toBase64(bytes);
|
|
150
|
+
console.log(encoded); // '3q2+7w=='
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Base58Check Encoding
|
|
156
|
+
|
|
157
|
+
Base58Check encoding with checksum verification, re-exported from `@btc-vision/bs58check`. Used for legacy Bitcoin addresses and WIF private keys.
|
|
158
|
+
|
|
159
|
+
> **Note:** `@btc-vision/bs58check` is a `devDependency` of this package, not a runtime `dependency`. If your project relies on `base58check`, you should add `@btc-vision/bs58check` to your own project's `dependencies`.
|
|
160
|
+
|
|
161
|
+
### base58check.encode
|
|
162
|
+
|
|
163
|
+
Encodes a `Uint8Array` payload into a Base58Check string (with 4-byte checksum appended).
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
function encode(payload: Uint8Array): string;
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { base58check } from '@btc-vision/bitcoin/io';
|
|
171
|
+
import { fromHex } from '@btc-vision/bitcoin';
|
|
172
|
+
|
|
173
|
+
// Encode a version byte + hash160 into a legacy address
|
|
174
|
+
const payload = fromHex('0014...'); // version prefix + payload
|
|
175
|
+
const address = base58check.encode(payload);
|
|
176
|
+
console.log(address); // '1...' or '3...'
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### base58check.decode
|
|
180
|
+
|
|
181
|
+
Decodes a Base58Check string into a `Uint8Array`. Verifies the 4-byte checksum and throws on invalid input.
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
function decode(str: string): Uint8Array;
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import { base58check } from '@btc-vision/bitcoin/io';
|
|
189
|
+
import { toHex } from '@btc-vision/bitcoin';
|
|
190
|
+
|
|
191
|
+
const payload = base58check.decode('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa');
|
|
192
|
+
console.log(toHex(payload)); // version byte + 20-byte pubkey hash
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### base58check.decodeUnsafe
|
|
196
|
+
|
|
197
|
+
Decodes a Base58Check string, returning `undefined` instead of throwing on invalid input.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
function decodeUnsafe(str: string): Uint8Array | undefined;
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
import { base58check } from '@btc-vision/bitcoin/io';
|
|
205
|
+
|
|
206
|
+
const result = base58check.decodeUnsafe('invalidstring');
|
|
207
|
+
if (result === undefined) {
|
|
208
|
+
console.log('Invalid Base58Check string');
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Buffer Utilities
|
|
215
|
+
|
|
216
|
+
Pure utility functions for `Uint8Array` operations. No DataView allocations. Optimized for performance with minimal allocations.
|
|
217
|
+
|
|
218
|
+
### concat
|
|
219
|
+
|
|
220
|
+
Concatenates multiple `Uint8Array` instances into a single array. Allocates exactly once for the result.
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
function concat(arrays: readonly Uint8Array[]): Uint8Array;
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import { concat, fromHex, toHex } from '@btc-vision/bitcoin';
|
|
228
|
+
|
|
229
|
+
const a = fromHex('deadbeef');
|
|
230
|
+
const b = fromHex('cafebabe');
|
|
231
|
+
const result = concat([a, b]);
|
|
232
|
+
console.log(toHex(result)); // 'deadbeefcafebabe'
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### equals
|
|
236
|
+
|
|
237
|
+
Checks if two `Uint8Array` instances have identical contents.
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
function equals(a: Uint8Array, b: Uint8Array): boolean;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
import { equals, fromHex } from '@btc-vision/bitcoin';
|
|
245
|
+
|
|
246
|
+
const a = fromHex('deadbeef');
|
|
247
|
+
const b = fromHex('deadbeef');
|
|
248
|
+
const c = fromHex('cafebabe');
|
|
249
|
+
|
|
250
|
+
equals(a, b); // true
|
|
251
|
+
equals(a, c); // false
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### compare
|
|
255
|
+
|
|
256
|
+
Compares two `Uint8Array` instances lexicographically. Returns a negative number if `a < b`, positive if `a > b`, and `0` if equal.
|
|
257
|
+
|
|
258
|
+
> **Note:** The return value is the arithmetic difference between the first differing bytes (or the difference in lengths), not a normalized -1/0/1. For example, comparing `0x01` to `0x03` returns `-2`, not `-1`.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
function compare(a: Uint8Array, b: Uint8Array): number;
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
import { compare, fromHex } from '@btc-vision/bitcoin';
|
|
266
|
+
|
|
267
|
+
const a = fromHex('0001');
|
|
268
|
+
const b = fromHex('0002');
|
|
269
|
+
|
|
270
|
+
compare(a, b); // -1 (a < b, difference: 0x01 - 0x02)
|
|
271
|
+
compare(b, a); // 1 (b > a, difference: 0x02 - 0x01)
|
|
272
|
+
compare(a, a); // 0 (equal)
|
|
273
|
+
|
|
274
|
+
// The return value is the arithmetic difference, not normalized to -1/0/1:
|
|
275
|
+
const x = fromHex('0001');
|
|
276
|
+
const y = fromHex('0005');
|
|
277
|
+
compare(x, y); // -4 (difference: 0x01 - 0x05)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### isZero
|
|
281
|
+
|
|
282
|
+
Checks if a `Uint8Array` contains only zero bytes.
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
function isZero(bytes: Uint8Array): boolean;
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
import { isZero } from '@btc-vision/bitcoin';
|
|
290
|
+
|
|
291
|
+
isZero(new Uint8Array(32)); // true
|
|
292
|
+
isZero(new Uint8Array([0, 0, 1])); // false
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### clone
|
|
296
|
+
|
|
297
|
+
Creates an independent copy of a `Uint8Array`. Modifications to the clone do not affect the original.
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
function clone(bytes: Uint8Array): Uint8Array;
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import { clone, fromHex } from '@btc-vision/bitcoin';
|
|
305
|
+
|
|
306
|
+
const original = fromHex('deadbeef');
|
|
307
|
+
const copy = clone(original);
|
|
308
|
+
copy[0] = 0; // Modifying copy doesn't affect original
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### reverse
|
|
312
|
+
|
|
313
|
+
Reverses a `Uint8Array` **in place**. Returns the same array reference.
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
function reverse(bytes: Uint8Array): Uint8Array;
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { reverse, fromHex, toHex } from '@btc-vision/bitcoin';
|
|
321
|
+
|
|
322
|
+
const bytes = fromHex('01020304');
|
|
323
|
+
reverse(bytes);
|
|
324
|
+
console.log(toHex(bytes)); // '04030201'
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### reverseCopy
|
|
328
|
+
|
|
329
|
+
Creates a **new** reversed copy of a `Uint8Array`. The original array is not modified.
|
|
330
|
+
|
|
331
|
+
```typescript
|
|
332
|
+
function reverseCopy(bytes: Uint8Array): Uint8Array;
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
import { reverseCopy, fromHex, toHex } from '@btc-vision/bitcoin';
|
|
337
|
+
|
|
338
|
+
const bytes = fromHex('01020304');
|
|
339
|
+
const reversed = reverseCopy(bytes);
|
|
340
|
+
console.log(toHex(reversed)); // '04030201'
|
|
341
|
+
console.log(toHex(bytes)); // '01020304' (original unchanged)
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### alloc
|
|
345
|
+
|
|
346
|
+
Allocates a new `Uint8Array` of the specified size, optionally filled with a byte value.
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
function alloc(size: number, fill?: number): Uint8Array;
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
| Parameter | Type | Default | Description |
|
|
353
|
+
|-----------|------|---------|-------------|
|
|
354
|
+
| `size` | `number` | - | Number of bytes to allocate |
|
|
355
|
+
| `fill` | `number` | `0` | Byte value to fill with |
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
import { alloc, toHex } from '@btc-vision/bitcoin';
|
|
359
|
+
|
|
360
|
+
const zeros = alloc(4); // 4 zero bytes: 00000000
|
|
361
|
+
const ones = alloc(4, 0xff); // 4 bytes of 0xff
|
|
362
|
+
console.log(toHex(ones)); // 'ffffffff'
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### xor
|
|
366
|
+
|
|
367
|
+
XORs two `Uint8Array` instances together, returning a new array with the result.
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
function xor(a: Uint8Array, b: Uint8Array): Uint8Array;
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
| Throws | Condition |
|
|
374
|
+
|--------|-----------|
|
|
375
|
+
| `TypeError` | Arrays have different lengths |
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import { xor, fromHex, toHex } from '@btc-vision/bitcoin';
|
|
379
|
+
|
|
380
|
+
const a = fromHex('ff00ff00');
|
|
381
|
+
const b = fromHex('0f0f0f0f');
|
|
382
|
+
const result = xor(a, b);
|
|
383
|
+
console.log(toHex(result)); // 'f00ff00f'
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
---
|
|
387
|
+
|
|
388
|
+
## UTF-8 Utilities
|
|
389
|
+
|
|
390
|
+
UTF-8 string encoding and decoding using the standard `TextEncoder`/`TextDecoder` APIs.
|
|
391
|
+
|
|
392
|
+
### fromUtf8
|
|
393
|
+
|
|
394
|
+
Creates a `Uint8Array` from a UTF-8 string.
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
function fromUtf8(str: string): Uint8Array;
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
import { fromUtf8, toHex } from '@btc-vision/bitcoin';
|
|
402
|
+
|
|
403
|
+
const bytes = fromUtf8('hello');
|
|
404
|
+
console.log(toHex(bytes)); // '68656c6c6f'
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### toUtf8
|
|
408
|
+
|
|
409
|
+
Decodes a `Uint8Array` to a UTF-8 string.
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
function toUtf8(bytes: Uint8Array): string;
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
import { toUtf8, fromHex } from '@btc-vision/bitcoin';
|
|
417
|
+
|
|
418
|
+
const bytes = fromHex('68656c6c6f');
|
|
419
|
+
const str = toUtf8(bytes);
|
|
420
|
+
console.log(str); // 'hello'
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Variable-Length Integers (varuint)
|
|
426
|
+
|
|
427
|
+
Bitcoin CompactSize variable-length integer encoding, re-exported from `varuint-bitcoin`. Used throughout the Bitcoin protocol for encoding lengths and counts.
|
|
428
|
+
|
|
429
|
+
### Encoding Format
|
|
430
|
+
|
|
431
|
+
| First byte | Total size | Value range |
|
|
432
|
+
|------------|-----------|-------------|
|
|
433
|
+
| `0x00` - `0xFC` | 1 byte | 0 - 252 |
|
|
434
|
+
| `0xFD` | 3 bytes | 253 - 65535 (0xFD + 2-byte LE uint16) |
|
|
435
|
+
| `0xFE` | 5 bytes | 65536 - 4294967295 (0xFE + 4-byte LE uint32) |
|
|
436
|
+
| `0xFF` | 9 bytes | 4294967296+ (0xFF + 8-byte LE uint64) |
|
|
437
|
+
|
|
438
|
+
### varuint.encode
|
|
439
|
+
|
|
440
|
+
Encodes a number or bigint as a CompactSize variable-length integer into a buffer.
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
function encode(
|
|
444
|
+
n: number | bigint,
|
|
445
|
+
buffer?: Uint8Array,
|
|
446
|
+
offset?: number,
|
|
447
|
+
): { buffer: Uint8Array; bytes: number };
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
| Parameter | Type | Description |
|
|
451
|
+
|-----------|------|-------------|
|
|
452
|
+
| `n` | `number \| bigint` | Value to encode |
|
|
453
|
+
| `buffer` | `Uint8Array` | Optional target buffer |
|
|
454
|
+
| `offset` | `number` | Optional offset within buffer |
|
|
455
|
+
|
|
456
|
+
Returns an object with the `buffer` containing the encoded data and `bytes` indicating how many bytes were written.
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
import { varuint } from '@btc-vision/bitcoin';
|
|
460
|
+
|
|
461
|
+
// Encode a small value (1 byte)
|
|
462
|
+
const small = varuint.encode(100);
|
|
463
|
+
console.log(small.bytes); // 1
|
|
464
|
+
|
|
465
|
+
// Encode a larger value (3 bytes)
|
|
466
|
+
const medium = varuint.encode(515);
|
|
467
|
+
console.log(medium.bytes); // 3
|
|
468
|
+
|
|
469
|
+
// Encode into an existing buffer
|
|
470
|
+
const buf = new Uint8Array(9);
|
|
471
|
+
const result = varuint.encode(70000, buf, 0);
|
|
472
|
+
console.log(result.bytes); // 5
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### varuint.decode
|
|
476
|
+
|
|
477
|
+
Decodes a CompactSize variable-length integer from a buffer.
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
function decode(
|
|
481
|
+
buffer: Uint8Array,
|
|
482
|
+
offset?: number,
|
|
483
|
+
): { numberValue: number | null; bigintValue: bigint; bytes: number };
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
Returns an object with `bigintValue` (always present), `numberValue` (null if the value exceeds `Number.MAX_SAFE_INTEGER`), and `bytes` indicating how many bytes were consumed.
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
import { varuint, fromHex } from '@btc-vision/bitcoin';
|
|
490
|
+
|
|
491
|
+
// Decode a single-byte varint
|
|
492
|
+
const small = varuint.decode(fromHex('64'));
|
|
493
|
+
console.log(small.numberValue); // 100
|
|
494
|
+
console.log(small.bytes); // 1
|
|
495
|
+
|
|
496
|
+
// Decode a 3-byte varint
|
|
497
|
+
const medium = varuint.decode(fromHex('fd0302'));
|
|
498
|
+
console.log(medium.numberValue); // 515
|
|
499
|
+
console.log(medium.bytes); // 3
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### varuint.encodingLength
|
|
503
|
+
|
|
504
|
+
Returns the number of bytes required to encode a given value.
|
|
505
|
+
|
|
506
|
+
```typescript
|
|
507
|
+
function encodingLength(n: number | bigint): number;
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
import { varuint } from '@btc-vision/bitcoin';
|
|
512
|
+
|
|
513
|
+
varuint.encodingLength(100); // 1
|
|
514
|
+
varuint.encodingLength(252); // 1
|
|
515
|
+
varuint.encodingLength(253); // 3
|
|
516
|
+
varuint.encodingLength(65535); // 3
|
|
517
|
+
varuint.encodingLength(65536); // 5
|
|
518
|
+
varuint.encodingLength(4294967295); // 5
|
|
519
|
+
varuint.encodingLength(4294967296); // 9
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Class: BinaryReader
|
|
525
|
+
|
|
526
|
+
Stateful binary reader for parsing binary data. Creates exactly one `DataView` instance that is reused for all read operations, eliminating garbage collection pressure.
|
|
527
|
+
|
|
528
|
+
```typescript
|
|
529
|
+
class BinaryReader {
|
|
530
|
+
constructor(data: Uint8Array, offset?: number);
|
|
531
|
+
|
|
532
|
+
// Properties
|
|
533
|
+
get offset(): number;
|
|
534
|
+
set offset(value: number);
|
|
535
|
+
get length(): number;
|
|
536
|
+
get remaining(): number;
|
|
537
|
+
get data(): Uint8Array;
|
|
538
|
+
|
|
539
|
+
// Static factory
|
|
540
|
+
static fromHex(hex: string): BinaryReader;
|
|
541
|
+
|
|
542
|
+
// Integer reads (little-endian)
|
|
543
|
+
readUInt8(): number;
|
|
544
|
+
readInt8(): number;
|
|
545
|
+
readUInt16LE(): number;
|
|
546
|
+
readInt16LE(): number;
|
|
547
|
+
readUInt32LE(): number;
|
|
548
|
+
readInt32LE(): number;
|
|
549
|
+
readUInt64LE(): bigint;
|
|
550
|
+
readInt64LE(): bigint;
|
|
551
|
+
|
|
552
|
+
// Byte reads
|
|
553
|
+
readBytes(length: number): Uint8Array; // returns subarray view (no copy)
|
|
554
|
+
readBytesCopy(length: number): Uint8Array; // returns independent copy
|
|
555
|
+
|
|
556
|
+
// Bitcoin CompactSize reads
|
|
557
|
+
readVarInt(): number;
|
|
558
|
+
readVarIntBig(): bigint;
|
|
559
|
+
readVarBytes(): Uint8Array;
|
|
560
|
+
readVector(): Uint8Array[];
|
|
561
|
+
|
|
562
|
+
// Navigation
|
|
563
|
+
peek(): number | undefined;
|
|
564
|
+
skip(length: number): void;
|
|
565
|
+
reset(): void;
|
|
566
|
+
hasMore(): boolean;
|
|
567
|
+
}
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Properties
|
|
571
|
+
|
|
572
|
+
| Property | Type | Description |
|
|
573
|
+
|----------|------|-------------|
|
|
574
|
+
| `offset` | `number` | Current read position (get/set) |
|
|
575
|
+
| `length` | `number` | Total length of the underlying buffer |
|
|
576
|
+
| `remaining` | `number` | Number of bytes remaining to read |
|
|
577
|
+
| `data` | `Uint8Array` | The underlying data buffer |
|
|
578
|
+
|
|
579
|
+
### Read Methods
|
|
580
|
+
|
|
581
|
+
| Method | Return Type | Description |
|
|
582
|
+
|--------|-------------|-------------|
|
|
583
|
+
| `readUInt8()` | `number` | Reads an 8-bit unsigned integer (0-255) |
|
|
584
|
+
| `readInt8()` | `number` | Reads an 8-bit signed integer (-128 to 127) |
|
|
585
|
+
| `readUInt16LE()` | `number` | Reads a 16-bit unsigned integer, little-endian |
|
|
586
|
+
| `readInt16LE()` | `number` | Reads a 16-bit signed integer, little-endian |
|
|
587
|
+
| `readUInt32LE()` | `number` | Reads a 32-bit unsigned integer, little-endian |
|
|
588
|
+
| `readInt32LE()` | `number` | Reads a 32-bit signed integer, little-endian |
|
|
589
|
+
| `readUInt64LE()` | `bigint` | Reads a 64-bit unsigned integer, little-endian |
|
|
590
|
+
| `readInt64LE()` | `bigint` | Reads a 64-bit signed integer, little-endian |
|
|
591
|
+
| `readBytes(length)` | `Uint8Array` | Reads bytes as a subarray view (no copy) |
|
|
592
|
+
| `readBytesCopy(length)` | `Uint8Array` | Reads bytes as an independent copy |
|
|
593
|
+
| `readVarInt()` | `number` | Reads a Bitcoin CompactSize varint |
|
|
594
|
+
| `readVarIntBig()` | `bigint` | Reads a CompactSize varint as bigint |
|
|
595
|
+
| `readVarBytes()` | `Uint8Array` | Reads a length-prefixed byte array |
|
|
596
|
+
| `readVector()` | `Uint8Array[]` | Reads an array of length-prefixed byte arrays |
|
|
597
|
+
|
|
598
|
+
### Navigation Methods
|
|
599
|
+
|
|
600
|
+
| Method | Return Type | Description |
|
|
601
|
+
|--------|-------------|-------------|
|
|
602
|
+
| `peek()` | `number \| undefined` | Returns next byte without advancing position |
|
|
603
|
+
| `skip(length)` | `void` | Skips specified number of bytes |
|
|
604
|
+
| `reset()` | `void` | Resets read position to beginning |
|
|
605
|
+
| `hasMore()` | `boolean` | Returns true if there are remaining bytes |
|
|
606
|
+
|
|
607
|
+
### Example: Parsing a Bitcoin Transaction
|
|
608
|
+
|
|
609
|
+
```typescript
|
|
610
|
+
import { BinaryReader } from '@btc-vision/bitcoin/io';
|
|
611
|
+
import { fromHex } from '@btc-vision/bitcoin';
|
|
612
|
+
|
|
613
|
+
const rawTx = fromHex('01000000...');
|
|
614
|
+
const reader = new BinaryReader(rawTx);
|
|
615
|
+
|
|
616
|
+
// Read transaction version
|
|
617
|
+
const version = reader.readInt32LE();
|
|
618
|
+
|
|
619
|
+
// Read input count
|
|
620
|
+
const inputCount = reader.readVarInt();
|
|
621
|
+
|
|
622
|
+
for (let i = 0; i < inputCount; i++) {
|
|
623
|
+
const txid = reader.readBytes(32); // Previous tx hash
|
|
624
|
+
const vout = reader.readUInt32LE(); // Previous output index
|
|
625
|
+
const scriptSig = reader.readVarBytes(); // Script signature
|
|
626
|
+
const sequence = reader.readUInt32LE(); // Sequence number
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Read output count
|
|
630
|
+
const outputCount = reader.readVarInt();
|
|
631
|
+
|
|
632
|
+
for (let i = 0; i < outputCount; i++) {
|
|
633
|
+
const value = reader.readUInt64LE(); // Satoshi value
|
|
634
|
+
const scriptPubKey = reader.readVarBytes(); // Output script
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const locktime = reader.readUInt32LE();
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Example: Using fromHex Factory
|
|
641
|
+
|
|
642
|
+
```typescript
|
|
643
|
+
import { BinaryReader } from '@btc-vision/bitcoin/io';
|
|
644
|
+
|
|
645
|
+
const reader = BinaryReader.fromHex('01000000');
|
|
646
|
+
const version = reader.readInt32LE(); // 1
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
### readBytes vs readBytesCopy
|
|
650
|
+
|
|
651
|
+
`readBytes()` returns a subarray view into the underlying buffer for zero-copy performance. If the original data might be modified or if you need to store the result independently, use `readBytesCopy()` instead.
|
|
652
|
+
|
|
653
|
+
```typescript
|
|
654
|
+
const reader = new BinaryReader(data);
|
|
655
|
+
|
|
656
|
+
// Fast: returns a view (shares memory with original)
|
|
657
|
+
const view = reader.readBytes(32);
|
|
658
|
+
|
|
659
|
+
// Safe: returns an independent copy
|
|
660
|
+
const copy = reader.readBytesCopy(32);
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
---
|
|
664
|
+
|
|
665
|
+
## Class: BinaryWriter
|
|
666
|
+
|
|
667
|
+
Stateful binary writer for serializing binary data. Creates exactly one `DataView` instance that is reused for all write operations. All write methods return `this` for method chaining.
|
|
668
|
+
|
|
669
|
+
```typescript
|
|
670
|
+
class BinaryWriter {
|
|
671
|
+
constructor(size: number);
|
|
672
|
+
constructor(buffer: Uint8Array, offset?: number);
|
|
673
|
+
|
|
674
|
+
// Properties
|
|
675
|
+
get offset(): number;
|
|
676
|
+
set offset(value: number);
|
|
677
|
+
get capacity(): number;
|
|
678
|
+
get remaining(): number;
|
|
679
|
+
get data(): Uint8Array;
|
|
680
|
+
|
|
681
|
+
// Static factory
|
|
682
|
+
static growable(initialCapacity?: number): GrowableBinaryWriter;
|
|
683
|
+
|
|
684
|
+
// Integer writes (little-endian)
|
|
685
|
+
writeUInt8(value: number): this;
|
|
686
|
+
writeInt8(value: number): this;
|
|
687
|
+
writeUInt16LE(value: number): this;
|
|
688
|
+
writeInt16LE(value: number): this;
|
|
689
|
+
writeUInt32LE(value: number): this;
|
|
690
|
+
writeInt32LE(value: number): this;
|
|
691
|
+
writeUInt64LE(value: bigint): this;
|
|
692
|
+
writeInt64LE(value: bigint): this;
|
|
693
|
+
|
|
694
|
+
// Byte writes
|
|
695
|
+
writeBytes(bytes: Uint8Array): this;
|
|
696
|
+
|
|
697
|
+
// Bitcoin CompactSize writes
|
|
698
|
+
writeVarInt(value: number): this;
|
|
699
|
+
writeVarIntBig(value: bigint): this;
|
|
700
|
+
writeVarBytes(bytes: Uint8Array): this;
|
|
701
|
+
writeVector(vector: readonly Uint8Array[]): this;
|
|
702
|
+
|
|
703
|
+
// Buffer operations
|
|
704
|
+
fill(value: number, length: number): this;
|
|
705
|
+
skip(length: number): this;
|
|
706
|
+
reset(): this;
|
|
707
|
+
|
|
708
|
+
// Finalization
|
|
709
|
+
end(): Uint8Array;
|
|
710
|
+
finish(): Uint8Array;
|
|
711
|
+
toHex(): string;
|
|
712
|
+
}
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### Properties
|
|
716
|
+
|
|
717
|
+
| Property | Type | Description |
|
|
718
|
+
|----------|------|-------------|
|
|
719
|
+
| `offset` | `number` | Current write position (get/set) |
|
|
720
|
+
| `capacity` | `number` | Total capacity of the underlying buffer |
|
|
721
|
+
| `remaining` | `number` | Number of bytes remaining in the buffer |
|
|
722
|
+
| `data` | `Uint8Array` | The underlying data buffer |
|
|
723
|
+
|
|
724
|
+
### Write Methods
|
|
725
|
+
|
|
726
|
+
| Method | Parameter Type | Description |
|
|
727
|
+
|--------|---------------|-------------|
|
|
728
|
+
| `writeUInt8(value)` | `number` | Writes an 8-bit unsigned integer (0-255) |
|
|
729
|
+
| `writeInt8(value)` | `number` | Writes an 8-bit signed integer (-128 to 127) |
|
|
730
|
+
| `writeUInt16LE(value)` | `number` | Writes a 16-bit unsigned integer, little-endian |
|
|
731
|
+
| `writeInt16LE(value)` | `number` | Writes a 16-bit signed integer, little-endian |
|
|
732
|
+
| `writeUInt32LE(value)` | `number` | Writes a 32-bit unsigned integer, little-endian |
|
|
733
|
+
| `writeInt32LE(value)` | `number` | Writes a 32-bit signed integer, little-endian |
|
|
734
|
+
| `writeUInt64LE(value)` | `bigint` | Writes a 64-bit unsigned integer, little-endian |
|
|
735
|
+
| `writeInt64LE(value)` | `bigint` | Writes a 64-bit signed integer, little-endian |
|
|
736
|
+
| `writeBytes(bytes)` | `Uint8Array` | Writes raw bytes |
|
|
737
|
+
| `writeVarInt(value)` | `number` | Writes a Bitcoin CompactSize varint |
|
|
738
|
+
| `writeVarIntBig(value)` | `bigint` | Writes a CompactSize varint from bigint |
|
|
739
|
+
| `writeVarBytes(bytes)` | `Uint8Array` | Writes a length-prefixed byte array |
|
|
740
|
+
| `writeVector(vector)` | `readonly Uint8Array[]` | Writes an array of length-prefixed byte arrays |
|
|
741
|
+
|
|
742
|
+
### Finalization Methods
|
|
743
|
+
|
|
744
|
+
| Method | Return Type | Description |
|
|
745
|
+
|--------|-------------|-------------|
|
|
746
|
+
| `end()` | `Uint8Array` | Returns the buffer; **throws** `Error` if not fully written |
|
|
747
|
+
| `finish()` | `Uint8Array` | Returns the written portion (subarray if partially written) |
|
|
748
|
+
| `toHex()` | `string` | Returns the written portion as a hex string |
|
|
749
|
+
|
|
750
|
+
### end() vs finish()
|
|
751
|
+
|
|
752
|
+
- `end()` verifies the buffer was **fully** written (offset equals capacity). Throws a plain `Error` (not a typed error subclass) if any bytes remain unwritten. Use this when you know the exact output size.
|
|
753
|
+
- `finish()` returns whatever has been written so far, without verification. Returns a subarray view if the buffer was only partially filled.
|
|
754
|
+
|
|
755
|
+
### Example: Serializing with Fixed Size
|
|
756
|
+
|
|
757
|
+
```typescript
|
|
758
|
+
import { BinaryWriter } from '@btc-vision/bitcoin/io';
|
|
759
|
+
|
|
760
|
+
const writer = new BinaryWriter(16);
|
|
761
|
+
writer
|
|
762
|
+
.writeInt32LE(1) // version
|
|
763
|
+
.writeUInt32LE(0) // input count
|
|
764
|
+
.writeUInt32LE(0) // output count
|
|
765
|
+
.writeUInt32LE(0); // locktime
|
|
766
|
+
|
|
767
|
+
const bytes = writer.end(); // OK: wrote exactly 16 bytes
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
### Example: Method Chaining
|
|
771
|
+
|
|
772
|
+
```typescript
|
|
773
|
+
import { BinaryWriter } from '@btc-vision/bitcoin/io';
|
|
774
|
+
import { fromHex } from '@btc-vision/bitcoin';
|
|
775
|
+
|
|
776
|
+
const writer = new BinaryWriter(100);
|
|
777
|
+
writer
|
|
778
|
+
.writeUInt8(0x01)
|
|
779
|
+
.writeVarBytes(fromHex('deadbeef'))
|
|
780
|
+
.writeUInt32LE(0xffffffff);
|
|
781
|
+
|
|
782
|
+
const result = writer.finish(); // Returns only the written portion
|
|
783
|
+
console.log(writer.toHex());
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
### Example: Writing into an Existing Buffer
|
|
787
|
+
|
|
788
|
+
```typescript
|
|
789
|
+
import { BinaryWriter } from '@btc-vision/bitcoin/io';
|
|
790
|
+
|
|
791
|
+
const buffer = new Uint8Array(1024);
|
|
792
|
+
const writer = new BinaryWriter(buffer, 10); // Start writing at offset 10
|
|
793
|
+
writer.writeUInt32LE(42);
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
---
|
|
797
|
+
|
|
798
|
+
## Class: GrowableBinaryWriter
|
|
799
|
+
|
|
800
|
+
A variant of `BinaryWriter` that automatically grows its internal buffer as needed. Use when the final serialized size is unknown.
|
|
801
|
+
|
|
802
|
+
> **Note:** `GrowableBinaryWriter` provides a subset of `BinaryWriter`'s write methods. The following `BinaryWriter` methods are **not available** on `GrowableBinaryWriter`:
|
|
803
|
+
> - `writeInt8()` -- use `writeUInt8(value & 0xff)` as a workaround
|
|
804
|
+
> - `writeInt16LE()`
|
|
805
|
+
> - `writeInt64LE()`
|
|
806
|
+
> - `writeVarIntBig()`
|
|
807
|
+
> - `fill()`
|
|
808
|
+
> - `skip()`
|
|
809
|
+
> - `reset()`
|
|
810
|
+
> - `end()`
|
|
811
|
+
>
|
|
812
|
+
> The `remaining` and `data` properties are also not available.
|
|
813
|
+
|
|
814
|
+
```typescript
|
|
815
|
+
class GrowableBinaryWriter {
|
|
816
|
+
constructor(initialCapacity?: number);
|
|
817
|
+
|
|
818
|
+
// Properties
|
|
819
|
+
get offset(): number;
|
|
820
|
+
set offset(value: number);
|
|
821
|
+
get capacity(): number;
|
|
822
|
+
|
|
823
|
+
// Write methods (subset of BinaryWriter)
|
|
824
|
+
writeUInt8(value: number): this;
|
|
825
|
+
writeUInt16LE(value: number): this;
|
|
826
|
+
writeUInt32LE(value: number): this;
|
|
827
|
+
writeInt32LE(value: number): this;
|
|
828
|
+
writeUInt64LE(value: bigint): this;
|
|
829
|
+
writeBytes(bytes: Uint8Array): this;
|
|
830
|
+
writeVarInt(value: number): this;
|
|
831
|
+
writeVarBytes(bytes: Uint8Array): this;
|
|
832
|
+
writeVector(vector: readonly Uint8Array[]): this;
|
|
833
|
+
|
|
834
|
+
// Finalization
|
|
835
|
+
finish(): Uint8Array;
|
|
836
|
+
toHex(): string;
|
|
837
|
+
}
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
The buffer starts at the given initial capacity (default 256 bytes) and doubles in size whenever more space is needed.
|
|
841
|
+
|
|
842
|
+
### Example: Dynamic Serialization
|
|
843
|
+
|
|
844
|
+
```typescript
|
|
845
|
+
import { BinaryWriter } from '@btc-vision/bitcoin/io';
|
|
846
|
+
import { fromHex } from '@btc-vision/bitcoin';
|
|
847
|
+
|
|
848
|
+
const writer = BinaryWriter.growable();
|
|
849
|
+
|
|
850
|
+
// Write variable amounts of data without worrying about buffer size
|
|
851
|
+
writer.writeUInt32LE(1);
|
|
852
|
+
writer.writeBytes(fromHex('aa'.repeat(500))); // Automatically grows
|
|
853
|
+
writer.writeVarInt(1000);
|
|
854
|
+
|
|
855
|
+
const result = writer.finish(); // Returns a copy of exactly the written bytes
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
---
|
|
859
|
+
|
|
860
|
+
## Common Patterns
|
|
861
|
+
|
|
862
|
+
### Round-Trip Encoding
|
|
863
|
+
|
|
864
|
+
```typescript
|
|
865
|
+
import { toHex, fromHex, toBase64, fromBase64 } from '@btc-vision/bitcoin';
|
|
866
|
+
|
|
867
|
+
const original = new Uint8Array([1, 2, 3, 4]);
|
|
868
|
+
|
|
869
|
+
// Hex round-trip
|
|
870
|
+
const hex = toHex(original);
|
|
871
|
+
const fromHexBytes = fromHex(hex);
|
|
872
|
+
|
|
873
|
+
// Base64 round-trip
|
|
874
|
+
const b64 = toBase64(original);
|
|
875
|
+
const fromB64Bytes = fromBase64(b64);
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
### Bitcoin Transaction ID (Reversed Hash Display)
|
|
879
|
+
|
|
880
|
+
```typescript
|
|
881
|
+
import { reverseCopy, toHex } from '@btc-vision/bitcoin';
|
|
882
|
+
|
|
883
|
+
// Bitcoin displays transaction hashes in reversed byte order
|
|
884
|
+
const txHashInternal = /* 32-byte hash from double-SHA256 */;
|
|
885
|
+
const txid = toHex(reverseCopy(txHashInternal));
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
### Building and Parsing a Length-Prefixed Message
|
|
889
|
+
|
|
890
|
+
```typescript
|
|
891
|
+
import { BinaryWriter, BinaryReader } from '@btc-vision/bitcoin/io';
|
|
892
|
+
import { fromHex } from '@btc-vision/bitcoin';
|
|
893
|
+
|
|
894
|
+
// Write
|
|
895
|
+
const writer = BinaryWriter.growable();
|
|
896
|
+
const payload = fromHex('deadbeefcafebabe');
|
|
897
|
+
writer.writeVarBytes(payload);
|
|
898
|
+
const serialized = writer.finish();
|
|
899
|
+
|
|
900
|
+
// Read
|
|
901
|
+
const reader = new BinaryReader(serialized);
|
|
902
|
+
const decoded = reader.readVarBytes();
|
|
903
|
+
// decoded contains deadbeefcafebabe
|
|
904
|
+
```
|
|
905
|
+
|
|
906
|
+
### Witness Vector Serialization
|
|
907
|
+
|
|
908
|
+
```typescript
|
|
909
|
+
import { BinaryWriter, BinaryReader } from '@btc-vision/bitcoin/io';
|
|
910
|
+
import { fromHex } from '@btc-vision/bitcoin';
|
|
911
|
+
|
|
912
|
+
// Write a witness stack
|
|
913
|
+
const witnessItems = [
|
|
914
|
+
fromHex('3045022100...'), // signature
|
|
915
|
+
fromHex('0279be667e...'), // public key
|
|
916
|
+
];
|
|
917
|
+
|
|
918
|
+
const writer = BinaryWriter.growable();
|
|
919
|
+
writer.writeVector(witnessItems);
|
|
920
|
+
const serialized = writer.finish();
|
|
921
|
+
|
|
922
|
+
// Read it back
|
|
923
|
+
const reader = new BinaryReader(serialized);
|
|
924
|
+
const decoded = reader.readVector();
|
|
925
|
+
// decoded[0] = signature, decoded[1] = public key
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
### Buffer Comparison for Sorting
|
|
929
|
+
|
|
930
|
+
```typescript
|
|
931
|
+
import { compare, fromHex } from '@btc-vision/bitcoin';
|
|
932
|
+
|
|
933
|
+
const hashes = [
|
|
934
|
+
fromHex('ff00'),
|
|
935
|
+
fromHex('0001'),
|
|
936
|
+
fromHex('aa00'),
|
|
937
|
+
];
|
|
938
|
+
|
|
939
|
+
// Sort in lexicographic order
|
|
940
|
+
hashes.sort(compare);
|
|
941
|
+
// Result: [0001, aa00, ff00]
|
|
942
|
+
```
|