@arkade-os/sdk 0.5.0-rc.2 → 0.5.0-rc.20
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 +90 -83
- package/dist/adapters/expo.cjs +5 -6
- package/dist/adapters/expo.d.cts +4 -4
- package/dist/adapters/expo.d.ts +4 -4
- package/dist/adapters/expo.js +3 -4
- package/dist/{asyncStorageTaskQueue-C5rBYlru.d.ts → asyncStorageTaskQueue-aL7K14e4.d.ts} +2 -2
- package/dist/{asyncStorageTaskQueue-BuDvgWh6.d.cts → asyncStorageTaskQueue-x8ok3tJy.d.cts} +2 -2
- package/dist/{chunk-43FKNLX4.cjs → chunk-5SLUXXWQ.cjs} +357 -1114
- package/dist/chunk-5SLUXXWQ.cjs.map +1 -0
- package/dist/{chunk-HLCGYOIH.cjs → chunk-6YVGWOLG.cjs} +37 -36
- package/dist/chunk-6YVGWOLG.cjs.map +1 -0
- package/dist/{chunk-4PKLULWT.js → chunk-AARSVV3S.js} +109 -246
- package/dist/chunk-AARSVV3S.js.map +1 -0
- package/dist/{chunk-D25O4EGY.cjs → chunk-AFJSJACF.cjs} +12 -10
- package/dist/chunk-AFJSJACF.cjs.map +1 -0
- package/dist/{chunk-6DNR46C7.js → chunk-IM3J3T5P.js} +7 -5
- package/dist/chunk-IM3J3T5P.js.map +1 -0
- package/dist/{chunk-ISO4TI5J.js → chunk-NR4XYTN3.js} +566 -459
- package/dist/chunk-NR4XYTN3.js.map +1 -0
- package/dist/{chunk-ZRNQV6HV.js → chunk-O2ZZD5Z6.js} +4578 -4396
- package/dist/chunk-O2ZZD5Z6.js.map +1 -0
- package/dist/{chunk-ZOTXDOS5.js → chunk-P267BXL7.js} +30 -29
- package/dist/chunk-P267BXL7.js.map +1 -0
- package/dist/{chunk-NVZJSKZS.cjs → chunk-P42MGA4K.cjs} +121 -257
- package/dist/chunk-P42MGA4K.cjs.map +1 -0
- package/dist/{chunk-GMZZQXV5.cjs → chunk-QARA4IYT.cjs} +4961 -4767
- package/dist/chunk-QARA4IYT.cjs.map +1 -0
- package/dist/{chunk-JZWLXNHV.cjs → chunk-T6N6B7HK.cjs} +574 -464
- package/dist/chunk-T6N6B7HK.cjs.map +1 -0
- package/dist/{chunk-3R476TDV.js → chunk-TIVYJIIX.js} +293 -1071
- package/dist/chunk-TIVYJIIX.js.map +1 -0
- package/dist/contracts/handlers/index.cjs +9 -10
- package/dist/contracts/handlers/index.d.cts +5 -5
- package/dist/contracts/handlers/index.d.ts +5 -5
- package/dist/contracts/handlers/index.js +2 -3
- package/dist/{delegate-BAX5QftB.d.ts → delegate-BT5iON1T.d.ts} +1 -1
- package/dist/{delegate-1yp1HyP7.d.cts → delegate-u6kXTtWY.d.cts} +1 -1
- package/dist/index-BCnhItOQ.d.cts +639 -0
- package/dist/{index-DUxufw76.d.cts → index-CK5QbTmZ.d.cts} +1387 -2404
- package/dist/{index-DUxufw76.d.ts → index-CK5QbTmZ.d.ts} +1387 -2404
- package/dist/index-D1D4cR-G.d.ts +639 -0
- package/dist/index.cjs +375 -340
- package/dist/index.d.cts +784 -1197
- package/dist/index.d.ts +784 -1197
- package/dist/index.js +4 -5
- package/dist/repositories/realm/index.cjs +201 -106
- package/dist/repositories/realm/index.cjs.map +1 -1
- package/dist/repositories/realm/index.d.cts +28 -16
- package/dist/repositories/realm/index.d.ts +28 -16
- package/dist/repositories/realm/index.js +190 -95
- package/dist/repositories/realm/index.js.map +1 -1
- package/dist/repositories/sqlite/index.cjs +301 -189
- package/dist/repositories/sqlite/index.cjs.map +1 -1
- package/dist/repositories/sqlite/index.d.cts +32 -21
- package/dist/repositories/sqlite/index.d.ts +32 -21
- package/dist/repositories/sqlite/index.js +294 -182
- package/dist/repositories/sqlite/index.js.map +1 -1
- package/dist/{taskRunner-D_iPiZIi.d.ts → taskRunner-BeYR6NpQ.d.ts} +2 -2
- package/dist/{taskRunner-Dr3NStc0.d.cts → taskRunner-Csey3EYJ.d.cts} +2 -2
- package/dist/wallet/expo/background.cjs +14 -15
- package/dist/wallet/expo/background.cjs.map +1 -1
- package/dist/wallet/expo/background.d.cts +10 -16
- package/dist/wallet/expo/background.d.ts +10 -16
- package/dist/wallet/expo/background.js +6 -7
- package/dist/wallet/expo/background.js.map +1 -1
- package/dist/wallet/expo/index.cjs +16 -23
- package/dist/wallet/expo/index.cjs.map +1 -1
- package/dist/wallet/expo/index.d.cts +6 -9
- package/dist/wallet/expo/index.d.ts +6 -9
- package/dist/wallet/expo/index.js +8 -15
- package/dist/wallet/expo/index.js.map +1 -1
- package/dist/wallet-DG3Qmbmt.d.cts +1848 -0
- package/dist/wallet-DzSLMxBZ.d.ts +1848 -0
- package/dist/worker/expo/index.cjs +9 -10
- package/dist/worker/expo/index.cjs.map +1 -1
- package/dist/worker/expo/index.d.cts +6 -6
- package/dist/worker/expo/index.d.ts +6 -6
- package/dist/worker/expo/index.js +5 -6
- package/dist/worker/expo/index.js.map +1 -1
- package/package.json +12 -51
- package/dist/adapters/asyncStorage.cjs +0 -48
- package/dist/adapters/asyncStorage.cjs.map +0 -1
- package/dist/adapters/asyncStorage.d.cts +0 -16
- package/dist/adapters/asyncStorage.d.ts +0 -16
- package/dist/adapters/asyncStorage.js +0 -46
- package/dist/adapters/asyncStorage.js.map +0 -1
- package/dist/adapters/fileSystem.cjs +0 -116
- package/dist/adapters/fileSystem.cjs.map +0 -1
- package/dist/adapters/fileSystem.d.cts +0 -17
- package/dist/adapters/fileSystem.d.ts +0 -17
- package/dist/adapters/fileSystem.js +0 -93
- package/dist/adapters/fileSystem.js.map +0 -1
- package/dist/adapters/indexedDB.cjs +0 -103
- package/dist/adapters/indexedDB.cjs.map +0 -1
- package/dist/adapters/indexedDB.d.cts +0 -18
- package/dist/adapters/indexedDB.d.ts +0 -18
- package/dist/adapters/indexedDB.js +0 -101
- package/dist/adapters/indexedDB.js.map +0 -1
- package/dist/adapters/localStorage.cjs +0 -50
- package/dist/adapters/localStorage.cjs.map +0 -1
- package/dist/adapters/localStorage.d.cts +0 -14
- package/dist/adapters/localStorage.d.ts +0 -14
- package/dist/adapters/localStorage.js +0 -48
- package/dist/adapters/localStorage.js.map +0 -1
- package/dist/chunk-3R476TDV.js.map +0 -1
- package/dist/chunk-43FKNLX4.cjs.map +0 -1
- package/dist/chunk-4PKLULWT.js.map +0 -1
- package/dist/chunk-5BLDMQED.cjs +0 -18
- package/dist/chunk-5BLDMQED.cjs.map +0 -1
- package/dist/chunk-6DNR46C7.js.map +0 -1
- package/dist/chunk-D25O4EGY.cjs.map +0 -1
- package/dist/chunk-GMZZQXV5.cjs.map +0 -1
- package/dist/chunk-HLCGYOIH.cjs.map +0 -1
- package/dist/chunk-ISO4TI5J.js.map +0 -1
- package/dist/chunk-JZWLXNHV.cjs.map +0 -1
- package/dist/chunk-NSBPE2FW.js +0 -15
- package/dist/chunk-NSBPE2FW.js.map +0 -1
- package/dist/chunk-NVZJSKZS.cjs.map +0 -1
- package/dist/chunk-ZOTXDOS5.js.map +0 -1
- package/dist/chunk-ZRNQV6HV.js.map +0 -1
- package/dist/hdWalletCapable-CmEU0NP1.d.ts +0 -2232
- package/dist/hdWalletCapable-eJgaT-ec.d.cts +0 -2232
- package/dist/index-Bem5vKzX.d.ts +0 -850
- package/dist/index-C0IanN1m.d.cts +0 -11
- package/dist/index-C0IanN1m.d.ts +0 -11
- package/dist/index-W_oMcOmG.d.cts +0 -850
|
@@ -1,192 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as bip68 from 'bip68';
|
|
3
|
-
import { TEST_NETWORK, NETWORK } from '@scure/btc-signer/utils.js';
|
|
1
|
+
import { TEST_NETWORK, NETWORK, concatBytes } from '@scure/btc-signer/utils.js';
|
|
4
2
|
import { hex, bech32m } from '@scure/base';
|
|
5
|
-
import { Script as Script$1 } from '@scure/btc-signer/script.js';
|
|
3
|
+
import { VarBytes, Script as Script$1 } from '@scure/btc-signer/script.js';
|
|
4
|
+
import * as bip68 from 'bip68';
|
|
5
|
+
import { ScriptNum, OP, p2tr_ms, Script, SigHash, p2tr, taprootNumsKey, Address, RawWitness, Transaction as Transaction$1, RawTx } from '@scure/btc-signer';
|
|
6
6
|
import { TAP_LEAF_VERSION } from '@scure/btc-signer/payment.js';
|
|
7
|
+
import * as P from 'micro-packed';
|
|
7
8
|
import { PSBTOutput } from '@scure/btc-signer/psbt.js';
|
|
8
9
|
import { schnorr } from '@noble/curves/secp256k1.js';
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
allowUnknownOutputs: true,
|
|
15
|
-
allowUnknownInputs: true
|
|
16
|
-
};
|
|
17
|
-
constructor(opts) {
|
|
18
|
-
super(withArkOpts(opts));
|
|
19
|
-
}
|
|
20
|
-
static fromPSBT(psbt_, opts) {
|
|
21
|
-
return Transaction$1.fromPSBT(psbt_, withArkOpts(opts));
|
|
22
|
-
}
|
|
23
|
-
static fromRaw(raw, opts) {
|
|
24
|
-
return Transaction$1.fromRaw(raw, withArkOpts(opts));
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
function withArkOpts(opts) {
|
|
28
|
-
return { ...Transaction.ARK_TX_OPTS, ...opts };
|
|
29
|
-
}
|
|
30
|
-
function formatSighash(type) {
|
|
31
|
-
return `0x${type.toString(16).padStart(2, "0")}`;
|
|
32
|
-
}
|
|
33
|
-
function assertAllowedSighashTypes(tx, allowedSighashTypes = [SigHash.DEFAULT]) {
|
|
34
|
-
for (let i = 0; i < tx.inputsLength; i++) {
|
|
35
|
-
const declared = tx.getInput(i).sighashType;
|
|
36
|
-
if (declared === void 0) continue;
|
|
37
|
-
if (!allowedSighashTypes.includes(declared)) {
|
|
38
|
-
throw new Error(`Unallowed sighash type ${formatSighash(declared)} for input ${i}.`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function timelockToSequence(timelock) {
|
|
43
|
-
return bip68.encode(
|
|
44
|
-
timelock.type === "blocks" ? { blocks: Number(timelock.value) } : { seconds: Number(timelock.value) }
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
function sequenceToTimelock(sequence) {
|
|
48
|
-
const decoded = bip68.decode(sequence);
|
|
49
|
-
if ("blocks" in decoded && decoded.blocks !== void 0) {
|
|
50
|
-
return { type: "blocks", value: BigInt(decoded.blocks) };
|
|
51
|
-
}
|
|
52
|
-
if ("seconds" in decoded && decoded.seconds !== void 0) {
|
|
53
|
-
return { type: "seconds", value: BigInt(decoded.seconds) };
|
|
54
|
-
}
|
|
55
|
-
throw new Error(`Invalid BIP68 sequence: ${sequence}`);
|
|
56
|
-
}
|
|
57
|
-
var ArkPsbtFieldKey = /* @__PURE__ */ ((ArkPsbtFieldKey2) => {
|
|
58
|
-
ArkPsbtFieldKey2["VtxoTaprootTree"] = "taptree";
|
|
59
|
-
ArkPsbtFieldKey2["VtxoTreeExpiry"] = "expiry";
|
|
60
|
-
ArkPsbtFieldKey2["Cosigner"] = "cosigner";
|
|
61
|
-
ArkPsbtFieldKey2["ConditionWitness"] = "condition";
|
|
62
|
-
ArkPsbtFieldKey2["PrevArkTx"] = "prevarktx";
|
|
63
|
-
ArkPsbtFieldKey2["PrevoutTx"] = "prevouttx";
|
|
64
|
-
return ArkPsbtFieldKey2;
|
|
65
|
-
})(ArkPsbtFieldKey || {});
|
|
66
|
-
var ArkPsbtFieldKeyType = 222;
|
|
67
|
-
function setArkPsbtField(tx, inputIndex, coder, value) {
|
|
68
|
-
tx.updateInput(inputIndex, {
|
|
69
|
-
unknown: [...tx.getInput(inputIndex)?.unknown ?? [], coder.encode(value)]
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
function getArkPsbtFields(tx, inputIndex, coder) {
|
|
73
|
-
const unknown = tx.getInput(inputIndex)?.unknown ?? [];
|
|
74
|
-
const fields = [];
|
|
75
|
-
for (const u of unknown) {
|
|
76
|
-
const v = coder.decode(u);
|
|
77
|
-
if (v !== null) fields.push(v);
|
|
78
|
-
}
|
|
79
|
-
return fields;
|
|
80
|
-
}
|
|
81
|
-
var VtxoTaprootTree = {
|
|
82
|
-
key: "taptree" /* VtxoTaprootTree */,
|
|
83
|
-
encode: (value) => [
|
|
84
|
-
{
|
|
85
|
-
type: ArkPsbtFieldKeyType,
|
|
86
|
-
key: encodedPsbtFieldKey["taptree" /* VtxoTaprootTree */]
|
|
87
|
-
},
|
|
88
|
-
value
|
|
89
|
-
],
|
|
90
|
-
decode: (value) => nullIfCatch(() => {
|
|
91
|
-
if (!checkKeyMatch(value[0], "taptree" /* VtxoTaprootTree */)) return null;
|
|
92
|
-
return value[1];
|
|
93
|
-
})
|
|
94
|
-
};
|
|
95
|
-
var ConditionWitness = {
|
|
96
|
-
key: "condition" /* ConditionWitness */,
|
|
97
|
-
encode: (value) => [
|
|
98
|
-
{
|
|
99
|
-
type: ArkPsbtFieldKeyType,
|
|
100
|
-
key: encodedPsbtFieldKey["condition" /* ConditionWitness */]
|
|
101
|
-
},
|
|
102
|
-
RawWitness.encode(value)
|
|
103
|
-
],
|
|
104
|
-
decode: (value) => nullIfCatch(() => {
|
|
105
|
-
if (!checkKeyMatch(value[0], "condition" /* ConditionWitness */)) return null;
|
|
106
|
-
return RawWitness.decode(value[1]);
|
|
107
|
-
})
|
|
108
|
-
};
|
|
109
|
-
var PrevArkTxField = {
|
|
110
|
-
key: "prevarktx" /* PrevArkTx */,
|
|
111
|
-
encode: (value) => [
|
|
112
|
-
{
|
|
113
|
-
type: ArkPsbtFieldKeyType,
|
|
114
|
-
key: encodedPsbtFieldKey["prevarktx" /* PrevArkTx */]
|
|
115
|
-
},
|
|
116
|
-
value
|
|
117
|
-
],
|
|
118
|
-
decode: (value) => nullIfCatch(() => {
|
|
119
|
-
if (!checkKeyMatch(value[0], "prevarktx" /* PrevArkTx */)) return null;
|
|
120
|
-
return value[1];
|
|
121
|
-
})
|
|
122
|
-
};
|
|
123
|
-
var PrevoutTxField = {
|
|
124
|
-
key: "prevouttx" /* PrevoutTx */,
|
|
125
|
-
encode: (value) => [
|
|
126
|
-
{
|
|
127
|
-
type: ArkPsbtFieldKeyType,
|
|
128
|
-
key: encodedPsbtFieldKey["prevouttx" /* PrevoutTx */]
|
|
129
|
-
},
|
|
130
|
-
value
|
|
131
|
-
],
|
|
132
|
-
decode: (value) => nullIfCatch(() => {
|
|
133
|
-
if (!checkKeyMatch(value[0], "prevouttx" /* PrevoutTx */)) return null;
|
|
134
|
-
return value[1];
|
|
135
|
-
})
|
|
136
|
-
};
|
|
137
|
-
var CosignerPublicKey = {
|
|
138
|
-
key: "cosigner" /* Cosigner */,
|
|
139
|
-
encode: (value) => [
|
|
140
|
-
{
|
|
141
|
-
type: ArkPsbtFieldKeyType,
|
|
142
|
-
key: new Uint8Array([...encodedPsbtFieldKey["cosigner" /* Cosigner */], value.index])
|
|
143
|
-
},
|
|
144
|
-
value.key
|
|
145
|
-
],
|
|
146
|
-
decode: (unknown) => nullIfCatch(() => {
|
|
147
|
-
if (!checkKeyMatch(unknown[0], "cosigner" /* Cosigner */, true)) return null;
|
|
148
|
-
return {
|
|
149
|
-
index: unknown[0].key[unknown[0].key.length - 1],
|
|
150
|
-
key: unknown[1]
|
|
151
|
-
};
|
|
152
|
-
})
|
|
153
|
-
};
|
|
154
|
-
var VtxoTreeExpiry = {
|
|
155
|
-
key: "expiry" /* VtxoTreeExpiry */,
|
|
156
|
-
encode: (value) => [
|
|
157
|
-
{
|
|
158
|
-
type: ArkPsbtFieldKeyType,
|
|
159
|
-
key: encodedPsbtFieldKey["expiry" /* VtxoTreeExpiry */]
|
|
160
|
-
},
|
|
161
|
-
ScriptNum(6, true).encode(value.value === 0n ? 0n : value.value)
|
|
162
|
-
],
|
|
163
|
-
decode: (unknown) => nullIfCatch(() => {
|
|
164
|
-
if (!checkKeyMatch(unknown[0], "expiry" /* VtxoTreeExpiry */)) return null;
|
|
165
|
-
const v = ScriptNum(6, true).decode(unknown[1]);
|
|
166
|
-
if (!v) return null;
|
|
167
|
-
return sequenceToTimelock(Number(v));
|
|
168
|
-
})
|
|
169
|
-
};
|
|
170
|
-
var encodedPsbtFieldKey = Object.fromEntries(
|
|
171
|
-
Object.values(ArkPsbtFieldKey).map((key) => [key, new TextEncoder().encode(key)])
|
|
172
|
-
);
|
|
173
|
-
var nullIfCatch = (fn) => {
|
|
174
|
-
try {
|
|
175
|
-
return fn();
|
|
176
|
-
} catch {
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __export = (target, all) => {
|
|
13
|
+
for (var name in all)
|
|
14
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
179
15
|
};
|
|
180
|
-
function checkKeyMatch(key, arkPsbtFieldKey, prefixOnly = false) {
|
|
181
|
-
if (key.type !== ArkPsbtFieldKeyType) return false;
|
|
182
|
-
const expected = encodedPsbtFieldKey[arkPsbtFieldKey];
|
|
183
|
-
if (key.key.length < expected.length) return false;
|
|
184
|
-
if (!prefixOnly && key.key.length !== expected.length) return false;
|
|
185
|
-
for (let i = 0; i < expected.length; i++) {
|
|
186
|
-
if (key.key[i] !== expected[i]) return false;
|
|
187
|
-
}
|
|
188
|
-
return true;
|
|
189
|
-
}
|
|
190
16
|
var getNetwork = (network) => {
|
|
191
17
|
const found = networks[network];
|
|
192
18
|
if (!found) throw new Error(`Unsupported network: ${network}`);
|
|
@@ -323,6 +149,26 @@ var ArkAddress = class _ArkAddress {
|
|
|
323
149
|
return Script$1.encode(["RETURN", this.vtxoTaprootKey]);
|
|
324
150
|
}
|
|
325
151
|
};
|
|
152
|
+
function timelockToSequence(timelock) {
|
|
153
|
+
return bip68.encode(
|
|
154
|
+
timelock.type === "blocks" ? { blocks: Number(timelock.value) } : { seconds: Number(timelock.value) }
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
function sequenceToTimelock(sequence) {
|
|
158
|
+
const decoded = bip68.decode(sequence);
|
|
159
|
+
if ("blocks" in decoded && decoded.blocks !== void 0) {
|
|
160
|
+
return { type: "blocks", value: BigInt(decoded.blocks) };
|
|
161
|
+
}
|
|
162
|
+
if ("seconds" in decoded && decoded.seconds !== void 0) {
|
|
163
|
+
return { type: "seconds", value: BigInt(decoded.seconds) };
|
|
164
|
+
}
|
|
165
|
+
throw new Error(`Invalid BIP68 sequence: ${sequence}`);
|
|
166
|
+
}
|
|
167
|
+
function sequenceToCanonicalTimelock(sequence) {
|
|
168
|
+
if (sequence < 0n || sequence >= 0x80000000n) return void 0;
|
|
169
|
+
const timelock = sequenceToTimelock(Number(sequence));
|
|
170
|
+
return BigInt(timelockToSequence(timelock)) === sequence ? timelock : void 0;
|
|
171
|
+
}
|
|
326
172
|
var MinimalScriptNum = ScriptNum(void 0, true);
|
|
327
173
|
function decodeTapscript(script) {
|
|
328
174
|
const types = [
|
|
@@ -570,6 +416,16 @@ var CSVMultisigTapscript;
|
|
|
570
416
|
}
|
|
571
417
|
CSVMultisigTapscript2.isScriptValid = isScriptValid;
|
|
572
418
|
})(CSVMultisigTapscript || (CSVMultisigTapscript = {}));
|
|
419
|
+
function isConditionScriptValid(script) {
|
|
420
|
+
const asm = Script.decode(script);
|
|
421
|
+
if (asm.length < 1) {
|
|
422
|
+
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
423
|
+
}
|
|
424
|
+
if (asm.lastIndexOf("VERIFY") === -1) {
|
|
425
|
+
return new Error("Invalid script: missing VERIFY operation");
|
|
426
|
+
}
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
573
429
|
var ConditionCSVMultisigTapscript;
|
|
574
430
|
((ConditionCSVMultisigTapscript2) => {
|
|
575
431
|
function encode2(params) {
|
|
@@ -594,7 +450,7 @@ var ConditionCSVMultisigTapscript;
|
|
|
594
450
|
throw isValid;
|
|
595
451
|
}
|
|
596
452
|
const asm = Script.decode(script);
|
|
597
|
-
|
|
453
|
+
const verifyIndex = asm.lastIndexOf("VERIFY");
|
|
598
454
|
if (verifyIndex === -1) {
|
|
599
455
|
throw Error("Invalid script: missing VERIFY operation");
|
|
600
456
|
}
|
|
@@ -629,26 +485,8 @@ var ConditionCSVMultisigTapscript;
|
|
|
629
485
|
return tapscript.type === "condition-csv-multisig" /* ConditionCSVMultisig */;
|
|
630
486
|
}
|
|
631
487
|
ConditionCSVMultisigTapscript2.is = is;
|
|
632
|
-
function getVerifyIndex(asm) {
|
|
633
|
-
let verifyIndex = -1;
|
|
634
|
-
for (let i = asm.length - 1; i >= 0; i--) {
|
|
635
|
-
if (asm[i] === "VERIFY") {
|
|
636
|
-
verifyIndex = i;
|
|
637
|
-
return verifyIndex;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
return verifyIndex;
|
|
641
|
-
}
|
|
642
488
|
function isScriptValid(script) {
|
|
643
|
-
|
|
644
|
-
if (asm.length < 1) {
|
|
645
|
-
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
646
|
-
}
|
|
647
|
-
let verifyIndex = getVerifyIndex(asm);
|
|
648
|
-
if (verifyIndex === -1) {
|
|
649
|
-
return new Error("Invalid script: missing VERIFY operation");
|
|
650
|
-
}
|
|
651
|
-
return true;
|
|
489
|
+
return isConditionScriptValid(script);
|
|
652
490
|
}
|
|
653
491
|
ConditionCSVMultisigTapscript2.isScriptValid = isScriptValid;
|
|
654
492
|
})(ConditionCSVMultisigTapscript || (ConditionCSVMultisigTapscript = {}));
|
|
@@ -676,7 +514,7 @@ var ConditionMultisigTapscript;
|
|
|
676
514
|
throw isValid;
|
|
677
515
|
}
|
|
678
516
|
const asm = Script.decode(script);
|
|
679
|
-
|
|
517
|
+
const verifyIndex = asm.lastIndexOf("VERIFY");
|
|
680
518
|
if (verifyIndex === -1) {
|
|
681
519
|
throw Error("Invalid script: missing VERIFY operation");
|
|
682
520
|
}
|
|
@@ -711,26 +549,8 @@ var ConditionMultisigTapscript;
|
|
|
711
549
|
return tapscript.type === "condition-multisig" /* ConditionMultisig */;
|
|
712
550
|
}
|
|
713
551
|
ConditionMultisigTapscript2.is = is;
|
|
714
|
-
function getVerifyIndex(asm) {
|
|
715
|
-
let verifyIndex = -1;
|
|
716
|
-
for (let i = asm.length - 1; i >= 0; i--) {
|
|
717
|
-
if (asm[i] === "VERIFY") {
|
|
718
|
-
verifyIndex = i;
|
|
719
|
-
return verifyIndex;
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
return verifyIndex;
|
|
723
|
-
}
|
|
724
552
|
function isScriptValid(script) {
|
|
725
|
-
|
|
726
|
-
if (asm.length < 1) {
|
|
727
|
-
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
728
|
-
}
|
|
729
|
-
let verifyIndex = getVerifyIndex(asm);
|
|
730
|
-
if (verifyIndex === -1) {
|
|
731
|
-
return new Error("Invalid script: missing VERIFY operation");
|
|
732
|
-
}
|
|
733
|
-
return true;
|
|
553
|
+
return isConditionScriptValid(script);
|
|
734
554
|
}
|
|
735
555
|
ConditionMultisigTapscript2.isScriptValid = isScriptValid;
|
|
736
556
|
})(ConditionMultisigTapscript || (ConditionMultisigTapscript = {}));
|
|
@@ -855,7 +675,25 @@ function assembleBtcdTaprootTree(scripts) {
|
|
|
855
675
|
}
|
|
856
676
|
return branches[0];
|
|
857
677
|
}
|
|
858
|
-
|
|
678
|
+
function btcdLeafLayout(count) {
|
|
679
|
+
const placeholders = Array.from({ length: count }, () => new Uint8Array());
|
|
680
|
+
const indexOf = new Map(placeholders.map((script, index) => [script, index]));
|
|
681
|
+
const layout = [];
|
|
682
|
+
const walk = (node, depth) => {
|
|
683
|
+
if (Array.isArray(node)) {
|
|
684
|
+
walk(node[0], depth + 1);
|
|
685
|
+
walk(node[1], depth + 1);
|
|
686
|
+
} else {
|
|
687
|
+
layout.push({ index: indexOf.get(node.script), depth });
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
walk(assembleBtcdTaprootTree(placeholders), 0);
|
|
691
|
+
return layout;
|
|
692
|
+
}
|
|
693
|
+
var TapTreeCoder = P.array(
|
|
694
|
+
null,
|
|
695
|
+
P.struct({ depth: P.U8, version: P.U8, script: VarBytes })
|
|
696
|
+
);
|
|
859
697
|
function scriptFromTapLeafScript(leaf) {
|
|
860
698
|
return leaf[1].subarray(0, leaf[1].length - 1);
|
|
861
699
|
}
|
|
@@ -875,7 +713,7 @@ var VtxoScript = class _VtxoScript {
|
|
|
875
713
|
constructor(scripts) {
|
|
876
714
|
this.scripts = scripts;
|
|
877
715
|
const tapTree = assembleBtcdTaprootTree(scripts);
|
|
878
|
-
const payment = p2tr(
|
|
716
|
+
const payment = p2tr(taprootNumsKey(), tapTree, void 0, true);
|
|
879
717
|
if (!payment.tapLeafScript || payment.tapLeafScript.length !== scripts.length) {
|
|
880
718
|
throw new Error("invalid scripts");
|
|
881
719
|
}
|
|
@@ -890,15 +728,46 @@ var VtxoScript = class _VtxoScript {
|
|
|
890
728
|
/**
|
|
891
729
|
* Decode a virtual output script from an encoded TapTree.
|
|
892
730
|
*
|
|
731
|
+
* Leaves are normally read in construction order and their depths
|
|
732
|
+
* ignored: that covers the {@link encode} form (every depth 1) and the
|
|
733
|
+
* placeholder depths other writers use, such as arkd's. The exception is
|
|
734
|
+
* the BIP-371 form {@link toBIP371TapTree} writes, whose leaves are in the
|
|
735
|
+
* tree's DFS order: for some leaf counts (6, 7, 10, ...) that differs from
|
|
736
|
+
* construction order. A tree whose depths are exactly the shape
|
|
737
|
+
* `assembleBtcdTaprootTree` builds is that form, so its leaves are mapped
|
|
738
|
+
* back to construction order first. No construction-order writer produces
|
|
739
|
+
* that depth sequence when the two orders differ, so this never reorders
|
|
740
|
+
* a tree that decoded correctly before.
|
|
741
|
+
*
|
|
742
|
+
* Every leaf must carry the base tapscript version: the tree is rebuilt
|
|
743
|
+
* with {@link TAP_LEAF_VERSION} leaves, so any other version would
|
|
744
|
+
* silently derive a different taproot key.
|
|
745
|
+
*
|
|
893
746
|
* @param tapTree - Encoded TapTree bytes
|
|
894
747
|
* @returns Decoded virtual output script
|
|
895
748
|
* @throws Error if the TapTree cannot be decoded into a valid script set
|
|
749
|
+
* or a leaf carries a version other than {@link TAP_LEAF_VERSION}
|
|
896
750
|
* @see encode
|
|
897
751
|
*/
|
|
898
752
|
static decode(tapTree) {
|
|
899
753
|
const leaves = TapTreeCoder.decode(tapTree);
|
|
754
|
+
const foreign = leaves.find((leaf) => leaf.version !== TAP_LEAF_VERSION);
|
|
755
|
+
if (foreign) {
|
|
756
|
+
throw new Error(`unsupported tap leaf version 0x${foreign.version.toString(16)}`);
|
|
757
|
+
}
|
|
900
758
|
const scripts = leaves.map((leaf) => leaf.script);
|
|
901
|
-
|
|
759
|
+
if (leaves.every((leaf) => leaf.depth === 1)) {
|
|
760
|
+
return new _VtxoScript(scripts);
|
|
761
|
+
}
|
|
762
|
+
const layout = btcdLeafLayout(leaves.length);
|
|
763
|
+
if (layout.some((slot, i) => slot.depth !== leaves[i].depth)) {
|
|
764
|
+
return new _VtxoScript(scripts);
|
|
765
|
+
}
|
|
766
|
+
const ordered = new Array(leaves.length);
|
|
767
|
+
layout.forEach((slot, i) => {
|
|
768
|
+
ordered[slot.index] = scripts[i];
|
|
769
|
+
});
|
|
770
|
+
return new _VtxoScript(ordered);
|
|
902
771
|
}
|
|
903
772
|
/**
|
|
904
773
|
* Encode the virtual output script to a TapTree byte representation.
|
|
@@ -981,21 +850,323 @@ var VtxoScript = class _VtxoScript {
|
|
|
981
850
|
return paths;
|
|
982
851
|
}
|
|
983
852
|
};
|
|
984
|
-
function
|
|
985
|
-
|
|
853
|
+
function toBIP371TapTree(tapTree) {
|
|
854
|
+
const scripts = TapTreeCoder.decode(tapTree).map((leaf) => leaf.script);
|
|
855
|
+
const vtxoScript = new VtxoScript(scripts);
|
|
856
|
+
return vtxoScript.leaves.map((leaf) => ({
|
|
857
|
+
depth: leaf[0].merklePath.length,
|
|
858
|
+
version: TAP_LEAF_VERSION,
|
|
859
|
+
script: scriptFromTapLeafScript(leaf)
|
|
860
|
+
}));
|
|
861
|
+
}
|
|
862
|
+
function getSequence(tapLeafScript) {
|
|
863
|
+
let sequence = void 0;
|
|
864
|
+
try {
|
|
865
|
+
const scriptWithLeafVersion = tapLeafScript[1];
|
|
866
|
+
const script = scriptWithLeafVersion.subarray(0, scriptWithLeafVersion.length - 1);
|
|
867
|
+
try {
|
|
868
|
+
const params = CSVMultisigTapscript.decode(script).params;
|
|
869
|
+
sequence = timelockToSequence(params.timelock);
|
|
870
|
+
} catch {
|
|
871
|
+
const params = CLTVMultisigTapscript.decode(script).params;
|
|
872
|
+
sequence = Number(params.absoluteTimelock);
|
|
873
|
+
}
|
|
874
|
+
} catch {
|
|
875
|
+
}
|
|
876
|
+
return sequence;
|
|
877
|
+
}
|
|
878
|
+
var Transaction = class extends Transaction$1 {
|
|
879
|
+
static ARK_TX_OPTS = {
|
|
880
|
+
unknown: "ignore",
|
|
881
|
+
allowUnknownOutputs: true,
|
|
882
|
+
allowUnknownInputs: true
|
|
883
|
+
};
|
|
884
|
+
constructor(opts) {
|
|
885
|
+
super(withArkOpts(opts));
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Decode a PSBT. PSBTs carrying a legacy `PSBT_OUT_TAP_TREE` (see
|
|
889
|
+
* {@link repairLegacyOutputTapTrees}) are repaired and decoded again
|
|
890
|
+
* instead of being rejected.
|
|
891
|
+
*/
|
|
892
|
+
static fromPSBT(psbt_, opts) {
|
|
893
|
+
try {
|
|
894
|
+
return Transaction$1.fromPSBT(psbt_, withArkOpts(opts));
|
|
895
|
+
} catch (err) {
|
|
896
|
+
const repaired = repairLegacyOutputTapTrees(psbt_);
|
|
897
|
+
if (!repaired) throw err;
|
|
898
|
+
return Transaction$1.fromPSBT(repaired, withArkOpts(opts));
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
static fromRaw(raw, opts) {
|
|
902
|
+
return Transaction$1.fromRaw(raw, withArkOpts(opts));
|
|
903
|
+
}
|
|
904
|
+
};
|
|
905
|
+
function withArkOpts(opts) {
|
|
906
|
+
return { ...Transaction.ARK_TX_OPTS, ...opts };
|
|
907
|
+
}
|
|
908
|
+
var PSBT_MAGIC = new Uint8Array([112, 115, 98, 116, 255]);
|
|
909
|
+
var PSBT_GLOBAL_UNSIGNED_TX = 0;
|
|
910
|
+
var PSBT_GLOBAL_INPUT_COUNT = 4;
|
|
911
|
+
var PSBT_OUT_TAP_TREE = 6;
|
|
912
|
+
function repairLegacyOutputTapTrees(psbt) {
|
|
913
|
+
let maps;
|
|
914
|
+
let inputsCount;
|
|
915
|
+
try {
|
|
916
|
+
maps = readPsbtMaps(psbt);
|
|
917
|
+
inputsCount = psbtInputsCount(maps[0]);
|
|
918
|
+
} catch {
|
|
919
|
+
return void 0;
|
|
920
|
+
}
|
|
921
|
+
let repaired = false;
|
|
922
|
+
for (const output of maps.slice(1 + inputsCount)) {
|
|
923
|
+
for (const kv of output) {
|
|
924
|
+
if (kv.key.length !== 1 || kv.key[0] !== PSBT_OUT_TAP_TREE) continue;
|
|
925
|
+
const value = legacyTapTreeToBIP371(kv.value);
|
|
926
|
+
if (!value) continue;
|
|
927
|
+
kv.value = value;
|
|
928
|
+
repaired = true;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
return repaired ? writePsbtMaps(maps) : void 0;
|
|
932
|
+
}
|
|
933
|
+
function legacyTapTreeToBIP371(value) {
|
|
934
|
+
try {
|
|
935
|
+
PSBTOutput.tapTree[2].decode(value);
|
|
936
|
+
return void 0;
|
|
937
|
+
} catch {
|
|
938
|
+
}
|
|
939
|
+
let leaves;
|
|
940
|
+
try {
|
|
941
|
+
leaves = TapTreeCoder.decode(value);
|
|
942
|
+
} catch {
|
|
943
|
+
return void 0;
|
|
944
|
+
}
|
|
945
|
+
if (leaves.length === 0 || leaves.some((leaf) => leaf.depth !== 1)) return void 0;
|
|
946
|
+
try {
|
|
947
|
+
return TapTreeCoder.encode(toBIP371TapTree(value));
|
|
948
|
+
} catch {
|
|
949
|
+
return void 0;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
function psbtInputsCount(global) {
|
|
953
|
+
for (const { key, value } of global) {
|
|
954
|
+
if (key.length !== 1) continue;
|
|
955
|
+
if (key[0] === PSBT_GLOBAL_UNSIGNED_TX) return RawTx.decode(value).inputs.length;
|
|
956
|
+
if (key[0] === PSBT_GLOBAL_INPUT_COUNT) return readCompactSize(value, 0)[0];
|
|
957
|
+
}
|
|
958
|
+
throw new Error("PSBT: missing input count");
|
|
959
|
+
}
|
|
960
|
+
function readPsbtMaps(psbt) {
|
|
961
|
+
for (let i = 0; i < PSBT_MAGIC.length; i++) {
|
|
962
|
+
if (psbt[i] !== PSBT_MAGIC[i]) throw new Error("PSBT: invalid magic");
|
|
963
|
+
}
|
|
964
|
+
const maps = [];
|
|
965
|
+
let pos = PSBT_MAGIC.length;
|
|
966
|
+
while (pos < psbt.length) {
|
|
967
|
+
const map = [];
|
|
968
|
+
for (; ; ) {
|
|
969
|
+
const [keyLen, afterKeyLen] = readCompactSize(psbt, pos);
|
|
970
|
+
pos = afterKeyLen;
|
|
971
|
+
if (keyLen === 0) break;
|
|
972
|
+
const key = readBytes(psbt, pos, keyLen);
|
|
973
|
+
pos += keyLen;
|
|
974
|
+
const [valueLen, afterValueLen] = readCompactSize(psbt, pos);
|
|
975
|
+
pos = afterValueLen;
|
|
976
|
+
const value = readBytes(psbt, pos, valueLen);
|
|
977
|
+
pos += valueLen;
|
|
978
|
+
map.push({ key, value });
|
|
979
|
+
}
|
|
980
|
+
maps.push(map);
|
|
981
|
+
}
|
|
982
|
+
if (maps.length === 0) throw new Error("PSBT: missing global map");
|
|
983
|
+
return maps;
|
|
984
|
+
}
|
|
985
|
+
function writePsbtMaps(maps) {
|
|
986
|
+
const parts = [PSBT_MAGIC];
|
|
987
|
+
for (const map of maps) {
|
|
988
|
+
for (const { key, value } of map) {
|
|
989
|
+
parts.push(writeCompactSize(key.length), key, writeCompactSize(value.length), value);
|
|
990
|
+
}
|
|
991
|
+
parts.push(new Uint8Array([0]));
|
|
992
|
+
}
|
|
993
|
+
return concatBytes(...parts);
|
|
994
|
+
}
|
|
995
|
+
function readBytes(data, pos, len) {
|
|
996
|
+
if (pos + len > data.length) throw new Error("PSBT: unexpected end of data");
|
|
997
|
+
return data.slice(pos, pos + len);
|
|
998
|
+
}
|
|
999
|
+
function readCompactSize(data, pos) {
|
|
1000
|
+
const first = readBytes(data, pos, 1)[0];
|
|
1001
|
+
if (first < 253) return [first, pos + 1];
|
|
1002
|
+
const width = first === 253 ? 2 : first === 254 ? 4 : 8;
|
|
1003
|
+
const bytes = readBytes(data, pos + 1, width);
|
|
1004
|
+
let value = 0;
|
|
1005
|
+
for (let i = width - 1; i >= 0; i--) value = value * 256 + bytes[i];
|
|
1006
|
+
if (!Number.isSafeInteger(value)) throw new Error("PSBT: compact size too large");
|
|
1007
|
+
return [value, pos + 1 + width];
|
|
1008
|
+
}
|
|
1009
|
+
function writeCompactSize(value) {
|
|
1010
|
+
if (value < 253) return new Uint8Array([value]);
|
|
1011
|
+
const width = value <= 65535 ? 2 : value <= 4294967295 ? 4 : 8;
|
|
1012
|
+
const out = new Uint8Array(1 + width);
|
|
1013
|
+
out[0] = width === 2 ? 253 : width === 4 ? 254 : 255;
|
|
1014
|
+
for (let i = 0, v = value; i < width; i++, v = Math.floor(v / 256)) out[1 + i] = v % 256;
|
|
1015
|
+
return out;
|
|
1016
|
+
}
|
|
1017
|
+
function formatSighash(type) {
|
|
1018
|
+
return `0x${type.toString(16).padStart(2, "0")}`;
|
|
1019
|
+
}
|
|
1020
|
+
function assertAllowedSighashTypes(tx, allowedSighashTypes = [SigHash.DEFAULT]) {
|
|
1021
|
+
for (let i = 0; i < tx.inputsLength; i++) {
|
|
1022
|
+
const declared = tx.getInput(i).sighashType;
|
|
1023
|
+
if (declared === void 0) continue;
|
|
1024
|
+
if (!allowedSighashTypes.includes(declared)) {
|
|
1025
|
+
throw new Error(`Unallowed sighash type ${formatSighash(declared)} for input ${i}.`);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
// src/utils/time.ts
|
|
1031
|
+
function assertNonNegativeMs(name, ms) {
|
|
1032
|
+
if (ms !== void 0 && (!Number.isSafeInteger(ms) || ms < 0)) {
|
|
1033
|
+
throw new Error(`${name} must be a non-negative safe integer`);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
var MAX_TIMER_MS = 2 ** 31 - 1;
|
|
1037
|
+
function assertTimerMs(name, ms) {
|
|
1038
|
+
assertNonNegativeMs(name, ms);
|
|
1039
|
+
if (ms !== void 0 && ms > MAX_TIMER_MS) {
|
|
1040
|
+
throw new Error(`${name} must not exceed ${MAX_TIMER_MS} milliseconds`);
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
var ArkPsbtFieldKey = /* @__PURE__ */ ((ArkPsbtFieldKey2) => {
|
|
1044
|
+
ArkPsbtFieldKey2["VtxoTaprootTree"] = "taptree";
|
|
1045
|
+
ArkPsbtFieldKey2["VtxoTreeExpiry"] = "expiry";
|
|
1046
|
+
ArkPsbtFieldKey2["Cosigner"] = "cosigner";
|
|
1047
|
+
ArkPsbtFieldKey2["ConditionWitness"] = "condition";
|
|
1048
|
+
ArkPsbtFieldKey2["PrevArkTx"] = "prevarktx";
|
|
1049
|
+
ArkPsbtFieldKey2["PrevoutTx"] = "prevouttx";
|
|
1050
|
+
return ArkPsbtFieldKey2;
|
|
1051
|
+
})(ArkPsbtFieldKey || {});
|
|
1052
|
+
var ArkPsbtFieldKeyType = 222;
|
|
1053
|
+
function setArkPsbtField(tx, inputIndex, coder, value) {
|
|
1054
|
+
tx.updateInput(inputIndex, {
|
|
1055
|
+
unknown: [...tx.getInput(inputIndex)?.unknown ?? [], coder.encode(value)]
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
function getArkPsbtFields(tx, inputIndex, coder) {
|
|
1059
|
+
const unknown = tx.getInput(inputIndex)?.unknown ?? [];
|
|
1060
|
+
return unknown.map((u) => coder.decode(u)).filter((v) => v !== null);
|
|
1061
|
+
}
|
|
1062
|
+
var VtxoTaprootTree = {
|
|
1063
|
+
key: "taptree" /* VtxoTaprootTree */,
|
|
1064
|
+
encode: (value) => [
|
|
1065
|
+
{
|
|
1066
|
+
type: ArkPsbtFieldKeyType,
|
|
1067
|
+
key: encodedPsbtFieldKey["taptree" /* VtxoTaprootTree */]
|
|
1068
|
+
},
|
|
1069
|
+
value
|
|
1070
|
+
],
|
|
1071
|
+
decode: (value) => nullIfCatch(() => {
|
|
1072
|
+
if (!checkKeyMatch(value[0], "taptree" /* VtxoTaprootTree */)) return null;
|
|
1073
|
+
return value[1];
|
|
1074
|
+
})
|
|
1075
|
+
};
|
|
1076
|
+
var ConditionWitness = {
|
|
1077
|
+
key: "condition" /* ConditionWitness */,
|
|
1078
|
+
encode: (value) => [
|
|
1079
|
+
{
|
|
1080
|
+
type: ArkPsbtFieldKeyType,
|
|
1081
|
+
key: encodedPsbtFieldKey["condition" /* ConditionWitness */]
|
|
1082
|
+
},
|
|
1083
|
+
RawWitness.encode(value)
|
|
1084
|
+
],
|
|
1085
|
+
decode: (value) => nullIfCatch(() => {
|
|
1086
|
+
if (!checkKeyMatch(value[0], "condition" /* ConditionWitness */)) return null;
|
|
1087
|
+
return RawWitness.decode(value[1]);
|
|
1088
|
+
})
|
|
1089
|
+
};
|
|
1090
|
+
var PrevArkTxField = {
|
|
1091
|
+
key: "prevarktx" /* PrevArkTx */,
|
|
1092
|
+
encode: (value) => [
|
|
1093
|
+
{
|
|
1094
|
+
type: ArkPsbtFieldKeyType,
|
|
1095
|
+
key: encodedPsbtFieldKey["prevarktx" /* PrevArkTx */]
|
|
1096
|
+
},
|
|
1097
|
+
value
|
|
1098
|
+
],
|
|
1099
|
+
decode: (value) => nullIfCatch(() => {
|
|
1100
|
+
if (!checkKeyMatch(value[0], "prevarktx" /* PrevArkTx */)) return null;
|
|
1101
|
+
return value[1];
|
|
1102
|
+
})
|
|
1103
|
+
};
|
|
1104
|
+
var PrevoutTxField = {
|
|
1105
|
+
key: "prevouttx" /* PrevoutTx */,
|
|
1106
|
+
encode: (value) => [
|
|
1107
|
+
{
|
|
1108
|
+
type: ArkPsbtFieldKeyType,
|
|
1109
|
+
key: encodedPsbtFieldKey["prevouttx" /* PrevoutTx */]
|
|
1110
|
+
},
|
|
1111
|
+
value
|
|
1112
|
+
],
|
|
1113
|
+
decode: (value) => nullIfCatch(() => {
|
|
1114
|
+
if (!checkKeyMatch(value[0], "prevouttx" /* PrevoutTx */)) return null;
|
|
1115
|
+
return value[1];
|
|
1116
|
+
})
|
|
1117
|
+
};
|
|
1118
|
+
var CosignerPublicKey = {
|
|
1119
|
+
key: "cosigner" /* Cosigner */,
|
|
1120
|
+
encode: (value) => [
|
|
1121
|
+
{
|
|
1122
|
+
type: ArkPsbtFieldKeyType,
|
|
1123
|
+
key: new Uint8Array([...encodedPsbtFieldKey["cosigner" /* Cosigner */], value.index])
|
|
1124
|
+
},
|
|
1125
|
+
value.key
|
|
1126
|
+
],
|
|
1127
|
+
decode: (unknown) => nullIfCatch(() => {
|
|
1128
|
+
if (!checkKeyMatch(unknown[0], "cosigner" /* Cosigner */, true)) return null;
|
|
1129
|
+
return {
|
|
1130
|
+
index: unknown[0].key[unknown[0].key.length - 1],
|
|
1131
|
+
key: unknown[1]
|
|
1132
|
+
};
|
|
1133
|
+
})
|
|
1134
|
+
};
|
|
1135
|
+
var VtxoTreeExpiry = {
|
|
1136
|
+
key: "expiry" /* VtxoTreeExpiry */,
|
|
1137
|
+
encode: (value) => [
|
|
1138
|
+
{
|
|
1139
|
+
type: ArkPsbtFieldKeyType,
|
|
1140
|
+
key: encodedPsbtFieldKey["expiry" /* VtxoTreeExpiry */]
|
|
1141
|
+
},
|
|
1142
|
+
ScriptNum(6, true).encode(value.value)
|
|
1143
|
+
],
|
|
1144
|
+
decode: (unknown) => nullIfCatch(() => {
|
|
1145
|
+
if (!checkKeyMatch(unknown[0], "expiry" /* VtxoTreeExpiry */)) return null;
|
|
1146
|
+
const v = ScriptNum(6, true).decode(unknown[1]);
|
|
1147
|
+
if (!v) return null;
|
|
1148
|
+
return sequenceToTimelock(Number(v));
|
|
1149
|
+
})
|
|
1150
|
+
};
|
|
1151
|
+
var encodedPsbtFieldKey = Object.fromEntries(
|
|
1152
|
+
Object.values(ArkPsbtFieldKey).map((key) => [key, new TextEncoder().encode(key)])
|
|
1153
|
+
);
|
|
1154
|
+
var nullIfCatch = (fn) => {
|
|
986
1155
|
try {
|
|
987
|
-
|
|
988
|
-
const script = scriptWithLeafVersion.subarray(0, scriptWithLeafVersion.length - 1);
|
|
989
|
-
try {
|
|
990
|
-
const params = CSVMultisigTapscript.decode(script).params;
|
|
991
|
-
sequence = timelockToSequence(params.timelock);
|
|
992
|
-
} catch {
|
|
993
|
-
const params = CLTVMultisigTapscript.decode(script).params;
|
|
994
|
-
sequence = Number(params.absoluteTimelock);
|
|
995
|
-
}
|
|
1156
|
+
return fn();
|
|
996
1157
|
} catch {
|
|
1158
|
+
return null;
|
|
997
1159
|
}
|
|
998
|
-
|
|
1160
|
+
};
|
|
1161
|
+
function checkKeyMatch(key, arkPsbtFieldKey, prefixOnly = false) {
|
|
1162
|
+
if (key.type !== ArkPsbtFieldKeyType) return false;
|
|
1163
|
+
const expected = encodedPsbtFieldKey[arkPsbtFieldKey];
|
|
1164
|
+
if (key.key.length < expected.length) return false;
|
|
1165
|
+
if (!prefixOnly && key.key.length !== expected.length) return false;
|
|
1166
|
+
for (let i = 0; i < expected.length; i++) {
|
|
1167
|
+
if (key.key[i] !== expected[i]) return false;
|
|
1168
|
+
}
|
|
1169
|
+
return true;
|
|
999
1170
|
}
|
|
1000
1171
|
|
|
1001
1172
|
// src/providers/eventSource.ts
|
|
@@ -1023,11 +1194,15 @@ function resolveEventSource(override) {
|
|
|
1023
1194
|
}
|
|
1024
1195
|
|
|
1025
1196
|
// package.json
|
|
1026
|
-
var version = "0.5.0-rc.
|
|
1197
|
+
var version = "0.5.0-rc.20";
|
|
1027
1198
|
|
|
1028
1199
|
// src/utils/fetch.ts
|
|
1029
1200
|
var buildVersion = "0.9.9";
|
|
1030
1201
|
var sdkVersion = `ts-sdk/${version}`;
|
|
1202
|
+
var ARKADE_VERSION_HEADERS = {
|
|
1203
|
+
"X-Build-Version": buildVersion,
|
|
1204
|
+
"X-SDK-VERSION": sdkVersion
|
|
1205
|
+
};
|
|
1031
1206
|
var FetchError = class extends Error {
|
|
1032
1207
|
/** The request URL that failed, when derivable from the `fetch` input. */
|
|
1033
1208
|
url;
|
|
@@ -1040,38 +1215,48 @@ var FetchError = class extends Error {
|
|
|
1040
1215
|
this.method = options.method;
|
|
1041
1216
|
}
|
|
1042
1217
|
};
|
|
1218
|
+
var READ_TIMEOUT_MS = 3e4;
|
|
1219
|
+
var warnedNoTimeoutSupport = false;
|
|
1220
|
+
function readDeadline(input, init) {
|
|
1221
|
+
if (init?.signal || input instanceof Request) return void 0;
|
|
1222
|
+
const { method } = describeRequest(input, init);
|
|
1223
|
+
const verb = method.toUpperCase();
|
|
1224
|
+
if (verb !== "GET" && verb !== "HEAD") return void 0;
|
|
1225
|
+
if (typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function") {
|
|
1226
|
+
return AbortSignal.timeout(READ_TIMEOUT_MS);
|
|
1227
|
+
}
|
|
1228
|
+
if (typeof AbortController === "function") {
|
|
1229
|
+
const controller = new AbortController();
|
|
1230
|
+
const timer = setTimeout(() => controller.abort(), READ_TIMEOUT_MS);
|
|
1231
|
+
timer?.unref?.();
|
|
1232
|
+
return controller.signal;
|
|
1233
|
+
}
|
|
1234
|
+
if (!warnedNoTimeoutSupport) {
|
|
1235
|
+
warnedNoTimeoutSupport = true;
|
|
1236
|
+
console.warn(
|
|
1237
|
+
"Neither AbortSignal.timeout nor AbortController is available in this runtime: provider reads are UNBOUNDED and READ_TIMEOUT_MS is not being applied."
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
return void 0;
|
|
1241
|
+
}
|
|
1043
1242
|
function baseFetch(input, init) {
|
|
1044
1243
|
if (typeof globalThis.fetch !== "function") {
|
|
1045
1244
|
throw new Error("Fetch API is not available in this environment.");
|
|
1046
1245
|
}
|
|
1047
|
-
|
|
1246
|
+
const signal = readDeadline(input, init);
|
|
1247
|
+
return globalThis.fetch(input, signal ? { ...init, signal } : init).catch((cause) => {
|
|
1048
1248
|
const { url, method } = describeRequest(input, init);
|
|
1049
1249
|
throw new FetchError(`Network request failed: ${method} ${url}`, { url, method, cause });
|
|
1050
1250
|
});
|
|
1051
1251
|
}
|
|
1052
1252
|
function fetch(input, init) {
|
|
1053
1253
|
const headers = new Headers(init?.headers);
|
|
1054
|
-
headers.set(
|
|
1055
|
-
headers.set("X-SDK-VERSION", sdkVersion);
|
|
1254
|
+
for (const [name, value] of Object.entries(ARKADE_VERSION_HEADERS)) headers.set(name, value);
|
|
1056
1255
|
return baseFetch(input, { ...init, headers });
|
|
1057
1256
|
}
|
|
1058
1257
|
function describeRequest(input, init) {
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
url = input;
|
|
1062
|
-
} else if (input instanceof URL) {
|
|
1063
|
-
url = input.href;
|
|
1064
|
-
} else {
|
|
1065
|
-
url = input.url;
|
|
1066
|
-
}
|
|
1067
|
-
let method;
|
|
1068
|
-
if (init?.method !== void 0) {
|
|
1069
|
-
method = init.method;
|
|
1070
|
-
} else if (input instanceof Request) {
|
|
1071
|
-
method = input.method;
|
|
1072
|
-
} else {
|
|
1073
|
-
method = "GET";
|
|
1074
|
-
}
|
|
1258
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
1259
|
+
const method = init?.method !== void 0 ? init.method : input instanceof Request ? input.method : "GET";
|
|
1075
1260
|
return { url, method };
|
|
1076
1261
|
}
|
|
1077
1262
|
|
|
@@ -1095,15 +1280,13 @@ var ArkErrorName = {
|
|
|
1095
1280
|
INVALID_TX_FILTER: "INVALID_TX_FILTER",
|
|
1096
1281
|
TX_FILTERS_LIMIT_EXCEEDED: "TX_FILTERS_LIMIT_EXCEEDED",
|
|
1097
1282
|
/**
|
|
1098
|
-
* A CLTV closure was spent before its absolute locktime matured.
|
|
1099
|
-
* `
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1102
|
-
* Self-healing, so defer and retry rather than fail: the server matures a
|
|
1103
|
-
* seconds-locktime against the **chain tip block's timestamp**, not its wall clock,
|
|
1104
|
-
* so a spend attempted promptly at maturity is rejected until a later block lands.
|
|
1283
|
+
* A CLTV closure was spent before its absolute locktime matured. `submitTx` only, with
|
|
1284
|
+
* metadata `{ locktime, current_locktime, type: "height" | "time" }`. Self-healing, so defer
|
|
1285
|
+
* and retry: the server matures a seconds-locktime against the **chain tip block's
|
|
1286
|
+
* timestamp**, not wall clock, so a prompt spend is rejected until a later block lands.
|
|
1105
1287
|
*/
|
|
1106
|
-
FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED"
|
|
1288
|
+
FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED",
|
|
1289
|
+
INVALID_INTENT_PROOF: "INVALID_INTENT_PROOF"
|
|
1107
1290
|
};
|
|
1108
1291
|
function isArkError(error, name) {
|
|
1109
1292
|
return error instanceof ArkError && (name === void 0 || error.name === name);
|
|
@@ -1179,8 +1362,8 @@ var Intent;
|
|
|
1179
1362
|
}
|
|
1180
1363
|
if (ins.length == 0) throw new Error("intent proof requires at least one input");
|
|
1181
1364
|
const inputs = ins.map(prepareCoinAsIntentProofInput);
|
|
1182
|
-
|
|
1183
|
-
|
|
1365
|
+
validateInputs(inputs);
|
|
1366
|
+
validateOutputs(outputs);
|
|
1184
1367
|
const toSpend = craftToSpendTx(message, inputs[0].witnessUtxo.script);
|
|
1185
1368
|
return craftToSignTx(toSpend, inputs, outputs, message);
|
|
1186
1369
|
}
|
|
@@ -1235,7 +1418,6 @@ var OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([OP.RETURN]);
|
|
|
1235
1418
|
var ZERO_32 = new Uint8Array(32).fill(0);
|
|
1236
1419
|
var MAX_INDEX = 4294967295;
|
|
1237
1420
|
var TAG_INTENT_PROOF = "ark-intent-proof-message";
|
|
1238
|
-
var PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE = 9;
|
|
1239
1421
|
function validateInput(input) {
|
|
1240
1422
|
if (input.index === void 0) throw new Error("intent proof input requires index");
|
|
1241
1423
|
if (input.txid === void 0) throw new Error("intent proof input requires txid");
|
|
@@ -1245,7 +1427,6 @@ function validateInput(input) {
|
|
|
1245
1427
|
}
|
|
1246
1428
|
function validateInputs(inputs) {
|
|
1247
1429
|
inputs.forEach(validateInput);
|
|
1248
|
-
return true;
|
|
1249
1430
|
}
|
|
1250
1431
|
function validateOutput(output) {
|
|
1251
1432
|
if (output.amount === void 0) throw new Error("intent proof output requires amount");
|
|
@@ -1254,7 +1435,6 @@ function validateOutput(output) {
|
|
|
1254
1435
|
}
|
|
1255
1436
|
function validateOutputs(outputs) {
|
|
1256
1437
|
outputs.forEach(validateOutput);
|
|
1257
|
-
return true;
|
|
1258
1438
|
}
|
|
1259
1439
|
function craftToSpendTx(message, pkScript, tag = TAG_INTENT_PROOF) {
|
|
1260
1440
|
const messageHash = hashMessage(message, tag);
|
|
@@ -1282,8 +1462,9 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
|
|
|
1282
1462
|
version: 2,
|
|
1283
1463
|
lockTime: 0
|
|
1284
1464
|
});
|
|
1465
|
+
const { unknown: _, ...toSpendInput } = firstInput;
|
|
1285
1466
|
tx.addInput({
|
|
1286
|
-
...
|
|
1467
|
+
...toSpendInput,
|
|
1287
1468
|
txid: toSpend.id,
|
|
1288
1469
|
index: 0,
|
|
1289
1470
|
witnessUtxo: {
|
|
@@ -1317,14 +1498,7 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
|
|
|
1317
1498
|
script: output.script
|
|
1318
1499
|
});
|
|
1319
1500
|
}
|
|
1320
|
-
|
|
1321
|
-
global.unknown = [
|
|
1322
|
-
...global.unknown ?? [],
|
|
1323
|
-
[
|
|
1324
|
-
{ type: PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE, key: new Uint8Array() },
|
|
1325
|
-
new TextEncoder().encode(message)
|
|
1326
|
-
]
|
|
1327
|
-
];
|
|
1501
|
+
tx.global.genericSignedMessage = new TextEncoder().encode(message);
|
|
1328
1502
|
return tx;
|
|
1329
1503
|
}
|
|
1330
1504
|
function hashMessage(message, tag = TAG_INTENT_PROOF) {
|
|
@@ -1461,7 +1635,7 @@ var DEFAULT_MAX_CONCURRENT = 6;
|
|
|
1461
1635
|
var DEFAULT_COOLDOWN_MS = 5e3;
|
|
1462
1636
|
var MAX_COOLDOWN_MS = 6e4;
|
|
1463
1637
|
var DEFAULT_JITTER_MS = 500;
|
|
1464
|
-
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1638
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.min(ms, MAX_TIMER_MS)));
|
|
1465
1639
|
function parseRetryAfterMs(header) {
|
|
1466
1640
|
if (header === null || header === void 0) return void 0;
|
|
1467
1641
|
const trimmed = header.trim();
|
|
@@ -1494,6 +1668,9 @@ var OriginRateGate = class {
|
|
|
1494
1668
|
maxCooldownMs;
|
|
1495
1669
|
jitterMs;
|
|
1496
1670
|
constructor(options) {
|
|
1671
|
+
assertNonNegativeMs("defaultCooldownMs", options?.defaultCooldownMs);
|
|
1672
|
+
assertNonNegativeMs("maxCooldownMs", options?.maxCooldownMs);
|
|
1673
|
+
assertNonNegativeMs("jitterMs", options?.jitterMs);
|
|
1497
1674
|
this.maxConcurrent = options?.maxConcurrent ?? DEFAULT_MAX_CONCURRENT;
|
|
1498
1675
|
this.defaultCooldownMs = options?.defaultCooldownMs ?? DEFAULT_COOLDOWN_MS;
|
|
1499
1676
|
this.maxCooldownMs = options?.maxCooldownMs ?? MAX_COOLDOWN_MS;
|
|
@@ -1699,6 +1876,20 @@ var RestArkProvider = class {
|
|
|
1699
1876
|
"Arkade server reported a configuration digest mismatch; server info was refreshed. Rebuild and retry the request under the new server info."
|
|
1700
1877
|
);
|
|
1701
1878
|
}
|
|
1879
|
+
async postJson(url, body, failureMessage) {
|
|
1880
|
+
const response = await this.authedFetch(url, {
|
|
1881
|
+
method: "POST",
|
|
1882
|
+
headers: {
|
|
1883
|
+
"Content-Type": "application/json"
|
|
1884
|
+
},
|
|
1885
|
+
body: JSON.stringify(body)
|
|
1886
|
+
});
|
|
1887
|
+
if (!response.ok) {
|
|
1888
|
+
const errorText = await response.text();
|
|
1889
|
+
handleError(errorText, failureMessage(errorText, response));
|
|
1890
|
+
}
|
|
1891
|
+
return response;
|
|
1892
|
+
}
|
|
1702
1893
|
async getInfo() {
|
|
1703
1894
|
const url = `${this.serverUrl}/v1/info`;
|
|
1704
1895
|
const response = await rateGate.runHttp(
|
|
@@ -1764,20 +1955,14 @@ var RestArkProvider = class {
|
|
|
1764
1955
|
}
|
|
1765
1956
|
async submitTx(signedArkTx, checkpointTxs) {
|
|
1766
1957
|
const url = `${this.serverUrl}/v1/tx/submit`;
|
|
1767
|
-
const response = await this.
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
"Content-Type": "application/json"
|
|
1771
|
-
},
|
|
1772
|
-
body: JSON.stringify({
|
|
1958
|
+
const response = await this.postJson(
|
|
1959
|
+
url,
|
|
1960
|
+
{
|
|
1773
1961
|
signedArkTx,
|
|
1774
1962
|
checkpointTxs
|
|
1775
|
-
}
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
const errorText = await response.text();
|
|
1779
|
-
handleError(errorText, `Failed to submit virtual transaction: ${errorText}`);
|
|
1780
|
-
}
|
|
1963
|
+
},
|
|
1964
|
+
(errorText) => `Failed to submit virtual transaction: ${errorText}`
|
|
1965
|
+
);
|
|
1781
1966
|
const data = await response.json();
|
|
1782
1967
|
return {
|
|
1783
1968
|
arkTxid: data.arkTxid,
|
|
@@ -1787,129 +1972,87 @@ var RestArkProvider = class {
|
|
|
1787
1972
|
}
|
|
1788
1973
|
async finalizeTx(arkTxid, finalCheckpointTxs) {
|
|
1789
1974
|
const url = `${this.serverUrl}/v1/tx/finalize`;
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
"Content-Type": "application/json"
|
|
1794
|
-
},
|
|
1795
|
-
body: JSON.stringify({
|
|
1975
|
+
await this.postJson(
|
|
1976
|
+
url,
|
|
1977
|
+
{
|
|
1796
1978
|
arkTxid,
|
|
1797
1979
|
finalCheckpointTxs
|
|
1798
|
-
}
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
const errorText = await response.text();
|
|
1802
|
-
handleError(errorText, `Failed to finalize offchain transaction: ${errorText}`);
|
|
1803
|
-
}
|
|
1980
|
+
},
|
|
1981
|
+
(errorText) => `Failed to finalize offchain transaction: ${errorText}`
|
|
1982
|
+
);
|
|
1804
1983
|
}
|
|
1805
1984
|
async registerIntent(intent) {
|
|
1806
1985
|
const url = `${this.serverUrl}/v1/batch/registerIntent`;
|
|
1807
|
-
const response = await this.
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
"Content-Type": "application/json"
|
|
1811
|
-
},
|
|
1812
|
-
body: JSON.stringify({
|
|
1986
|
+
const response = await this.postJson(
|
|
1987
|
+
url,
|
|
1988
|
+
{
|
|
1813
1989
|
intent: {
|
|
1814
1990
|
proof: intent.proof,
|
|
1815
1991
|
message: Intent.encodeMessage(intent.message)
|
|
1816
1992
|
}
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
const errorText = await response.text();
|
|
1821
|
-
handleError(errorText, `Failed to register intent: ${errorText}`);
|
|
1822
|
-
}
|
|
1993
|
+
},
|
|
1994
|
+
(errorText) => `Failed to register intent: ${errorText}`
|
|
1995
|
+
);
|
|
1823
1996
|
const data = await response.json();
|
|
1824
1997
|
return data.intentId;
|
|
1825
1998
|
}
|
|
1826
1999
|
async deleteIntent(intent) {
|
|
1827
2000
|
const url = `${this.serverUrl}/v1/batch/deleteIntent`;
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
"Content-Type": "application/json"
|
|
1832
|
-
},
|
|
1833
|
-
body: JSON.stringify({
|
|
2001
|
+
await this.postJson(
|
|
2002
|
+
url,
|
|
2003
|
+
{
|
|
1834
2004
|
intent: {
|
|
1835
2005
|
proof: intent.proof,
|
|
1836
2006
|
message: Intent.encodeMessage(intent.message)
|
|
1837
2007
|
}
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
const errorText = await response.text();
|
|
1842
|
-
handleError(errorText, `Failed to delete intent: ${errorText}`);
|
|
1843
|
-
}
|
|
2008
|
+
},
|
|
2009
|
+
(errorText) => `Failed to delete intent: ${errorText}`
|
|
2010
|
+
);
|
|
1844
2011
|
}
|
|
1845
2012
|
async confirmRegistration(intentId) {
|
|
1846
2013
|
const url = `${this.serverUrl}/v1/batch/ack`;
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
"Content-Type": "application/json"
|
|
1851
|
-
},
|
|
1852
|
-
body: JSON.stringify({
|
|
2014
|
+
await this.postJson(
|
|
2015
|
+
url,
|
|
2016
|
+
{
|
|
1853
2017
|
intentId
|
|
1854
|
-
}
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
const errorText = await response.text();
|
|
1858
|
-
handleError(errorText, `Failed to confirm registration: ${errorText}`);
|
|
1859
|
-
}
|
|
2018
|
+
},
|
|
2019
|
+
(errorText) => `Failed to confirm registration: ${errorText}`
|
|
2020
|
+
);
|
|
1860
2021
|
}
|
|
1861
2022
|
async submitTreeNonces(batchId, pubkey, nonces) {
|
|
1862
2023
|
const url = `${this.serverUrl}/v1/batch/tree/submitNonces`;
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
"Content-Type": "application/json"
|
|
1867
|
-
},
|
|
1868
|
-
body: JSON.stringify({
|
|
2024
|
+
await this.postJson(
|
|
2025
|
+
url,
|
|
2026
|
+
{
|
|
1869
2027
|
batchId,
|
|
1870
2028
|
pubkey,
|
|
1871
2029
|
treeNonces: encodeMusig2Nonces(nonces)
|
|
1872
|
-
}
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
const errorText = await response.text();
|
|
1876
|
-
handleError(errorText, `Failed to submit tree nonces: ${errorText}`);
|
|
1877
|
-
}
|
|
2030
|
+
},
|
|
2031
|
+
(errorText) => `Failed to submit tree nonces: ${errorText}`
|
|
2032
|
+
);
|
|
1878
2033
|
}
|
|
1879
2034
|
async submitTreeSignatures(batchId, pubkey, signatures) {
|
|
1880
2035
|
const url = `${this.serverUrl}/v1/batch/tree/submitSignatures`;
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
"Content-Type": "application/json"
|
|
1885
|
-
},
|
|
1886
|
-
body: JSON.stringify({
|
|
2036
|
+
await this.postJson(
|
|
2037
|
+
url,
|
|
2038
|
+
{
|
|
1887
2039
|
batchId,
|
|
1888
2040
|
pubkey,
|
|
1889
2041
|
treeSignatures: encodeMusig2Signatures(signatures)
|
|
1890
|
-
}
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
const errorText = await response.text();
|
|
1894
|
-
handleError(errorText, `Failed to submit tree signatures: ${errorText}`);
|
|
1895
|
-
}
|
|
2042
|
+
},
|
|
2043
|
+
(errorText) => `Failed to submit tree signatures: ${errorText}`
|
|
2044
|
+
);
|
|
1896
2045
|
}
|
|
1897
2046
|
async submitSignedForfeitTxs(signedForfeitTxs, signedCommitmentTx) {
|
|
1898
2047
|
const url = `${this.serverUrl}/v1/batch/submitForfeitTxs`;
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
"Content-Type": "application/json"
|
|
1903
|
-
},
|
|
1904
|
-
body: JSON.stringify({
|
|
2048
|
+
await this.postJson(
|
|
2049
|
+
url,
|
|
2050
|
+
{
|
|
1905
2051
|
signedForfeitTxs,
|
|
1906
2052
|
signedCommitmentTx
|
|
1907
|
-
}
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
const errorText = await response.text();
|
|
1911
|
-
handleError(errorText, `Failed to submit forfeit transactions: ${response.statusText}`);
|
|
1912
|
-
}
|
|
2053
|
+
},
|
|
2054
|
+
(_, res) => `Failed to submit forfeit transactions: ${res.statusText}`
|
|
2055
|
+
);
|
|
1913
2056
|
}
|
|
1914
2057
|
getEventStream(signal, topics) {
|
|
1915
2058
|
const url = `${this.serverUrl}/v1/batch/events`;
|
|
@@ -2032,22 +2175,16 @@ var RestArkProvider = class {
|
|
|
2032
2175
|
}
|
|
2033
2176
|
async getPendingTxs(intent) {
|
|
2034
2177
|
const url = `${this.serverUrl}/v1/tx/pending`;
|
|
2035
|
-
const response = await this.
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
"Content-Type": "application/json"
|
|
2039
|
-
},
|
|
2040
|
-
body: JSON.stringify({
|
|
2178
|
+
const response = await this.postJson(
|
|
2179
|
+
url,
|
|
2180
|
+
{
|
|
2041
2181
|
intent: {
|
|
2042
2182
|
proof: intent.proof,
|
|
2043
2183
|
message: Intent.encodeMessage(intent.message)
|
|
2044
2184
|
}
|
|
2045
|
-
}
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
const errorText = await response.text();
|
|
2049
|
-
handleError(errorText, `Failed to get pending transactions: ${errorText}`);
|
|
2050
|
-
}
|
|
2185
|
+
},
|
|
2186
|
+
(errorText) => `Failed to get pending transactions: ${errorText}`
|
|
2187
|
+
);
|
|
2051
2188
|
const data = await response.json();
|
|
2052
2189
|
return data.pendingTxs;
|
|
2053
2190
|
}
|
|
@@ -2267,60 +2404,23 @@ function parseWireExpiry(raw) {
|
|
|
2267
2404
|
if (ms >= EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(ms) };
|
|
2268
2405
|
return { expiresAtHeight: n };
|
|
2269
2406
|
}
|
|
2270
|
-
function toBatchExpiry(c) {
|
|
2271
|
-
if (c.expiresAt !== void 0) return c.expiresAt.getTime();
|
|
2272
|
-
if (c.expiresAtHeight !== void 0) return c.expiresAtHeight * 1e3;
|
|
2273
|
-
return void 0;
|
|
2274
|
-
}
|
|
2275
|
-
function parseLegacyExpiry(batchExpiry) {
|
|
2276
|
-
if (batchExpiry === void 0 || batchExpiry <= 0) return {};
|
|
2277
|
-
if (batchExpiry >= EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(batchExpiry) };
|
|
2278
|
-
return { expiresAtHeight: batchExpiry / 1e3 };
|
|
2279
|
-
}
|
|
2280
|
-
function toVirtualStatus(c) {
|
|
2281
|
-
return {
|
|
2282
|
-
// Precedence is load-bearing: consumers bucket on this label, so any other order silently
|
|
2283
|
-
// moves VTXOs between buckets.
|
|
2284
|
-
state: c.isSpent ? "spent" : c.isSwept ? "swept" : c.isPreconfirmed ? "preconfirmed" : "settled",
|
|
2285
|
-
commitmentTxIds: c.commitmentTxIds,
|
|
2286
|
-
batchExpiry: toBatchExpiry(c)
|
|
2287
|
-
};
|
|
2288
|
-
}
|
|
2289
2407
|
function normalizeVtxo(v) {
|
|
2290
|
-
const
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
// as `Date` but returns NaN from `.getTime()` — comparing false against everything.
|
|
2295
|
-
{
|
|
2296
|
-
expiresAt: v.expiresAt === void 0 ? void 0 : new Date(v.expiresAt),
|
|
2297
|
-
expiresAtHeight: v.expiresAtHeight
|
|
2298
|
-
}
|
|
2299
|
-
) : parseLegacyExpiry(v.virtualStatus?.batchExpiry);
|
|
2300
|
-
const isSpent = v.isSpent ?? state === "spent";
|
|
2301
|
-
const isSwept = v.isSwept ?? state === "swept";
|
|
2302
|
-
const isPreconfirmed = v.isPreconfirmed ?? state === "preconfirmed";
|
|
2303
|
-
const commitmentTxIds = v.commitmentTxIds ?? v.virtualStatus?.commitmentTxIds ?? [];
|
|
2408
|
+
const expiry = {
|
|
2409
|
+
expiresAt: v.expiresAt === void 0 ? void 0 : new Date(v.expiresAt),
|
|
2410
|
+
expiresAtHeight: v.expiresAtHeight
|
|
2411
|
+
};
|
|
2304
2412
|
return {
|
|
2305
2413
|
...v,
|
|
2306
|
-
isSpent,
|
|
2307
|
-
isSwept,
|
|
2308
|
-
isPreconfirmed,
|
|
2414
|
+
isSpent: v.isSpent ?? false,
|
|
2415
|
+
isSwept: v.isSwept ?? false,
|
|
2416
|
+
isPreconfirmed: v.isPreconfirmed ?? false,
|
|
2309
2417
|
spentBy: v.spentBy ?? "",
|
|
2310
|
-
commitmentTxIds,
|
|
2311
|
-
...expiry
|
|
2312
|
-
virtualStatus: v.virtualStatus ?? toVirtualStatus({ isSpent, isSwept, isPreconfirmed, commitmentTxIds, ...expiry })
|
|
2418
|
+
commitmentTxIds: v.commitmentTxIds ?? [],
|
|
2419
|
+
...expiry
|
|
2313
2420
|
};
|
|
2314
2421
|
}
|
|
2315
2422
|
function convertVtxo(vtxo) {
|
|
2316
2423
|
const expiry = parseWireExpiry(vtxo.expiresAt);
|
|
2317
|
-
const facts = {
|
|
2318
|
-
isSpent: vtxo.isSpent,
|
|
2319
|
-
isSwept: vtxo.isSwept,
|
|
2320
|
-
isPreconfirmed: vtxo.isPreconfirmed,
|
|
2321
|
-
commitmentTxIds: vtxo.commitmentTxids,
|
|
2322
|
-
...expiry
|
|
2323
|
-
};
|
|
2324
2424
|
return {
|
|
2325
2425
|
txid: vtxo.outpoint.txid,
|
|
2326
2426
|
vout: vtxo.outpoint.vout,
|
|
@@ -2329,8 +2429,11 @@ function convertVtxo(vtxo) {
|
|
|
2329
2429
|
confirmed: !vtxo.isSwept && !vtxo.isPreconfirmed,
|
|
2330
2430
|
isLeaf: !vtxo.isPreconfirmed
|
|
2331
2431
|
},
|
|
2332
|
-
|
|
2333
|
-
|
|
2432
|
+
isSpent: vtxo.isSpent,
|
|
2433
|
+
isSwept: vtxo.isSwept,
|
|
2434
|
+
isPreconfirmed: vtxo.isPreconfirmed,
|
|
2435
|
+
commitmentTxIds: vtxo.commitmentTxids,
|
|
2436
|
+
...expiry,
|
|
2334
2437
|
spentBy: vtxo.spentBy ?? "",
|
|
2335
2438
|
settledBy: vtxo.settledBy,
|
|
2336
2439
|
arkTxId: vtxo.arkTxid,
|
|
@@ -2347,11 +2450,16 @@ async function getNormalizedVtxos(provider, opts) {
|
|
|
2347
2450
|
const { vtxos, page } = await provider.getVtxos(opts);
|
|
2348
2451
|
return { vtxos: vtxos.map(normalizeVtxo), page };
|
|
2349
2452
|
}
|
|
2453
|
+
var SCRIPT_CHUNK_CONCURRENCY = 4;
|
|
2350
2454
|
async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
|
|
2351
2455
|
const { pageSize = DEFAULT_PAGE_SIZE, ...filters } = opts;
|
|
2352
2456
|
const all = [];
|
|
2457
|
+
const chunks = [];
|
|
2353
2458
|
for (let i = 0; i < scripts.length; i += SCRIPT_QUERY_CHUNK_SIZE) {
|
|
2354
|
-
|
|
2459
|
+
chunks.push(scripts.slice(i, i + SCRIPT_QUERY_CHUNK_SIZE));
|
|
2460
|
+
}
|
|
2461
|
+
const fetchChunk = async (chunk) => {
|
|
2462
|
+
const result = [];
|
|
2355
2463
|
let pageIndex = 0;
|
|
2356
2464
|
let hasMore = true;
|
|
2357
2465
|
while (hasMore) {
|
|
@@ -2361,11 +2469,18 @@ async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
|
|
|
2361
2469
|
pageIndex,
|
|
2362
2470
|
pageSize
|
|
2363
2471
|
});
|
|
2364
|
-
|
|
2472
|
+
result.push(...vtxos);
|
|
2365
2473
|
hasMore = page ? vtxos.length === pageSize : false;
|
|
2366
2474
|
pageIndex++;
|
|
2367
2475
|
if (hasMore) await new Promise((r) => setTimeout(r, 500));
|
|
2368
2476
|
}
|
|
2477
|
+
return result;
|
|
2478
|
+
};
|
|
2479
|
+
for (let i = 0; i < chunks.length; i += SCRIPT_CHUNK_CONCURRENCY) {
|
|
2480
|
+
const batch = await Promise.all(
|
|
2481
|
+
chunks.slice(i, i + SCRIPT_CHUNK_CONCURRENCY).map(fetchChunk)
|
|
2482
|
+
);
|
|
2483
|
+
for (const result of batch) all.push(...result);
|
|
2369
2484
|
}
|
|
2370
2485
|
return all;
|
|
2371
2486
|
}
|
|
@@ -2388,7 +2503,7 @@ async function fetchVtxoCreatedAtByTxid(provider, txids) {
|
|
|
2388
2503
|
}
|
|
2389
2504
|
return createdAt;
|
|
2390
2505
|
}
|
|
2391
|
-
function
|
|
2506
|
+
function isVtxoSpent(vtxo) {
|
|
2392
2507
|
const n = normalizeVtxo(vtxo);
|
|
2393
2508
|
return !!n.isSpent || !!n.spentBy || !!n.settledBy;
|
|
2394
2509
|
}
|
|
@@ -2399,41 +2514,33 @@ function isPastExpiry(vtxo, now) {
|
|
|
2399
2514
|
}
|
|
2400
2515
|
function canSpendOffchain(vtxo, now) {
|
|
2401
2516
|
const n = normalizeVtxo(vtxo);
|
|
2402
|
-
return !
|
|
2517
|
+
return !isVtxoSpent(n) && !n.isUnrolled && !(n.isSwept || isPastExpiry(n, now));
|
|
2403
2518
|
}
|
|
2404
2519
|
function canRecoverOnchain(vtxo, now) {
|
|
2405
2520
|
const n = normalizeVtxo(vtxo);
|
|
2406
|
-
return !
|
|
2521
|
+
return !isVtxoSpent(n) && !n.isUnrolled && (n.isSwept || isPastExpiry(n, now));
|
|
2407
2522
|
}
|
|
2408
2523
|
function canSweepOnchain(vtxo) {
|
|
2409
2524
|
const n = normalizeVtxo(vtxo);
|
|
2410
|
-
return !
|
|
2525
|
+
return !isVtxoSpent(n) && !!n.isUnrolled;
|
|
2526
|
+
}
|
|
2527
|
+
function requiresForfeit(vtxo) {
|
|
2528
|
+
const n = normalizeVtxo(vtxo);
|
|
2529
|
+
return !n.isSwept && !n.isUnrolled;
|
|
2411
2530
|
}
|
|
2412
2531
|
function toOffchainInputFeeParams(vtxo) {
|
|
2413
|
-
const batchExpiry = toBatchExpiry(vtxo);
|
|
2414
2532
|
return {
|
|
2415
2533
|
amount: BigInt(vtxo.value),
|
|
2416
2534
|
type: vtxo.isSwept ? "recoverable" : "vtxo",
|
|
2417
2535
|
weight: 0,
|
|
2418
2536
|
birth: vtxo.createdAt,
|
|
2419
|
-
expiry:
|
|
2537
|
+
expiry: vtxo.expiresAt
|
|
2420
2538
|
};
|
|
2421
2539
|
}
|
|
2422
2540
|
function isVirtualCoin(input) {
|
|
2423
2541
|
return typeof input === "object" && input !== null && typeof input.script === "string";
|
|
2424
2542
|
}
|
|
2425
|
-
function isSpendable(vtxo) {
|
|
2426
|
-
return !hasTerminalSpend(vtxo);
|
|
2427
|
-
}
|
|
2428
|
-
function isRecoverable(vtxo) {
|
|
2429
|
-
const n = normalizeVtxo(vtxo);
|
|
2430
|
-
return n.isSwept && !hasTerminalSpend(n);
|
|
2431
|
-
}
|
|
2432
|
-
function isExpired(vtxo) {
|
|
2433
|
-
const n = normalizeVtxo(vtxo);
|
|
2434
|
-
return n.isSwept || n.expiresAt !== void 0 && n.expiresAt.getTime() <= Date.now();
|
|
2435
|
-
}
|
|
2436
2543
|
|
|
2437
|
-
export { ArkAddress, ArkError, ArkErrorName, ArkPsbtFieldKey, ArkPsbtFieldKeyType, BITCOIN_EMULATOR_PUBKEY, CLTVMultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, ConditionWitness, CosignerPublicKey, DEFAULT_ARKADE_SERVER_URL, DEFAULT_NETWORK, DEFAULT_NETWORK_NAME, DEFAULT_PAGE_SIZE, DigestMismatchError, EventSourceUnavailableError, FetchError, INFO_FETCH_TIMEOUT_MS, Intent, MUTINYNET_EMULATOR_PUBKEY, MultisigTapscript, OP_RETURN_EMPTY_PKSCRIPT, PrevArkTxField, PrevoutTxField, ProviderUnavailableError, REGTEST_EMULATOR_PUBKEY, RestArkProvider, SCRIPT_QUERY_CHUNK_SIZE, ServerResponseMismatchError, SettlementEventType, TapTreeCoder, Transaction, VtxoScript, VtxoTaprootTree, VtxoTreeExpiry, assembleBtcdTaprootTree, assertAllowedSighashTypes, baseFetch, buildVersion, canRecoverOnchain, canSpendOffchain, canSweepOnchain, configureEventSource, convertVtxo, craftToSpendTx, decodeTapscript, defaultEmulatorPubkey, eventSourceIterator,
|
|
2438
|
-
//# sourceMappingURL=chunk-
|
|
2439
|
-
//# sourceMappingURL=chunk-
|
|
2544
|
+
export { ARKADE_VERSION_HEADERS, ArkAddress, ArkError, ArkErrorName, ArkPsbtFieldKey, ArkPsbtFieldKeyType, BITCOIN_EMULATOR_PUBKEY, CLTVMultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, ConditionWitness, CosignerPublicKey, DEFAULT_ARKADE_SERVER_URL, DEFAULT_NETWORK, DEFAULT_NETWORK_NAME, DEFAULT_PAGE_SIZE, DigestMismatchError, EXPIRY_MIN_PLAUSIBLE_MS, EventSourceUnavailableError, FetchError, INFO_FETCH_TIMEOUT_MS, Intent, MUTINYNET_EMULATOR_PUBKEY, MultisigTapscript, OP_RETURN_EMPTY_PKSCRIPT, PrevArkTxField, PrevoutTxField, ProviderUnavailableError, READ_TIMEOUT_MS, REGTEST_EMULATOR_PUBKEY, RestArkProvider, SCRIPT_QUERY_CHUNK_SIZE, ServerResponseMismatchError, SettlementEventType, TapTreeCoder, Transaction, VtxoScript, VtxoTaprootTree, VtxoTreeExpiry, __export, assembleBtcdTaprootTree, assertAllowedSighashTypes, assertNonNegativeMs, assertTimerMs, baseFetch, buildVersion, canRecoverOnchain, canSpendOffchain, canSweepOnchain, configureEventSource, convertVtxo, craftToSpendTx, decodeTapscript, defaultEmulatorPubkey, eventSourceIterator, fetchVtxoCreatedAtByTxid, formatSighash, getAllNormalizedVtxos, getArkPsbtFields, getConfiguredEventSource, getNetwork, getNormalizedVtxos, getSequence, isArkError, isEventSourceError, isEventSourceUnavailableError, isFetchTimeoutError, isPastExpiry, isRetryableProviderError, isVirtualCoin, isVtxoSpent, maybeArkError, networkFromArkadeInfo, networks, normalizeVtxo, rateGate, requiresForfeit, resolveEmulatorPubkey, resolveEventSource, resolveTimeHeight, scriptFromTapLeafScript, sdkVersion, sequenceToCanonicalTimelock, sequenceToTimelock, setArkPsbtField, throwIfHttpUnavailable, timelockToSequence, toBIP371TapTree, toOffchainInputFeeParams, toProviderUnavailable };
|
|
2545
|
+
//# sourceMappingURL=chunk-NR4XYTN3.js.map
|
|
2546
|
+
//# sourceMappingURL=chunk-NR4XYTN3.js.map
|