@btc-vision/bitcoin 6.4.11 → 6.5.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/chunks/crypto-0PweVewC.js +2033 -0
- package/browser/chunks/payments-CgasufRS.js +1047 -0
- package/browser/chunks/psbt-BIwOrKer.js +4096 -0
- package/browser/chunks/script-CROJPzz_.js +318 -0
- package/browser/chunks/transaction-DchBu35N.js +432 -0
- package/browser/chunks/utils-CO5kmxe9.js +761 -0
- package/browser/crypto/crypto.d.ts +1 -1
- package/browser/crypto.d.ts +1 -1
- package/browser/hooks/HookedSigner.d.ts +1 -1
- package/browser/index.d.ts +6 -4
- package/browser/index.js +92 -2
- package/browser/payments/index.d.ts +2 -2
- package/browser/payments/lazy.d.ts +1 -1
- package/browser/psbt/bip371.d.ts +5 -1
- package/browser/psbt.d.ts +1 -1
- package/browser/typeforce.d.ts +38 -0
- package/browser/types.d.ts +22 -20
- package/build/address.js +2 -2
- package/build/bip66.js +2 -2
- package/build/block.js +2 -2
- package/build/crypto.d.ts +1 -1
- package/build/crypto.js +2 -3
- package/build/hooks/HookedSigner.d.ts +1 -1
- package/build/index.d.ts +6 -4
- package/build/index.js +2 -2
- package/build/payments/bip341.js +1 -1
- package/build/payments/index.d.ts +2 -2
- package/build/payments/lazy.d.ts +1 -1
- package/build/payments/p2op.js +3 -3
- package/build/payments/p2pk.js +1 -1
- package/build/payments/p2pkh.js +3 -3
- package/build/payments/p2sh.js +3 -3
- package/build/payments/p2tr.js +9 -5
- package/build/payments/p2wpkh.js +3 -3
- package/build/payments/p2wsh.js +2 -2
- package/build/psbt/bip371.d.ts +5 -1
- package/build/psbt/bip371.js +10 -7
- package/build/psbt/psbtutils.js +5 -4
- package/build/psbt.d.ts +1 -1
- package/build/psbt.js +78 -45
- package/build/script.js +2 -2
- package/build/script_signature.js +7 -7
- package/build/transaction.js +22 -10
- package/build/tsconfig.tsbuildinfo +1 -0
- package/build/types.d.ts +22 -20
- package/build/types.js +10 -9
- package/package.json +37 -63
- package/src/address.ts +2 -2
- package/src/bip66.ts +2 -2
- package/src/block.ts +8 -5
- package/src/crypto.ts +3 -4
- package/src/ecc_lib.ts +1 -1
- package/src/hooks/HookedSigner.ts +1 -1
- package/src/index.ts +6 -6
- package/src/payments/bip341.ts +1 -1
- package/src/payments/embed.ts +1 -2
- package/src/payments/index.ts +4 -4
- package/src/payments/lazy.ts +3 -3
- package/src/payments/p2op.ts +4 -3
- package/src/payments/p2pk.ts +1 -1
- package/src/payments/p2pkh.ts +3 -3
- package/src/payments/p2sh.ts +13 -5
- package/src/payments/p2tr.ts +8 -9
- package/src/payments/p2wpkh.ts +3 -3
- package/src/payments/p2wsh.ts +4 -4
- package/src/psbt/bip371.ts +22 -13
- package/src/psbt/psbtutils.ts +8 -5
- package/src/psbt.ts +127 -80
- package/src/script.ts +4 -4
- package/src/script_signature.ts +7 -7
- package/src/transaction.ts +31 -18
- package/src/typeforce.d.ts +38 -0
- package/src/types.ts +34 -29
- package/test/address.spec.ts +12 -4
- package/test/bitcoin.core.spec.ts +1 -1
- package/test/block.spec.ts +1 -1
- package/test/bufferutils.spec.ts +1 -1
- package/test/crypto.spec.ts +3 -2
- package/test/fixtures/address.json +1 -1
- package/test/integration/addresses.spec.ts +1 -1
- package/test/integration/bip32.spec.ts +2 -2
- package/test/integration/blocks.spec.ts +1 -1
- package/test/integration/cltv.spec.ts +3 -3
- package/test/integration/csv.spec.ts +3 -3
- package/test/integration/payments.spec.ts +1 -1
- package/test/integration/taproot.spec.ts +8 -7
- package/test/integration/transactions.spec.ts +2 -2
- package/test/payments.spec.ts +4 -3
- package/test/psbt.spec.ts +106 -74
- package/test/script.spec.ts +73 -7
- package/test/script_number.spec.ts +1 -1
- package/test/script_signature.spec.ts +1 -1
- package/test/transaction.spec.ts +1 -1
- package/test/tsconfig.json +1 -1
- package/test/types.spec.ts +1 -1
- package/vite.config.browser.ts +93 -0
- package/vitest.config.ts +16 -0
- package/.babelrc +0 -4
- package/.mocharc.json +0 -13
- package/browser/index.js.LICENSE.txt +0 -14
- package/cjs/package.json +0 -3
- package/gulpfile.js +0 -42
- package/src/crypto/crypto-browser.js +0 -75
- package/test/ts-node-register.js +0 -7
- package/webpack.config.js +0 -79
package/build/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import typeforce from 'typeforce';
|
|
2
|
+
export { typeforce };
|
|
3
|
+
export type TypeforceValidator = (value: unknown) => boolean;
|
|
2
4
|
export declare function stacksEqual(a: Buffer[], b: Buffer[]): boolean;
|
|
3
5
|
export declare function isPoint(p: Buffer | number | undefined | null): boolean;
|
|
4
6
|
export declare function Satoshi(value: number): boolean;
|
|
@@ -11,27 +13,27 @@ export interface Tapleaf {
|
|
|
11
13
|
version?: number;
|
|
12
14
|
}
|
|
13
15
|
export declare const TAPLEAF_VERSION_MASK = 254;
|
|
14
|
-
export declare function isTapleaf(o:
|
|
16
|
+
export declare function isTapleaf(o: unknown): o is Tapleaf;
|
|
15
17
|
export type Taptree = [Taptree | Tapleaf, Taptree | Tapleaf] | Tapleaf;
|
|
16
|
-
export declare function isTaptree(scriptTree:
|
|
18
|
+
export declare function isTaptree(scriptTree: unknown): scriptTree is Taptree;
|
|
17
19
|
export interface TinySecp256k1Interface {
|
|
18
20
|
isXOnlyPoint(p: Uint8Array): boolean;
|
|
19
21
|
xOnlyPointAddTweak(p: Uint8Array, tweak: Uint8Array): XOnlyPointAddTweakResult | null;
|
|
20
22
|
}
|
|
21
|
-
export declare const Buffer256bit:
|
|
22
|
-
export declare const Hash160bit:
|
|
23
|
-
export declare const Hash256bit:
|
|
24
|
-
export declare const Number:
|
|
25
|
-
export declare const Array:
|
|
26
|
-
export declare const Boolean:
|
|
27
|
-
export declare const String:
|
|
28
|
-
export declare const Buffer:
|
|
29
|
-
export declare const Hex:
|
|
30
|
-
export declare const maybe:
|
|
31
|
-
export declare const tuple:
|
|
32
|
-
export declare const UInt8:
|
|
33
|
-
export declare const UInt32:
|
|
34
|
-
export declare const Function:
|
|
35
|
-
export declare const BufferN:
|
|
36
|
-
export declare const Null:
|
|
37
|
-
export declare const oneOf:
|
|
23
|
+
export declare const Buffer256bit: TypeforceValidator;
|
|
24
|
+
export declare const Hash160bit: TypeforceValidator;
|
|
25
|
+
export declare const Hash256bit: TypeforceValidator;
|
|
26
|
+
export declare const Number: TypeforceValidator;
|
|
27
|
+
export declare const Array: TypeforceValidator;
|
|
28
|
+
export declare const Boolean: TypeforceValidator;
|
|
29
|
+
export declare const String: TypeforceValidator;
|
|
30
|
+
export declare const Buffer: TypeforceValidator;
|
|
31
|
+
export declare const Hex: TypeforceValidator;
|
|
32
|
+
export declare const maybe: (type: unknown) => TypeforceValidator;
|
|
33
|
+
export declare const tuple: (...types: unknown[]) => TypeforceValidator;
|
|
34
|
+
export declare const UInt8: TypeforceValidator;
|
|
35
|
+
export declare const UInt32: TypeforceValidator;
|
|
36
|
+
export declare const Function: TypeforceValidator;
|
|
37
|
+
export declare const BufferN: (n: number) => TypeforceValidator;
|
|
38
|
+
export declare const Null: TypeforceValidator;
|
|
39
|
+
export declare const oneOf: (...types: unknown[]) => TypeforceValidator;
|
package/build/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Buffer as NBuffer } from 'buffer';
|
|
2
|
-
import
|
|
3
|
-
export
|
|
2
|
+
import typeforce from 'typeforce';
|
|
3
|
+
export { typeforce };
|
|
4
4
|
const ZERO32 = NBuffer.alloc(32, 0);
|
|
5
5
|
const EC_P = NBuffer.from('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f', 'hex');
|
|
6
6
|
export function stacksEqual(a, b) {
|
|
@@ -16,7 +16,7 @@ export function isPoint(p) {
|
|
|
16
16
|
if (p.length < 33)
|
|
17
17
|
return false;
|
|
18
18
|
const t = p[0];
|
|
19
|
-
const x = p.
|
|
19
|
+
const x = p.subarray(1, 33);
|
|
20
20
|
if (x.compare(ZERO32) === 0)
|
|
21
21
|
return false;
|
|
22
22
|
if (x.compare(EC_P) >= 0)
|
|
@@ -26,7 +26,7 @@ export function isPoint(p) {
|
|
|
26
26
|
}
|
|
27
27
|
if (p.length !== 65)
|
|
28
28
|
return false;
|
|
29
|
-
const y = p.
|
|
29
|
+
const y = p.subarray(33);
|
|
30
30
|
if (y.compare(ZERO32) === 0)
|
|
31
31
|
return false;
|
|
32
32
|
if (y.compare(EC_P) >= 0)
|
|
@@ -39,16 +39,17 @@ export function Satoshi(value) {
|
|
|
39
39
|
}
|
|
40
40
|
export const TAPLEAF_VERSION_MASK = 0xfe;
|
|
41
41
|
export function isTapleaf(o) {
|
|
42
|
-
if (!o || !('output' in o))
|
|
42
|
+
if (!o || typeof o !== 'object' || !('output' in o))
|
|
43
43
|
return false;
|
|
44
|
-
|
|
44
|
+
const obj = o;
|
|
45
|
+
if (!NBuffer.isBuffer(obj.output))
|
|
45
46
|
return false;
|
|
46
|
-
if (
|
|
47
|
-
return (
|
|
47
|
+
if (obj.version !== undefined)
|
|
48
|
+
return (obj.version & TAPLEAF_VERSION_MASK) === obj.version;
|
|
48
49
|
return true;
|
|
49
50
|
}
|
|
50
51
|
export function isTaptree(scriptTree) {
|
|
51
|
-
if (!Array(scriptTree))
|
|
52
|
+
if (!globalThis.Array.isArray(scriptTree))
|
|
52
53
|
return isTapleaf(scriptTree);
|
|
53
54
|
if (scriptTree.length !== 2)
|
|
54
55
|
return false;
|
package/package.json
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btc-vision/bitcoin",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.5.2",
|
|
5
5
|
"description": "Client-side Bitcoin JavaScript library",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": ">=
|
|
7
|
+
"node": ">=24.0.0"
|
|
8
8
|
},
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"browser":
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
"browser": {
|
|
12
|
+
"types": "./browser/index.d.ts",
|
|
13
|
+
"import": "./browser/index.js"
|
|
14
|
+
},
|
|
15
|
+
"node": {
|
|
16
|
+
"types": "./build/index.d.ts",
|
|
17
|
+
"import": "./build/index.js"
|
|
18
|
+
},
|
|
19
|
+
"types": "./build/index.d.ts",
|
|
20
|
+
"import": "./build/index.js"
|
|
15
21
|
},
|
|
16
22
|
"./browser": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"types": "./browser/index.d.ts"
|
|
23
|
+
"types": "./browser/index.d.ts",
|
|
24
|
+
"import": "./browser/index.js"
|
|
20
25
|
}
|
|
21
26
|
},
|
|
22
27
|
"browser": {
|
|
@@ -48,101 +53,70 @@
|
|
|
48
53
|
"url": "https://github.com/btc-vision/bitcoin.git"
|
|
49
54
|
},
|
|
50
55
|
"scripts": {
|
|
51
|
-
"watch": "
|
|
52
|
-
"build": "
|
|
56
|
+
"watch": "tsc --watch",
|
|
57
|
+
"build": "eslint src && tsc",
|
|
53
58
|
"setup": "npm i && npm run build",
|
|
54
|
-
"browserBuild": "
|
|
59
|
+
"browserBuild": "vite build --config vite.config.browser.ts",
|
|
55
60
|
"audit": "better-npm-audit audit -l high",
|
|
56
|
-
"build:tests": "npm run clean:jstests && tsc -p ./test/tsconfig.json",
|
|
57
61
|
"clean": "rimraf build",
|
|
58
|
-
"
|
|
59
|
-
"coverage-report": "npm run build && npm run nobuild:coverage-report",
|
|
60
|
-
"coverage-html": "npm run build && npm run nobuild:coverage-html",
|
|
61
|
-
"coverage": "npm run build && npm run nobuild:coverage",
|
|
62
|
+
"coverage": "vitest run --coverage",
|
|
62
63
|
"doc": "typedoc",
|
|
63
64
|
"format": "npm run prettier -- --write",
|
|
64
|
-
"formatjs": "npm run
|
|
65
|
-
"format:ci": "npm run prettier -- --check && npm run
|
|
65
|
+
"formatjs": "npm run prettier -- --write",
|
|
66
|
+
"format:ci": "npm run prettier -- --check && npm run prettier -- --check",
|
|
66
67
|
"gitdiff:ci": "npm run build && git diff --exit-code",
|
|
67
|
-
"integration": "
|
|
68
|
+
"integration": "vitest run --config vitest.config.integration.ts",
|
|
68
69
|
"lint": "eslint src/**",
|
|
69
70
|
"lint:tests": "eslint test/**/*.spec.ts",
|
|
70
|
-
"mocha:ts": "cross-env TS_NODE_PROJECT=test/tsconfig.json mocha -n loader=ts-node/esm -n experimental-specifier-resolution=node --extension ts --timeout 10000 --recursive \"test/**/*.spec.ts\"",
|
|
71
|
-
"nobuild:coverage-report": "nyc report --reporter=lcov",
|
|
72
|
-
"nobuild:coverage-html": "nyc report --reporter=html",
|
|
73
|
-
"nobuild:coverage": "npm run build:tests && nyc --check-coverage --branches 85 --functions 90 --lines 90 mocha && npm run clean:jstests",
|
|
74
|
-
"nobuild:integration": "npm run mocha:ts -- --timeout 50000 'test/integration/*.ts'",
|
|
75
|
-
"nobuild:unit": "npm run mocha:ts -- 'test/*.ts'",
|
|
76
71
|
"prettier": "prettier \"src/**/*.ts\" \"test/**/*.ts\" --ignore-path ./.prettierignore",
|
|
77
|
-
"test": "npm run build && npm run format:ci && npm run lint &&
|
|
78
|
-
"
|
|
72
|
+
"test": "npm run build && npm run format:ci && npm run lint && vitest run",
|
|
73
|
+
"test:watch": "vitest",
|
|
74
|
+
"unit": "vitest run"
|
|
79
75
|
},
|
|
80
76
|
"devDependencies": {
|
|
81
|
-
"@
|
|
82
|
-
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
83
|
-
"@babel/plugin-transform-runtime": "^7.27.1",
|
|
84
|
-
"@babel/preset-env": "^7.27.2",
|
|
85
|
-
"@babel/preset-flow": "^7.27.1",
|
|
86
|
-
"@babel/preset-react": "^7.27.1",
|
|
87
|
-
"@babel/preset-typescript": "^7.27.1",
|
|
77
|
+
"@eslint/js": "^9.39.2",
|
|
88
78
|
"@types/bs58check": "^2.1.2",
|
|
89
|
-
"@types/
|
|
90
|
-
"@types/node": "^22.15.21",
|
|
91
|
-
"@types/proxyquire": "^1.3.31",
|
|
79
|
+
"@types/node": "^22.19.3",
|
|
92
80
|
"@types/randombytes": "^2.0.3",
|
|
81
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
93
82
|
"better-npm-audit": "^3.11.0",
|
|
94
83
|
"bip39": "^3.1.0",
|
|
95
84
|
"bip65": "^1.0.3",
|
|
96
85
|
"bip68": "^1.0.4",
|
|
97
86
|
"bs58": "^6.0.0",
|
|
98
87
|
"dhttp": "^3.0.3",
|
|
99
|
-
"ecpair": "^2.0
|
|
100
|
-
"eslint": "9.
|
|
101
|
-
"gulp": "^5.0.0",
|
|
102
|
-
"gulp-cached": "^1.1.1",
|
|
103
|
-
"gulp-typescript": "^6.0.0-alpha.1",
|
|
104
|
-
"hoodwink": "^2.0.0",
|
|
88
|
+
"ecpair": "^2.1.0",
|
|
89
|
+
"eslint": "^9.39.1",
|
|
105
90
|
"https-browserify": "^1.0.0",
|
|
106
91
|
"minimaldata": "^1.0.2",
|
|
107
|
-
"mocha": "^11.5.0",
|
|
108
|
-
"nyc": "^17.1.0",
|
|
109
92
|
"os-browserify": "^0.3.0",
|
|
110
93
|
"prettier": "^3.5.3",
|
|
111
|
-
"proxyquire": "^2.1.3",
|
|
112
94
|
"randombytes": "^2.1.0",
|
|
113
95
|
"regtest-client": "0.2.1",
|
|
114
96
|
"rimraf": "^6.0.1",
|
|
115
97
|
"stream-browserify": "^3.0.0",
|
|
116
98
|
"stream-http": "^3.2.0",
|
|
117
99
|
"tiny-secp256k1": "^2.2.3",
|
|
118
|
-
"ts-loader": "^9.5.2",
|
|
119
100
|
"ts-node": "^10.9.2",
|
|
120
101
|
"typedoc": "^0.28.5",
|
|
121
102
|
"typescript": "^5.8.3",
|
|
122
103
|
"typescript-eslint": "^8.32.1",
|
|
123
|
-
"
|
|
124
|
-
"
|
|
104
|
+
"vite": "^7.3.0",
|
|
105
|
+
"vite-plugin-dts": "^4.5.4",
|
|
106
|
+
"vite-plugin-node-polyfills": "^0.24.0",
|
|
107
|
+
"vitest": "^4.0.16"
|
|
125
108
|
},
|
|
126
109
|
"dependencies": {
|
|
127
|
-
"@
|
|
128
|
-
"@btc-vision/logger": "^1.0.
|
|
129
|
-
"@
|
|
130
|
-
"@noble/
|
|
131
|
-
"@noble/secp256k1": "^2.2.3",
|
|
110
|
+
"@btc-vision/bip32": "^6.0.3",
|
|
111
|
+
"@btc-vision/logger": "^1.0.8",
|
|
112
|
+
"@noble/hashes": "^2.0.1",
|
|
113
|
+
"@noble/secp256k1": "^2.3.0",
|
|
132
114
|
"assert": "^2.1.0",
|
|
133
|
-
"babel-loader": "^10.0.0",
|
|
134
|
-
"babel-plugin-transform-import-meta": "^2.3.2",
|
|
135
|
-
"babel-preset-react": "^6.24.1",
|
|
136
|
-
"babelify": "^10.0.0",
|
|
137
|
-
"bip32": "^4.0.0",
|
|
138
115
|
"bech32": "^2.0.0",
|
|
139
116
|
"bip174": "^2.1.1",
|
|
140
117
|
"browserify-zlib": "^0.2.0",
|
|
141
118
|
"bs58check": "^4.0.0",
|
|
142
119
|
"buffer": "^6.0.3",
|
|
143
|
-
"gulp-clean": "^0.4.0",
|
|
144
|
-
"gulp-eslint-new": "^2.4.0",
|
|
145
|
-
"gulp-logger-new": "^1.0.1",
|
|
146
120
|
"process": "^0.11.10",
|
|
147
121
|
"typeforce": "^1.18.0",
|
|
148
122
|
"varuint-bitcoin": "^2.0.0"
|
package/src/address.ts
CHANGED
|
@@ -179,7 +179,7 @@ export function fromBech32(address: string): Bech32Result {
|
|
|
179
179
|
* encode address hash to base58 address with version
|
|
180
180
|
*/
|
|
181
181
|
export function toBase58Check(hash: Buffer, version: number): string {
|
|
182
|
-
typeforce(tuple(Hash160bit, UInt8),
|
|
182
|
+
typeforce(tuple(Hash160bit, UInt8), [hash, version]);
|
|
183
183
|
|
|
184
184
|
const payload = Buffer.allocUnsafe(21);
|
|
185
185
|
payload.writeUInt8(version, 0);
|
|
@@ -300,5 +300,5 @@ export function toOutputScript(address: string, network?: Network): Buffer {
|
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
-
|
|
303
|
+
throw new TypeError(address + ' has no matching Script');
|
|
304
304
|
}
|
package/src/bip66.ts
CHANGED
|
@@ -52,8 +52,8 @@ export function decode(buffer: Buffer): { r: Buffer; s: Buffer } {
|
|
|
52
52
|
|
|
53
53
|
// non-BIP66 - extract R, S values
|
|
54
54
|
return {
|
|
55
|
-
r: buffer.
|
|
56
|
-
s: buffer.
|
|
55
|
+
r: buffer.subarray(4, 4 + lenR),
|
|
56
|
+
s: buffer.subarray(6 + lenR),
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
|
package/src/block.ts
CHANGED
|
@@ -34,8 +34,11 @@ export class Block {
|
|
|
34
34
|
|
|
35
35
|
if (buffer.length === 80) return block;
|
|
36
36
|
|
|
37
|
-
const readTransaction = ():
|
|
38
|
-
const tx = Transaction.fromBuffer(
|
|
37
|
+
const readTransaction = (): Transaction => {
|
|
38
|
+
const tx = Transaction.fromBuffer(
|
|
39
|
+
bufferReader.buffer.subarray(bufferReader.offset),
|
|
40
|
+
true,
|
|
41
|
+
);
|
|
39
42
|
bufferReader.offset += tx.byteLength();
|
|
40
43
|
return tx;
|
|
41
44
|
};
|
|
@@ -72,7 +75,7 @@ export class Block {
|
|
|
72
75
|
if (transactions.length === 0) throw errorMerkleNoTxes;
|
|
73
76
|
if (forWitness && !txesHaveWitnessCommit(transactions)) throw errorWitnessNotSegwit;
|
|
74
77
|
|
|
75
|
-
const hashes = transactions.map((transaction) => transaction.getHash(forWitness
|
|
78
|
+
const hashes = transactions.map((transaction) => transaction.getHash(forWitness));
|
|
76
79
|
|
|
77
80
|
const rootHash = fastMerkleRoot(hashes, bcrypto.hash256);
|
|
78
81
|
|
|
@@ -89,8 +92,8 @@ export class Block {
|
|
|
89
92
|
// The root is prepended with 0xaa21a9ed so check for 0x6a24aa21a9ed
|
|
90
93
|
// If multiple commits are found, the output with highest index is assumed.
|
|
91
94
|
const witnessCommits = this.transactions![0].outs.filter((out) =>
|
|
92
|
-
out.script.
|
|
93
|
-
).map((out) => out.script.
|
|
95
|
+
out.script.subarray(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex')),
|
|
96
|
+
).map((out) => out.script.subarray(6, 38));
|
|
94
97
|
if (witnessCommits.length === 0) return null;
|
|
95
98
|
// Use the commit with the highest output (should only be one though)
|
|
96
99
|
const result = witnessCommits[witnessCommits.length - 1];
|
package/src/crypto.ts
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @packageDocumentation
|
|
6
6
|
*/
|
|
7
|
-
import { ripemd160 as _ripemd160 } from '@noble/hashes/
|
|
8
|
-
import {
|
|
9
|
-
import { sha256 as _sha256 } from '@noble/hashes/sha256';
|
|
7
|
+
import { ripemd160 as _ripemd160, sha1 as _sha1 } from '@noble/hashes/legacy.js';
|
|
8
|
+
import { sha256 as _sha256 } from '@noble/hashes/sha2.js';
|
|
10
9
|
|
|
11
10
|
export function ripemd160(buffer: Buffer): Buffer {
|
|
12
11
|
return Buffer.from(_ripemd160(Uint8Array.from(buffer)));
|
|
@@ -39,7 +38,7 @@ export const TAGS = [
|
|
|
39
38
|
'KeyAgg list',
|
|
40
39
|
'KeyAgg coefficient',
|
|
41
40
|
] as const;
|
|
42
|
-
export type TaggedHashPrefix = typeof TAGS[number];
|
|
41
|
+
export type TaggedHashPrefix = (typeof TAGS)[number];
|
|
43
42
|
type TaggedHashPrefixes = {
|
|
44
43
|
[key in TaggedHashPrefix]: Buffer;
|
|
45
44
|
};
|
package/src/ecc_lib.ts
CHANGED
|
@@ -15,7 +15,7 @@ export function initEccLib(eccLib: TinySecp256k1Interface | undefined): void {
|
|
|
15
15
|
_ECCLIB_CACHE.eccLib = eccLib;
|
|
16
16
|
} else if (eccLib !== _ECCLIB_CACHE.eccLib) {
|
|
17
17
|
// new instance, verify it
|
|
18
|
-
verifyEcc(eccLib
|
|
18
|
+
verifyEcc(eccLib);
|
|
19
19
|
_ECCLIB_CACHE.eccLib = eccLib;
|
|
20
20
|
}
|
|
21
21
|
}
|
package/src/index.ts
CHANGED
|
@@ -32,10 +32,11 @@ export * from './psbt.js';
|
|
|
32
32
|
export { opcodes } from './opcodes.js';
|
|
33
33
|
export { Transaction } from './transaction.js';
|
|
34
34
|
/** @hidden */
|
|
35
|
-
export { Network } from './networks.js';
|
|
35
|
+
export type { Network } from './networks.js';
|
|
36
36
|
/** @hidden */
|
|
37
37
|
export { initEccLib } from './ecc_lib.js';
|
|
38
|
-
export {
|
|
38
|
+
export { PaymentType } from './payments/index.js';
|
|
39
|
+
export type {
|
|
39
40
|
Payment,
|
|
40
41
|
PaymentCreator,
|
|
41
42
|
PaymentOpts,
|
|
@@ -53,9 +54,8 @@ export {
|
|
|
53
54
|
P2OPPayment,
|
|
54
55
|
P2OPPaymentParams,
|
|
55
56
|
StackFunction,
|
|
56
|
-
PaymentType,
|
|
57
57
|
} from './payments/index.js';
|
|
58
|
-
export { Input as TxInput, Output as TxOutput } from './transaction.js';
|
|
58
|
+
export type { Input as TxInput, Output as TxOutput } from './transaction.js';
|
|
59
59
|
|
|
60
60
|
export interface PsbtInput extends _PsbtInput {}
|
|
61
61
|
|
|
@@ -85,12 +85,12 @@ export * from './bufferutils.js';
|
|
|
85
85
|
export * from './payments/bip341.js';
|
|
86
86
|
export * from './psbt/psbtutils.js';
|
|
87
87
|
|
|
88
|
-
export {
|
|
88
|
+
export { TAPLEAF_VERSION_MASK } from './types.js';
|
|
89
|
+
export type {
|
|
89
90
|
Taptree,
|
|
90
91
|
XOnlyPointAddTweakResult,
|
|
91
92
|
Tapleaf,
|
|
92
93
|
TinySecp256k1Interface,
|
|
93
|
-
TAPLEAF_VERSION_MASK,
|
|
94
94
|
} from './types.js';
|
|
95
95
|
|
|
96
96
|
const bitcoin = {
|
package/src/payments/bip341.ts
CHANGED
|
@@ -49,7 +49,7 @@ export function rootHashFromPath(controlBlock: Buffer, leafHash: Buffer): Buffer
|
|
|
49
49
|
|
|
50
50
|
let kj = leafHash;
|
|
51
51
|
for (let j = 0; j < m; j++) {
|
|
52
|
-
const ej = controlBlock.
|
|
52
|
+
const ej = controlBlock.subarray(33 + 32 * j, 65 + 32 * j);
|
|
53
53
|
if (kj.compare(ej) < 0) {
|
|
54
54
|
kj = tapBranchHash(kj, ej);
|
|
55
55
|
} else {
|
package/src/payments/embed.ts
CHANGED
|
@@ -52,8 +52,7 @@ export function p2data(a: Omit<EmbedPayment, 'name'>, opts?: PaymentOpts): Embed
|
|
|
52
52
|
if (chunks![0] !== OPS.OP_RETURN) throw new TypeError('Output is invalid');
|
|
53
53
|
if (!chunks!.slice(1).every(typef.Buffer)) throw new TypeError('Output is invalid');
|
|
54
54
|
|
|
55
|
-
if (a.data && !stacksEqual(a.data, o.data
|
|
56
|
-
throw new TypeError('Data mismatch');
|
|
55
|
+
if (a.data && !stacksEqual(a.data, o.data)) throw new TypeError('Data mismatch');
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
|
package/src/payments/index.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { Network } from '../networks';
|
|
10
|
-
import { Taptree } from '../types';
|
|
9
|
+
import type { Network } from '../networks.js';
|
|
10
|
+
import type { Taptree } from '../types.js';
|
|
11
11
|
|
|
12
12
|
export * from './bip341.js';
|
|
13
13
|
export * from './embed.js';
|
|
@@ -58,8 +58,8 @@ export interface BasePayment {
|
|
|
58
58
|
|
|
59
59
|
/** Helper used by redeeming script-template outputs (P2SH, P2WSH). */
|
|
60
60
|
export interface ScriptRedeem extends BasePayment {
|
|
61
|
-
output?: Buffer;
|
|
62
|
-
redeemVersion?: number;
|
|
61
|
+
output?: Buffer; // script template
|
|
62
|
+
redeemVersion?: number; // tapscript leaves etc.
|
|
63
63
|
network?: Network; // network parameters (mainnet if omitted)
|
|
64
64
|
}
|
|
65
65
|
|
package/src/payments/lazy.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export function prop<T extends
|
|
1
|
+
export function prop<T extends object>(object: T, name: string, f: () => T[keyof T]): void {
|
|
2
2
|
Object.defineProperty(object, name, {
|
|
3
3
|
configurable: true,
|
|
4
4
|
enumerable: true,
|
|
5
5
|
get(): unknown {
|
|
6
|
-
const _value = f.call(this);
|
|
7
|
-
this[name] = _value;
|
|
6
|
+
const _value = f.call(this as T);
|
|
7
|
+
(this as Record<string, unknown>)[name] = _value;
|
|
8
8
|
return _value;
|
|
9
9
|
},
|
|
10
10
|
set(_value: unknown): void {
|
package/src/payments/p2op.ts
CHANGED
|
@@ -115,7 +115,7 @@ export function p2op(a: Omit<P2OPPaymentParams, 'name'>, opts?: PaymentOpts): P2
|
|
|
115
115
|
} else {
|
|
116
116
|
throw new TypeError('Unsupported push opcode in P2OP script');
|
|
117
117
|
}
|
|
118
|
-
return a.output.
|
|
118
|
+
return a.output.subarray(pushPos, pushPos + progLen);
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
if (a.address) {
|
|
@@ -131,7 +131,7 @@ export function p2op(a: Omit<P2OPPaymentParams, 'name'>, opts?: PaymentOpts): P2
|
|
|
131
131
|
|
|
132
132
|
lazy.prop(o, 'hash160', () => {
|
|
133
133
|
if (!o.program) return;
|
|
134
|
-
return o.program.
|
|
134
|
+
return o.program.subarray(1);
|
|
135
135
|
});
|
|
136
136
|
|
|
137
137
|
lazy.prop(o, 'output', () => {
|
|
@@ -188,7 +188,8 @@ export function p2op(a: Omit<P2OPPaymentParams, 'name'>, opts?: PaymentOpts): P2
|
|
|
188
188
|
if (a.deploymentVersion !== undefined && a.deploymentVersion !== prog[0])
|
|
189
189
|
throw new TypeError('deploymentVersion mismatch');
|
|
190
190
|
|
|
191
|
-
if (a.hash160 && !a.hash160.equals(prog.
|
|
191
|
+
if (a.hash160 && !a.hash160.equals(prog.subarray(1)))
|
|
192
|
+
throw new TypeError('hash160 mismatch');
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
return Object.assign(o, a);
|
package/src/payments/p2pk.ts
CHANGED
package/src/payments/p2pkh.ts
CHANGED
|
@@ -43,7 +43,7 @@ export function p2pkh(a: Omit<P2PKHPayment, 'name'>, opts?: PaymentOpts): P2PKHP
|
|
|
43
43
|
const _address = lazy.value(() => {
|
|
44
44
|
const payload = Buffer.from(bs58check.default.decode(a.address!));
|
|
45
45
|
const version = payload.readUInt8(0);
|
|
46
|
-
const hash = payload.
|
|
46
|
+
const hash = payload.subarray(1);
|
|
47
47
|
return { version, hash };
|
|
48
48
|
});
|
|
49
49
|
|
|
@@ -68,7 +68,7 @@ export function p2pkh(a: Omit<P2PKHPayment, 'name'>, opts?: PaymentOpts): P2PKHP
|
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
lazy.prop(o, 'hash', () => {
|
|
71
|
-
if (a.output) return a.output.
|
|
71
|
+
if (a.output) return a.output.subarray(3, 23);
|
|
72
72
|
if (a.address) return _address().hash;
|
|
73
73
|
if (a.pubkey || o.pubkey) return bcrypto.hash160(a.pubkey! || o.pubkey!);
|
|
74
74
|
});
|
|
@@ -153,7 +153,7 @@ export function p2pkh(a: Omit<P2PKHPayment, 'name'>, opts?: PaymentOpts): P2PKHP
|
|
|
153
153
|
throw new TypeError('Output is invalid');
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
const hash2 = a.output.
|
|
156
|
+
const hash2 = a.output.subarray(3, 23);
|
|
157
157
|
if (hash.length > 0 && !hash.equals(hash2)) throw new TypeError('Hash mismatch');
|
|
158
158
|
else hash = hash2;
|
|
159
159
|
}
|
package/src/payments/p2sh.ts
CHANGED
|
@@ -3,7 +3,15 @@ import * as bcrypto from '../crypto.js';
|
|
|
3
3
|
import { bitcoin as BITCOIN_NETWORK } from '../networks.js';
|
|
4
4
|
import * as bscript from '../script.js';
|
|
5
5
|
import { stacksEqual, typeforce as typef } from '../types.js';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
P2SHPayment,
|
|
8
|
+
Payment,
|
|
9
|
+
PaymentOpts,
|
|
10
|
+
PaymentType,
|
|
11
|
+
ScriptRedeem,
|
|
12
|
+
Stack,
|
|
13
|
+
StackFunction,
|
|
14
|
+
} from './index.js';
|
|
7
15
|
import * as lazy from './lazy.js';
|
|
8
16
|
|
|
9
17
|
const OPS = bscript.opcodes;
|
|
@@ -58,7 +66,7 @@ export function p2sh(a: Omit<P2SHPayment, 'name'>, opts?: PaymentOpts): P2SHPaym
|
|
|
58
66
|
const _address = lazy.value(() => {
|
|
59
67
|
const payload = Buffer.from(bs58check.default.decode(a.address!));
|
|
60
68
|
const version = payload.readUInt8(0);
|
|
61
|
-
const hash = payload.
|
|
69
|
+
const hash = payload.subarray(1);
|
|
62
70
|
return { version, hash };
|
|
63
71
|
});
|
|
64
72
|
const _chunks = lazy.value(() => {
|
|
@@ -87,7 +95,7 @@ export function p2sh(a: Omit<P2SHPayment, 'name'>, opts?: PaymentOpts): P2SHPaym
|
|
|
87
95
|
});
|
|
88
96
|
lazy.prop(o, 'hash', () => {
|
|
89
97
|
// in order of least effort
|
|
90
|
-
if (a.output) return a.output.
|
|
98
|
+
if (a.output) return a.output.subarray(2, 22);
|
|
91
99
|
if (a.address) return _address().hash;
|
|
92
100
|
if (o.redeem && o.redeem.output) return bcrypto.hash160(o.redeem.output);
|
|
93
101
|
});
|
|
@@ -113,7 +121,7 @@ export function p2sh(a: Omit<P2SHPayment, 'name'>, opts?: PaymentOpts): P2SHPaym
|
|
|
113
121
|
});
|
|
114
122
|
lazy.prop(o, 'name', () => {
|
|
115
123
|
const nameParts = ['p2sh'];
|
|
116
|
-
if (o.redeem !== undefined && o.redeem.name !== undefined) nameParts.push(o.redeem.name
|
|
124
|
+
if (o.redeem !== undefined && o.redeem.name !== undefined) nameParts.push(o.redeem.name);
|
|
117
125
|
return nameParts.join('-');
|
|
118
126
|
});
|
|
119
127
|
|
|
@@ -140,7 +148,7 @@ export function p2sh(a: Omit<P2SHPayment, 'name'>, opts?: PaymentOpts): P2SHPaym
|
|
|
140
148
|
)
|
|
141
149
|
throw new TypeError('Output is invalid');
|
|
142
150
|
|
|
143
|
-
const hash2 = a.output.
|
|
151
|
+
const hash2 = a.output.subarray(2, 22);
|
|
144
152
|
if (hash.length > 0 && !hash.equals(hash2)) throw new TypeError('Hash mismatch');
|
|
145
153
|
else hash = hash2;
|
|
146
154
|
}
|
package/src/payments/p2tr.ts
CHANGED
|
@@ -137,7 +137,7 @@ export function p2tr(a: Omit<P2TRPayment, 'name'>, opts?: PaymentOpts): P2TRPaym
|
|
|
137
137
|
});
|
|
138
138
|
lazy.prop(o, 'pubkey', () => {
|
|
139
139
|
if (a.pubkey) return a.pubkey;
|
|
140
|
-
if (a.output) return a.output.
|
|
140
|
+
if (a.output) return a.output.subarray(2);
|
|
141
141
|
if (a.address) return _address().data;
|
|
142
142
|
if (o.internalPubkey) {
|
|
143
143
|
const tweakedKey = tweakKey(o.internalPubkey, o.hash);
|
|
@@ -147,7 +147,7 @@ export function p2tr(a: Omit<P2TRPayment, 'name'>, opts?: PaymentOpts): P2TRPaym
|
|
|
147
147
|
lazy.prop(o, 'internalPubkey', () => {
|
|
148
148
|
if (a.internalPubkey) return a.internalPubkey;
|
|
149
149
|
const witness = _witness();
|
|
150
|
-
if (witness && witness.length > 1) return witness[witness.length - 1].
|
|
150
|
+
if (witness && witness.length > 1) return witness[witness.length - 1].subarray(1, 33);
|
|
151
151
|
});
|
|
152
152
|
lazy.prop(o, 'signature', () => {
|
|
153
153
|
if (a.signature) return a.signature;
|
|
@@ -199,9 +199,9 @@ export function p2tr(a: Omit<P2TRPayment, 'name'>, opts?: PaymentOpts): P2TRPaym
|
|
|
199
199
|
if (a.output) {
|
|
200
200
|
if (a.output.length !== 34 || a.output[0] !== OPS.OP_1 || a.output[1] !== 0x20)
|
|
201
201
|
throw new TypeError('Output is invalid');
|
|
202
|
-
if (pubkey.length > 0 && !pubkey.equals(a.output.
|
|
202
|
+
if (pubkey.length > 0 && !pubkey.equals(a.output.subarray(2)))
|
|
203
203
|
throw new TypeError('Pubkey mismatch');
|
|
204
|
-
else pubkey = a.output.
|
|
204
|
+
else pubkey = a.output.subarray(2);
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
if (a.internalPubkey) {
|
|
@@ -211,10 +211,9 @@ export function p2tr(a: Omit<P2TRPayment, 'name'>, opts?: PaymentOpts): P2TRPaym
|
|
|
211
211
|
else pubkey = tweakedKey!.x;
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
|
|
215
|
-
if (!getEccLib().isXOnlyPoint(pubkey))
|
|
216
|
-
|
|
217
|
-
}*/
|
|
214
|
+
if (pubkey && pubkey.length) {
|
|
215
|
+
if (!getEccLib().isXOnlyPoint(pubkey)) throw new TypeError('Invalid pubkey for p2tr');
|
|
216
|
+
}
|
|
218
217
|
|
|
219
218
|
const hashTree = _hashTree();
|
|
220
219
|
|
|
@@ -276,7 +275,7 @@ export function p2tr(a: Omit<P2TRPayment, 'name'>, opts?: PaymentOpts): P2TRPaym
|
|
|
276
275
|
if (m > 128)
|
|
277
276
|
throw new TypeError(`The script path is too long. Got ${m}, expected max 128.`);
|
|
278
277
|
|
|
279
|
-
const internalPubkey = controlBlock.
|
|
278
|
+
const internalPubkey = controlBlock.subarray(1, 33);
|
|
280
279
|
if (a.internalPubkey && !a.internalPubkey.equals(internalPubkey))
|
|
281
280
|
throw new TypeError('Internal pubkey mismatch');
|
|
282
281
|
|