@btc-vision/bitcoin 7.0.0-alpha.0 → 7.0.0-alpha.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.
- package/browser/address.d.ts +6 -2
- package/browser/address.d.ts.map +1 -1
- package/browser/block.d.ts.map +1 -1
- package/browser/branded.d.ts +3 -14
- package/browser/branded.d.ts.map +1 -1
- package/browser/crypto.d.ts +1 -1
- package/browser/ecc/context.d.ts +4 -4
- package/browser/ecc/context.d.ts.map +1 -1
- package/browser/ecc/types.d.ts +1 -1
- package/browser/ecc/types.d.ts.map +1 -1
- package/browser/index.d.ts +3 -2
- package/browser/index.d.ts.map +1 -1
- package/browser/index.js +3579 -3539
- package/browser/io/BinaryReader.d.ts +15 -15
- package/browser/io/BinaryReader.d.ts.map +1 -1
- package/browser/io/BinaryWriter.d.ts +17 -17
- package/browser/io/BinaryWriter.d.ts.map +1 -1
- package/browser/io/MemoryPool.d.ts +20 -20
- package/browser/io/MemoryPool.d.ts.map +1 -1
- package/browser/opcodes.d.ts +11 -0
- package/browser/opcodes.d.ts.map +1 -1
- package/browser/payments/bip341.d.ts +1 -1
- package/browser/payments/bip341.d.ts.map +1 -1
- package/browser/payments/embed.d.ts +1 -1
- package/browser/payments/embed.d.ts.map +1 -1
- package/browser/payments/p2ms.d.ts.map +1 -1
- package/browser/payments/p2op.d.ts +1 -1
- package/browser/payments/p2op.d.ts.map +1 -1
- package/browser/payments/p2pk.d.ts +1 -1
- package/browser/payments/p2pk.d.ts.map +1 -1
- package/browser/payments/p2pkh.d.ts +1 -1
- package/browser/payments/p2pkh.d.ts.map +1 -1
- package/browser/payments/p2sh.d.ts.map +1 -1
- package/browser/payments/p2tr.d.ts +2 -2
- package/browser/payments/p2tr.d.ts.map +1 -1
- package/browser/payments/p2wpkh.d.ts +1 -1
- package/browser/payments/p2wpkh.d.ts.map +1 -1
- package/browser/payments/p2wsh.d.ts.map +1 -1
- package/browser/payments/types.d.ts +1 -1
- package/browser/payments/types.d.ts.map +1 -1
- package/browser/psbt/PsbtCache.d.ts +54 -0
- package/browser/psbt/PsbtCache.d.ts.map +1 -0
- package/browser/psbt/PsbtFinalizer.d.ts +21 -0
- package/browser/psbt/PsbtFinalizer.d.ts.map +1 -0
- package/browser/psbt/PsbtSigner.d.ts +32 -0
- package/browser/psbt/PsbtSigner.d.ts.map +1 -0
- package/browser/psbt/PsbtTransaction.d.ts +25 -0
- package/browser/psbt/PsbtTransaction.d.ts.map +1 -0
- package/browser/psbt/bip371.d.ts.map +1 -1
- package/browser/psbt/types.d.ts +14 -14
- package/browser/psbt/types.d.ts.map +1 -1
- package/browser/psbt/validation.d.ts +1 -1
- package/browser/psbt/validation.d.ts.map +1 -1
- package/browser/psbt.d.ts +27 -39
- package/browser/psbt.d.ts.map +1 -1
- package/browser/script.d.ts.map +1 -1
- package/browser/transaction.d.ts +4 -4
- package/browser/transaction.d.ts.map +1 -1
- package/browser/types.d.ts +4 -2
- package/browser/types.d.ts.map +1 -1
- package/browser/workers/WorkerSigningPool.d.ts +17 -17
- package/browser/workers/WorkerSigningPool.d.ts.map +1 -1
- package/browser/workers/WorkerSigningPool.node.d.ts +12 -12
- package/browser/workers/WorkerSigningPool.node.d.ts.map +1 -1
- package/browser/workers/index.d.ts +3 -50
- package/browser/workers/index.d.ts.map +1 -1
- package/browser/workers/index.node.d.ts +24 -0
- package/browser/workers/index.node.d.ts.map +1 -0
- package/browser/workers/psbt-parallel.d.ts +1 -1
- package/browser/workers/psbt-parallel.d.ts.map +1 -1
- package/browser/workers/types.d.ts.map +1 -1
- package/build/address.d.ts +6 -2
- package/build/address.d.ts.map +1 -1
- package/build/address.js +32 -19
- package/build/address.js.map +1 -1
- package/build/block.d.ts.map +1 -1
- package/build/block.js +2 -4
- package/build/block.js.map +1 -1
- package/build/branded.d.ts +3 -14
- package/build/branded.d.ts.map +1 -1
- package/build/branded.js +0 -5
- package/build/branded.js.map +1 -1
- package/build/crypto.d.ts +1 -1
- package/build/ecc/context.d.ts +4 -4
- package/build/ecc/context.d.ts.map +1 -1
- package/build/ecc/context.js +75 -52
- package/build/ecc/context.js.map +1 -1
- package/build/ecc/types.d.ts +1 -1
- package/build/ecc/types.d.ts.map +1 -1
- package/build/index.d.ts +3 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -3
- package/build/index.js.map +1 -1
- package/build/io/BinaryReader.d.ts +15 -15
- package/build/io/BinaryReader.d.ts.map +1 -1
- package/build/io/BinaryReader.js +17 -17
- package/build/io/BinaryReader.js.map +1 -1
- package/build/io/BinaryWriter.d.ts +17 -17
- package/build/io/BinaryWriter.d.ts.map +1 -1
- package/build/io/BinaryWriter.js +39 -39
- package/build/io/BinaryWriter.js.map +1 -1
- package/build/io/MemoryPool.d.ts +20 -20
- package/build/io/MemoryPool.d.ts.map +1 -1
- package/build/io/MemoryPool.js +28 -28
- package/build/io/MemoryPool.js.map +1 -1
- package/build/opcodes.d.ts +11 -0
- package/build/opcodes.d.ts.map +1 -1
- package/build/opcodes.js +19 -4
- package/build/opcodes.js.map +1 -1
- package/build/payments/bip341.d.ts +1 -2
- package/build/payments/bip341.d.ts.map +1 -1
- package/build/payments/bip341.js +1 -2
- package/build/payments/bip341.js.map +1 -1
- package/build/payments/embed.d.ts +1 -1
- package/build/payments/embed.d.ts.map +1 -1
- package/build/payments/embed.js +14 -14
- package/build/payments/embed.js.map +1 -1
- package/build/payments/p2ms.d.ts.map +1 -1
- package/build/payments/p2ms.js +21 -21
- package/build/payments/p2ms.js.map +1 -1
- package/build/payments/p2op.d.ts +1 -1
- package/build/payments/p2op.d.ts.map +1 -1
- package/build/payments/p2op.js +18 -18
- package/build/payments/p2op.js.map +1 -1
- package/build/payments/p2pk.d.ts +1 -1
- package/build/payments/p2pk.d.ts.map +1 -1
- package/build/payments/p2pk.js +17 -17
- package/build/payments/p2pk.js.map +1 -1
- package/build/payments/p2pkh.d.ts +1 -1
- package/build/payments/p2pkh.d.ts.map +1 -1
- package/build/payments/p2pkh.js +20 -20
- package/build/payments/p2pkh.js.map +1 -1
- package/build/payments/p2sh.d.ts.map +1 -1
- package/build/payments/p2sh.js +22 -20
- package/build/payments/p2sh.js.map +1 -1
- package/build/payments/p2tr.d.ts +2 -2
- package/build/payments/p2tr.d.ts.map +1 -1
- package/build/payments/p2tr.js +23 -23
- package/build/payments/p2tr.js.map +1 -1
- package/build/payments/p2wpkh.d.ts +1 -1
- package/build/payments/p2wpkh.d.ts.map +1 -1
- package/build/payments/p2wpkh.js +20 -20
- package/build/payments/p2wpkh.js.map +1 -1
- package/build/payments/p2wsh.d.ts.map +1 -1
- package/build/payments/p2wsh.js +22 -22
- package/build/payments/p2wsh.js.map +1 -1
- package/build/payments/types.d.ts +1 -1
- package/build/payments/types.d.ts.map +1 -1
- package/build/psbt/PsbtCache.d.ts +54 -0
- package/build/psbt/PsbtCache.d.ts.map +1 -0
- package/build/psbt/PsbtCache.js +249 -0
- package/build/psbt/PsbtCache.js.map +1 -0
- package/build/psbt/PsbtFinalizer.d.ts +21 -0
- package/build/psbt/PsbtFinalizer.d.ts.map +1 -0
- package/build/psbt/PsbtFinalizer.js +157 -0
- package/build/psbt/PsbtFinalizer.js.map +1 -0
- package/build/psbt/PsbtSigner.d.ts +32 -0
- package/build/psbt/PsbtSigner.d.ts.map +1 -0
- package/build/psbt/PsbtSigner.js +192 -0
- package/build/psbt/PsbtSigner.js.map +1 -0
- package/build/psbt/PsbtTransaction.d.ts +25 -0
- package/build/psbt/PsbtTransaction.d.ts.map +1 -0
- package/build/psbt/PsbtTransaction.js +61 -0
- package/build/psbt/PsbtTransaction.js.map +1 -0
- package/build/psbt/bip371.d.ts.map +1 -1
- package/build/psbt/bip371.js +6 -2
- package/build/psbt/bip371.js.map +1 -1
- package/build/psbt/psbtutils.js +1 -1
- package/build/psbt/psbtutils.js.map +1 -1
- package/build/psbt/types.d.ts +14 -14
- package/build/psbt/types.d.ts.map +1 -1
- package/build/psbt/validation.d.ts +1 -1
- package/build/psbt/validation.d.ts.map +1 -1
- package/build/psbt/validation.js +1 -1
- package/build/psbt/validation.js.map +1 -1
- package/build/psbt.d.ts +27 -39
- package/build/psbt.d.ts.map +1 -1
- package/build/psbt.js +142 -755
- package/build/psbt.js.map +1 -1
- package/build/script.d.ts.map +1 -1
- package/build/script.js +4 -4
- package/build/script.js.map +1 -1
- package/build/transaction.d.ts +4 -4
- package/build/transaction.d.ts.map +1 -1
- package/build/transaction.js +6 -5
- package/build/transaction.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/build/types.d.ts +4 -2
- package/build/types.d.ts.map +1 -1
- package/build/types.js +12 -9
- package/build/types.js.map +1 -1
- package/build/workers/WorkerSigningPool.d.ts +17 -17
- package/build/workers/WorkerSigningPool.d.ts.map +1 -1
- package/build/workers/WorkerSigningPool.js +25 -25
- package/build/workers/WorkerSigningPool.js.map +1 -1
- package/build/workers/WorkerSigningPool.node.d.ts +12 -12
- package/build/workers/WorkerSigningPool.node.d.ts.map +1 -1
- package/build/workers/WorkerSigningPool.node.js +23 -23
- package/build/workers/WorkerSigningPool.node.js.map +1 -1
- package/build/workers/index.d.ts +3 -3
- package/build/workers/index.d.ts.map +1 -1
- package/build/workers/index.js +0 -3
- package/build/workers/index.js.map +1 -1
- package/build/workers/index.node.d.ts +24 -0
- package/build/workers/index.node.d.ts.map +1 -0
- package/build/workers/index.node.js +26 -0
- package/build/workers/index.node.js.map +1 -0
- package/build/workers/psbt-parallel.d.ts +1 -1
- package/build/workers/psbt-parallel.d.ts.map +1 -1
- package/build/workers/psbt-parallel.js.map +1 -1
- package/build/workers/types.d.ts.map +1 -1
- package/build/workers/types.js.map +1 -1
- package/package.json +30 -10
- package/src/address.ts +53 -21
- package/src/block.ts +15 -8
- package/src/branded.ts +15 -13
- package/src/crypto.ts +1 -1
- package/src/ecc/context.ts +85 -64
- package/src/ecc/types.ts +1 -8
- package/src/index.ts +48 -14
- package/src/io/BinaryReader.ts +18 -18
- package/src/io/BinaryWriter.ts +43 -43
- package/src/io/MemoryPool.ts +32 -32
- package/src/opcodes.ts +21 -4
- package/src/payments/bip341.ts +2 -4
- package/src/payments/embed.ts +18 -18
- package/src/payments/p2ms.ts +32 -25
- package/src/payments/p2op.ts +22 -22
- package/src/payments/p2pk.ts +20 -20
- package/src/payments/p2pkh.ts +25 -25
- package/src/payments/p2sh.ts +30 -27
- package/src/payments/p2tr.ts +31 -31
- package/src/payments/p2wpkh.ts +25 -25
- package/src/payments/p2wsh.ts +27 -27
- package/src/payments/types.ts +1 -1
- package/src/psbt/PsbtCache.ts +325 -0
- package/src/psbt/PsbtFinalizer.ts +213 -0
- package/src/psbt/PsbtSigner.ts +302 -0
- package/src/psbt/PsbtTransaction.ts +82 -0
- package/src/psbt/bip371.ts +7 -3
- package/src/psbt/psbtutils.ts +1 -1
- package/src/psbt/types.ts +14 -21
- package/src/psbt/validation.ts +5 -12
- package/src/psbt.ts +363 -1130
- package/src/script.ts +6 -9
- package/src/transaction.ts +18 -14
- package/src/types.ts +28 -17
- package/src/workers/WorkerSigningPool.node.ts +31 -31
- package/src/workers/WorkerSigningPool.ts +35 -39
- package/src/workers/index.node.ts +27 -0
- package/src/workers/index.ts +7 -9
- package/src/workers/psbt-parallel.ts +2 -7
- package/src/workers/types.ts +5 -1
- package/test/address.spec.ts +2 -2
- package/test/bitcoin.core.spec.ts +5 -2
- package/test/browser/payments.spec.ts +151 -0
- package/test/browser/psbt.spec.ts +1510 -0
- package/test/browser/script.spec.ts +223 -0
- package/test/browser/setup.ts +13 -0
- package/test/browser/workers-signing.spec.ts +537 -0
- package/test/crypto.spec.ts +2 -2
- package/test/fixtures/core/base58_encode_decode.json +12 -48
- package/test/fixtures/core/base58_keys_invalid.json +50 -150
- package/test/fixtures/core/sighash.json +1 -3
- package/test/fixtures/core/tx_valid.json +133 -501
- package/test/fixtures/embed.json +3 -11
- package/test/fixtures/p2ms.json +21 -91
- package/test/fixtures/p2pk.json +5 -24
- package/test/fixtures/p2pkh.json +7 -36
- package/test/fixtures/p2sh.json +8 -54
- package/test/fixtures/p2tr.json +2 -6
- package/test/fixtures/p2wpkh.json +7 -36
- package/test/fixtures/p2wsh.json +14 -59
- package/test/fixtures/psbt.json +2 -6
- package/test/fixtures/script.json +12 -48
- package/test/integration/addresses.spec.ts +11 -5
- package/test/integration/bip32.spec.ts +1 -1
- package/test/integration/cltv.spec.ts +10 -6
- package/test/integration/csv.spec.ts +10 -9
- package/test/integration/payments.spec.ts +8 -4
- package/test/integration/taproot.spec.ts +26 -6
- package/test/integration/transactions.spec.ts +22 -8
- package/test/payments.spec.ts +1 -1
- package/test/payments.utils.ts +1 -1
- package/test/psbt.spec.ts +250 -64
- package/test/script_signature.spec.ts +1 -1
- package/test/transaction.spec.ts +18 -5
- package/test/tsconfig.json +6 -20
- package/test/workers-pool.spec.ts +22 -23
- package/test/workers-signing.spec.ts +7 -3
- package/test/workers.spec.ts +6 -7
- package/typedoc.json +39 -0
- package/vitest.config.browser.ts +68 -0
- package/browser/ecpair.d.ts +0 -99
- package/src/ecpair.d.ts +0 -99
- package/test/taproot-cache.spec.ts +0 -694
package/src/address.ts
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { bech32, bech32m } from 'bech32';
|
|
11
11
|
import * as bs58check from 'bs58check';
|
|
12
|
-
import {
|
|
12
|
+
import { type Bech32Result, fromBech32 } from './bech32utils.js';
|
|
13
13
|
import { alloc } from './io/index.js';
|
|
14
|
-
import * as networks from './networks.js';
|
|
15
14
|
import type { Network } from './networks.js';
|
|
15
|
+
import * as networks from './networks.js';
|
|
16
16
|
import { p2op } from './payments/p2op.js';
|
|
17
17
|
import { p2pkh } from './payments/p2pkh.js';
|
|
18
18
|
import { p2sh } from './payments/p2sh.js';
|
|
@@ -21,7 +21,14 @@ import { p2wpkh } from './payments/p2wpkh.js';
|
|
|
21
21
|
import { p2wsh } from './payments/p2wsh.js';
|
|
22
22
|
import * as bscript from './script.js';
|
|
23
23
|
import { opcodes } from './script.js';
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
type Bytes20,
|
|
26
|
+
isBytes20,
|
|
27
|
+
isUInt8,
|
|
28
|
+
toBytes20,
|
|
29
|
+
toBytes32,
|
|
30
|
+
type XOnlyPublicKey,
|
|
31
|
+
} from './types.js';
|
|
25
32
|
|
|
26
33
|
export { fromBech32, type Bech32Result };
|
|
27
34
|
|
|
@@ -180,27 +187,51 @@ export function toBech32(
|
|
|
180
187
|
}
|
|
181
188
|
|
|
182
189
|
/**
|
|
183
|
-
* decode address from output script with network, return address if matched
|
|
190
|
+
* decode address from output script with network, return address if matched.
|
|
191
|
+
*
|
|
192
|
+
* Uses fast byte-pattern matching for common script types (P2PKH, P2SH,
|
|
193
|
+
* P2WPKH, P2WSH, P2TR) to avoid constructing payment objects and catching
|
|
194
|
+
* exceptions. Falls back to payment constructors for exotic types.
|
|
184
195
|
*/
|
|
185
196
|
export function fromOutputScript(output: Uint8Array, network?: Network): string {
|
|
186
|
-
// TODO: Network
|
|
187
197
|
network = network || networks.bitcoin;
|
|
198
|
+
const len = output.length;
|
|
199
|
+
|
|
200
|
+
// P2PKH: OP_DUP(0x76) OP_HASH160(0xa9) 0x14 <20-byte hash> OP_EQUALVERIFY(0x88) OP_CHECKSIG(0xac)
|
|
201
|
+
if (
|
|
202
|
+
len === 25 &&
|
|
203
|
+
output[0] === 0x76 &&
|
|
204
|
+
output[1] === 0xa9 &&
|
|
205
|
+
output[2] === 0x14 &&
|
|
206
|
+
output[23] === 0x88 &&
|
|
207
|
+
output[24] === 0xac
|
|
208
|
+
) {
|
|
209
|
+
return toBase58Check(output.subarray(3, 23) as Bytes20, network.pubKeyHash);
|
|
210
|
+
}
|
|
188
211
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
return
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
212
|
+
// P2SH: OP_HASH160(0xa9) 0x14 <20-byte hash> OP_EQUAL(0x87)
|
|
213
|
+
if (len === 23 && output[0] === 0xa9 && output[1] === 0x14 && output[22] === 0x87) {
|
|
214
|
+
return toBase58Check(output.subarray(2, 22) as Bytes20, network.scriptHash);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// P2WPKH: OP_0(0x00) 0x14 <20-byte hash>
|
|
218
|
+
if (len === 22 && output[0] === 0x00 && output[1] === 0x14) {
|
|
219
|
+
return toBech32(output.subarray(2, 22), 0, network.bech32);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// P2WSH: OP_0(0x00) 0x20 <32-byte hash>
|
|
223
|
+
if (len === 34 && output[0] === 0x00 && output[1] === 0x20) {
|
|
224
|
+
return toBech32(output.subarray(2, 34), 0, network.bech32);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// P2TR: OP_1(0x51) 0x20 <32-byte x-only pubkey>
|
|
228
|
+
if (len === 34 && output[0] === 0x51 && output[1] === 0x20) {
|
|
229
|
+
const words = bech32m.toWords(output.subarray(2, 34));
|
|
230
|
+
words.unshift(1);
|
|
231
|
+
return bech32m.encode(network.bech32, words);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Fallback for exotic types
|
|
204
235
|
try {
|
|
205
236
|
return toFutureOPNetAddress(output, network);
|
|
206
237
|
} catch (e) {}
|
|
@@ -282,7 +313,8 @@ export function toOutputScript(
|
|
|
282
313
|
return p2wsh({ hash: toBytes32(decodeBech32.data) }).output as Uint8Array;
|
|
283
314
|
} else if (decodeBech32.version === 1) {
|
|
284
315
|
if (decodeBech32.data.length === 32)
|
|
285
|
-
return p2tr({ pubkey: decodeBech32.data as XOnlyPublicKey })
|
|
316
|
+
return p2tr({ pubkey: decodeBech32.data as XOnlyPublicKey })
|
|
317
|
+
.output as Uint8Array;
|
|
286
318
|
} else if (decodeBech32.version === FUTURE_OPNET_VERSION) {
|
|
287
319
|
if (!network.bech32Opnet) throw new Error(address + ' has an invalid prefix');
|
|
288
320
|
return p2op({
|
package/src/block.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import * as bcrypto from './crypto.js';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
alloc,
|
|
4
|
+
BinaryReader,
|
|
5
|
+
BinaryWriter,
|
|
6
|
+
compare,
|
|
7
|
+
equals,
|
|
8
|
+
fromHex,
|
|
9
|
+
reverse,
|
|
10
|
+
toHex,
|
|
11
|
+
varuint,
|
|
12
|
+
} from './io/index.js';
|
|
3
13
|
import { fastMerkleRoot } from './merkle.js';
|
|
4
14
|
import { Transaction } from './transaction.js';
|
|
5
15
|
import type { Bytes32 } from './types.js';
|
|
@@ -70,10 +80,7 @@ export class Block {
|
|
|
70
80
|
if (buffer.length === 80) return block;
|
|
71
81
|
|
|
72
82
|
const readTransaction = (): Transaction => {
|
|
73
|
-
const tx = Transaction.fromBuffer(
|
|
74
|
-
reader.data.subarray(reader.offset),
|
|
75
|
-
true,
|
|
76
|
-
);
|
|
83
|
+
const tx = Transaction.fromBuffer(reader.data.subarray(reader.offset), true);
|
|
77
84
|
reader.offset += tx.byteLength();
|
|
78
85
|
return tx;
|
|
79
86
|
};
|
|
@@ -158,9 +165,9 @@ export class Block {
|
|
|
158
165
|
// There is no rule for the index of the output, so use filter to find it.
|
|
159
166
|
// The root is prepended with 0xaa21a9ed so check for 0x6a24aa21a9ed
|
|
160
167
|
// If multiple commits are found, the output with highest index is assumed.
|
|
161
|
-
const witnessCommits = this.transactions[0]!.outs
|
|
162
|
-
|
|
163
|
-
|
|
168
|
+
const witnessCommits = this.transactions[0]!.outs.filter((out) =>
|
|
169
|
+
equals(out.script.subarray(0, 6), WITNESS_COMMIT_PREFIX),
|
|
170
|
+
).map((out) => out.script.subarray(6, 38));
|
|
164
171
|
if (witnessCommits.length === 0) return null;
|
|
165
172
|
// Use the commit with the highest output (should only be one though)
|
|
166
173
|
const result = witnessCommits[witnessCommits.length - 1];
|
package/src/branded.ts
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Branded type definitions for type-safe primitives.
|
|
3
3
|
*
|
|
4
|
+
* Re-exported from @btc-vision/ecpair to ensure cross-package type compatibility.
|
|
5
|
+
*
|
|
4
6
|
* @packageDocumentation
|
|
5
7
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
export type {
|
|
9
|
+
Brand,
|
|
10
|
+
Bytes32,
|
|
11
|
+
Bytes20,
|
|
12
|
+
PublicKey,
|
|
13
|
+
XOnlyPublicKey,
|
|
14
|
+
Satoshi,
|
|
15
|
+
PrivateKey,
|
|
16
|
+
Signature,
|
|
17
|
+
SchnorrSignature,
|
|
18
|
+
MessageHash,
|
|
19
|
+
Script,
|
|
20
|
+
} from '@btc-vision/ecpair';
|
package/src/crypto.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { ripemd160 as _ripemd160, sha1 as _sha1 } from '@noble/hashes/legacy.js';
|
|
8
8
|
import { sha256 as _sha256 } from '@noble/hashes/sha2.js';
|
|
9
9
|
import { concat } from './io/index.js';
|
|
10
|
-
import type {
|
|
10
|
+
import type { Bytes20, Bytes32 } from './types.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Computes RIPEMD-160 hash of the input.
|
package/src/ecc/context.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @packageDocumentation
|
|
6
6
|
*/
|
|
7
7
|
import type { EccLib } from './types.js';
|
|
8
|
-
import {
|
|
8
|
+
import { equals, fromHex } from '../io/index.js';
|
|
9
9
|
import type { Bytes32, XOnlyPublicKey } from '../types.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -35,6 +35,13 @@ export class EccContext {
|
|
|
35
35
|
this.#lib = lib;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* The underlying ECC library instance.
|
|
40
|
+
*/
|
|
41
|
+
get lib(): EccLib {
|
|
42
|
+
return this.#lib;
|
|
43
|
+
}
|
|
44
|
+
|
|
38
45
|
/**
|
|
39
46
|
* Initializes the ECC context with the provided library.
|
|
40
47
|
* The library is verified before being set as active.
|
|
@@ -52,6 +59,10 @@ export class EccContext {
|
|
|
52
59
|
* ```
|
|
53
60
|
*/
|
|
54
61
|
static init(lib: EccLib): EccContext {
|
|
62
|
+
// Skip re-verification if same lib is already initialized
|
|
63
|
+
if (EccContext.#instance && EccContext.#instance.#lib === lib) {
|
|
64
|
+
return EccContext.#instance;
|
|
65
|
+
}
|
|
55
66
|
verifyEcc(lib);
|
|
56
67
|
EccContext.#instance = new EccContext(lib);
|
|
57
68
|
return EccContext.#instance;
|
|
@@ -113,13 +124,6 @@ export class EccContext {
|
|
|
113
124
|
static isInitialized(): boolean {
|
|
114
125
|
return EccContext.#instance !== undefined;
|
|
115
126
|
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* The underlying ECC library instance.
|
|
119
|
-
*/
|
|
120
|
-
get lib(): EccLib {
|
|
121
|
-
return this.#lib;
|
|
122
|
-
}
|
|
123
127
|
}
|
|
124
128
|
|
|
125
129
|
/**
|
|
@@ -177,32 +181,64 @@ export function getEccLib(): EccLib {
|
|
|
177
181
|
// ============================================================================
|
|
178
182
|
|
|
179
183
|
interface TweakAddVector {
|
|
180
|
-
pubkey:
|
|
181
|
-
tweak:
|
|
184
|
+
pubkey: Uint8Array;
|
|
185
|
+
tweak: Uint8Array;
|
|
182
186
|
parity: 0 | 1 | -1;
|
|
183
|
-
result:
|
|
187
|
+
result: Uint8Array | null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Lazily decoded test vectors (decoded once on first verification)
|
|
191
|
+
let _tweakVectors: TweakAddVector[] | undefined;
|
|
192
|
+
let _validPoints: Uint8Array[] | undefined;
|
|
193
|
+
let _invalidPoints: Uint8Array[] | undefined;
|
|
194
|
+
|
|
195
|
+
function getTweakVectors(): TweakAddVector[] {
|
|
196
|
+
if (!_tweakVectors) {
|
|
197
|
+
_tweakVectors = [
|
|
198
|
+
{
|
|
199
|
+
pubkey: fromHex('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
|
|
200
|
+
tweak: fromHex('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'),
|
|
201
|
+
parity: -1,
|
|
202
|
+
result: null,
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
pubkey: fromHex('1617d38ed8d8657da4d4761e8057bc396ea9e4b9d29776d4be096016dbd2509b'),
|
|
206
|
+
tweak: fromHex('a8397a935f0dfceba6ba9618f6451ef4d80637abf4e6af2669fbc9de6a8fd2ac'),
|
|
207
|
+
parity: 1,
|
|
208
|
+
result: fromHex('e478f99dab91052ab39a33ea35fd5e6e4933f4d28023cd597c9a1f6760346adf'),
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
pubkey: fromHex('2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991'),
|
|
212
|
+
tweak: fromHex('823c3cd2142744b075a87eade7e1b8678ba308d566226a0056ca2b7a76f86b47'),
|
|
213
|
+
parity: 0,
|
|
214
|
+
result: fromHex('9534f8dc8c6deda2dc007655981c78b49c5d96c778fbf363462a11ec9dfd948c'),
|
|
215
|
+
},
|
|
216
|
+
];
|
|
217
|
+
}
|
|
218
|
+
return _tweakVectors;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function getValidPoints(): Uint8Array[] {
|
|
222
|
+
if (!_validPoints) {
|
|
223
|
+
_validPoints = [
|
|
224
|
+
fromHex('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
|
|
225
|
+
fromHex('fffffffffffffffffffffffffffffffffffffffffffffffffffffffeeffffc2e'),
|
|
226
|
+
fromHex('f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9'),
|
|
227
|
+
fromHex('0000000000000000000000000000000000000000000000000000000000000001'),
|
|
228
|
+
];
|
|
229
|
+
}
|
|
230
|
+
return _validPoints;
|
|
184
231
|
}
|
|
185
232
|
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
tweak: 'a8397a935f0dfceba6ba9618f6451ef4d80637abf4e6af2669fbc9de6a8fd2ac',
|
|
196
|
-
parity: 1,
|
|
197
|
-
result: 'e478f99dab91052ab39a33ea35fd5e6e4933f4d28023cd597c9a1f6760346adf',
|
|
198
|
-
},
|
|
199
|
-
{
|
|
200
|
-
pubkey: '2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991',
|
|
201
|
-
tweak: '823c3cd2142744b075a87eade7e1b8678ba308d566226a0056ca2b7a76f86b47',
|
|
202
|
-
parity: 0,
|
|
203
|
-
result: '9534f8dc8c6deda2dc007655981c78b49c5d96c778fbf363462a11ec9dfd948c',
|
|
204
|
-
},
|
|
205
|
-
];
|
|
233
|
+
function getInvalidPoints(): Uint8Array[] {
|
|
234
|
+
if (!_invalidPoints) {
|
|
235
|
+
_invalidPoints = [
|
|
236
|
+
fromHex('0000000000000000000000000000000000000000000000000000000000000000'),
|
|
237
|
+
fromHex('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'),
|
|
238
|
+
];
|
|
239
|
+
}
|
|
240
|
+
return _invalidPoints;
|
|
241
|
+
}
|
|
206
242
|
|
|
207
243
|
/**
|
|
208
244
|
* Verifies that the ECC library implementation is correct.
|
|
@@ -216,29 +252,17 @@ function verifyEcc(ecc: EccLib): void {
|
|
|
216
252
|
throw new Error('ECC library missing isXOnlyPoint function');
|
|
217
253
|
}
|
|
218
254
|
|
|
219
|
-
// Test isXOnlyPoint with valid points
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
|
|
224
|
-
'0000000000000000000000000000000000000000000000000000000000000001',
|
|
225
|
-
];
|
|
226
|
-
|
|
227
|
-
for (const hex of validPoints) {
|
|
228
|
-
if (!ecc.isXOnlyPoint(fromHex(hex))) {
|
|
229
|
-
throw new Error(`ECC library isXOnlyPoint failed for valid point: ${hex}`);
|
|
255
|
+
// Test isXOnlyPoint with valid points (pre-decoded)
|
|
256
|
+
for (const point of getValidPoints()) {
|
|
257
|
+
if (!ecc.isXOnlyPoint(point)) {
|
|
258
|
+
throw new Error('ECC library isXOnlyPoint failed for a valid point');
|
|
230
259
|
}
|
|
231
260
|
}
|
|
232
261
|
|
|
233
|
-
// Test isXOnlyPoint with invalid points
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
];
|
|
238
|
-
|
|
239
|
-
for (const hex of invalidPoints) {
|
|
240
|
-
if (ecc.isXOnlyPoint(fromHex(hex))) {
|
|
241
|
-
throw new Error(`ECC library isXOnlyPoint should reject invalid point: ${hex}`);
|
|
262
|
+
// Test isXOnlyPoint with invalid points (pre-decoded)
|
|
263
|
+
for (const point of getInvalidPoints()) {
|
|
264
|
+
if (ecc.isXOnlyPoint(point)) {
|
|
265
|
+
throw new Error('ECC library isXOnlyPoint should reject invalid point');
|
|
242
266
|
}
|
|
243
267
|
}
|
|
244
268
|
|
|
@@ -247,30 +271,27 @@ function verifyEcc(ecc: EccLib): void {
|
|
|
247
271
|
throw new Error('ECC library missing xOnlyPointAddTweak function');
|
|
248
272
|
}
|
|
249
273
|
|
|
250
|
-
for (const vector of
|
|
251
|
-
const result = ecc.xOnlyPointAddTweak(
|
|
274
|
+
for (const vector of getTweakVectors()) {
|
|
275
|
+
const result = ecc.xOnlyPointAddTweak(
|
|
276
|
+
vector.pubkey as XOnlyPublicKey,
|
|
277
|
+
vector.tweak as Bytes32,
|
|
278
|
+
);
|
|
252
279
|
|
|
253
280
|
if (vector.result === null) {
|
|
254
281
|
if (result !== null) {
|
|
255
282
|
throw new Error(
|
|
256
|
-
|
|
283
|
+
'ECC library xOnlyPointAddTweak should return null for test vector',
|
|
257
284
|
);
|
|
258
285
|
}
|
|
259
286
|
} else {
|
|
260
287
|
if (result === null) {
|
|
261
|
-
throw new Error(
|
|
262
|
-
`ECC library xOnlyPointAddTweak returned null unexpectedly for: ${vector.pubkey}`,
|
|
263
|
-
);
|
|
288
|
+
throw new Error('ECC library xOnlyPointAddTweak returned null unexpectedly');
|
|
264
289
|
}
|
|
265
290
|
if (result.parity !== vector.parity) {
|
|
266
|
-
throw new Error(
|
|
267
|
-
`ECC library xOnlyPointAddTweak parity mismatch for: ${vector.pubkey}`,
|
|
268
|
-
);
|
|
291
|
+
throw new Error('ECC library xOnlyPointAddTweak parity mismatch');
|
|
269
292
|
}
|
|
270
|
-
if (!equals(result.xOnlyPubkey,
|
|
271
|
-
throw new Error(
|
|
272
|
-
`ECC library xOnlyPointAddTweak result mismatch for: ${vector.pubkey}`,
|
|
273
|
-
);
|
|
293
|
+
if (!equals(result.xOnlyPubkey, vector.result)) {
|
|
294
|
+
throw new Error('ECC library xOnlyPointAddTweak result mismatch');
|
|
274
295
|
}
|
|
275
296
|
}
|
|
276
297
|
}
|
package/src/ecc/types.ts
CHANGED
|
@@ -5,14 +5,7 @@
|
|
|
5
5
|
* @packageDocumentation
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
9
|
-
Bytes32,
|
|
10
|
-
PrivateKey,
|
|
11
|
-
PublicKey,
|
|
12
|
-
Signature,
|
|
13
|
-
SchnorrSignature,
|
|
14
|
-
XOnlyPublicKey,
|
|
15
|
-
} from '../branded.js';
|
|
8
|
+
import type { Bytes32, PrivateKey, PublicKey, SchnorrSignature, Signature, XOnlyPublicKey, } from '../branded.js';
|
|
16
9
|
|
|
17
10
|
/**
|
|
18
11
|
* Parity of the y-coordinate for an x-only public key.
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,18 @@ import * as payments from './payments/index.js';
|
|
|
17
17
|
import * as script from './script.js';
|
|
18
18
|
import * as crypto from './crypto.js';
|
|
19
19
|
import * as Transaction from './transaction.js';
|
|
20
|
+
// Custom error types
|
|
21
|
+
import {
|
|
22
|
+
AddressError,
|
|
23
|
+
BitcoinError,
|
|
24
|
+
EccError,
|
|
25
|
+
InvalidInputError,
|
|
26
|
+
InvalidOutputError,
|
|
27
|
+
PsbtError,
|
|
28
|
+
ScriptError,
|
|
29
|
+
SignatureError,
|
|
30
|
+
ValidationError,
|
|
31
|
+
} from './errors.js';
|
|
20
32
|
|
|
21
33
|
export * as address from './address.js';
|
|
22
34
|
export * as crypto from './crypto.js';
|
|
@@ -27,7 +39,42 @@ export * as script from './script.js';
|
|
|
27
39
|
export { Block } from './block.js';
|
|
28
40
|
/** @hidden */
|
|
29
41
|
export * from './crypto.js';
|
|
30
|
-
export
|
|
42
|
+
export {
|
|
43
|
+
Psbt,
|
|
44
|
+
PsbtCache,
|
|
45
|
+
PsbtSigner,
|
|
46
|
+
PsbtFinalizer,
|
|
47
|
+
PsbtTransaction,
|
|
48
|
+
transactionFromBuffer,
|
|
49
|
+
getFinalScripts,
|
|
50
|
+
prepareFinalScripts,
|
|
51
|
+
} from './psbt.js';
|
|
52
|
+
export type {
|
|
53
|
+
TransactionInput,
|
|
54
|
+
PsbtTxInput,
|
|
55
|
+
TransactionOutput,
|
|
56
|
+
PsbtTxOutput,
|
|
57
|
+
ValidateSigFunction,
|
|
58
|
+
PsbtBaseExtended,
|
|
59
|
+
PsbtOptsOptional,
|
|
60
|
+
PsbtOpts,
|
|
61
|
+
PsbtInputExtended,
|
|
62
|
+
PsbtOutputExtended,
|
|
63
|
+
PsbtOutputExtendedScript,
|
|
64
|
+
HDSigner,
|
|
65
|
+
HDSignerAsync,
|
|
66
|
+
SignerAlternative,
|
|
67
|
+
Signer,
|
|
68
|
+
SignerAsync,
|
|
69
|
+
TaprootHashCheckSigner,
|
|
70
|
+
PsbtCacheInterface,
|
|
71
|
+
TxCacheNumberKey,
|
|
72
|
+
ScriptType,
|
|
73
|
+
AllScriptType,
|
|
74
|
+
GetScriptReturn,
|
|
75
|
+
FinalScriptsFunc,
|
|
76
|
+
FinalTaprootScriptsFunc,
|
|
77
|
+
} from './psbt.js';
|
|
31
78
|
/** @hidden */
|
|
32
79
|
export { opcodes } from './opcodes.js';
|
|
33
80
|
export { Transaction } from './transaction.js';
|
|
@@ -140,19 +187,6 @@ export {
|
|
|
140
187
|
} from './types.js';
|
|
141
188
|
export type { XOnlyPointAddTweakResult } from './ecc/types.js';
|
|
142
189
|
|
|
143
|
-
// Custom error types
|
|
144
|
-
import {
|
|
145
|
-
BitcoinError,
|
|
146
|
-
ValidationError,
|
|
147
|
-
InvalidInputError,
|
|
148
|
-
InvalidOutputError,
|
|
149
|
-
ScriptError,
|
|
150
|
-
PsbtError,
|
|
151
|
-
EccError,
|
|
152
|
-
AddressError,
|
|
153
|
-
SignatureError,
|
|
154
|
-
} from './errors.js';
|
|
155
|
-
|
|
156
190
|
export {
|
|
157
191
|
BitcoinError,
|
|
158
192
|
ValidationError,
|
package/src/io/BinaryReader.ts
CHANGED
|
@@ -70,24 +70,6 @@ export class BinaryReader {
|
|
|
70
70
|
this.#offset = offset;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
/**
|
|
74
|
-
* Creates a BinaryReader from a hex string.
|
|
75
|
-
*
|
|
76
|
-
* @param hex - Hex string (with or without 0x prefix)
|
|
77
|
-
* @returns A new BinaryReader instance
|
|
78
|
-
*
|
|
79
|
-
* @example
|
|
80
|
-
* ```typescript
|
|
81
|
-
* import { BinaryReader } from '@btc-vision/bitcoin';
|
|
82
|
-
*
|
|
83
|
-
* const reader = BinaryReader.fromHex('01000000');
|
|
84
|
-
* const version = reader.readInt32LE(); // 1
|
|
85
|
-
* ```
|
|
86
|
-
*/
|
|
87
|
-
public static fromHex(hex: string): BinaryReader {
|
|
88
|
-
return new BinaryReader(fromHex(hex));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
73
|
/**
|
|
92
74
|
* Current read position in the buffer.
|
|
93
75
|
*/
|
|
@@ -129,6 +111,24 @@ export class BinaryReader {
|
|
|
129
111
|
return this.#data;
|
|
130
112
|
}
|
|
131
113
|
|
|
114
|
+
/**
|
|
115
|
+
* Creates a BinaryReader from a hex string.
|
|
116
|
+
*
|
|
117
|
+
* @param hex - Hex string (with or without 0x prefix)
|
|
118
|
+
* @returns A new BinaryReader instance
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* import { BinaryReader } from '@btc-vision/bitcoin';
|
|
123
|
+
*
|
|
124
|
+
* const reader = BinaryReader.fromHex('01000000');
|
|
125
|
+
* const version = reader.readInt32LE(); // 1
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
public static fromHex(hex: string): BinaryReader {
|
|
129
|
+
return new BinaryReader(fromHex(hex));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
132
|
/**
|
|
133
133
|
* Reads an 8-bit unsigned integer.
|
|
134
134
|
*
|
package/src/io/BinaryWriter.ts
CHANGED
|
@@ -91,26 +91,6 @@ export class BinaryWriter {
|
|
|
91
91
|
this.#view = new DataView(this.#data.buffer, this.#data.byteOffset, this.#data.byteLength);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
/**
|
|
95
|
-
* Creates a BinaryWriter with automatic capacity management.
|
|
96
|
-
*
|
|
97
|
-
* Initial capacity is 256 bytes, grows as needed.
|
|
98
|
-
*
|
|
99
|
-
* @returns A new GrowableBinaryWriter instance
|
|
100
|
-
*
|
|
101
|
-
* @example
|
|
102
|
-
* ```typescript
|
|
103
|
-
* import { BinaryWriter } from '@btc-vision/bitcoin';
|
|
104
|
-
*
|
|
105
|
-
* const writer = BinaryWriter.growable();
|
|
106
|
-
* writer.writeUInt32LE(1);
|
|
107
|
-
* writer.writeBytes(new Uint8Array(1000)); // Automatically grows
|
|
108
|
-
* ```
|
|
109
|
-
*/
|
|
110
|
-
public static growable(initialCapacity: number = 256): GrowableBinaryWriter {
|
|
111
|
-
return new GrowableBinaryWriter(initialCapacity);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
94
|
/**
|
|
115
95
|
* Current write position in the buffer.
|
|
116
96
|
*/
|
|
@@ -152,6 +132,26 @@ export class BinaryWriter {
|
|
|
152
132
|
return this.#data;
|
|
153
133
|
}
|
|
154
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Creates a BinaryWriter with automatic capacity management.
|
|
137
|
+
*
|
|
138
|
+
* Initial capacity is 256 bytes, grows as needed.
|
|
139
|
+
*
|
|
140
|
+
* @returns A new GrowableBinaryWriter instance
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* import { BinaryWriter } from '@btc-vision/bitcoin';
|
|
145
|
+
*
|
|
146
|
+
* const writer = BinaryWriter.growable();
|
|
147
|
+
* writer.writeUInt32LE(1);
|
|
148
|
+
* writer.writeBytes(new Uint8Array(1000)); // Automatically grows
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
public static growable(initialCapacity: number = 256): GrowableBinaryWriter {
|
|
152
|
+
return new GrowableBinaryWriter(initialCapacity);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
155
|
/**
|
|
156
156
|
* Writes an 8-bit unsigned integer.
|
|
157
157
|
*
|
|
@@ -583,29 +583,6 @@ export class GrowableBinaryWriter {
|
|
|
583
583
|
return this.#data.length;
|
|
584
584
|
}
|
|
585
585
|
|
|
586
|
-
/**
|
|
587
|
-
* Ensures the buffer has enough space for additional bytes.
|
|
588
|
-
*
|
|
589
|
-
* @param additionalBytes - Number of additional bytes needed
|
|
590
|
-
*/
|
|
591
|
-
#ensureCapacity(additionalBytes: number): void {
|
|
592
|
-
const required = this.#offset + additionalBytes;
|
|
593
|
-
if (required <= this.#data.length) {
|
|
594
|
-
return;
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
// Grow by at least 2x or to required size
|
|
598
|
-
let newCapacity = this.#data.length * 2;
|
|
599
|
-
while (newCapacity < required) {
|
|
600
|
-
newCapacity *= 2;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
const newData = new Uint8Array(newCapacity);
|
|
604
|
-
newData.set(this.#data.subarray(0, this.#offset));
|
|
605
|
-
this.#data = newData;
|
|
606
|
-
this.#view = new DataView(this.#data.buffer);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
586
|
public writeUInt8(value: number): this {
|
|
610
587
|
this.#ensureCapacity(1);
|
|
611
588
|
this.#data[this.#offset++] = value & 0xff;
|
|
@@ -693,4 +670,27 @@ export class GrowableBinaryWriter {
|
|
|
693
670
|
public toHex(): string {
|
|
694
671
|
return toHex(this.finish());
|
|
695
672
|
}
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Ensures the buffer has enough space for additional bytes.
|
|
676
|
+
*
|
|
677
|
+
* @param additionalBytes - Number of additional bytes needed
|
|
678
|
+
*/
|
|
679
|
+
#ensureCapacity(additionalBytes: number): void {
|
|
680
|
+
const required = this.#offset + additionalBytes;
|
|
681
|
+
if (required <= this.#data.length) {
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Grow by at least 2x or to required size
|
|
686
|
+
let newCapacity = this.#data.length * 2;
|
|
687
|
+
while (newCapacity < required) {
|
|
688
|
+
newCapacity *= 2;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const newData = new Uint8Array(newCapacity);
|
|
692
|
+
newData.set(this.#data.subarray(0, this.#offset));
|
|
693
|
+
this.#data = newData;
|
|
694
|
+
this.#view = new DataView(this.#data.buffer);
|
|
695
|
+
}
|
|
696
696
|
}
|