bitcoin-wallet-connector 0.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 +208 -0
- package/lib/BitcoinConnectionProvider.d.ts +23 -0
- package/lib/BitcoinWalletAdapterConnector-Bq835yj0.mjs +123 -0
- package/lib/BitcoinWalletAdapterConnector-Bq835yj0.mjs.map +1 -0
- package/lib/BitcoinWalletAdapterConnector-DMef0iHV.js +2 -0
- package/lib/BitcoinWalletAdapterConnector-DMef0iHV.js.map +1 -0
- package/lib/BitcoinWalletAdapterConnector.d.ts +30 -0
- package/lib/BitgetWalletAdapter.impl-C_HLO7Oi.mjs +10 -0
- package/lib/BitgetWalletAdapter.impl-C_HLO7Oi.mjs.map +1 -0
- package/lib/BitgetWalletAdapter.impl-CxnKMf7U.js +2 -0
- package/lib/BitgetWalletAdapter.impl-CxnKMf7U.js.map +1 -0
- package/lib/LeatherWalletAdapter.impl-B2QgX_tO.js +2 -0
- package/lib/LeatherWalletAdapter.impl-B2QgX_tO.js.map +1 -0
- package/lib/LeatherWalletAdapter.impl-RUYx555r.mjs +184 -0
- package/lib/LeatherWalletAdapter.impl-RUYx555r.mjs.map +1 -0
- package/lib/MagicEdenWalletAdapter.impl-CrA6SGvG.mjs +235 -0
- package/lib/MagicEdenWalletAdapter.impl-CrA6SGvG.mjs.map +1 -0
- package/lib/MagicEdenWalletAdapter.impl-Di3Nu2S5.js +2 -0
- package/lib/MagicEdenWalletAdapter.impl-Di3Nu2S5.js.map +1 -0
- package/lib/OkxWalletAdapter.impl-BepoUL1B.mjs +67 -0
- package/lib/OkxWalletAdapter.impl-BepoUL1B.mjs.map +1 -0
- package/lib/OkxWalletAdapter.impl-C8kesjGu.js +2 -0
- package/lib/OkxWalletAdapter.impl-C8kesjGu.js.map +1 -0
- package/lib/UnisatCompatibleWalletAdapterImpl-Cq2Oqk1b.js +2 -0
- package/lib/UnisatCompatibleWalletAdapterImpl-Cq2Oqk1b.js.map +1 -0
- package/lib/UnisatCompatibleWalletAdapterImpl-M38FqkZI.mjs +137 -0
- package/lib/UnisatCompatibleWalletAdapterImpl-M38FqkZI.mjs.map +1 -0
- package/lib/UnisatWalletAdapter.impl-CJB22se8.mjs +14 -0
- package/lib/UnisatWalletAdapter.impl-CJB22se8.mjs.map +1 -0
- package/lib/UnisatWalletAdapter.impl-EISvxdpc.js +2 -0
- package/lib/UnisatWalletAdapter.impl-EISvxdpc.js.map +1 -0
- package/lib/WalletAdapters.types-CnvOqHFH.mjs +32 -0
- package/lib/WalletAdapters.types-CnvOqHFH.mjs.map +1 -0
- package/lib/WalletAdapters.types-De_x1lzr.js +2 -0
- package/lib/WalletAdapters.types-De_x1lzr.js.map +1 -0
- package/lib/WalletAdapters.types.d.ts +110 -0
- package/lib/XverseCompatibleWalletAdapterImpl-Bf-BK5VK.js +2 -0
- package/lib/XverseCompatibleWalletAdapterImpl-Bf-BK5VK.js.map +1 -0
- package/lib/XverseCompatibleWalletAdapterImpl-DXKnO_-V.mjs +151 -0
- package/lib/XverseCompatibleWalletAdapterImpl-DXKnO_-V.mjs.map +1 -0
- package/lib/XverseWalletAdapter.impl-CZO0RQva.mjs +105 -0
- package/lib/XverseWalletAdapter.impl-CZO0RQva.mjs.map +1 -0
- package/lib/XverseWalletAdapter.impl-lJwMi-Iv.js +2 -0
- package/lib/XverseWalletAdapter.impl-lJwMi-Iv.js.map +1 -0
- package/lib/adapters/BitgetWalletAdapter.d.ts +2 -0
- package/lib/adapters/BitgetWalletAdapter.impl.d.ts +8 -0
- package/lib/adapters/LeatherWalletAdapter.d.ts +2 -0
- package/lib/adapters/LeatherWalletAdapter.impl.d.ts +41 -0
- package/lib/adapters/MagicEdenWalletAdapter.d.ts +11 -0
- package/lib/adapters/MagicEdenWalletAdapter.impl.d.ts +22 -0
- package/lib/adapters/MockAddressWalletAdapter.d.ts +33 -0
- package/lib/adapters/OkxWalletAdapter.d.ts +2 -0
- package/lib/adapters/OkxWalletAdapter.impl.d.ts +51 -0
- package/lib/adapters/UnisatWalletAdapter.d.ts +2 -0
- package/lib/adapters/UnisatWalletAdapter.impl.d.ts +14 -0
- package/lib/adapters/XverseWalletAdapter.d.ts +3 -0
- package/lib/adapters/XverseWalletAdapter.impl.d.ts +14 -0
- package/lib/adapters/index.d.ts +7 -0
- package/lib/adapters.js +2 -0
- package/lib/adapters.js.map +1 -0
- package/lib/adapters.mjs +11 -0
- package/lib/adapters.mjs.map +1 -0
- package/lib/bitget-C7oB4Ffq.mjs +5 -0
- package/lib/bitget-C7oB4Ffq.mjs.map +1 -0
- package/lib/bitget-DXnsxx_y.js +2 -0
- package/lib/bitget-DXnsxx_y.js.map +1 -0
- package/lib/index-CaV3F1Nm.js +424 -0
- package/lib/index-CaV3F1Nm.js.map +1 -0
- package/lib/index-CcQUdePc.mjs +12224 -0
- package/lib/index-CcQUdePc.mjs.map +1 -0
- package/lib/index-D7YwhNAG.mjs +3946 -0
- package/lib/index-D7YwhNAG.mjs.map +1 -0
- package/lib/index-Zx0KcpYx.js +2 -0
- package/lib/index-Zx0KcpYx.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -0
- package/lib/index.mjs +20 -0
- package/lib/index.mjs.map +1 -0
- package/lib/leather-BoQG_CPn.mjs +5 -0
- package/lib/leather-BoQG_CPn.mjs.map +1 -0
- package/lib/leather-DJ8nWmM8.js +2 -0
- package/lib/leather-DJ8nWmM8.js.map +1 -0
- package/lib/magiceden-B36CEQa6.js +2 -0
- package/lib/magiceden-B36CEQa6.js.map +1 -0
- package/lib/magiceden-Cg7d3agI.mjs +5 -0
- package/lib/magiceden-Cg7d3agI.mjs.map +1 -0
- package/lib/misc-B5EWO_dn.mjs +10 -0
- package/lib/misc-B5EWO_dn.mjs.map +1 -0
- package/lib/misc-CigR0RqC.js +2 -0
- package/lib/misc-CigR0RqC.js.map +1 -0
- package/lib/okx-ChwzM0dK.js +2 -0
- package/lib/okx-ChwzM0dK.js.map +1 -0
- package/lib/okx-DWbHwazu.mjs +5 -0
- package/lib/okx-DWbHwazu.mjs.map +1 -0
- package/lib/react.d.ts +2 -0
- package/lib/react.js +2 -0
- package/lib/react.js.map +1 -0
- package/lib/react.mjs +128 -0
- package/lib/react.mjs.map +1 -0
- package/lib/transaction-CiLOYSE_.mjs +1063 -0
- package/lib/transaction-CiLOYSE_.mjs.map +1 -0
- package/lib/transaction-CzdnbXSo.js +2 -0
- package/lib/transaction-CzdnbXSo.js.map +1 -0
- package/lib/unisat-BvZW5h0U.js +2 -0
- package/lib/unisat-BvZW5h0U.js.map +1 -0
- package/lib/unisat-pLgab4nG.mjs +5 -0
- package/lib/unisat-pLgab4nG.mjs.map +1 -0
- package/lib/utils/StateChannel.d.ts +14 -0
- package/lib/utils/UnisatCompatibleWalletAdapterImpl.d.ts +99 -0
- package/lib/utils/XverseCompatibleWalletAdapterImpl.d.ts +80 -0
- package/lib/utils/XverseCompatibleWalletAdapterImpl_legacy.d.ts +44 -0
- package/lib/utils/bitcoinAddressHelpers.d.ts +14 -0
- package/lib/utils/bitcoinNetworkHelpers.d.ts +4 -0
- package/lib/utils/createAdapterAvailability.d.ts +15 -0
- package/lib/utils/error.d.ts +6 -0
- package/lib/utils/misc.d.ts +3 -0
- package/lib/xverse-IKOHyGi-.js +2 -0
- package/lib/xverse-IKOHyGi-.js.map +1 -0
- package/lib/xverse-iHLNanCB.mjs +5 -0
- package/lib/xverse-iHLNanCB.mjs.map +1 -0
- package/package.json +86 -0
- package/src/BitcoinConnectionProvider.stories.tsx +329 -0
- package/src/BitcoinConnectionProvider.tsx +234 -0
- package/src/BitcoinWalletAdapterConnector.ts +166 -0
- package/src/WalletAdapters.types.ts +154 -0
- package/src/_/bitget.png +0 -0
- package/src/_/leather.svg +4 -0
- package/src/_/magiceden.png +0 -0
- package/src/_/okx.png +0 -0
- package/src/_/unisat.svg +31 -0
- package/src/_/xverse.png +0 -0
- package/src/adapters/BitgetWalletAdapter.impl.ts +22 -0
- package/src/adapters/BitgetWalletAdapter.ts +44 -0
- package/src/adapters/LeatherWalletAdapter.impl.ts +324 -0
- package/src/adapters/LeatherWalletAdapter.ts +35 -0
- package/src/adapters/MagicEdenWalletAdapter.impl.ts +139 -0
- package/src/adapters/MagicEdenWalletAdapter.ts +51 -0
- package/src/adapters/MockAddressWalletAdapter.ts +199 -0
- package/src/adapters/OkxWalletAdapter.impl.ts +168 -0
- package/src/adapters/OkxWalletAdapter.ts +37 -0
- package/src/adapters/UnisatWalletAdapter.impl.ts +32 -0
- package/src/adapters/UnisatWalletAdapter.ts +50 -0
- package/src/adapters/XverseWalletAdapter.impl.ts +150 -0
- package/src/adapters/XverseWalletAdapter.ts +37 -0
- package/src/adapters/index.ts +7 -0
- package/src/env.d.ts +9 -0
- package/src/index.ts +3 -0
- package/src/react.ts +9 -0
- package/src/utils/StateChannel.ts +39 -0
- package/src/utils/UnisatCompatibleWalletAdapterImpl.ts +342 -0
- package/src/utils/XverseCompatibleWalletAdapterImpl.ts +288 -0
- package/src/utils/XverseCompatibleWalletAdapterImpl_legacy.ts +278 -0
- package/src/utils/bitcoinAddressHelpers.ts +132 -0
- package/src/utils/bitcoinNetworkHelpers.ts +17 -0
- package/src/utils/createAdapterAvailability.ts +92 -0
- package/src/utils/error.ts +13 -0
- package/src/utils/misc.ts +10 -0
|
@@ -0,0 +1,1063 @@
|
|
|
1
|
+
import { v as W, s as v, k as b, l as E, R as Dt, m as _, n as q, o as N, I as Gt, h as I, p as L, q as J, r as gt, t as wt, P as X, C as P, u as jt, V as K, w as Y, x as Qt, y as M, z as Jt, N as Kt, E as k, A as Tt, D as Xt, F as Vt, G as Zt, H as te, J as ee, K as B, Q as bt, S as It, T as $, W as Yt, Y as ne, Z as U, _ as Z, $ as at, a0 as z, a1 as F, a2 as ut, a3 as ie, a4 as V, a5 as qt, a6 as se, a7 as At, a8 as oe, a9 as re, aa as ae, ab as ue, ac as pe } from "./index-D7YwhNAG.mjs";
|
|
2
|
+
const ft = W(b(null), (n) => J(n, X.ecdsa)), nt = W(b(32), (n) => J(n, X.schnorr)), Ut = W(b(null), (n) => {
|
|
3
|
+
if (n.length !== 64 && n.length !== 65)
|
|
4
|
+
throw new Error("Schnorr signature should be 64 or 65 bytes long");
|
|
5
|
+
return n;
|
|
6
|
+
}), ot = v({
|
|
7
|
+
fingerprint: jt,
|
|
8
|
+
path: N(null, E)
|
|
9
|
+
}), zt = v({
|
|
10
|
+
hashes: N(P, b(32)),
|
|
11
|
+
der: ot
|
|
12
|
+
}), ce = b(78), le = v({ pubKey: nt, leafHash: b(32) }), fe = v({
|
|
13
|
+
version: Y,
|
|
14
|
+
// With parity :(
|
|
15
|
+
internalKey: b(32),
|
|
16
|
+
merklePath: N(null, b(32))
|
|
17
|
+
}), G = W(fe, (n) => {
|
|
18
|
+
if (n.merklePath.length > 128)
|
|
19
|
+
throw new Error("TaprootControlBlock: merklePath should be of length 0..128 (inclusive)");
|
|
20
|
+
return n;
|
|
21
|
+
}), he = N(null, v({
|
|
22
|
+
depth: Y,
|
|
23
|
+
version: Y,
|
|
24
|
+
script: K
|
|
25
|
+
})), x = b(null), Lt = b(20), H = b(32), St = {
|
|
26
|
+
unsignedTx: [0, !1, M, [0], [0], !1],
|
|
27
|
+
xpub: [1, ce, ot, [], [0, 2], !1],
|
|
28
|
+
txVersion: [2, !1, E, [2], [2], !1],
|
|
29
|
+
fallbackLocktime: [3, !1, E, [], [2], !1],
|
|
30
|
+
inputCount: [4, !1, P, [2], [2], !1],
|
|
31
|
+
outputCount: [5, !1, P, [2], [2], !1],
|
|
32
|
+
txModifiable: [6, !1, Y, [], [2], !1],
|
|
33
|
+
// TODO: bitfield
|
|
34
|
+
version: [251, !1, E, [], [0, 2], !1],
|
|
35
|
+
proprietary: [252, x, x, [], [0, 2], !1]
|
|
36
|
+
}, rt = {
|
|
37
|
+
nonWitnessUtxo: [0, !1, q, [], [0, 2], !1],
|
|
38
|
+
witnessUtxo: [1, !1, _, [], [0, 2], !1],
|
|
39
|
+
partialSig: [2, ft, x, [], [0, 2], !1],
|
|
40
|
+
sighashType: [3, !1, E, [], [0, 2], !1],
|
|
41
|
+
redeemScript: [4, !1, x, [], [0, 2], !1],
|
|
42
|
+
witnessScript: [5, !1, x, [], [0, 2], !1],
|
|
43
|
+
bip32Derivation: [6, ft, ot, [], [0, 2], !1],
|
|
44
|
+
finalScriptSig: [7, !1, x, [], [0, 2], !1],
|
|
45
|
+
finalScriptWitness: [8, !1, Dt, [], [0, 2], !1],
|
|
46
|
+
porCommitment: [9, !1, x, [], [0, 2], !1],
|
|
47
|
+
ripemd160: [10, Lt, x, [], [0, 2], !1],
|
|
48
|
+
sha256: [11, H, x, [], [0, 2], !1],
|
|
49
|
+
hash160: [12, Lt, x, [], [0, 2], !1],
|
|
50
|
+
hash256: [13, H, x, [], [0, 2], !1],
|
|
51
|
+
txid: [14, !1, H, [2], [2], !0],
|
|
52
|
+
index: [15, !1, E, [2], [2], !0],
|
|
53
|
+
sequence: [16, !1, E, [], [2], !0],
|
|
54
|
+
requiredTimeLocktime: [17, !1, E, [], [2], !1],
|
|
55
|
+
requiredHeightLocktime: [18, !1, E, [], [2], !1],
|
|
56
|
+
tapKeySig: [19, !1, Ut, [], [0, 2], !1],
|
|
57
|
+
tapScriptSig: [20, le, Ut, [], [0, 2], !1],
|
|
58
|
+
tapLeafScript: [21, G, x, [], [0, 2], !1],
|
|
59
|
+
tapBip32Derivation: [22, H, zt, [], [0, 2], !1],
|
|
60
|
+
tapInternalKey: [23, !1, nt, [], [0, 2], !1],
|
|
61
|
+
tapMerkleRoot: [24, !1, H, [], [0, 2], !1],
|
|
62
|
+
proprietary: [252, x, x, [], [0, 2], !1]
|
|
63
|
+
}, de = [
|
|
64
|
+
"txid",
|
|
65
|
+
"sequence",
|
|
66
|
+
"index",
|
|
67
|
+
"witnessUtxo",
|
|
68
|
+
"nonWitnessUtxo",
|
|
69
|
+
"finalScriptSig",
|
|
70
|
+
"finalScriptWitness",
|
|
71
|
+
"unknown"
|
|
72
|
+
], ge = [
|
|
73
|
+
"partialSig",
|
|
74
|
+
"finalScriptSig",
|
|
75
|
+
"finalScriptWitness",
|
|
76
|
+
"tapKeySig",
|
|
77
|
+
"tapScriptSig"
|
|
78
|
+
], it = {
|
|
79
|
+
redeemScript: [0, !1, x, [], [0, 2], !1],
|
|
80
|
+
witnessScript: [1, !1, x, [], [0, 2], !1],
|
|
81
|
+
bip32Derivation: [2, ft, ot, [], [0, 2], !1],
|
|
82
|
+
amount: [3, !1, Gt, [2], [2], !0],
|
|
83
|
+
script: [4, !1, x, [2], [2], !0],
|
|
84
|
+
tapInternalKey: [5, !1, nt, [], [0, 2], !1],
|
|
85
|
+
tapTree: [6, !1, he, [], [0, 2], !1],
|
|
86
|
+
tapBip32Derivation: [7, nt, zt, [], [0, 2], !1],
|
|
87
|
+
proprietary: [252, x, x, [], [0, 2], !1]
|
|
88
|
+
}, we = [], vt = N(Kt, v({
|
|
89
|
+
// <key> := <keylen> <keytype> <keydata> WHERE keylen = len(keytype)+len(keydata)
|
|
90
|
+
key: Jt(P, v({ type: P, key: b(null) })),
|
|
91
|
+
// <value> := <valuelen> <valuedata>
|
|
92
|
+
value: b(P)
|
|
93
|
+
}));
|
|
94
|
+
function ht(n) {
|
|
95
|
+
const [t, e, i, o, s, r] = n;
|
|
96
|
+
return { type: t, kc: e, vc: i, reqInc: o, allowInc: s, silentIgnore: r };
|
|
97
|
+
}
|
|
98
|
+
v({ type: P, key: b(null) });
|
|
99
|
+
function yt(n) {
|
|
100
|
+
const t = {};
|
|
101
|
+
for (const e in n) {
|
|
102
|
+
const [i, o, s] = n[e];
|
|
103
|
+
t[i] = [e, o, s];
|
|
104
|
+
}
|
|
105
|
+
return Qt({
|
|
106
|
+
encodeStream: (e, i) => {
|
|
107
|
+
let o = [];
|
|
108
|
+
for (const s in n) {
|
|
109
|
+
const r = i[s];
|
|
110
|
+
if (r === void 0)
|
|
111
|
+
continue;
|
|
112
|
+
const [a, u, f] = n[s];
|
|
113
|
+
if (!u)
|
|
114
|
+
o.push({ key: { type: a, key: k }, value: f.encode(r) });
|
|
115
|
+
else {
|
|
116
|
+
const p = r.map(([c, l]) => [
|
|
117
|
+
u.encode(c),
|
|
118
|
+
f.encode(l)
|
|
119
|
+
]);
|
|
120
|
+
p.sort((c, l) => Tt(c[0], l[0]));
|
|
121
|
+
for (const [c, l] of p)
|
|
122
|
+
o.push({ key: { key: c, type: a }, value: l });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (i.unknown) {
|
|
126
|
+
i.unknown.sort((s, r) => Tt(s[0].key, r[0].key));
|
|
127
|
+
for (const [s, r] of i.unknown)
|
|
128
|
+
o.push({ key: s, value: r });
|
|
129
|
+
}
|
|
130
|
+
vt.encodeStream(e, o);
|
|
131
|
+
},
|
|
132
|
+
decodeStream: (e) => {
|
|
133
|
+
const i = vt.decodeStream(e), o = {}, s = {};
|
|
134
|
+
for (const r of i) {
|
|
135
|
+
let a = "unknown", u = r.key.key, f = r.value;
|
|
136
|
+
if (t[r.key.type]) {
|
|
137
|
+
const [p, c, l] = t[r.key.type];
|
|
138
|
+
if (a = p, !c && u.length)
|
|
139
|
+
throw new Error(`PSBT: Non-empty key for ${a} (key=${I.encode(u)} value=${I.encode(f)}`);
|
|
140
|
+
if (u = c ? c.decode(u) : void 0, f = l.decode(f), !c) {
|
|
141
|
+
if (o[a])
|
|
142
|
+
throw new Error(`PSBT: Same keys: ${a} (key=${u} value=${f})`);
|
|
143
|
+
o[a] = f, s[a] = !0;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
} else
|
|
147
|
+
u = { type: r.key.type, key: r.key.key };
|
|
148
|
+
if (s[a])
|
|
149
|
+
throw new Error(`PSBT: Key type with empty key and no key=${a} val=${f}`);
|
|
150
|
+
o[a] || (o[a] = []), o[a].push([u, f]);
|
|
151
|
+
}
|
|
152
|
+
return o;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
const mt = W(yt(rt), (n) => {
|
|
157
|
+
if (n.finalScriptWitness && !n.finalScriptWitness.length)
|
|
158
|
+
throw new Error("validateInput: empty finalScriptWitness");
|
|
159
|
+
if (n.partialSig && !n.partialSig.length)
|
|
160
|
+
throw new Error("Empty partialSig");
|
|
161
|
+
if (n.partialSig)
|
|
162
|
+
for (const [t] of n.partialSig)
|
|
163
|
+
J(t, X.ecdsa);
|
|
164
|
+
if (n.bip32Derivation)
|
|
165
|
+
for (const [t] of n.bip32Derivation)
|
|
166
|
+
J(t, X.ecdsa);
|
|
167
|
+
if (n.requiredTimeLocktime !== void 0 && n.requiredTimeLocktime < 5e8)
|
|
168
|
+
throw new Error(`validateInput: wrong timeLocktime=${n.requiredTimeLocktime}`);
|
|
169
|
+
if (n.requiredHeightLocktime !== void 0 && (n.requiredHeightLocktime <= 0 || n.requiredHeightLocktime >= 5e8))
|
|
170
|
+
throw new Error(`validateInput: wrong heighLocktime=${n.requiredHeightLocktime}`);
|
|
171
|
+
if (n.tapLeafScript)
|
|
172
|
+
for (const [t, e] of n.tapLeafScript) {
|
|
173
|
+
if ((t.version & 254) !== e[e.length - 1])
|
|
174
|
+
throw new Error("validateInput: tapLeafScript version mimatch");
|
|
175
|
+
if (e[e.length - 1] & 1)
|
|
176
|
+
throw new Error("validateInput: tapLeafScript version has parity bit!");
|
|
177
|
+
}
|
|
178
|
+
return n;
|
|
179
|
+
}), kt = W(yt(it), (n) => {
|
|
180
|
+
if (n.bip32Derivation)
|
|
181
|
+
for (const [t] of n.bip32Derivation)
|
|
182
|
+
J(t, X.ecdsa);
|
|
183
|
+
return n;
|
|
184
|
+
}), Ft = W(yt(St), (n) => {
|
|
185
|
+
if ((n.version || 0) === 0) {
|
|
186
|
+
if (!n.unsignedTx)
|
|
187
|
+
throw new Error("PSBTv0: missing unsignedTx");
|
|
188
|
+
for (const e of n.unsignedTx.inputs)
|
|
189
|
+
if (e.finalScriptSig && e.finalScriptSig.length)
|
|
190
|
+
throw new Error("PSBTv0: input scriptSig found in unsignedTx");
|
|
191
|
+
}
|
|
192
|
+
return n;
|
|
193
|
+
}), Se = v({
|
|
194
|
+
magic: gt(wt(new Uint8Array([255])), "psbt"),
|
|
195
|
+
global: Ft,
|
|
196
|
+
inputs: N("global/unsignedTx/inputs/length", mt),
|
|
197
|
+
outputs: N(null, kt)
|
|
198
|
+
}), ye = v({
|
|
199
|
+
magic: gt(wt(new Uint8Array([255])), "psbt"),
|
|
200
|
+
global: Ft,
|
|
201
|
+
inputs: N("global/inputCount", mt),
|
|
202
|
+
outputs: N("global/outputCount", kt)
|
|
203
|
+
});
|
|
204
|
+
v({
|
|
205
|
+
magic: gt(wt(new Uint8Array([255])), "psbt"),
|
|
206
|
+
items: N(null, Xt(N(Kt, Zt([te(P), b(ee)])), Vt.dict()))
|
|
207
|
+
});
|
|
208
|
+
function pt(n, t, e) {
|
|
209
|
+
for (const i in e) {
|
|
210
|
+
if (i === "unknown" || !t[i])
|
|
211
|
+
continue;
|
|
212
|
+
const { allowInc: o } = ht(t[i]);
|
|
213
|
+
if (!o.includes(n))
|
|
214
|
+
throw new Error(`PSBTv${n}: field ${i} is not allowed`);
|
|
215
|
+
}
|
|
216
|
+
for (const i in t) {
|
|
217
|
+
const { reqInc: o } = ht(t[i]);
|
|
218
|
+
if (o.includes(n) && e[i] === void 0)
|
|
219
|
+
throw new Error(`PSBTv${n}: missing required field ${i}`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function Nt(n, t, e) {
|
|
223
|
+
const i = {};
|
|
224
|
+
for (const o in e) {
|
|
225
|
+
const s = o;
|
|
226
|
+
if (s !== "unknown") {
|
|
227
|
+
if (!t[s])
|
|
228
|
+
continue;
|
|
229
|
+
const { allowInc: r, silentIgnore: a } = ht(t[s]);
|
|
230
|
+
if (!r.includes(n)) {
|
|
231
|
+
if (a)
|
|
232
|
+
continue;
|
|
233
|
+
throw new Error(`Failed to serialize in PSBTv${n}: ${s} but versions allows inclusion=${r}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
i[s] = e[s];
|
|
237
|
+
}
|
|
238
|
+
return i;
|
|
239
|
+
}
|
|
240
|
+
function Ht(n) {
|
|
241
|
+
const t = n && n.global && n.global.version || 0;
|
|
242
|
+
pt(t, St, n.global);
|
|
243
|
+
for (const r of n.inputs)
|
|
244
|
+
pt(t, rt, r);
|
|
245
|
+
for (const r of n.outputs)
|
|
246
|
+
pt(t, it, r);
|
|
247
|
+
const e = t ? n.global.inputCount : n.global.unsignedTx.inputs.length;
|
|
248
|
+
if (n.inputs.length < e)
|
|
249
|
+
throw new Error("Not enough inputs");
|
|
250
|
+
const i = n.inputs.slice(e);
|
|
251
|
+
if (i.length > 1 || i.length && Object.keys(i[0]).length)
|
|
252
|
+
throw new Error(`Unexpected inputs left in tx=${i}`);
|
|
253
|
+
const o = t ? n.global.outputCount : n.global.unsignedTx.outputs.length;
|
|
254
|
+
if (n.outputs.length < o)
|
|
255
|
+
throw new Error("Not outputs inputs");
|
|
256
|
+
const s = n.outputs.slice(o);
|
|
257
|
+
if (s.length > 1 || s.length && Object.keys(s[0]).length)
|
|
258
|
+
throw new Error(`Unexpected outputs left in tx=${s}`);
|
|
259
|
+
return n;
|
|
260
|
+
}
|
|
261
|
+
function dt(n, t, e, i, o) {
|
|
262
|
+
const s = { ...e, ...t };
|
|
263
|
+
for (const r in n) {
|
|
264
|
+
const a = r, [u, f, p] = n[a], c = i && !i.includes(r);
|
|
265
|
+
if (t[r] === void 0 && r in t) {
|
|
266
|
+
if (c)
|
|
267
|
+
throw new Error(`Cannot remove signed field=${r}`);
|
|
268
|
+
delete s[r];
|
|
269
|
+
} else if (f) {
|
|
270
|
+
const l = e && e[r] ? e[r] : [];
|
|
271
|
+
let g = t[a];
|
|
272
|
+
if (g) {
|
|
273
|
+
if (!Array.isArray(g))
|
|
274
|
+
throw new Error(`keyMap(${r}): KV pairs should be [k, v][]`);
|
|
275
|
+
g = g.map((d) => {
|
|
276
|
+
if (d.length !== 2)
|
|
277
|
+
throw new Error(`keyMap(${r}): KV pairs should be [k, v][]`);
|
|
278
|
+
return [
|
|
279
|
+
typeof d[0] == "string" ? f.decode(I.decode(d[0])) : d[0],
|
|
280
|
+
typeof d[1] == "string" ? p.decode(I.decode(d[1])) : d[1]
|
|
281
|
+
];
|
|
282
|
+
});
|
|
283
|
+
const y = {}, w = (d, m, S) => {
|
|
284
|
+
if (y[d] === void 0) {
|
|
285
|
+
y[d] = [m, S];
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const T = I.encode(p.encode(y[d][1])), A = I.encode(p.encode(S));
|
|
289
|
+
if (T !== A)
|
|
290
|
+
throw new Error(`keyMap(${a}): same key=${d} oldVal=${T} newVal=${A}`);
|
|
291
|
+
};
|
|
292
|
+
for (const [d, m] of l) {
|
|
293
|
+
const S = I.encode(f.encode(d));
|
|
294
|
+
w(S, d, m);
|
|
295
|
+
}
|
|
296
|
+
for (const [d, m] of g) {
|
|
297
|
+
const S = I.encode(f.encode(d));
|
|
298
|
+
if (m === void 0) {
|
|
299
|
+
if (c)
|
|
300
|
+
throw new Error(`Cannot remove signed field=${a}/${d}`);
|
|
301
|
+
delete y[S];
|
|
302
|
+
} else
|
|
303
|
+
w(S, d, m);
|
|
304
|
+
}
|
|
305
|
+
s[a] = Object.values(y);
|
|
306
|
+
}
|
|
307
|
+
} else if (typeof s[r] == "string")
|
|
308
|
+
s[r] = p.decode(I.decode(s[r]));
|
|
309
|
+
else if (c && r in t && e && e[r] !== void 0 && !L(p.encode(t[r]), p.encode(e[r])))
|
|
310
|
+
throw new Error(`Cannot change signed field=${r}`);
|
|
311
|
+
}
|
|
312
|
+
for (const r in s)
|
|
313
|
+
if (!n[r]) {
|
|
314
|
+
if (o && r === "unknown")
|
|
315
|
+
continue;
|
|
316
|
+
delete s[r];
|
|
317
|
+
}
|
|
318
|
+
return s;
|
|
319
|
+
}
|
|
320
|
+
const Ot = W(Se, Ht), Pt = W(ye, Ht), tt = new Uint8Array(32), me = {
|
|
321
|
+
amount: 0xffffffffffffffffn,
|
|
322
|
+
script: k
|
|
323
|
+
}, ke = (n) => Math.ceil(n / 4), Ee = 8, xe = 2, C = 0, Rt = 4294967295;
|
|
324
|
+
Vt.decimal(Ee);
|
|
325
|
+
const j = (n, t) => n === void 0 ? t : n;
|
|
326
|
+
function st(n) {
|
|
327
|
+
if (Array.isArray(n))
|
|
328
|
+
return n.map((t) => st(t));
|
|
329
|
+
if (V(n))
|
|
330
|
+
return Uint8Array.from(n);
|
|
331
|
+
if (["number", "bigint", "boolean", "string", "undefined"].includes(typeof n))
|
|
332
|
+
return n;
|
|
333
|
+
if (n === null)
|
|
334
|
+
return n;
|
|
335
|
+
if (typeof n == "object")
|
|
336
|
+
return Object.fromEntries(Object.entries(n).map(([t, e]) => [t, st(e)]));
|
|
337
|
+
throw new Error(`cloneDeep: unknown type=${n} (${typeof n})`);
|
|
338
|
+
}
|
|
339
|
+
const h = {
|
|
340
|
+
DEFAULT: 0,
|
|
341
|
+
ALL: 1,
|
|
342
|
+
NONE: 2,
|
|
343
|
+
SINGLE: 3,
|
|
344
|
+
ANYONECANPAY: 128
|
|
345
|
+
}, Te = {
|
|
346
|
+
DEFAULT: h.DEFAULT,
|
|
347
|
+
ALL: h.ALL,
|
|
348
|
+
NONE: h.NONE,
|
|
349
|
+
SINGLE: h.SINGLE,
|
|
350
|
+
DEFAULT_ANYONECANPAY: h.DEFAULT | h.ANYONECANPAY,
|
|
351
|
+
ALL_ANYONECANPAY: h.ALL | h.ANYONECANPAY,
|
|
352
|
+
NONE_ANYONECANPAY: h.NONE | h.ANYONECANPAY,
|
|
353
|
+
SINGLE_ANYONECANPAY: h.SINGLE | h.ANYONECANPAY
|
|
354
|
+
}, be = ue(Te);
|
|
355
|
+
function Ie(n, t, e, i = k) {
|
|
356
|
+
return L(e, t) && (n = pe(n, i), t = qt(n)), { privKey: n, pubKey: t };
|
|
357
|
+
}
|
|
358
|
+
function D(n) {
|
|
359
|
+
if (n.script === void 0 || n.amount === void 0)
|
|
360
|
+
throw new Error("Transaction/output: script and amount required");
|
|
361
|
+
return { script: n.script, amount: n.amount };
|
|
362
|
+
}
|
|
363
|
+
function R(n) {
|
|
364
|
+
if (n.txid === void 0 || n.index === void 0)
|
|
365
|
+
throw new Error("Transaction/input: txid and index required");
|
|
366
|
+
return {
|
|
367
|
+
txid: n.txid,
|
|
368
|
+
index: n.index,
|
|
369
|
+
sequence: j(n.sequence, Rt),
|
|
370
|
+
finalScriptSig: j(n.finalScriptSig, k)
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function ct(n) {
|
|
374
|
+
for (const t in n) {
|
|
375
|
+
const e = t;
|
|
376
|
+
de.includes(e) || delete n[e];
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const lt = v({ txid: b(32, !0), index: E });
|
|
380
|
+
function Ae(n) {
|
|
381
|
+
if (typeof n != "number" || typeof be[n] != "string")
|
|
382
|
+
throw new Error(`Invalid SigHash=${n}`);
|
|
383
|
+
return n;
|
|
384
|
+
}
|
|
385
|
+
function $t(n) {
|
|
386
|
+
const t = n & 31;
|
|
387
|
+
return {
|
|
388
|
+
isAny: !!(n & h.ANYONECANPAY),
|
|
389
|
+
isNone: t === h.NONE,
|
|
390
|
+
isSingle: t === h.SINGLE
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
function Ue(n) {
|
|
394
|
+
if (n !== void 0 && {}.toString.call(n) !== "[object Object]")
|
|
395
|
+
throw new Error(`Wrong object type for transaction options: ${n}`);
|
|
396
|
+
const t = {
|
|
397
|
+
...n,
|
|
398
|
+
// Defaults
|
|
399
|
+
version: j(n.version, xe),
|
|
400
|
+
lockTime: j(n.lockTime, 0),
|
|
401
|
+
PSBTVersion: j(n.PSBTVersion, 0)
|
|
402
|
+
};
|
|
403
|
+
if (typeof t.allowUnknowInput < "u" && (n.allowUnknownInputs = t.allowUnknowInput), typeof t.allowUnknowOutput < "u" && (n.allowUnknownOutputs = t.allowUnknowOutput), typeof t.lockTime != "number")
|
|
404
|
+
throw new Error("Transaction lock time should be number");
|
|
405
|
+
if (E.encode(t.lockTime), t.PSBTVersion !== 0 && t.PSBTVersion !== 2)
|
|
406
|
+
throw new Error(`Unknown PSBT version ${t.PSBTVersion}`);
|
|
407
|
+
for (const e of [
|
|
408
|
+
"allowUnknownVersion",
|
|
409
|
+
"allowUnknownOutputs",
|
|
410
|
+
"allowUnknownInputs",
|
|
411
|
+
"disableScriptCheck",
|
|
412
|
+
"bip174jsCompat",
|
|
413
|
+
"allowLegacyWitnessUtxo",
|
|
414
|
+
"lowR"
|
|
415
|
+
]) {
|
|
416
|
+
const i = t[e];
|
|
417
|
+
if (i !== void 0 && typeof i != "boolean")
|
|
418
|
+
throw new Error(`Transation options wrong type: ${e}=${i} (${typeof i})`);
|
|
419
|
+
}
|
|
420
|
+
if (t.allowUnknownVersion ? typeof t.version == "number" : ![-1, 0, 1, 2, 3].includes(t.version))
|
|
421
|
+
throw new Error(`Unknown version: ${t.version}`);
|
|
422
|
+
if (t.customScripts !== void 0) {
|
|
423
|
+
const e = t.customScripts;
|
|
424
|
+
if (!Array.isArray(e))
|
|
425
|
+
throw new Error(`wrong custom scripts type (expected array): customScripts=${e} (${typeof e})`);
|
|
426
|
+
for (const i of e) {
|
|
427
|
+
if (typeof i.encode != "function" || typeof i.decode != "function")
|
|
428
|
+
throw new Error(`wrong script=${i} (${typeof i})`);
|
|
429
|
+
if (i.finalizeTaproot !== void 0 && typeof i.finalizeTaproot != "function")
|
|
430
|
+
throw new Error(`wrong script=${i} (${typeof i})`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return Object.freeze(t);
|
|
434
|
+
}
|
|
435
|
+
function Wt(n) {
|
|
436
|
+
if (n.nonWitnessUtxo && n.index !== void 0) {
|
|
437
|
+
const t = n.nonWitnessUtxo.outputs.length - 1;
|
|
438
|
+
if (n.index > t)
|
|
439
|
+
throw new Error(`validateInput: index(${n.index}) not in nonWitnessUtxo`);
|
|
440
|
+
const e = n.nonWitnessUtxo.outputs[n.index];
|
|
441
|
+
if (n.witnessUtxo && (!L(n.witnessUtxo.script, e.script) || n.witnessUtxo.amount !== e.amount))
|
|
442
|
+
throw new Error("validateInput: witnessUtxo different from nonWitnessUtxo");
|
|
443
|
+
if (n.txid) {
|
|
444
|
+
if (n.nonWitnessUtxo.outputs.length - 1 < n.index)
|
|
445
|
+
throw new Error("nonWitnessUtxo: incorect output index");
|
|
446
|
+
const o = Q.fromRaw(q.encode(n.nonWitnessUtxo), {
|
|
447
|
+
allowUnknownOutputs: !0,
|
|
448
|
+
disableScriptCheck: !0,
|
|
449
|
+
allowUnknownInputs: !0
|
|
450
|
+
}), s = I.encode(n.txid);
|
|
451
|
+
if (o.isFinal && o.id !== s)
|
|
452
|
+
throw new Error(`nonWitnessUtxo: wrong txid, exp=${s} got=${o.id}`);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return n;
|
|
456
|
+
}
|
|
457
|
+
function et(n) {
|
|
458
|
+
if (n.nonWitnessUtxo) {
|
|
459
|
+
if (n.index === void 0)
|
|
460
|
+
throw new Error("Unknown input index");
|
|
461
|
+
return n.nonWitnessUtxo.outputs[n.index];
|
|
462
|
+
} else {
|
|
463
|
+
if (n.witnessUtxo)
|
|
464
|
+
return n.witnessUtxo;
|
|
465
|
+
throw new Error("Cannot find previous output info");
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
function Bt(n, t, e, i = !1, o = !1) {
|
|
469
|
+
let { nonWitnessUtxo: s, txid: r } = n;
|
|
470
|
+
typeof s == "string" && (s = I.decode(s)), V(s) && (s = q.decode(s)), !("nonWitnessUtxo" in n) && s === void 0 && (s = t?.nonWitnessUtxo), typeof r == "string" && (r = I.decode(r)), r === void 0 && (r = t?.txid);
|
|
471
|
+
let a = { ...t, ...n, nonWitnessUtxo: s, txid: r };
|
|
472
|
+
!("nonWitnessUtxo" in n) && a.nonWitnessUtxo === void 0 && delete a.nonWitnessUtxo, a.sequence === void 0 && (a.sequence = Rt), a.tapMerkleRoot === null && delete a.tapMerkleRoot, a = dt(rt, a, t, e, o), mt.encode(a);
|
|
473
|
+
let u;
|
|
474
|
+
return a.nonWitnessUtxo && a.index !== void 0 ? u = a.nonWitnessUtxo.outputs[a.index] : a.witnessUtxo && (u = a.witnessUtxo), u && !i && Yt(u && u.script, a.redeemScript, a.witnessScript), a;
|
|
475
|
+
}
|
|
476
|
+
function Ct(n, t = !1) {
|
|
477
|
+
let e = "legacy", i = h.ALL;
|
|
478
|
+
const o = et(n), s = $.decode(o.script);
|
|
479
|
+
let r = s.type, a = s;
|
|
480
|
+
const u = [s];
|
|
481
|
+
if (s.type === "tr")
|
|
482
|
+
return i = h.DEFAULT, {
|
|
483
|
+
txType: "taproot",
|
|
484
|
+
type: "tr",
|
|
485
|
+
last: s,
|
|
486
|
+
lastScript: o.script,
|
|
487
|
+
defaultSighash: i,
|
|
488
|
+
sighash: n.sighashType || i
|
|
489
|
+
};
|
|
490
|
+
{
|
|
491
|
+
if ((s.type === "wpkh" || s.type === "wsh") && (e = "segwit"), s.type === "sh") {
|
|
492
|
+
if (!n.redeemScript)
|
|
493
|
+
throw new Error("inputType: sh without redeemScript");
|
|
494
|
+
let l = $.decode(n.redeemScript);
|
|
495
|
+
(l.type === "wpkh" || l.type === "wsh") && (e = "segwit"), u.push(l), a = l, r += `-${l.type}`;
|
|
496
|
+
}
|
|
497
|
+
if (a.type === "wsh") {
|
|
498
|
+
if (!n.witnessScript)
|
|
499
|
+
throw new Error("inputType: wsh without witnessScript");
|
|
500
|
+
let l = $.decode(n.witnessScript);
|
|
501
|
+
l.type === "wsh" && (e = "segwit"), u.push(l), a = l, r += `-${l.type}`;
|
|
502
|
+
}
|
|
503
|
+
const f = u[u.length - 1];
|
|
504
|
+
if (f.type === "sh" || f.type === "wsh")
|
|
505
|
+
throw new Error("inputType: sh/wsh cannot be terminal type");
|
|
506
|
+
const p = $.encode(f), c = {
|
|
507
|
+
type: r,
|
|
508
|
+
txType: e,
|
|
509
|
+
last: f,
|
|
510
|
+
lastScript: p,
|
|
511
|
+
defaultSighash: i,
|
|
512
|
+
sighash: n.sighashType || i
|
|
513
|
+
};
|
|
514
|
+
if (e === "legacy" && !t && !n.nonWitnessUtxo)
|
|
515
|
+
throw new Error("Transaction/sign: legacy input without nonWitnessUtxo, can result in attack that forces paying higher fees. Pass allowLegacyWitnessUtxo=true, if you sure");
|
|
516
|
+
return c;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
class Q {
|
|
520
|
+
global = {};
|
|
521
|
+
inputs = [];
|
|
522
|
+
// use getInput()
|
|
523
|
+
outputs = [];
|
|
524
|
+
// use getOutput()
|
|
525
|
+
opts;
|
|
526
|
+
constructor(t = {}) {
|
|
527
|
+
const e = this.opts = Ue(t);
|
|
528
|
+
e.lockTime !== C && (this.global.fallbackLocktime = e.lockTime), this.global.txVersion = e.version;
|
|
529
|
+
}
|
|
530
|
+
// Import
|
|
531
|
+
static fromRaw(t, e = {}) {
|
|
532
|
+
const i = q.decode(t), o = new Q({ ...e, version: i.version, lockTime: i.lockTime });
|
|
533
|
+
for (const s of i.outputs)
|
|
534
|
+
o.addOutput(s);
|
|
535
|
+
if (o.outputs = i.outputs, o.inputs = i.inputs, i.witnesses)
|
|
536
|
+
for (let s = 0; s < i.witnesses.length; s++)
|
|
537
|
+
o.inputs[s].finalScriptWitness = i.witnesses[s];
|
|
538
|
+
return o;
|
|
539
|
+
}
|
|
540
|
+
// PSBT
|
|
541
|
+
static fromPSBT(t, e = {}) {
|
|
542
|
+
let i;
|
|
543
|
+
try {
|
|
544
|
+
i = Ot.decode(t);
|
|
545
|
+
} catch (c) {
|
|
546
|
+
try {
|
|
547
|
+
i = Pt.decode(t);
|
|
548
|
+
} catch {
|
|
549
|
+
throw c;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
const o = i.global.version || 0;
|
|
553
|
+
if (o !== 0 && o !== 2)
|
|
554
|
+
throw new Error(`Wrong PSBT version=${o}`);
|
|
555
|
+
const s = i.global.unsignedTx, r = o === 0 ? s?.version : i.global.txVersion, a = o === 0 ? s?.lockTime : i.global.fallbackLocktime, u = new Q({ ...e, version: r, lockTime: a, PSBTVersion: o }), f = o === 0 ? s?.inputs.length : i.global.inputCount;
|
|
556
|
+
u.inputs = i.inputs.slice(0, f).map((c, l) => Wt({
|
|
557
|
+
finalScriptSig: k,
|
|
558
|
+
...i.global.unsignedTx?.inputs[l],
|
|
559
|
+
...c
|
|
560
|
+
}));
|
|
561
|
+
const p = o === 0 ? s?.outputs.length : i.global.outputCount;
|
|
562
|
+
return u.outputs = i.outputs.slice(0, p).map((c, l) => ({
|
|
563
|
+
...c,
|
|
564
|
+
...i.global.unsignedTx?.outputs[l]
|
|
565
|
+
})), u.global = { ...i.global, txVersion: r }, a !== C && (u.global.fallbackLocktime = a), u;
|
|
566
|
+
}
|
|
567
|
+
toPSBT(t = this.opts.PSBTVersion) {
|
|
568
|
+
if (t !== 0 && t !== 2)
|
|
569
|
+
throw new Error(`Wrong PSBT version=${t}`);
|
|
570
|
+
const e = this.inputs.map((s) => Wt(Nt(t, rt, s)));
|
|
571
|
+
for (const s of e)
|
|
572
|
+
s.partialSig && !s.partialSig.length && delete s.partialSig, s.finalScriptSig && !s.finalScriptSig.length && delete s.finalScriptSig, s.finalScriptWitness && !s.finalScriptWitness.length && delete s.finalScriptWitness;
|
|
573
|
+
const i = this.outputs.map((s) => Nt(t, it, s)), o = { ...this.global };
|
|
574
|
+
return t === 0 ? (o.unsignedTx = M.decode(M.encode({
|
|
575
|
+
version: this.version,
|
|
576
|
+
lockTime: this.lockTime,
|
|
577
|
+
inputs: this.inputs.map(R).map((s) => ({
|
|
578
|
+
...s,
|
|
579
|
+
finalScriptSig: k
|
|
580
|
+
})),
|
|
581
|
+
outputs: this.outputs.map(D)
|
|
582
|
+
})), delete o.fallbackLocktime, delete o.txVersion) : (o.version = t, o.txVersion = this.version, o.inputCount = this.inputs.length, o.outputCount = this.outputs.length, o.fallbackLocktime && o.fallbackLocktime === C && delete o.fallbackLocktime), this.opts.bip174jsCompat && (e.length || e.push({}), i.length || i.push({})), (t === 0 ? Ot : Pt).encode({
|
|
583
|
+
global: o,
|
|
584
|
+
inputs: e,
|
|
585
|
+
outputs: i
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
// BIP370 lockTime (https://github.com/bitcoin/bips/blob/master/bip-0370.mediawiki#determining-lock-time)
|
|
589
|
+
get lockTime() {
|
|
590
|
+
let t = C, e = 0, i = C, o = 0;
|
|
591
|
+
for (const s of this.inputs)
|
|
592
|
+
s.requiredHeightLocktime && (t = Math.max(t, s.requiredHeightLocktime), e++), s.requiredTimeLocktime && (i = Math.max(i, s.requiredTimeLocktime), o++);
|
|
593
|
+
return e && e >= o ? t : i !== C ? i : this.global.fallbackLocktime || C;
|
|
594
|
+
}
|
|
595
|
+
get version() {
|
|
596
|
+
if (this.global.txVersion === void 0)
|
|
597
|
+
throw new Error("No global.txVersion");
|
|
598
|
+
return this.global.txVersion;
|
|
599
|
+
}
|
|
600
|
+
inputStatus(t) {
|
|
601
|
+
this.checkInputIdx(t);
|
|
602
|
+
const e = this.inputs[t];
|
|
603
|
+
return e.finalScriptSig && e.finalScriptSig.length || e.finalScriptWitness && e.finalScriptWitness.length ? "finalized" : e.tapKeySig || e.tapScriptSig && e.tapScriptSig.length || e.partialSig && e.partialSig.length ? "signed" : "unsigned";
|
|
604
|
+
}
|
|
605
|
+
// Cannot replace unpackSighash, tests rely on very generic implemenetation with signing inputs outside of range
|
|
606
|
+
// We will lose some vectors -> smaller test coverage of preimages (very important!)
|
|
607
|
+
inputSighash(t) {
|
|
608
|
+
this.checkInputIdx(t);
|
|
609
|
+
const e = this.inputs[t].sighashType, i = e === void 0 ? h.DEFAULT : e, o = i === h.DEFAULT ? h.ALL : i & 3;
|
|
610
|
+
return { sigInputs: i & h.ANYONECANPAY, sigOutputs: o };
|
|
611
|
+
}
|
|
612
|
+
// Very nice for debug purposes, but slow. If there is too much inputs/outputs to add, will be quadratic.
|
|
613
|
+
// Some cache will be nice, but there chance to have bugs with cache invalidation
|
|
614
|
+
signStatus() {
|
|
615
|
+
let t = !0, e = !0, i = [], o = [];
|
|
616
|
+
for (let s = 0; s < this.inputs.length; s++) {
|
|
617
|
+
if (this.inputStatus(s) === "unsigned")
|
|
618
|
+
continue;
|
|
619
|
+
const { sigInputs: a, sigOutputs: u } = this.inputSighash(s);
|
|
620
|
+
if (a === h.ANYONECANPAY ? i.push(s) : t = !1, u === h.ALL)
|
|
621
|
+
e = !1;
|
|
622
|
+
else if (u === h.SINGLE)
|
|
623
|
+
o.push(s);
|
|
624
|
+
else if (u !== h.NONE) throw new Error(`Wrong signature hash output type: ${u}`);
|
|
625
|
+
}
|
|
626
|
+
return { addInput: t, addOutput: e, inputs: i, outputs: o };
|
|
627
|
+
}
|
|
628
|
+
get isFinal() {
|
|
629
|
+
for (let t = 0; t < this.inputs.length; t++)
|
|
630
|
+
if (this.inputStatus(t) !== "finalized")
|
|
631
|
+
return !1;
|
|
632
|
+
return !0;
|
|
633
|
+
}
|
|
634
|
+
// Info utils
|
|
635
|
+
get hasWitnesses() {
|
|
636
|
+
let t = !1;
|
|
637
|
+
for (const e of this.inputs)
|
|
638
|
+
e.finalScriptWitness && e.finalScriptWitness.length && (t = !0);
|
|
639
|
+
return t;
|
|
640
|
+
}
|
|
641
|
+
// https://en.bitcoin.it/wiki/Weight_units
|
|
642
|
+
get weight() {
|
|
643
|
+
if (!this.isFinal)
|
|
644
|
+
throw new Error("Transaction is not finalized");
|
|
645
|
+
let t = 32;
|
|
646
|
+
const e = this.outputs.map(D);
|
|
647
|
+
t += 4 * P.encode(this.outputs.length).length;
|
|
648
|
+
for (const i of e)
|
|
649
|
+
t += 32 + 4 * K.encode(i.script).length;
|
|
650
|
+
this.hasWitnesses && (t += 2), t += 4 * P.encode(this.inputs.length).length;
|
|
651
|
+
for (const i of this.inputs)
|
|
652
|
+
t += 160 + 4 * K.encode(i.finalScriptSig || k).length, this.hasWitnesses && i.finalScriptWitness && (t += Dt.encode(i.finalScriptWitness).length);
|
|
653
|
+
return t;
|
|
654
|
+
}
|
|
655
|
+
get vsize() {
|
|
656
|
+
return ke(this.weight);
|
|
657
|
+
}
|
|
658
|
+
toBytes(t = !1, e = !1) {
|
|
659
|
+
return q.encode({
|
|
660
|
+
version: this.version,
|
|
661
|
+
lockTime: this.lockTime,
|
|
662
|
+
inputs: this.inputs.map(R).map((i) => ({
|
|
663
|
+
...i,
|
|
664
|
+
finalScriptSig: t && i.finalScriptSig || k
|
|
665
|
+
})),
|
|
666
|
+
outputs: this.outputs.map(D),
|
|
667
|
+
witnesses: this.inputs.map((i) => i.finalScriptWitness || []),
|
|
668
|
+
segwitFlag: e && this.hasWitnesses
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
get unsignedTx() {
|
|
672
|
+
return this.toBytes(!1, !1);
|
|
673
|
+
}
|
|
674
|
+
get hex() {
|
|
675
|
+
return I.encode(this.toBytes(!0, this.hasWitnesses));
|
|
676
|
+
}
|
|
677
|
+
get hash() {
|
|
678
|
+
return I.encode(B(this.toBytes(!0)));
|
|
679
|
+
}
|
|
680
|
+
get id() {
|
|
681
|
+
return I.encode(B(this.toBytes(!0)).reverse());
|
|
682
|
+
}
|
|
683
|
+
// Input stuff
|
|
684
|
+
checkInputIdx(t) {
|
|
685
|
+
if (!Number.isSafeInteger(t) || 0 > t || t >= this.inputs.length)
|
|
686
|
+
throw new Error(`Wrong input index=${t}`);
|
|
687
|
+
}
|
|
688
|
+
getInput(t) {
|
|
689
|
+
return this.checkInputIdx(t), st(this.inputs[t]);
|
|
690
|
+
}
|
|
691
|
+
get inputsLength() {
|
|
692
|
+
return this.inputs.length;
|
|
693
|
+
}
|
|
694
|
+
// Modification
|
|
695
|
+
addInput(t, e = !1) {
|
|
696
|
+
if (!e && !this.signStatus().addInput)
|
|
697
|
+
throw new Error("Tx has signed inputs, cannot add new one");
|
|
698
|
+
return this.inputs.push(Bt(t, void 0, void 0, this.opts.disableScriptCheck)), this.inputs.length - 1;
|
|
699
|
+
}
|
|
700
|
+
updateInput(t, e, i = !1) {
|
|
701
|
+
this.checkInputIdx(t);
|
|
702
|
+
let o;
|
|
703
|
+
if (!i) {
|
|
704
|
+
const s = this.signStatus();
|
|
705
|
+
(!s.addInput || s.inputs.includes(t)) && (o = ge);
|
|
706
|
+
}
|
|
707
|
+
this.inputs[t] = Bt(e, this.inputs[t], o, this.opts.disableScriptCheck, this.opts.allowUnknown);
|
|
708
|
+
}
|
|
709
|
+
// Output stuff
|
|
710
|
+
checkOutputIdx(t) {
|
|
711
|
+
if (!Number.isSafeInteger(t) || 0 > t || t >= this.outputs.length)
|
|
712
|
+
throw new Error(`Wrong output index=${t}`);
|
|
713
|
+
}
|
|
714
|
+
getOutput(t) {
|
|
715
|
+
return this.checkOutputIdx(t), st(this.outputs[t]);
|
|
716
|
+
}
|
|
717
|
+
getOutputAddress(t, e = bt) {
|
|
718
|
+
const i = this.getOutput(t);
|
|
719
|
+
if (i.script)
|
|
720
|
+
return It(e).encode($.decode(i.script));
|
|
721
|
+
}
|
|
722
|
+
get outputsLength() {
|
|
723
|
+
return this.outputs.length;
|
|
724
|
+
}
|
|
725
|
+
normalizeOutput(t, e, i) {
|
|
726
|
+
let { amount: o, script: s } = t;
|
|
727
|
+
if (o === void 0 && (o = e?.amount), typeof o != "bigint")
|
|
728
|
+
throw new Error(`Wrong amount type, should be of type bigint in sats, but got ${o} of type ${typeof o}`);
|
|
729
|
+
typeof s == "string" && (s = I.decode(s)), s === void 0 && (s = e?.script);
|
|
730
|
+
let r = { ...e, ...t, amount: o, script: s };
|
|
731
|
+
if (r.amount === void 0 && delete r.amount, r = dt(it, r, e, i, this.opts.allowUnknown), kt.encode(r), r.script && !this.opts.allowUnknownOutputs && $.decode(r.script).type === "unknown")
|
|
732
|
+
throw new Error("Transaction/output: unknown output script type, there is a chance that input is unspendable. Pass allowUnknownOutputs=true, if you sure");
|
|
733
|
+
return this.opts.disableScriptCheck || Yt(r.script, r.redeemScript, r.witnessScript), r;
|
|
734
|
+
}
|
|
735
|
+
addOutput(t, e = !1) {
|
|
736
|
+
if (!e && !this.signStatus().addOutput)
|
|
737
|
+
throw new Error("Tx has signed outputs, cannot add new one");
|
|
738
|
+
return this.outputs.push(this.normalizeOutput(t)), this.outputs.length - 1;
|
|
739
|
+
}
|
|
740
|
+
updateOutput(t, e, i = !1) {
|
|
741
|
+
this.checkOutputIdx(t);
|
|
742
|
+
let o;
|
|
743
|
+
if (!i) {
|
|
744
|
+
const s = this.signStatus();
|
|
745
|
+
(!s.addOutput || s.outputs.includes(t)) && (o = we);
|
|
746
|
+
}
|
|
747
|
+
this.outputs[t] = this.normalizeOutput(e, this.outputs[t], o);
|
|
748
|
+
}
|
|
749
|
+
addOutputAddress(t, e, i = bt) {
|
|
750
|
+
return this.addOutput({ script: $.encode(It(i).decode(t)), amount: e });
|
|
751
|
+
}
|
|
752
|
+
// Utils
|
|
753
|
+
get fee() {
|
|
754
|
+
let t = 0n;
|
|
755
|
+
for (const i of this.inputs) {
|
|
756
|
+
const o = et(i);
|
|
757
|
+
if (!o)
|
|
758
|
+
throw new Error("Empty input amount");
|
|
759
|
+
t += o.amount;
|
|
760
|
+
}
|
|
761
|
+
const e = this.outputs.map(D);
|
|
762
|
+
for (const i of e)
|
|
763
|
+
t -= i.amount;
|
|
764
|
+
return t;
|
|
765
|
+
}
|
|
766
|
+
// Signing
|
|
767
|
+
// Based on https://github.com/bitcoin/bitcoin/blob/5871b5b5ab57a0caf9b7514eb162c491c83281d5/test/functional/test_framework/script.py#L624
|
|
768
|
+
// There is optimization opportunity to re-use hashes for multiple inputs for witness v0/v1,
|
|
769
|
+
// but we are trying to be less complicated for audit purpose for now.
|
|
770
|
+
preimageLegacy(t, e, i) {
|
|
771
|
+
const { isAny: o, isNone: s, isSingle: r } = $t(i);
|
|
772
|
+
if (t < 0 || !Number.isSafeInteger(t))
|
|
773
|
+
throw new Error(`Invalid input idx=${t}`);
|
|
774
|
+
if (r && t >= this.outputs.length || t >= this.inputs.length)
|
|
775
|
+
return ne.encode(1n);
|
|
776
|
+
e = U.encode(U.decode(e).filter((p) => p !== "CODESEPARATOR"));
|
|
777
|
+
let a = this.inputs.map(R).map((p, c) => ({
|
|
778
|
+
...p,
|
|
779
|
+
finalScriptSig: c === t ? e : k
|
|
780
|
+
}));
|
|
781
|
+
o ? a = [a[t]] : (s || r) && (a = a.map((p, c) => ({
|
|
782
|
+
...p,
|
|
783
|
+
sequence: c === t ? p.sequence : 0
|
|
784
|
+
})));
|
|
785
|
+
let u = this.outputs.map(D);
|
|
786
|
+
s ? u = [] : r && (u = u.slice(0, t).fill(me).concat([u[t]]));
|
|
787
|
+
const f = q.encode({
|
|
788
|
+
lockTime: this.lockTime,
|
|
789
|
+
version: this.version,
|
|
790
|
+
segwitFlag: !1,
|
|
791
|
+
inputs: a,
|
|
792
|
+
outputs: u
|
|
793
|
+
});
|
|
794
|
+
return B(f, Z.encode(i));
|
|
795
|
+
}
|
|
796
|
+
preimageWitnessV0(t, e, i, o) {
|
|
797
|
+
const { isAny: s, isNone: r, isSingle: a } = $t(i);
|
|
798
|
+
let u = tt, f = tt, p = tt;
|
|
799
|
+
const c = this.inputs.map(R), l = this.outputs.map(D);
|
|
800
|
+
s || (u = B(...c.map(lt.encode))), !s && !a && !r && (f = B(...c.map((y) => E.encode(y.sequence)))), !a && !r ? p = B(...l.map(_.encode)) : a && t < l.length && (p = B(_.encode(l[t])));
|
|
801
|
+
const g = c[t];
|
|
802
|
+
return B(Z.encode(this.version), u, f, b(32, !0).encode(g.txid), E.encode(g.index), K.encode(e), at.encode(o), E.encode(g.sequence), p, E.encode(this.lockTime), E.encode(i));
|
|
803
|
+
}
|
|
804
|
+
preimageWitnessV1(t, e, i, o, s = -1, r, a = 192, u) {
|
|
805
|
+
if (!Array.isArray(o) || this.inputs.length !== o.length)
|
|
806
|
+
throw new Error(`Invalid amounts array=${o}`);
|
|
807
|
+
if (!Array.isArray(e) || this.inputs.length !== e.length)
|
|
808
|
+
throw new Error(`Invalid prevOutScript array=${e}`);
|
|
809
|
+
const f = [
|
|
810
|
+
Y.encode(0),
|
|
811
|
+
Y.encode(i),
|
|
812
|
+
// U8 sigHash
|
|
813
|
+
Z.encode(this.version),
|
|
814
|
+
E.encode(this.lockTime)
|
|
815
|
+
], p = i === h.DEFAULT ? h.ALL : i & 3, c = i & h.ANYONECANPAY, l = this.inputs.map(R), g = this.outputs.map(D);
|
|
816
|
+
c !== h.ANYONECANPAY && f.push(...[
|
|
817
|
+
l.map(lt.encode),
|
|
818
|
+
o.map(at.encode),
|
|
819
|
+
e.map(K.encode),
|
|
820
|
+
l.map((w) => E.encode(w.sequence))
|
|
821
|
+
].map((w) => z(F(...w)))), p === h.ALL && f.push(z(F(...g.map(_.encode))));
|
|
822
|
+
const y = (u ? 1 : 0) | (r ? 2 : 0);
|
|
823
|
+
if (f.push(new Uint8Array([y])), c === h.ANYONECANPAY) {
|
|
824
|
+
const w = l[t];
|
|
825
|
+
f.push(lt.encode(w), at.encode(o[t]), K.encode(e[t]), E.encode(w.sequence));
|
|
826
|
+
} else
|
|
827
|
+
f.push(E.encode(t));
|
|
828
|
+
return y & 1 && f.push(z(K.encode(u || k))), p === h.SINGLE && f.push(t < g.length ? z(_.encode(g[t])) : tt), r && f.push(ut(r, a), Y.encode(0), Z.encode(s)), ie("TapSighash", ...f);
|
|
829
|
+
}
|
|
830
|
+
// Signer can be privateKey OR instance of bip32 HD stuff
|
|
831
|
+
signIdx(t, e, i, o) {
|
|
832
|
+
this.checkInputIdx(e);
|
|
833
|
+
const s = this.inputs[e], r = Ct(s, this.opts.allowLegacyWitnessUtxo);
|
|
834
|
+
if (!V(t)) {
|
|
835
|
+
if (!s.bip32Derivation || !s.bip32Derivation.length)
|
|
836
|
+
throw new Error("bip32Derivation: empty");
|
|
837
|
+
const p = s.bip32Derivation.filter((l) => l[1].fingerprint == t.fingerprint).map(([l, { path: g }]) => {
|
|
838
|
+
let y = t;
|
|
839
|
+
for (const w of g)
|
|
840
|
+
y = y.deriveChild(w);
|
|
841
|
+
if (!L(y.publicKey, l))
|
|
842
|
+
throw new Error("bip32Derivation: wrong pubKey");
|
|
843
|
+
if (!y.privateKey)
|
|
844
|
+
throw new Error("bip32Derivation: no privateKey");
|
|
845
|
+
return y;
|
|
846
|
+
});
|
|
847
|
+
if (!p.length)
|
|
848
|
+
throw new Error(`bip32Derivation: no items with fingerprint=${t.fingerprint}`);
|
|
849
|
+
let c = !1;
|
|
850
|
+
for (const l of p)
|
|
851
|
+
this.signIdx(l.privateKey, e) && (c = !0);
|
|
852
|
+
return c;
|
|
853
|
+
}
|
|
854
|
+
i ? i.forEach(Ae) : i = [r.defaultSighash];
|
|
855
|
+
const a = r.sighash;
|
|
856
|
+
if (!i.includes(a))
|
|
857
|
+
throw new Error(`Input with not allowed sigHash=${a}. Allowed: ${i.join(", ")}`);
|
|
858
|
+
const { sigOutputs: u } = this.inputSighash(e);
|
|
859
|
+
if (u === h.SINGLE && e >= this.outputs.length)
|
|
860
|
+
throw new Error(`Input with sighash SINGLE, but there is no output with corresponding index=${e}`);
|
|
861
|
+
const f = et(s);
|
|
862
|
+
if (r.txType === "taproot") {
|
|
863
|
+
const p = this.inputs.map(et), c = p.map((d) => d.script), l = p.map((d) => d.amount);
|
|
864
|
+
let g = !1, y = qt(t), w = s.tapMerkleRoot || k;
|
|
865
|
+
if (s.tapInternalKey) {
|
|
866
|
+
const { pubKey: d, privKey: m } = Ie(t, y, s.tapInternalKey, w), [S] = se(s.tapInternalKey, w);
|
|
867
|
+
if (L(S, d)) {
|
|
868
|
+
const T = this.preimageWitnessV1(e, c, a, l), A = F(At(T, m, o), a !== h.DEFAULT ? new Uint8Array([a]) : k);
|
|
869
|
+
this.updateInput(e, { tapKeySig: A }, !0), g = !0;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
if (s.tapLeafScript) {
|
|
873
|
+
s.tapScriptSig = s.tapScriptSig || [];
|
|
874
|
+
for (const [d, m] of s.tapLeafScript) {
|
|
875
|
+
const S = m.subarray(0, -1), T = U.decode(S), A = m[m.length - 1], O = ut(S, A);
|
|
876
|
+
if (T.findIndex((xt) => V(xt) && L(xt, y)) === -1)
|
|
877
|
+
continue;
|
|
878
|
+
const _t = this.preimageWitnessV1(e, c, a, l, void 0, S, A), Mt = F(At(_t, t, o), a !== h.DEFAULT ? new Uint8Array([a]) : k);
|
|
879
|
+
this.updateInput(e, { tapScriptSig: [[{ pubKey: y, leafHash: O }, Mt]] }, !0), g = !0;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
if (!g)
|
|
883
|
+
throw new Error("No taproot scripts signed");
|
|
884
|
+
return !0;
|
|
885
|
+
} else {
|
|
886
|
+
const p = oe(t);
|
|
887
|
+
let c = !1;
|
|
888
|
+
const l = re(p);
|
|
889
|
+
for (const w of U.decode(r.lastScript))
|
|
890
|
+
V(w) && (L(w, p) || L(w, l)) && (c = !0);
|
|
891
|
+
if (!c)
|
|
892
|
+
throw new Error(`Input script doesn't have pubKey: ${r.lastScript}`);
|
|
893
|
+
let g;
|
|
894
|
+
if (r.txType === "legacy")
|
|
895
|
+
g = this.preimageLegacy(e, r.lastScript, a);
|
|
896
|
+
else if (r.txType === "segwit") {
|
|
897
|
+
let w = r.lastScript;
|
|
898
|
+
r.last.type === "wpkh" && (w = $.encode({ type: "pkh", hash: r.last.hash })), g = this.preimageWitnessV0(e, w, a, f.amount);
|
|
899
|
+
} else
|
|
900
|
+
throw new Error(`Transaction/sign: unknown tx type: ${r.txType}`);
|
|
901
|
+
const y = ae(g, t, this.opts.lowR);
|
|
902
|
+
this.updateInput(e, {
|
|
903
|
+
partialSig: [[p, F(y, new Uint8Array([a]))]]
|
|
904
|
+
}, !0);
|
|
905
|
+
}
|
|
906
|
+
return !0;
|
|
907
|
+
}
|
|
908
|
+
// This is bad API. Will work if user creates and signs tx, but if
|
|
909
|
+
// there is some complex workflow with exchanging PSBT and signing them,
|
|
910
|
+
// then it is better to validate which output user signs. How could a better API look like?
|
|
911
|
+
// Example: user adds input, sends to another party, then signs received input (mixer etc),
|
|
912
|
+
// another user can add different input for same key and user will sign it.
|
|
913
|
+
// Even worse: another user can add bip32 derivation, and spend money from different address.
|
|
914
|
+
// Better api: signIdx
|
|
915
|
+
sign(t, e, i) {
|
|
916
|
+
let o = 0;
|
|
917
|
+
for (let s = 0; s < this.inputs.length; s++)
|
|
918
|
+
try {
|
|
919
|
+
this.signIdx(t, s, e, i) && o++;
|
|
920
|
+
} catch {
|
|
921
|
+
}
|
|
922
|
+
if (!o)
|
|
923
|
+
throw new Error("No inputs signed");
|
|
924
|
+
return o;
|
|
925
|
+
}
|
|
926
|
+
finalizeIdx(t) {
|
|
927
|
+
if (this.checkInputIdx(t), this.fee < 0n)
|
|
928
|
+
throw new Error("Outputs spends more than inputs amount");
|
|
929
|
+
const e = this.inputs[t], i = Ct(e, this.opts.allowLegacyWitnessUtxo);
|
|
930
|
+
if (i.txType === "taproot") {
|
|
931
|
+
if (e.tapKeySig)
|
|
932
|
+
e.finalScriptWitness = [e.tapKeySig];
|
|
933
|
+
else if (e.tapLeafScript && e.tapScriptSig) {
|
|
934
|
+
const u = e.tapLeafScript.sort((f, p) => G.encode(f[0]).length - G.encode(p[0]).length);
|
|
935
|
+
for (const [f, p] of u) {
|
|
936
|
+
const c = p.slice(0, -1), l = p[p.length - 1], g = $.decode(c), y = ut(c, l), w = e.tapScriptSig.filter((m) => L(m[0].leafHash, y));
|
|
937
|
+
let d = [];
|
|
938
|
+
if (g.type === "tr_ms") {
|
|
939
|
+
const m = g.m, S = g.pubkeys;
|
|
940
|
+
let T = 0;
|
|
941
|
+
for (const A of S) {
|
|
942
|
+
const O = w.findIndex((Et) => L(Et[0].pubKey, A));
|
|
943
|
+
if (T === m || O === -1) {
|
|
944
|
+
d.push(k);
|
|
945
|
+
continue;
|
|
946
|
+
}
|
|
947
|
+
d.push(w[O][1]), T++;
|
|
948
|
+
}
|
|
949
|
+
if (T !== m)
|
|
950
|
+
continue;
|
|
951
|
+
} else if (g.type === "tr_ns") {
|
|
952
|
+
for (const m of g.pubkeys) {
|
|
953
|
+
const S = w.findIndex((T) => L(T[0].pubKey, m));
|
|
954
|
+
S !== -1 && d.push(w[S][1]);
|
|
955
|
+
}
|
|
956
|
+
if (d.length !== g.pubkeys.length)
|
|
957
|
+
continue;
|
|
958
|
+
} else if (g.type === "unknown" && this.opts.allowUnknownInputs) {
|
|
959
|
+
const m = U.decode(c);
|
|
960
|
+
if (d = w.map(([{ pubKey: S }, T]) => {
|
|
961
|
+
const A = m.findIndex((O) => V(O) && L(O, S));
|
|
962
|
+
if (A === -1)
|
|
963
|
+
throw new Error("finalize/taproot: cannot find position of pubkey in script");
|
|
964
|
+
return { signature: T, pos: A };
|
|
965
|
+
}).sort((S, T) => S.pos - T.pos).map((S) => S.signature), !d.length)
|
|
966
|
+
continue;
|
|
967
|
+
} else {
|
|
968
|
+
const m = this.opts.customScripts;
|
|
969
|
+
if (m)
|
|
970
|
+
for (const S of m) {
|
|
971
|
+
if (!S.finalizeTaproot)
|
|
972
|
+
continue;
|
|
973
|
+
const T = U.decode(c), A = S.encode(T);
|
|
974
|
+
if (A === void 0)
|
|
975
|
+
continue;
|
|
976
|
+
const O = S.finalizeTaproot(c, A, w);
|
|
977
|
+
if (O) {
|
|
978
|
+
e.finalScriptWitness = O.concat(G.encode(f)), e.finalScriptSig = k, ct(e);
|
|
979
|
+
return;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
throw new Error("Finalize: Unknown tapLeafScript");
|
|
983
|
+
}
|
|
984
|
+
e.finalScriptWitness = d.reverse().concat([c, G.encode(f)]);
|
|
985
|
+
break;
|
|
986
|
+
}
|
|
987
|
+
if (!e.finalScriptWitness)
|
|
988
|
+
throw new Error("finalize/taproot: empty witness");
|
|
989
|
+
} else
|
|
990
|
+
throw new Error("finalize/taproot: unknown input");
|
|
991
|
+
e.finalScriptSig = k, ct(e);
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
if (!e.partialSig || !e.partialSig.length)
|
|
995
|
+
throw new Error("Not enough partial sign");
|
|
996
|
+
let o = k, s = [];
|
|
997
|
+
if (i.last.type === "ms") {
|
|
998
|
+
const u = i.last.m, f = i.last.pubkeys;
|
|
999
|
+
let p = [];
|
|
1000
|
+
for (const c of f) {
|
|
1001
|
+
const l = e.partialSig.find((g) => L(c, g[0]));
|
|
1002
|
+
l && p.push(l[1]);
|
|
1003
|
+
}
|
|
1004
|
+
if (p = p.slice(0, u), p.length !== u)
|
|
1005
|
+
throw new Error(`Multisig: wrong signatures count, m=${u} n=${f.length} signatures=${p.length}`);
|
|
1006
|
+
o = U.encode([0, ...p]);
|
|
1007
|
+
} else if (i.last.type === "pk")
|
|
1008
|
+
o = U.encode([e.partialSig[0][1]]);
|
|
1009
|
+
else if (i.last.type === "pkh")
|
|
1010
|
+
o = U.encode([e.partialSig[0][1], e.partialSig[0][0]]);
|
|
1011
|
+
else if (i.last.type === "wpkh")
|
|
1012
|
+
o = k, s = [e.partialSig[0][1], e.partialSig[0][0]];
|
|
1013
|
+
else if (i.last.type === "unknown" && !this.opts.allowUnknownInputs)
|
|
1014
|
+
throw new Error("Unknown inputs not allowed");
|
|
1015
|
+
let r, a;
|
|
1016
|
+
if (i.type.includes("wsh-") && (o.length && i.lastScript.length && (s = U.decode(o).map((u) => {
|
|
1017
|
+
if (u === 0)
|
|
1018
|
+
return k;
|
|
1019
|
+
if (V(u))
|
|
1020
|
+
return u;
|
|
1021
|
+
throw new Error(`Wrong witness op=${u}`);
|
|
1022
|
+
})), s = s.concat(i.lastScript)), i.txType === "segwit" && (a = s), i.type.startsWith("sh-wsh-") ? r = U.encode([U.encode([0, z(i.lastScript)])]) : i.type.startsWith("sh-") ? r = U.encode([...U.decode(o), i.lastScript]) : i.type.startsWith("wsh-") || i.txType !== "segwit" && (r = o), !r && !a)
|
|
1023
|
+
throw new Error("Unknown error finalizing input");
|
|
1024
|
+
r && (e.finalScriptSig = r), a && (e.finalScriptWitness = a), ct(e);
|
|
1025
|
+
}
|
|
1026
|
+
finalize() {
|
|
1027
|
+
for (let t = 0; t < this.inputs.length; t++)
|
|
1028
|
+
this.finalizeIdx(t);
|
|
1029
|
+
}
|
|
1030
|
+
extract() {
|
|
1031
|
+
if (!this.isFinal)
|
|
1032
|
+
throw new Error("Transaction has unfinalized inputs");
|
|
1033
|
+
if (!this.outputs.length)
|
|
1034
|
+
throw new Error("Transaction has no outputs");
|
|
1035
|
+
if (this.fee < 0n)
|
|
1036
|
+
throw new Error("Outputs spends more than inputs amount");
|
|
1037
|
+
return this.toBytes(!0, !0);
|
|
1038
|
+
}
|
|
1039
|
+
combine(t) {
|
|
1040
|
+
for (const o of ["PSBTVersion", "version", "lockTime"])
|
|
1041
|
+
if (this.opts[o] !== t.opts[o])
|
|
1042
|
+
throw new Error(`Transaction/combine: different ${o} this=${this.opts[o]} other=${t.opts[o]}`);
|
|
1043
|
+
for (const o of ["inputs", "outputs"])
|
|
1044
|
+
if (this[o].length !== t[o].length)
|
|
1045
|
+
throw new Error(`Transaction/combine: different ${o} length this=${this[o].length} other=${t[o].length}`);
|
|
1046
|
+
const e = this.global.unsignedTx ? M.encode(this.global.unsignedTx) : k, i = t.global.unsignedTx ? M.encode(t.global.unsignedTx) : k;
|
|
1047
|
+
if (!L(e, i))
|
|
1048
|
+
throw new Error("Transaction/combine: different unsigned tx");
|
|
1049
|
+
this.global = dt(St, this.global, t.global, void 0, this.opts.allowUnknown);
|
|
1050
|
+
for (let o = 0; o < this.inputs.length; o++)
|
|
1051
|
+
this.updateInput(o, t.inputs[o], !0);
|
|
1052
|
+
for (let o = 0; o < this.outputs.length; o++)
|
|
1053
|
+
this.updateOutput(o, t.outputs[o], !0);
|
|
1054
|
+
return this;
|
|
1055
|
+
}
|
|
1056
|
+
clone() {
|
|
1057
|
+
return Q.fromPSBT(this.toPSBT(this.opts.PSBTVersion), this.opts);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
export {
|
|
1061
|
+
Q as T
|
|
1062
|
+
};
|
|
1063
|
+
//# sourceMappingURL=transaction-CiLOYSE_.mjs.map
|