@btc-vision/bitcoin 7.0.0-alpha.1 → 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 +5 -1
- package/browser/address.d.ts.map +1 -1
- package/browser/branded.d.ts +3 -14
- package/browser/branded.d.ts.map +1 -1
- package/browser/ecc/context.d.ts.map +1 -1
- package/browser/index.d.ts +2 -1
- package/browser/index.d.ts.map +1 -1
- package/browser/index.js +2964 -2919
- package/browser/opcodes.d.ts +11 -0
- package/browser/opcodes.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/types.d.ts +13 -13
- 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/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/build/address.d.ts +5 -1
- package/build/address.d.ts.map +1 -1
- package/build/address.js +29 -17
- package/build/address.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/ecc/context.d.ts.map +1 -1
- package/build/ecc/context.js +68 -45
- package/build/ecc/context.js.map +1 -1
- package/build/index.d.ts +2 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -1
- package/build/index.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/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/types.d.ts +13 -13
- 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.d.ts +27 -39
- package/build/psbt.d.ts.map +1 -1
- package/build/psbt.js +139 -746
- package/build/psbt.js.map +1 -1
- package/build/script.d.ts.map +1 -1
- package/build/script.js +2 -2
- 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 +5 -4
- 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 +9 -0
- package/build/types.js.map +1 -1
- package/build/workers/WorkerSigningPool.js +1 -1
- package/build/workers/WorkerSigningPool.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/package.json +28 -9
- package/src/address.ts +41 -18
- package/src/branded.ts +15 -13
- package/src/ecc/context.ts +75 -57
- package/src/index.ts +36 -1
- package/src/opcodes.ts +21 -4
- 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/types.ts +13 -13
- package/src/psbt/validation.ts +1 -1
- package/src/psbt.ts +299 -1090
- package/src/script.ts +2 -2
- package/src/transaction.ts +9 -8
- package/src/types.ts +13 -0
- package/src/workers/WorkerSigningPool.ts +1 -1
- package/src/workers/index.node.ts +27 -0
- package/src/workers/index.ts +7 -9
- 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 +11 -1
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAIH,eAAe;AACf,OAAO,EACH,aAAa,EAeb,cAAc,EACd,eAAe,EACf,aAAa,EACb,aAAa,EAMb,WAAW,GAEd,MAAM,YAAY,CAAC;AAEpB,sBAAsB;AACtB,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE3E,sDAAsD;AACtD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEnG,+CAA+C;AAC/C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE9D,oCAAoC;AACpC,OAAO,EACH,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,GAGxB,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,MAAM,UAAU,aAAa;IACzB,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC3D,OAAO,MAAM,CAAC;IAClB,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QACjE,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAyB;IAa7D,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAEhC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACrB,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QAC9E,MAAM,IAAI,GAAG,qBAAqB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACvD,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IAChB,CAAC;SAAM,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IAChB,CAAC;SAAM,CAAC;QACJ,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACnE,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js worker pool entry point.
|
|
3
|
+
*
|
|
4
|
+
* This module provides direct access to Node.js-specific worker functionality.
|
|
5
|
+
* It re-exports everything from the base index plus Node.js specific exports.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { NodeWorkerSigningPool } from '@btc-vision/bitcoin/workers';
|
|
10
|
+
*
|
|
11
|
+
* const pool = NodeWorkerSigningPool.getInstance({ workerCount: 4 });
|
|
12
|
+
* await pool.initialize();
|
|
13
|
+
* pool.preserveWorkers();
|
|
14
|
+
*
|
|
15
|
+
* const result = await pool.signBatch(tasks, keyPair);
|
|
16
|
+
*
|
|
17
|
+
* await pool.shutdown();
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
export * from './index.js';
|
|
23
|
+
export { NodeWorkerSigningPool, type NodeWorkerPoolConfig } from './WorkerSigningPool.node.js';
|
|
24
|
+
//# sourceMappingURL=index.node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.node.d.ts","sourceRoot":"","sources":["../../src/workers/index.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,cAAc,YAAY,CAAC;AAG3B,OAAO,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node.js worker pool entry point.
|
|
3
|
+
*
|
|
4
|
+
* This module provides direct access to Node.js-specific worker functionality.
|
|
5
|
+
* It re-exports everything from the base index plus Node.js specific exports.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { NodeWorkerSigningPool } from '@btc-vision/bitcoin/workers';
|
|
10
|
+
*
|
|
11
|
+
* const pool = NodeWorkerSigningPool.getInstance({ workerCount: 4 });
|
|
12
|
+
* await pool.initialize();
|
|
13
|
+
* pool.preserveWorkers();
|
|
14
|
+
*
|
|
15
|
+
* const result = await pool.signBatch(tasks, keyPair);
|
|
16
|
+
*
|
|
17
|
+
* await pool.shutdown();
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
// Re-export everything from browser-safe index
|
|
23
|
+
export * from './index.js';
|
|
24
|
+
// Node.js specific exports
|
|
25
|
+
export { NodeWorkerSigningPool } from './WorkerSigningPool.node.js';
|
|
26
|
+
//# sourceMappingURL=index.node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.node.js","sourceRoot":"","sources":["../../src/workers/index.node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,+CAA+C;AAC/C,cAAc,YAAY,CAAC;AAE3B,2BAA2B;AAC3B,OAAO,EAAE,qBAAqB,EAA6B,MAAM,6BAA6B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btc-vision/bitcoin",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "7.0.0-alpha.
|
|
4
|
+
"version": "7.0.0-alpha.2",
|
|
5
5
|
"sideEffects": false,
|
|
6
|
-
"overrides": {
|
|
7
|
-
"ecpair": {
|
|
8
|
-
"valibot": "^1.2.0"
|
|
9
|
-
}
|
|
10
|
-
},
|
|
11
6
|
"description": "Client-side Bitcoin JavaScript library",
|
|
12
7
|
"engines": {
|
|
13
8
|
"node": ">=24.0.0"
|
|
@@ -33,6 +28,21 @@
|
|
|
33
28
|
"import": "./browser/index.js",
|
|
34
29
|
"default": "./browser/index.js"
|
|
35
30
|
},
|
|
31
|
+
"./workers": {
|
|
32
|
+
"browser": {
|
|
33
|
+
"types": "./browser/workers/index.d.ts",
|
|
34
|
+
"import": "./browser/workers/index.js",
|
|
35
|
+
"default": "./browser/workers/index.js"
|
|
36
|
+
},
|
|
37
|
+
"node": {
|
|
38
|
+
"types": "./build/workers/index.node.d.ts",
|
|
39
|
+
"import": "./build/workers/index.node.js",
|
|
40
|
+
"default": "./build/workers/index.node.js"
|
|
41
|
+
},
|
|
42
|
+
"types": "./build/workers/index.d.ts",
|
|
43
|
+
"import": "./build/workers/index.js",
|
|
44
|
+
"default": "./build/workers/index.js"
|
|
45
|
+
},
|
|
36
46
|
"./address": {
|
|
37
47
|
"types": "./build/address.d.ts",
|
|
38
48
|
"import": "./build/address.js"
|
|
@@ -89,6 +99,8 @@
|
|
|
89
99
|
"browser": {
|
|
90
100
|
"./build/index.js": "./browser/index.js",
|
|
91
101
|
"./build/index.d.ts": "./browser/index.d.ts",
|
|
102
|
+
"./build/workers/index.node.js": "./browser/workers/index.js",
|
|
103
|
+
"./build/workers/index.node.d.ts": "./browser/workers/index.d.ts",
|
|
92
104
|
"Buffer": "buffer",
|
|
93
105
|
"crypto": "./src/crypto/crypto-browser.js",
|
|
94
106
|
"stream": "stream-browserify",
|
|
@@ -132,6 +144,8 @@
|
|
|
132
144
|
"test": "npm run build && npm run lint && vitest run",
|
|
133
145
|
"test:watch": "vitest",
|
|
134
146
|
"unit": "vitest run",
|
|
147
|
+
"test:browser": "vitest run --config vitest.config.browser.ts",
|
|
148
|
+
"test:browser:watch": "vitest --config vitest.config.browser.ts",
|
|
135
149
|
"bench": "vitest bench benchmark/",
|
|
136
150
|
"bench:run": "npx tsx benchmark/signing.bench.ts",
|
|
137
151
|
"check:circular": "madge --circular --extensions ts,tsx src/",
|
|
@@ -143,6 +157,8 @@
|
|
|
143
157
|
"@types/bs58check": "^3.0.1",
|
|
144
158
|
"@types/node": "^25.0.10",
|
|
145
159
|
"@types/randombytes": "^2.0.3",
|
|
160
|
+
"@vitest/browser": "^4.0.18",
|
|
161
|
+
"@vitest/browser-playwright": "^4.0.18",
|
|
146
162
|
"@vitest/coverage-v8": "^4.0.18",
|
|
147
163
|
"better-npm-audit": "^3.11.0",
|
|
148
164
|
"bip39": "^3.1.0",
|
|
@@ -150,12 +166,12 @@
|
|
|
150
166
|
"bip68": "^1.0.4",
|
|
151
167
|
"bs58": "^6.0.0",
|
|
152
168
|
"dhttp": "^3.0.3",
|
|
153
|
-
"ecpair": "^3.0.0",
|
|
154
169
|
"eslint": "^9.39.2",
|
|
155
170
|
"https-browserify": "^1.0.0",
|
|
156
171
|
"madge": "^8.0.0",
|
|
157
172
|
"minimaldata": "^1.0.2",
|
|
158
173
|
"os-browserify": "^0.3.0",
|
|
174
|
+
"playwright": "^1.58.0",
|
|
159
175
|
"prettier": "^3.8.1",
|
|
160
176
|
"randombytes": "^2.1.0",
|
|
161
177
|
"regtest-client": "0.2.1",
|
|
@@ -171,10 +187,13 @@
|
|
|
171
187
|
"vite": "^7.3.1",
|
|
172
188
|
"vite-plugin-dts": "^4.5.4",
|
|
173
189
|
"vite-plugin-node-polyfills": "^0.25.0",
|
|
190
|
+
"vite-plugin-top-level-await": "^1.6.0",
|
|
191
|
+
"vite-plugin-wasm": "^3.5.0",
|
|
174
192
|
"vitest": "^4.0.18"
|
|
175
193
|
},
|
|
176
194
|
"dependencies": {
|
|
177
|
-
"@btc-vision/bip32": "^
|
|
195
|
+
"@btc-vision/bip32": "^7.0.1",
|
|
196
|
+
"@btc-vision/ecpair": "^4.0.1",
|
|
178
197
|
"@btc-vision/logger": "^1.0.8",
|
|
179
198
|
"@noble/hashes": "^2.0.1",
|
|
180
199
|
"@noble/secp256k1": "^3.0.0",
|
|
@@ -187,4 +206,4 @@
|
|
|
187
206
|
"process": "^0.11.10",
|
|
188
207
|
"varuint-bitcoin": "^2.0.0"
|
|
189
208
|
}
|
|
190
|
-
}
|
|
209
|
+
}
|
package/src/address.ts
CHANGED
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
type Bytes20,
|
|
26
26
|
isBytes20,
|
|
27
27
|
isUInt8,
|
|
28
|
-
type Script,
|
|
29
28
|
toBytes20,
|
|
30
29
|
toBytes32,
|
|
31
30
|
type XOnlyPublicKey,
|
|
@@ -188,27 +187,51 @@ export function toBech32(
|
|
|
188
187
|
}
|
|
189
188
|
|
|
190
189
|
/**
|
|
191
|
-
* 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.
|
|
192
195
|
*/
|
|
193
196
|
export function fromOutputScript(output: Uint8Array, network?: Network): string {
|
|
194
|
-
// TODO: Network
|
|
195
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
|
+
}
|
|
196
211
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
|
212
235
|
try {
|
|
213
236
|
return toFutureOPNetAddress(output, network);
|
|
214
237
|
} catch (e) {}
|
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/ecc/context.ts
CHANGED
|
@@ -59,6 +59,10 @@ export class EccContext {
|
|
|
59
59
|
* ```
|
|
60
60
|
*/
|
|
61
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
|
+
}
|
|
62
66
|
verifyEcc(lib);
|
|
63
67
|
EccContext.#instance = new EccContext(lib);
|
|
64
68
|
return EccContext.#instance;
|
|
@@ -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;
|
|
184
219
|
}
|
|
185
220
|
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
{
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
|
|
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;
|
|
231
|
+
}
|
|
232
|
+
|
|
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,33 +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
|
|
274
|
+
for (const vector of getTweakVectors()) {
|
|
251
275
|
const result = ecc.xOnlyPointAddTweak(
|
|
252
|
-
|
|
253
|
-
|
|
276
|
+
vector.pubkey as XOnlyPublicKey,
|
|
277
|
+
vector.tweak as Bytes32,
|
|
254
278
|
);
|
|
255
279
|
|
|
256
280
|
if (vector.result === null) {
|
|
257
281
|
if (result !== null) {
|
|
258
282
|
throw new Error(
|
|
259
|
-
|
|
283
|
+
'ECC library xOnlyPointAddTweak should return null for test vector',
|
|
260
284
|
);
|
|
261
285
|
}
|
|
262
286
|
} else {
|
|
263
287
|
if (result === null) {
|
|
264
|
-
throw new Error(
|
|
265
|
-
`ECC library xOnlyPointAddTweak returned null unexpectedly for: ${vector.pubkey}`,
|
|
266
|
-
);
|
|
288
|
+
throw new Error('ECC library xOnlyPointAddTweak returned null unexpectedly');
|
|
267
289
|
}
|
|
268
290
|
if (result.parity !== vector.parity) {
|
|
269
|
-
throw new Error(
|
|
270
|
-
`ECC library xOnlyPointAddTweak parity mismatch for: ${vector.pubkey}`,
|
|
271
|
-
);
|
|
291
|
+
throw new Error('ECC library xOnlyPointAddTweak parity mismatch');
|
|
272
292
|
}
|
|
273
|
-
if (!equals(result.xOnlyPubkey,
|
|
274
|
-
throw new Error(
|
|
275
|
-
`ECC library xOnlyPointAddTweak result mismatch for: ${vector.pubkey}`,
|
|
276
|
-
);
|
|
293
|
+
if (!equals(result.xOnlyPubkey, vector.result)) {
|
|
294
|
+
throw new Error('ECC library xOnlyPointAddTweak result mismatch');
|
|
277
295
|
}
|
|
278
296
|
}
|
|
279
297
|
}
|
package/src/index.ts
CHANGED
|
@@ -39,7 +39,42 @@ export * as script from './script.js';
|
|
|
39
39
|
export { Block } from './block.js';
|
|
40
40
|
/** @hidden */
|
|
41
41
|
export * from './crypto.js';
|
|
42
|
-
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';
|
|
43
78
|
/** @hidden */
|
|
44
79
|
export { opcodes } from './opcodes.js';
|
|
45
80
|
export { Transaction } from './transaction.js';
|
package/src/opcodes.ts
CHANGED
|
@@ -273,8 +273,25 @@ export const opcodes: Opcodes = {
|
|
|
273
273
|
OP_INVALIDOPCODE: 255,
|
|
274
274
|
};
|
|
275
275
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
276
|
+
let _reverseOps: { [key: number]: string } | undefined;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Returns the reverse mapping from opcode number to opcode name.
|
|
280
|
+
* Lazily computed on first call.
|
|
281
|
+
*/
|
|
282
|
+
export function getReverseOps(): { [key: number]: string } {
|
|
283
|
+
if (!_reverseOps) {
|
|
284
|
+
_reverseOps = {};
|
|
285
|
+
for (const op of Object.keys(opcodes)) {
|
|
286
|
+
const code = opcodes[op as keyof Opcodes];
|
|
287
|
+
_reverseOps[code] = op;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return _reverseOps;
|
|
280
291
|
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* @deprecated Use {@link getReverseOps}() for lazy initialization.
|
|
295
|
+
* This eagerly-initialized alias exists for backward compatibility.
|
|
296
|
+
*/
|
|
297
|
+
export const REVERSE_OPS: { [key: number]: string } = getReverseOps();
|