@scure/btc-signer 0.5.0 → 1.0.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 +51 -35
- package/index.d.ts +149 -60
- package/index.d.ts.map +1 -1
- package/index.js +41 -8
- package/index.js.map +1 -1
- package/index.ts +51 -21
- package/package.json +8 -8
package/index.ts
CHANGED
|
@@ -26,6 +26,23 @@ const concat = P.concatBytes;
|
|
|
26
26
|
// Make base58check work
|
|
27
27
|
export const base58check = _b58(sha256);
|
|
28
28
|
|
|
29
|
+
export function cloneDeep<T>(obj: T): T {
|
|
30
|
+
if (Array.isArray(obj)) return obj.map((i) => cloneDeep(i)) as unknown as T;
|
|
31
|
+
// slice of nodejs Buffer doesn't copy
|
|
32
|
+
else if (obj instanceof Uint8Array) return Uint8Array.from(obj) as unknown as T;
|
|
33
|
+
// immutable
|
|
34
|
+
else if (['number', 'bigint', 'boolean', 'string', 'undefined'].includes(typeof obj)) return obj;
|
|
35
|
+
// null is object
|
|
36
|
+
else if (obj === null) return obj;
|
|
37
|
+
// should be last, so it won't catch other types
|
|
38
|
+
else if (typeof obj === 'object') {
|
|
39
|
+
return Object.fromEntries(
|
|
40
|
+
Object.entries(obj).map(([k, v]) => [k, cloneDeep(v)])
|
|
41
|
+
) as unknown as T;
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`cloneDeep: unknown type=${obj} (${typeof obj})`);
|
|
44
|
+
}
|
|
45
|
+
|
|
29
46
|
enum PubT {
|
|
30
47
|
ecdsa,
|
|
31
48
|
schnorr,
|
|
@@ -463,7 +480,7 @@ const PSBTGlobal = {
|
|
|
463
480
|
outputCount: [0x05, false, CompactSizeLen, [2], [2], false],
|
|
464
481
|
txModifiable: [0x06, false, P.U8, [], [2], false], // TODO: bitfield
|
|
465
482
|
version: [0xfb, false, P.U32LE, [], [0, 2], false],
|
|
466
|
-
|
|
483
|
+
proprietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
|
|
467
484
|
} as const;
|
|
468
485
|
// prettier-ignore
|
|
469
486
|
const PSBTInput = {
|
|
@@ -492,7 +509,7 @@ const PSBTInput = {
|
|
|
492
509
|
tapBip32Derivation: [0x16, Bytes32, TaprootBIP32Der, [], [0, 2], false],
|
|
493
510
|
tapInternalKey: [0x17, false, PubKeySchnorr, [], [0, 2], false],
|
|
494
511
|
tapMerkleRoot: [0x18, false, Bytes32, [], [0, 2], false],
|
|
495
|
-
|
|
512
|
+
proprietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
|
|
496
513
|
} as const;
|
|
497
514
|
// All other keys removed when finalizing
|
|
498
515
|
const PSBTInputFinalKeys: (keyof TransactionInput)[] = [
|
|
@@ -525,7 +542,7 @@ const PSBTOutput = {
|
|
|
525
542
|
tapInternalKey: [0x05, false, PubKeySchnorr, [], [0, 2], false],
|
|
526
543
|
tapTree: [0x06, false, tapTree, [], [0, 2], false],
|
|
527
544
|
tapBip32Derivation: [0x07, PubKeySchnorr, TaprootBIP32Der, [], [0, 2], false],
|
|
528
|
-
|
|
545
|
+
proprietary: [0xfc, BytesInf, BytesInf, [], [0, 2], false],
|
|
529
546
|
} as const;
|
|
530
547
|
|
|
531
548
|
// Can be modified even on signed input
|
|
@@ -564,10 +581,11 @@ function PSBTKeyMap<T extends PSBTKeyMap>(psbtEnum: T): P.CoderType<PSBTKeyMapKe
|
|
|
564
581
|
const val = value[name];
|
|
565
582
|
if (val === undefined) continue;
|
|
566
583
|
const [type, kc, vc] = psbtEnum[name];
|
|
567
|
-
if (!kc)
|
|
568
|
-
|
|
584
|
+
if (!kc) {
|
|
585
|
+
out.push({ key: { type, key: P.EMPTY }, value: vc.encode(val) });
|
|
586
|
+
} else {
|
|
569
587
|
// Low level interface, returns keys as is (with duplicates). Useful for debug
|
|
570
|
-
const kv: [Bytes, Bytes][] = val
|
|
588
|
+
const kv: [Bytes, Bytes][] = val!.map(
|
|
571
589
|
([k, v]: [P.UnwrapCoder<typeof kc>, P.UnwrapCoder<typeof vc>]) => [
|
|
572
590
|
kc.encode(k),
|
|
573
591
|
vc.encode(v),
|
|
@@ -1538,10 +1556,7 @@ function cleanFinalInput(i: TransactionInput) {
|
|
|
1538
1556
|
}
|
|
1539
1557
|
|
|
1540
1558
|
export type TransactionOutput = P.UnwrapCoder<typeof PSBTOutputCoder>;
|
|
1541
|
-
export type TransactionOutputUpdate = ExtendType<
|
|
1542
|
-
TransactionOutput,
|
|
1543
|
-
{ amount?: string | number; script?: string }
|
|
1544
|
-
>;
|
|
1559
|
+
export type TransactionOutputUpdate = ExtendType<TransactionOutput, { script?: string }>;
|
|
1545
1560
|
export type TransactionOutputRequired = {
|
|
1546
1561
|
script: Bytes;
|
|
1547
1562
|
amount: bigint;
|
|
@@ -1642,6 +1657,17 @@ function validateOpts(opts: TxOpts) {
|
|
|
1642
1657
|
}
|
|
1643
1658
|
|
|
1644
1659
|
export class Transaction {
|
|
1660
|
+
private global: PSBTKeyMapKeys<typeof PSBTGlobal> = {};
|
|
1661
|
+
private inputs: TransactionInput[] = []; // use getInput()
|
|
1662
|
+
private outputs: TransactionOutput[] = []; // use getOutput()
|
|
1663
|
+
readonly opts: ReturnType<typeof validateOpts>;
|
|
1664
|
+
constructor(opts: TxOpts = {}) {
|
|
1665
|
+
const _opts = (this.opts = validateOpts(opts));
|
|
1666
|
+
// Merge with global structure of PSBTv2
|
|
1667
|
+
if (_opts.lockTime !== DEFAULT_LOCKTIME) this.global.fallbackLocktime = _opts.lockTime;
|
|
1668
|
+
this.global.txVersion = _opts.version;
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1645
1671
|
// Import
|
|
1646
1672
|
static fromRaw(raw: Bytes, opts: TxOpts = {}) {
|
|
1647
1673
|
const parsed = RawTx.decode(raw);
|
|
@@ -1687,7 +1713,7 @@ export class Transaction {
|
|
|
1687
1713
|
...i,
|
|
1688
1714
|
...parsed.global.unsignedTx?.outputs[j],
|
|
1689
1715
|
}));
|
|
1690
|
-
tx.global = { ...parsed.global, txVersion: version }; // just in case
|
|
1716
|
+
tx.global = { ...parsed.global, txVersion: version }; // just in case proprietary/unknown fields
|
|
1691
1717
|
if (lockTime !== DEFAULT_LOCKTIME) tx.global.fallbackLocktime = lockTime;
|
|
1692
1718
|
return tx;
|
|
1693
1719
|
}
|
|
@@ -1725,16 +1751,6 @@ export class Transaction {
|
|
|
1725
1751
|
outputs,
|
|
1726
1752
|
});
|
|
1727
1753
|
}
|
|
1728
|
-
private global: PSBTKeyMapKeys<typeof PSBTGlobal> = {};
|
|
1729
|
-
private inputs: TransactionInput[] = [];
|
|
1730
|
-
private outputs: TransactionOutput[] = [];
|
|
1731
|
-
readonly opts: ReturnType<typeof validateOpts>;
|
|
1732
|
-
constructor(opts: TxOpts = {}) {
|
|
1733
|
-
const _opts = (this.opts = validateOpts(opts));
|
|
1734
|
-
// Merge with global structure of PSBTv2
|
|
1735
|
-
if (_opts.lockTime !== DEFAULT_LOCKTIME) this.global.fallbackLocktime = _opts.lockTime;
|
|
1736
|
-
this.global.txVersion = _opts.version;
|
|
1737
|
-
}
|
|
1738
1754
|
|
|
1739
1755
|
// BIP370 lockTime (https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#determining-lock-time)
|
|
1740
1756
|
get lockTime() {
|
|
@@ -1884,6 +1900,13 @@ export class Transaction {
|
|
|
1884
1900
|
if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.inputs.length)
|
|
1885
1901
|
throw new Error(`Wrong input index=${idx}`);
|
|
1886
1902
|
}
|
|
1903
|
+
getInput(idx: number) {
|
|
1904
|
+
this.checkInputIdx(idx);
|
|
1905
|
+
return cloneDeep(this.inputs[idx]);
|
|
1906
|
+
}
|
|
1907
|
+
get inputsLength() {
|
|
1908
|
+
return this.inputs.length;
|
|
1909
|
+
}
|
|
1887
1910
|
// Modification
|
|
1888
1911
|
private normalizeInput(
|
|
1889
1912
|
i: TransactionInputUpdate,
|
|
@@ -1934,6 +1957,13 @@ export class Transaction {
|
|
|
1934
1957
|
if (!Number.isSafeInteger(idx) || 0 > idx || idx >= this.outputs.length)
|
|
1935
1958
|
throw new Error(`Wrong output index=${idx}`);
|
|
1936
1959
|
}
|
|
1960
|
+
getOutput(idx: number) {
|
|
1961
|
+
this.checkOutputIdx(idx);
|
|
1962
|
+
return cloneDeep(this.outputs[idx]);
|
|
1963
|
+
}
|
|
1964
|
+
get outputsLength() {
|
|
1965
|
+
return this.outputs.length;
|
|
1966
|
+
}
|
|
1937
1967
|
private normalizeOutput(
|
|
1938
1968
|
o: TransactionOutputUpdate,
|
|
1939
1969
|
cur?: TransactionOutput,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scure/btc-signer",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Audited minimal library for creating, signing & decoding Bitcoin transactions: with Schnorr, Taproot, UTXO & PSBT",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Audited & minimal library for creating, signing & decoding Bitcoin transactions: with Schnorr, Taproot, UTXO & PSBT",
|
|
5
5
|
"files": [
|
|
6
6
|
"index.js",
|
|
7
7
|
"index.js.map",
|
|
@@ -14,17 +14,17 @@
|
|
|
14
14
|
"module": "index.js",
|
|
15
15
|
"types": "index.d.ts",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@noble/curves": "~0.
|
|
18
|
-
"@noble/hashes": "~1.
|
|
19
|
-
"@scure/base": "~1.1.
|
|
17
|
+
"@noble/curves": "~1.0.0",
|
|
18
|
+
"@noble/hashes": "~1.3.0",
|
|
19
|
+
"@scure/base": "~1.1.1",
|
|
20
20
|
"micro-packed": "~0.3.2"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@scure/bip32": "~1.
|
|
23
|
+
"@scure/bip32": "~1.3.0",
|
|
24
24
|
"micro-packed-debugger": "0.3.1",
|
|
25
25
|
"micro-should": "0.4.0",
|
|
26
|
-
"prettier": "2.
|
|
27
|
-
"typescript": "
|
|
26
|
+
"prettier": "2.8.4",
|
|
27
|
+
"typescript": "5.0.2"
|
|
28
28
|
},
|
|
29
29
|
"author": "Paul Miller (https://paulmillr.com)",
|
|
30
30
|
"license": "MIT",
|