@bitcoinerlab/descriptors-core 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +710 -0
- package/dist/adapters/applyPR2137.d.ts +2 -0
- package/dist/adapters/applyPR2137.js +150 -0
- package/dist/adapters/bitcoinjs.d.ts +8 -0
- package/dist/adapters/bitcoinjs.js +36 -0
- package/dist/adapters/scure/address.d.ts +2 -0
- package/dist/adapters/scure/address.js +50 -0
- package/dist/adapters/scure/bip32.d.ts +2 -0
- package/dist/adapters/scure/bip32.js +16 -0
- package/dist/adapters/scure/common.d.ts +14 -0
- package/dist/adapters/scure/common.js +36 -0
- package/dist/adapters/scure/ecpair.d.ts +2 -0
- package/dist/adapters/scure/ecpair.js +58 -0
- package/dist/adapters/scure/payments.d.ts +2 -0
- package/dist/adapters/scure/payments.js +216 -0
- package/dist/adapters/scure/psbt.d.ts +43 -0
- package/dist/adapters/scure/psbt.js +382 -0
- package/dist/adapters/scure/script.d.ts +20 -0
- package/dist/adapters/scure/script.js +163 -0
- package/dist/adapters/scure/transaction.d.ts +2 -0
- package/dist/adapters/scure/transaction.js +32 -0
- package/dist/adapters/scure.d.ts +6 -0
- package/dist/adapters/scure.js +37 -0
- package/dist/adapters/scureKeys.d.ts +4 -0
- package/dist/adapters/scureKeys.js +135 -0
- package/dist/bip174.d.ts +87 -0
- package/dist/bip174.js +12 -0
- package/dist/bitcoinLib.d.ts +385 -0
- package/dist/bitcoinLib.js +19 -0
- package/dist/bitcoinjs-lib-internals.d.ts +6 -0
- package/dist/bitcoinjs-lib-internals.js +60 -0
- package/dist/bitcoinjs.d.ts +12 -0
- package/dist/bitcoinjs.js +18 -0
- package/dist/checksum.d.ts +6 -0
- package/dist/checksum.js +58 -0
- package/dist/crypto.d.ts +3 -0
- package/dist/crypto.js +79 -0
- package/dist/descriptors.d.ts +481 -0
- package/dist/descriptors.js +1888 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +87 -0
- package/dist/keyExpressions.d.ts +124 -0
- package/dist/keyExpressions.js +310 -0
- package/dist/keyInterfaces.d.ts +5 -0
- package/dist/keyInterfaces.js +50 -0
- package/dist/ledger.d.ts +183 -0
- package/dist/ledger.js +618 -0
- package/dist/miniscript.d.ts +125 -0
- package/dist/miniscript.js +310 -0
- package/dist/multipath.d.ts +13 -0
- package/dist/multipath.js +76 -0
- package/dist/networkUtils.d.ts +3 -0
- package/dist/networkUtils.js +16 -0
- package/dist/networks.d.ts +16 -0
- package/dist/networks.js +31 -0
- package/dist/parseUtils.d.ts +7 -0
- package/dist/parseUtils.js +46 -0
- package/dist/psbt.d.ts +40 -0
- package/dist/psbt.js +228 -0
- package/dist/re.d.ts +31 -0
- package/dist/re.js +79 -0
- package/dist/resourceLimits.d.ts +28 -0
- package/dist/resourceLimits.js +84 -0
- package/dist/scriptExpressions.d.ts +95 -0
- package/dist/scriptExpressions.js +98 -0
- package/dist/scure.d.ts +4 -0
- package/dist/scure.js +10 -0
- package/dist/signers.d.ts +161 -0
- package/dist/signers.js +324 -0
- package/dist/tapMiniscript.d.ts +231 -0
- package/dist/tapMiniscript.js +524 -0
- package/dist/tapTree.d.ts +91 -0
- package/dist/tapTree.js +166 -0
- package/dist/types.d.ts +296 -0
- package/dist/types.js +4 -0
- package/package.json +148 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2026 Jose-Luis Landabaso - https://bitcoinerlab.com
|
|
3
|
+
// Distributed under the MIT software license
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.wrapScurePrivateKey = wrapScurePrivateKey;
|
|
6
|
+
exports.wrapScurePublicKey = wrapScurePublicKey;
|
|
7
|
+
exports.wrapScureHDKey = wrapScureHDKey;
|
|
8
|
+
const bip32_1 = require("@scure/bip32");
|
|
9
|
+
const base_1 = require("@scure/base");
|
|
10
|
+
const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
|
|
11
|
+
const utils_js_1 = require("@noble/curves/utils.js");
|
|
12
|
+
const common_1 = require("./scure/common");
|
|
13
|
+
const CURVE_N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
|
14
|
+
function mod(a, n) {
|
|
15
|
+
const result = a % n;
|
|
16
|
+
return result >= 0n ? result : result + n;
|
|
17
|
+
}
|
|
18
|
+
function tweakPrivateKey(privateKey, tweak, publicKey) {
|
|
19
|
+
if (tweak.length !== 32)
|
|
20
|
+
throw new Error('Error: invalid tweak value');
|
|
21
|
+
const tweakNum = (0, utils_js_1.bytesToNumberBE)(tweak);
|
|
22
|
+
if (tweakNum <= 0n || tweakNum >= CURVE_N)
|
|
23
|
+
throw new Error('Error: invalid tweak value');
|
|
24
|
+
let d = (0, utils_js_1.bytesToNumberBE)(privateKey);
|
|
25
|
+
if (publicKey[0] === 0x03)
|
|
26
|
+
d = mod(-d, CURVE_N);
|
|
27
|
+
const tweaked = mod(d + tweakNum, CURVE_N);
|
|
28
|
+
if (tweaked === 0n)
|
|
29
|
+
throw new Error('Error: invalid tweak value');
|
|
30
|
+
return (0, utils_js_1.numberToBytesBE)(tweaked, 32);
|
|
31
|
+
}
|
|
32
|
+
function wrapScurePrivateKey(privateKey, compressed = true) {
|
|
33
|
+
if (!secp256k1_js_1.secp256k1.utils.isValidSecretKey(privateKey))
|
|
34
|
+
throw new Error('Error: invalid private key');
|
|
35
|
+
const compressedPublicKey = secp256k1_js_1.secp256k1.getPublicKey(privateKey, true);
|
|
36
|
+
const publicKey = compressed
|
|
37
|
+
? compressedPublicKey
|
|
38
|
+
: secp256k1_js_1.secp256k1.getPublicKey(privateKey, false);
|
|
39
|
+
const xOnlyPubkey = compressedPublicKey.slice(1, 33);
|
|
40
|
+
return {
|
|
41
|
+
publicKey,
|
|
42
|
+
privateKey,
|
|
43
|
+
sign(hash) {
|
|
44
|
+
return secp256k1_js_1.secp256k1.sign(hash, privateKey, {
|
|
45
|
+
prehash: false,
|
|
46
|
+
lowS: true,
|
|
47
|
+
format: 'compact'
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
verify(hash, signature) {
|
|
51
|
+
return secp256k1_js_1.secp256k1.verify(signature, hash, publicKey, {
|
|
52
|
+
prehash: false,
|
|
53
|
+
lowS: true,
|
|
54
|
+
format: 'compact'
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
tweak(t) {
|
|
58
|
+
return wrapScurePrivateKey(tweakPrivateKey(privateKey, t, compressedPublicKey), compressed);
|
|
59
|
+
},
|
|
60
|
+
signSchnorr(hash) {
|
|
61
|
+
return secp256k1_js_1.schnorr.sign(hash, privateKey);
|
|
62
|
+
},
|
|
63
|
+
verifySchnorr(hash, signature) {
|
|
64
|
+
return secp256k1_js_1.schnorr.verify(signature, hash, xOnlyPubkey);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function wrapScurePublicKey(publicKey) {
|
|
69
|
+
if (!secp256k1_js_1.secp256k1.utils.isValidPublicKey(publicKey))
|
|
70
|
+
throw new Error('Error: invalid public key point');
|
|
71
|
+
const compressedPubkey = publicKey.length === 33
|
|
72
|
+
? publicKey
|
|
73
|
+
: secp256k1_js_1.secp256k1.Point.fromHex(base_1.hex.encode(publicKey)).toBytes(true);
|
|
74
|
+
const xOnlyPubkey = compressedPubkey.slice(1, 33);
|
|
75
|
+
return {
|
|
76
|
+
publicKey,
|
|
77
|
+
sign() {
|
|
78
|
+
throw new Error('Error: private key is required for signing');
|
|
79
|
+
},
|
|
80
|
+
verify(hash, signature) {
|
|
81
|
+
return secp256k1_js_1.secp256k1.verify(signature, hash, publicKey, {
|
|
82
|
+
prehash: false,
|
|
83
|
+
lowS: true,
|
|
84
|
+
format: 'compact'
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
tweak() {
|
|
88
|
+
throw new Error('Error: private key is required for tweak');
|
|
89
|
+
},
|
|
90
|
+
verifySchnorr(hash, signature) {
|
|
91
|
+
return secp256k1_js_1.schnorr.verify(signature, hash, xOnlyPubkey);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function normalizePath(path) {
|
|
96
|
+
const p = path.replaceAll('H', "'").replaceAll('h', "'");
|
|
97
|
+
if (p === 'm' || p === "m'")
|
|
98
|
+
return 'm';
|
|
99
|
+
if (p.startsWith('m/'))
|
|
100
|
+
return p;
|
|
101
|
+
if (p.startsWith('/'))
|
|
102
|
+
return `m${p}`;
|
|
103
|
+
return `m/${p}`;
|
|
104
|
+
}
|
|
105
|
+
function wrapScureHDKey(node) {
|
|
106
|
+
if (!node.publicKey)
|
|
107
|
+
throw new Error('Error: scure HDKey is missing publicKey for BIP32 usage');
|
|
108
|
+
return {
|
|
109
|
+
publicKey: node.publicKey,
|
|
110
|
+
...(node.privateKey ? { privateKey: node.privateKey } : {}),
|
|
111
|
+
fingerprint: (0, common_1.uint32ToBytesBE)(node.fingerprint),
|
|
112
|
+
derive(index) {
|
|
113
|
+
return wrapScureHDKey(node.deriveChild(index));
|
|
114
|
+
},
|
|
115
|
+
derivePath(path) {
|
|
116
|
+
return wrapScureHDKey(node.derive(normalizePath(path)));
|
|
117
|
+
},
|
|
118
|
+
neutered() {
|
|
119
|
+
return wrapScureHDKey(bip32_1.HDKey.fromExtendedKey(node.publicExtendedKey, node.versions));
|
|
120
|
+
},
|
|
121
|
+
toBase58() {
|
|
122
|
+
return node.privateKey ? node.privateExtendedKey : node.publicExtendedKey;
|
|
123
|
+
},
|
|
124
|
+
sign(hash) {
|
|
125
|
+
if (!node.privateKey)
|
|
126
|
+
throw new Error('Error: cannot sign with neutered ScureHDKeyLike');
|
|
127
|
+
return node.sign(hash);
|
|
128
|
+
},
|
|
129
|
+
tweak(t) {
|
|
130
|
+
if (!node.privateKey)
|
|
131
|
+
throw new Error('Error: cannot tweak a neutered ScureHDKeyLike');
|
|
132
|
+
return wrapScurePrivateKey(node.privateKey).tweak(t);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
package/dist/bip174.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal local subset of the bip174 type surface used by this codebase.
|
|
3
|
+
*
|
|
4
|
+
* This file is intentionally self-contained so the library can stop exposing
|
|
5
|
+
* `bip174` as a dependency.
|
|
6
|
+
*/
|
|
7
|
+
/** @internal */
|
|
8
|
+
export interface KeyValue {
|
|
9
|
+
key: Uint8Array;
|
|
10
|
+
value: Uint8Array;
|
|
11
|
+
}
|
|
12
|
+
/** @internal */
|
|
13
|
+
export interface PartialSig {
|
|
14
|
+
pubkey: Uint8Array;
|
|
15
|
+
signature: Uint8Array;
|
|
16
|
+
}
|
|
17
|
+
/** @internal */
|
|
18
|
+
export interface Bip32Derivation {
|
|
19
|
+
masterFingerprint: Uint8Array;
|
|
20
|
+
pubkey: Uint8Array;
|
|
21
|
+
path: string;
|
|
22
|
+
}
|
|
23
|
+
/** @internal */
|
|
24
|
+
export interface WitnessUtxo {
|
|
25
|
+
script: Uint8Array;
|
|
26
|
+
value: bigint;
|
|
27
|
+
}
|
|
28
|
+
/** @internal */
|
|
29
|
+
export type NonWitnessUtxo = Uint8Array;
|
|
30
|
+
/** @internal */
|
|
31
|
+
export type SighashType = number;
|
|
32
|
+
/** @internal */
|
|
33
|
+
export type RedeemScript = Uint8Array;
|
|
34
|
+
/** @internal */
|
|
35
|
+
export type WitnessScript = Uint8Array;
|
|
36
|
+
/** @internal */
|
|
37
|
+
export type FinalScriptSig = Uint8Array;
|
|
38
|
+
/** @internal */
|
|
39
|
+
export type FinalScriptWitness = Uint8Array;
|
|
40
|
+
/** @internal */
|
|
41
|
+
export type TapKeySig = Uint8Array;
|
|
42
|
+
/** @internal */
|
|
43
|
+
export type TapInternalKey = Uint8Array;
|
|
44
|
+
/** @internal */
|
|
45
|
+
export type TapMerkleRoot = Uint8Array;
|
|
46
|
+
/** @internal */
|
|
47
|
+
export interface TapScriptSig extends PartialSig {
|
|
48
|
+
leafHash: Uint8Array;
|
|
49
|
+
}
|
|
50
|
+
/** @internal */
|
|
51
|
+
export interface TapLeafScript {
|
|
52
|
+
controlBlock: Uint8Array;
|
|
53
|
+
leafVersion: number;
|
|
54
|
+
script: Uint8Array;
|
|
55
|
+
}
|
|
56
|
+
/** @internal */
|
|
57
|
+
export interface TapBip32Derivation extends Bip32Derivation {
|
|
58
|
+
leafHashes: Uint8Array[];
|
|
59
|
+
}
|
|
60
|
+
/** @internal */
|
|
61
|
+
export interface PsbtInputUpdate {
|
|
62
|
+
partialSig?: PartialSig[];
|
|
63
|
+
nonWitnessUtxo?: NonWitnessUtxo;
|
|
64
|
+
witnessUtxo?: WitnessUtxo;
|
|
65
|
+
sighashType?: SighashType;
|
|
66
|
+
redeemScript?: RedeemScript;
|
|
67
|
+
witnessScript?: WitnessScript;
|
|
68
|
+
bip32Derivation?: Bip32Derivation[];
|
|
69
|
+
finalScriptSig?: FinalScriptSig;
|
|
70
|
+
finalScriptWitness?: FinalScriptWitness;
|
|
71
|
+
tapKeySig?: TapKeySig;
|
|
72
|
+
tapScriptSig?: TapScriptSig[];
|
|
73
|
+
tapLeafScript?: TapLeafScript[];
|
|
74
|
+
tapBip32Derivation?: TapBip32Derivation[];
|
|
75
|
+
tapInternalKey?: TapInternalKey;
|
|
76
|
+
tapMerkleRoot?: TapMerkleRoot;
|
|
77
|
+
}
|
|
78
|
+
/** @internal */
|
|
79
|
+
export interface PsbtInput extends PsbtInputUpdate {
|
|
80
|
+
unknownKeyVals?: KeyValue[];
|
|
81
|
+
}
|
|
82
|
+
/** @internal */
|
|
83
|
+
export interface PsbtInputExtended extends PsbtInput {
|
|
84
|
+
[index: string]: unknown;
|
|
85
|
+
}
|
|
86
|
+
/** @internal */
|
|
87
|
+
export declare function checkForInput(inputs: PsbtInput[], inputIndex: number): PsbtInput;
|
package/dist/bip174.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2026 Jose-Luis Landabaso - https://bitcoinerlab.com
|
|
3
|
+
// Distributed under the MIT software license
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.checkForInput = checkForInput;
|
|
6
|
+
/** @internal */
|
|
7
|
+
function checkForInput(inputs, inputIndex) {
|
|
8
|
+
const input = inputs[inputIndex];
|
|
9
|
+
if (!input)
|
|
10
|
+
throw new Error(`No input #${inputIndex}`);
|
|
11
|
+
return input;
|
|
12
|
+
}
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This module defines the BitcoinLib interface – the abstraction boundary
|
|
3
|
+
* between the descriptor library core and the underlying Bitcoin
|
|
4
|
+
* implementation (bitcoinjs-lib, @scure/btc-signer, or any other).
|
|
5
|
+
*
|
|
6
|
+
* Adapters implement this interface. The core library receives it via
|
|
7
|
+
* DescriptorsFactory and threads it through closures.
|
|
8
|
+
*/
|
|
9
|
+
import type { Network } from './networks';
|
|
10
|
+
import type { PsbtInput } from './bip174';
|
|
11
|
+
/**
|
|
12
|
+
* Structural signer interface accepted by this library for single-key signing.
|
|
13
|
+
*
|
|
14
|
+
* In practice, pass an object from
|
|
15
|
+
* {@link https://github.com/bitcoinjs/ecpair | `ecpair`} (bitcoinjs stack).
|
|
16
|
+
*
|
|
17
|
+
* Example (bitcoinjs stack):
|
|
18
|
+
* ```ts
|
|
19
|
+
* import * as ecc from '@bitcoinerlab/secp256k1';
|
|
20
|
+
* import { ECPairFactory } from 'ecpair';
|
|
21
|
+
*
|
|
22
|
+
* const ECPair = ECPairFactory(ecc);
|
|
23
|
+
* const signer = ECPair.fromWIF('L1...');
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export interface ECPairInterfaceLike {
|
|
27
|
+
publicKey: Uint8Array;
|
|
28
|
+
privateKey?: Uint8Array;
|
|
29
|
+
sign(hash: Uint8Array, lowR?: boolean): Uint8Array;
|
|
30
|
+
verify(hash: Uint8Array, signature: Uint8Array): boolean;
|
|
31
|
+
tweak(t: Uint8Array): ECPairInterfaceLike;
|
|
32
|
+
signSchnorr?(hash: Uint8Array): Uint8Array;
|
|
33
|
+
verifySchnorr?(hash: Uint8Array, signature: Uint8Array): boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Full bitcoinjs ecpair-compatible interface.
|
|
37
|
+
*
|
|
38
|
+
* This is exposed only for factory return typing when the adapter is the
|
|
39
|
+
* native bitcoinjs stack. Internal code should continue using
|
|
40
|
+
* `ECPairInterfaceLike`.
|
|
41
|
+
*/
|
|
42
|
+
/** @internal */
|
|
43
|
+
interface ECPairInterface extends ECPairInterfaceLike {
|
|
44
|
+
compressed: boolean;
|
|
45
|
+
network: Network;
|
|
46
|
+
lowR: boolean;
|
|
47
|
+
toWIF(): string;
|
|
48
|
+
signSchnorr(hash: Uint8Array): Uint8Array;
|
|
49
|
+
verifySchnorr(hash: Uint8Array, signature: Uint8Array): boolean;
|
|
50
|
+
tweak(t: Uint8Array): ECPairInterface;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Structural HD node interface accepted by this library.
|
|
54
|
+
*
|
|
55
|
+
* In practice, pass a node from
|
|
56
|
+
* {@link https://github.com/bitcoinjs/bip32 | `bip32`} (bitcoinjs stack).
|
|
57
|
+
*
|
|
58
|
+
* Example (bitcoinjs stack):
|
|
59
|
+
* ```ts
|
|
60
|
+
* import * as ecc from '@bitcoinerlab/secp256k1';
|
|
61
|
+
* import { BIP32Factory } from 'bip32';
|
|
62
|
+
*
|
|
63
|
+
* const BIP32 = BIP32Factory(ecc);
|
|
64
|
+
* const node = BIP32.fromSeed(seedBytes);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export interface BIP32InterfaceLike {
|
|
68
|
+
publicKey: Uint8Array;
|
|
69
|
+
privateKey?: Uint8Array;
|
|
70
|
+
fingerprint: Uint8Array;
|
|
71
|
+
derive(index: number): BIP32InterfaceLike;
|
|
72
|
+
derivePath(path: string): BIP32InterfaceLike;
|
|
73
|
+
neutered(): BIP32InterfaceLike;
|
|
74
|
+
toBase58(): string;
|
|
75
|
+
sign(hash: Uint8Array): Uint8Array;
|
|
76
|
+
tweak(t: Uint8Array): Omit<ECPairInterfaceLike, 'tweak' | 'privateKey'>;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Full bitcoinjs bip32-compatible interface.
|
|
80
|
+
*
|
|
81
|
+
* This is exposed only for factory return typing when the adapter is the
|
|
82
|
+
* native bitcoinjs stack. Internal code should continue using
|
|
83
|
+
* `BIP32InterfaceLike`.
|
|
84
|
+
*/
|
|
85
|
+
/** @internal */
|
|
86
|
+
interface BIP32Interface extends BIP32InterfaceLike {
|
|
87
|
+
chainCode: Uint8Array;
|
|
88
|
+
network: Network;
|
|
89
|
+
depth: number;
|
|
90
|
+
index: number;
|
|
91
|
+
parentFingerprint: number;
|
|
92
|
+
identifier: Uint8Array;
|
|
93
|
+
isNeutered(): boolean;
|
|
94
|
+
neutered(): BIP32Interface;
|
|
95
|
+
derive(index: number): BIP32Interface;
|
|
96
|
+
deriveHardened(index: number): BIP32Interface;
|
|
97
|
+
derivePath(path: string): BIP32Interface;
|
|
98
|
+
toWIF(): string;
|
|
99
|
+
tweak(t: Uint8Array): Omit<ECPairInterface, 'tweak' | 'privateKey'>;
|
|
100
|
+
lowR: boolean;
|
|
101
|
+
verify(hash: Uint8Array, signature: Uint8Array): boolean;
|
|
102
|
+
signSchnorr(hash: Uint8Array): Uint8Array;
|
|
103
|
+
verifySchnorr(hash: Uint8Array, signature: Uint8Array): boolean;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Structural subset of
|
|
107
|
+
* {@link https://github.com/paulmillr/scure-bip32 | `@scure/bip32` `HDKey`}.
|
|
108
|
+
*
|
|
109
|
+
* Use this when signing with the scure stack.
|
|
110
|
+
*
|
|
111
|
+
* Example (scure stack):
|
|
112
|
+
* ```ts
|
|
113
|
+
* import { HDKey } from '@scure/bip32';
|
|
114
|
+
*
|
|
115
|
+
* const masterNode = HDKey.fromMasterSeed(seedBytes);
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
export interface ScureHDKeyLike {
|
|
119
|
+
publicKey: Uint8Array | null;
|
|
120
|
+
privateKey: Uint8Array | null;
|
|
121
|
+
fingerprint: number;
|
|
122
|
+
versions?: {
|
|
123
|
+
public: number;
|
|
124
|
+
private: number;
|
|
125
|
+
};
|
|
126
|
+
derive(path: string): ScureHDKeyLike;
|
|
127
|
+
deriveChild(index: number): ScureHDKeyLike;
|
|
128
|
+
sign(hash: Uint8Array): Uint8Array;
|
|
129
|
+
publicExtendedKey: string;
|
|
130
|
+
privateExtendedKey: string;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Internal key-factory shape used by this library.
|
|
134
|
+
*
|
|
135
|
+
* In user code, this usually corresponds to
|
|
136
|
+
* {@link https://github.com/bitcoinjs/ecpair | `ECPairFactory` output}.
|
|
137
|
+
* @internal
|
|
138
|
+
*/
|
|
139
|
+
export interface ECPairAPILike {
|
|
140
|
+
isPoint(maybePoint: unknown): boolean;
|
|
141
|
+
fromPublicKey(buffer: Uint8Array, options?: {
|
|
142
|
+
compressed?: boolean;
|
|
143
|
+
network?: Network;
|
|
144
|
+
}): ECPairInterfaceLike;
|
|
145
|
+
fromWIF(wifString: string, network?: Network | Network[]): ECPairInterfaceLike;
|
|
146
|
+
}
|
|
147
|
+
/** Full bitcoinjs ecpair-compatible API.
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
150
|
+
export interface ECPairAPI {
|
|
151
|
+
isPoint(maybePoint: unknown): boolean;
|
|
152
|
+
fromPrivateKey(buffer: Uint8Array, options?: {
|
|
153
|
+
compressed?: boolean;
|
|
154
|
+
network?: Network;
|
|
155
|
+
}): ECPairInterface;
|
|
156
|
+
fromPublicKey(buffer: Uint8Array, options?: {
|
|
157
|
+
compressed?: boolean;
|
|
158
|
+
network?: Network;
|
|
159
|
+
}): ECPairInterface;
|
|
160
|
+
makeRandom(options?: {
|
|
161
|
+
compressed?: boolean;
|
|
162
|
+
network?: Network;
|
|
163
|
+
rng?: (arg?: number) => Uint8Array;
|
|
164
|
+
}): ECPairInterface;
|
|
165
|
+
fromWIF(wifString: string, network?: Network | Network[]): ECPairInterface;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Internal HD-factory shape used by this library.
|
|
169
|
+
*
|
|
170
|
+
* In user code, this usually corresponds to
|
|
171
|
+
* {@link https://github.com/bitcoinjs/bip32 | `BIP32Factory` output}.
|
|
172
|
+
* @internal
|
|
173
|
+
*/
|
|
174
|
+
export interface BIP32APILike {
|
|
175
|
+
fromBase58(inString: string, network?: Network): BIP32InterfaceLike;
|
|
176
|
+
}
|
|
177
|
+
/** Full bitcoinjs bip32-compatible API.
|
|
178
|
+
* @internal
|
|
179
|
+
*/
|
|
180
|
+
export interface BIP32API {
|
|
181
|
+
fromSeed(seed: Uint8Array, network?: Network): BIP32Interface;
|
|
182
|
+
fromBase58(inString: string, network?: Network): BIP32Interface;
|
|
183
|
+
fromPublicKey(publicKey: Uint8Array, chainCode: Uint8Array, network?: Network): BIP32Interface;
|
|
184
|
+
fromPrivateKey(privateKey: Uint8Array, chainCode: Uint8Array, network?: Network): BIP32Interface;
|
|
185
|
+
}
|
|
186
|
+
/** @internal */
|
|
187
|
+
export interface Payment {
|
|
188
|
+
output?: Uint8Array;
|
|
189
|
+
address?: string;
|
|
190
|
+
input?: Uint8Array;
|
|
191
|
+
witness?: Uint8Array[];
|
|
192
|
+
redeem?: Payment;
|
|
193
|
+
hash?: Uint8Array;
|
|
194
|
+
pubkey?: Uint8Array;
|
|
195
|
+
/** Taproot x-only internal pubkey (32 bytes). */
|
|
196
|
+
internalPubkey?: Uint8Array;
|
|
197
|
+
network?: Network;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Minimal PSBT interface consumed by this library.
|
|
201
|
+
*
|
|
202
|
+
* This is intentionally a bitcoinjs-compatible structural subset so raw
|
|
203
|
+
* `bitcoinjs-lib.Psbt` instances can be passed directly to public APIs.
|
|
204
|
+
* The scure adapter maps `@scure/btc-signer.Transaction` to this surface.
|
|
205
|
+
* @internal
|
|
206
|
+
*/
|
|
207
|
+
export interface PsbtTxInput {
|
|
208
|
+
hash: Uint8Array;
|
|
209
|
+
index: number;
|
|
210
|
+
sequence?: number;
|
|
211
|
+
}
|
|
212
|
+
/** @internal */
|
|
213
|
+
export type PsbtLikeInputUpdate = Partial<PsbtInput>;
|
|
214
|
+
/**
|
|
215
|
+
* Minimal interface compatible with bitcoinjs-lib Psbt.
|
|
216
|
+
*
|
|
217
|
+
* In user code, simply pass a concrete
|
|
218
|
+
* {@link https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/ts_src/psbt.ts | bitcoinjs-lib `Psbt`}.
|
|
219
|
+
*
|
|
220
|
+
* Example (bitcoinjs stack):
|
|
221
|
+
* ```ts
|
|
222
|
+
* import { Psbt, networks } from 'bitcoinjs-lib';
|
|
223
|
+
*
|
|
224
|
+
* const psbt = new Psbt({ network: networks.bitcoin });
|
|
225
|
+
* ```
|
|
226
|
+
*
|
|
227
|
+
* Notes:
|
|
228
|
+
* - This interface is structural and intentionally minimal.
|
|
229
|
+
* - Some nested fields use internal helper types (for docs bloat control).
|
|
230
|
+
*/
|
|
231
|
+
export interface PsbtLike {
|
|
232
|
+
addInput(input: PsbtInput): void;
|
|
233
|
+
addOutput(output: {
|
|
234
|
+
script: Uint8Array;
|
|
235
|
+
value: bigint;
|
|
236
|
+
}): void;
|
|
237
|
+
readonly inputCount: number;
|
|
238
|
+
readonly data: {
|
|
239
|
+
inputs: PsbtInput[];
|
|
240
|
+
};
|
|
241
|
+
readonly txInputs: PsbtTxInput[];
|
|
242
|
+
setLocktime(locktime: number): void;
|
|
243
|
+
readonly locktime: number;
|
|
244
|
+
signInput(index: number, signer: ECPairInterfaceLike): void;
|
|
245
|
+
signAllInputs(signer: ECPairInterfaceLike): void;
|
|
246
|
+
signInputHD(index: number, hdSigner: BIP32InterfaceLike): void;
|
|
247
|
+
signAllInputsHD(hdSigner: BIP32InterfaceLike): void;
|
|
248
|
+
finalizeInput(index: number, finalizer?: FinalScriptsFunc): void;
|
|
249
|
+
finalizeTaprootInput(index: number, tapLeafHashToFinalize: Uint8Array | undefined, finalizer: () => {
|
|
250
|
+
finalScriptWitness: Uint8Array;
|
|
251
|
+
}): void;
|
|
252
|
+
validateSignaturesOfInput(index: number, validator: (pubkey: Uint8Array, msghash: Uint8Array, signature: Uint8Array) => boolean): boolean;
|
|
253
|
+
updateInput(index: number, data: PsbtLikeInputUpdate): void;
|
|
254
|
+
toBase64(): string;
|
|
255
|
+
}
|
|
256
|
+
/** @internal */
|
|
257
|
+
export type FinalScriptsFunc = (inputIndex: number, input: PsbtInput, script: Uint8Array, isSegwit: boolean, isP2SH: boolean, isP2WSH: boolean) => {
|
|
258
|
+
finalScriptSig: Uint8Array | undefined;
|
|
259
|
+
finalScriptWitness: Uint8Array | undefined;
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* Minimal interface compatible with @scure/btc-signer Transaction.
|
|
263
|
+
*
|
|
264
|
+
* In user code, simply pass a concrete
|
|
265
|
+
* {@link https://github.com/paulmillr/scure-btc-signer | `@scure/btc-signer` `Transaction`}.
|
|
266
|
+
*
|
|
267
|
+
* Example (scure stack):
|
|
268
|
+
* ```ts
|
|
269
|
+
* import { Transaction } from '@scure/btc-signer';
|
|
270
|
+
*
|
|
271
|
+
* const tx = new Transaction({ allowUnknownOutputs: true });
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
export interface ScureTransactionLike {
|
|
275
|
+
inputsLength: number;
|
|
276
|
+
outputsLength: number;
|
|
277
|
+
getInput(index: number): unknown;
|
|
278
|
+
getOutput(index: number): unknown;
|
|
279
|
+
addInput(input: unknown): void;
|
|
280
|
+
addOutput(output: {
|
|
281
|
+
script: Uint8Array;
|
|
282
|
+
amount: bigint;
|
|
283
|
+
}): void;
|
|
284
|
+
sign(signer: unknown): number;
|
|
285
|
+
signIdx(signer: unknown, index: number): boolean;
|
|
286
|
+
finalize(): void;
|
|
287
|
+
finalizeIdx(index: number): void;
|
|
288
|
+
toPSBT(): Uint8Array;
|
|
289
|
+
lockTime: number;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Type guard to detect if a transaction object is a
|
|
293
|
+
* `@scure/btc-signer` `Transaction`.
|
|
294
|
+
* Checks for scure-specific properties that distinguish it from bitcoinjs-lib Psbt.
|
|
295
|
+
* @internal
|
|
296
|
+
*/
|
|
297
|
+
export declare function isScureTransaction(psbt: PsbtLike | ScureTransactionLike): psbt is ScureTransactionLike;
|
|
298
|
+
/** @internal */
|
|
299
|
+
export interface Transaction {
|
|
300
|
+
getId(): string;
|
|
301
|
+
outs: Array<{
|
|
302
|
+
script: Uint8Array;
|
|
303
|
+
value: bigint;
|
|
304
|
+
}>;
|
|
305
|
+
toBuffer(): Uint8Array;
|
|
306
|
+
}
|
|
307
|
+
/** @internal */
|
|
308
|
+
export type Tapleaf = {
|
|
309
|
+
output: Uint8Array;
|
|
310
|
+
version?: number;
|
|
311
|
+
};
|
|
312
|
+
/** @internal */
|
|
313
|
+
export type Taptree = [Taptree | Tapleaf, Taptree | Tapleaf] | Tapleaf;
|
|
314
|
+
/**
|
|
315
|
+
* The complete Bitcoin backend adapter.
|
|
316
|
+
*
|
|
317
|
+
* Implementations wrap either bitcoinjs-lib or @scure/btc-signer.
|
|
318
|
+
* Received by `DescriptorsFactory` and threaded through the library.
|
|
319
|
+
* @internal
|
|
320
|
+
*/
|
|
321
|
+
export interface BitcoinLib {
|
|
322
|
+
payments: {
|
|
323
|
+
p2pk(a: {
|
|
324
|
+
pubkey: Uint8Array;
|
|
325
|
+
network?: Network;
|
|
326
|
+
}): Payment;
|
|
327
|
+
p2pkh(a: {
|
|
328
|
+
pubkey?: Uint8Array;
|
|
329
|
+
hash?: Uint8Array;
|
|
330
|
+
output?: Uint8Array;
|
|
331
|
+
network?: Network;
|
|
332
|
+
}): Payment;
|
|
333
|
+
p2sh(a: {
|
|
334
|
+
redeem?: Payment;
|
|
335
|
+
output?: Uint8Array;
|
|
336
|
+
network?: Network;
|
|
337
|
+
}): Payment;
|
|
338
|
+
p2wpkh(a: {
|
|
339
|
+
pubkey?: Uint8Array;
|
|
340
|
+
hash?: Uint8Array;
|
|
341
|
+
output?: Uint8Array;
|
|
342
|
+
network?: Network;
|
|
343
|
+
}): Payment;
|
|
344
|
+
p2wsh(a: {
|
|
345
|
+
redeem?: Payment;
|
|
346
|
+
output?: Uint8Array;
|
|
347
|
+
network?: Network;
|
|
348
|
+
}): Payment;
|
|
349
|
+
p2ms(a: {
|
|
350
|
+
m: number;
|
|
351
|
+
pubkeys: Uint8Array[];
|
|
352
|
+
network?: Network;
|
|
353
|
+
}): Payment;
|
|
354
|
+
p2tr(a: {
|
|
355
|
+
internalPubkey?: Uint8Array;
|
|
356
|
+
scriptTree?: Taptree;
|
|
357
|
+
redeem?: {
|
|
358
|
+
output: Uint8Array;
|
|
359
|
+
redeemVersion?: number;
|
|
360
|
+
};
|
|
361
|
+
output?: Uint8Array;
|
|
362
|
+
network?: Network;
|
|
363
|
+
}): Payment;
|
|
364
|
+
};
|
|
365
|
+
script: {
|
|
366
|
+
fromASM(asm: string): Uint8Array;
|
|
367
|
+
toStack(scriptBuf: Uint8Array): Uint8Array[];
|
|
368
|
+
decompile(scriptBuf: Uint8Array): Array<number | Uint8Array> | null;
|
|
369
|
+
countNonPushOnlyOPs(chunks: Array<number | Uint8Array>): number;
|
|
370
|
+
number: {
|
|
371
|
+
encode(n: number): Uint8Array;
|
|
372
|
+
};
|
|
373
|
+
};
|
|
374
|
+
Transaction: {
|
|
375
|
+
fromHex(hex: string): Transaction;
|
|
376
|
+
fromBuffer(buf: Uint8Array): Transaction;
|
|
377
|
+
};
|
|
378
|
+
address: {
|
|
379
|
+
toOutputScript(addr: string, network?: Network): Uint8Array;
|
|
380
|
+
};
|
|
381
|
+
ECPair: ECPairAPILike;
|
|
382
|
+
BIP32: BIP32APILike;
|
|
383
|
+
verifySchnorr(msghash: Uint8Array, pubkey: Uint8Array, signature: Uint8Array): boolean;
|
|
384
|
+
}
|
|
385
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2026 Jose-Luis Landabaso - https://bitcoinerlab.com
|
|
3
|
+
// Distributed under the MIT software license
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.isScureTransaction = isScureTransaction;
|
|
6
|
+
/**
|
|
7
|
+
* Type guard to detect if a transaction object is a
|
|
8
|
+
* `@scure/btc-signer` `Transaction`.
|
|
9
|
+
* Checks for scure-specific properties that distinguish it from bitcoinjs-lib Psbt.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
function isScureTransaction(psbt) {
|
|
13
|
+
const candidate = psbt;
|
|
14
|
+
return ('inputsLength' in candidate &&
|
|
15
|
+
'outputsLength' in candidate &&
|
|
16
|
+
'toPSBT' in candidate &&
|
|
17
|
+
typeof candidate.toPSBT === 'function' &&
|
|
18
|
+
'lockTime' in candidate);
|
|
19
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PsbtInput } from './bip174';
|
|
2
|
+
import { type Tapleaf } from './bitcoinLib';
|
|
3
|
+
export declare function tapleafHash(leaf: Tapleaf): Uint8Array;
|
|
4
|
+
export declare function tapTweakHash(pubKey: Uint8Array, h?: Uint8Array): Uint8Array;
|
|
5
|
+
export declare function witnessStackToScriptWitness(witness: Uint8Array[]): Uint8Array;
|
|
6
|
+
export declare function isTaprootInput(input: PsbtInput | undefined): boolean;
|