@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,11 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var btcSigner = require('@scure/btc-signer');
|
|
4
|
-
var bip68 = require('bip68');
|
|
5
3
|
var utils_js = require('@scure/btc-signer/utils.js');
|
|
6
4
|
var base = require('@scure/base');
|
|
7
5
|
var script_js = require('@scure/btc-signer/script.js');
|
|
6
|
+
var bip68 = require('bip68');
|
|
7
|
+
var btcSigner = require('@scure/btc-signer');
|
|
8
8
|
var payment_js = require('@scure/btc-signer/payment.js');
|
|
9
|
+
var P = require('micro-packed');
|
|
9
10
|
var psbt_js = require('@scure/btc-signer/psbt.js');
|
|
10
11
|
var secp256k1_js = require('@noble/curves/secp256k1.js');
|
|
11
12
|
|
|
@@ -28,187 +29,13 @@ function _interopNamespace(e) {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
var bip68__namespace = /*#__PURE__*/_interopNamespace(bip68);
|
|
32
|
+
var P__namespace = /*#__PURE__*/_interopNamespace(P);
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
var
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
allowUnknownOutputs: true,
|
|
37
|
-
allowUnknownInputs: true
|
|
38
|
-
};
|
|
39
|
-
constructor(opts) {
|
|
40
|
-
super(withArkOpts(opts));
|
|
41
|
-
}
|
|
42
|
-
static fromPSBT(psbt_, opts) {
|
|
43
|
-
return btcSigner.Transaction.fromPSBT(psbt_, withArkOpts(opts));
|
|
44
|
-
}
|
|
45
|
-
static fromRaw(raw, opts) {
|
|
46
|
-
return btcSigner.Transaction.fromRaw(raw, withArkOpts(opts));
|
|
47
|
-
}
|
|
34
|
+
var __defProp = Object.defineProperty;
|
|
35
|
+
var __export = (target, all) => {
|
|
36
|
+
for (var name in all)
|
|
37
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
48
38
|
};
|
|
49
|
-
function withArkOpts(opts) {
|
|
50
|
-
return { ...Transaction.ARK_TX_OPTS, ...opts };
|
|
51
|
-
}
|
|
52
|
-
function formatSighash(type) {
|
|
53
|
-
return `0x${type.toString(16).padStart(2, "0")}`;
|
|
54
|
-
}
|
|
55
|
-
function assertAllowedSighashTypes(tx, allowedSighashTypes = [btcSigner.SigHash.DEFAULT]) {
|
|
56
|
-
for (let i = 0; i < tx.inputsLength; i++) {
|
|
57
|
-
const declared = tx.getInput(i).sighashType;
|
|
58
|
-
if (declared === void 0) continue;
|
|
59
|
-
if (!allowedSighashTypes.includes(declared)) {
|
|
60
|
-
throw new Error(`Unallowed sighash type ${formatSighash(declared)} for input ${i}.`);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
function timelockToSequence(timelock) {
|
|
65
|
-
return bip68__namespace.encode(
|
|
66
|
-
timelock.type === "blocks" ? { blocks: Number(timelock.value) } : { seconds: Number(timelock.value) }
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
function sequenceToTimelock(sequence) {
|
|
70
|
-
const decoded = bip68__namespace.decode(sequence);
|
|
71
|
-
if ("blocks" in decoded && decoded.blocks !== void 0) {
|
|
72
|
-
return { type: "blocks", value: BigInt(decoded.blocks) };
|
|
73
|
-
}
|
|
74
|
-
if ("seconds" in decoded && decoded.seconds !== void 0) {
|
|
75
|
-
return { type: "seconds", value: BigInt(decoded.seconds) };
|
|
76
|
-
}
|
|
77
|
-
throw new Error(`Invalid BIP68 sequence: ${sequence}`);
|
|
78
|
-
}
|
|
79
|
-
var ArkPsbtFieldKey = /* @__PURE__ */ ((ArkPsbtFieldKey2) => {
|
|
80
|
-
ArkPsbtFieldKey2["VtxoTaprootTree"] = "taptree";
|
|
81
|
-
ArkPsbtFieldKey2["VtxoTreeExpiry"] = "expiry";
|
|
82
|
-
ArkPsbtFieldKey2["Cosigner"] = "cosigner";
|
|
83
|
-
ArkPsbtFieldKey2["ConditionWitness"] = "condition";
|
|
84
|
-
ArkPsbtFieldKey2["PrevArkTx"] = "prevarktx";
|
|
85
|
-
ArkPsbtFieldKey2["PrevoutTx"] = "prevouttx";
|
|
86
|
-
return ArkPsbtFieldKey2;
|
|
87
|
-
})(ArkPsbtFieldKey || {});
|
|
88
|
-
var ArkPsbtFieldKeyType = 222;
|
|
89
|
-
function setArkPsbtField(tx, inputIndex, coder, value) {
|
|
90
|
-
tx.updateInput(inputIndex, {
|
|
91
|
-
unknown: [...tx.getInput(inputIndex)?.unknown ?? [], coder.encode(value)]
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
function getArkPsbtFields(tx, inputIndex, coder) {
|
|
95
|
-
const unknown = tx.getInput(inputIndex)?.unknown ?? [];
|
|
96
|
-
const fields = [];
|
|
97
|
-
for (const u of unknown) {
|
|
98
|
-
const v = coder.decode(u);
|
|
99
|
-
if (v !== null) fields.push(v);
|
|
100
|
-
}
|
|
101
|
-
return fields;
|
|
102
|
-
}
|
|
103
|
-
var VtxoTaprootTree = {
|
|
104
|
-
key: "taptree" /* VtxoTaprootTree */,
|
|
105
|
-
encode: (value) => [
|
|
106
|
-
{
|
|
107
|
-
type: ArkPsbtFieldKeyType,
|
|
108
|
-
key: encodedPsbtFieldKey["taptree" /* VtxoTaprootTree */]
|
|
109
|
-
},
|
|
110
|
-
value
|
|
111
|
-
],
|
|
112
|
-
decode: (value) => nullIfCatch(() => {
|
|
113
|
-
if (!checkKeyMatch(value[0], "taptree" /* VtxoTaprootTree */)) return null;
|
|
114
|
-
return value[1];
|
|
115
|
-
})
|
|
116
|
-
};
|
|
117
|
-
var ConditionWitness = {
|
|
118
|
-
key: "condition" /* ConditionWitness */,
|
|
119
|
-
encode: (value) => [
|
|
120
|
-
{
|
|
121
|
-
type: ArkPsbtFieldKeyType,
|
|
122
|
-
key: encodedPsbtFieldKey["condition" /* ConditionWitness */]
|
|
123
|
-
},
|
|
124
|
-
btcSigner.RawWitness.encode(value)
|
|
125
|
-
],
|
|
126
|
-
decode: (value) => nullIfCatch(() => {
|
|
127
|
-
if (!checkKeyMatch(value[0], "condition" /* ConditionWitness */)) return null;
|
|
128
|
-
return btcSigner.RawWitness.decode(value[1]);
|
|
129
|
-
})
|
|
130
|
-
};
|
|
131
|
-
var PrevArkTxField = {
|
|
132
|
-
key: "prevarktx" /* PrevArkTx */,
|
|
133
|
-
encode: (value) => [
|
|
134
|
-
{
|
|
135
|
-
type: ArkPsbtFieldKeyType,
|
|
136
|
-
key: encodedPsbtFieldKey["prevarktx" /* PrevArkTx */]
|
|
137
|
-
},
|
|
138
|
-
value
|
|
139
|
-
],
|
|
140
|
-
decode: (value) => nullIfCatch(() => {
|
|
141
|
-
if (!checkKeyMatch(value[0], "prevarktx" /* PrevArkTx */)) return null;
|
|
142
|
-
return value[1];
|
|
143
|
-
})
|
|
144
|
-
};
|
|
145
|
-
var PrevoutTxField = {
|
|
146
|
-
key: "prevouttx" /* PrevoutTx */,
|
|
147
|
-
encode: (value) => [
|
|
148
|
-
{
|
|
149
|
-
type: ArkPsbtFieldKeyType,
|
|
150
|
-
key: encodedPsbtFieldKey["prevouttx" /* PrevoutTx */]
|
|
151
|
-
},
|
|
152
|
-
value
|
|
153
|
-
],
|
|
154
|
-
decode: (value) => nullIfCatch(() => {
|
|
155
|
-
if (!checkKeyMatch(value[0], "prevouttx" /* PrevoutTx */)) return null;
|
|
156
|
-
return value[1];
|
|
157
|
-
})
|
|
158
|
-
};
|
|
159
|
-
var CosignerPublicKey = {
|
|
160
|
-
key: "cosigner" /* Cosigner */,
|
|
161
|
-
encode: (value) => [
|
|
162
|
-
{
|
|
163
|
-
type: ArkPsbtFieldKeyType,
|
|
164
|
-
key: new Uint8Array([...encodedPsbtFieldKey["cosigner" /* Cosigner */], value.index])
|
|
165
|
-
},
|
|
166
|
-
value.key
|
|
167
|
-
],
|
|
168
|
-
decode: (unknown) => nullIfCatch(() => {
|
|
169
|
-
if (!checkKeyMatch(unknown[0], "cosigner" /* Cosigner */, true)) return null;
|
|
170
|
-
return {
|
|
171
|
-
index: unknown[0].key[unknown[0].key.length - 1],
|
|
172
|
-
key: unknown[1]
|
|
173
|
-
};
|
|
174
|
-
})
|
|
175
|
-
};
|
|
176
|
-
var VtxoTreeExpiry = {
|
|
177
|
-
key: "expiry" /* VtxoTreeExpiry */,
|
|
178
|
-
encode: (value) => [
|
|
179
|
-
{
|
|
180
|
-
type: ArkPsbtFieldKeyType,
|
|
181
|
-
key: encodedPsbtFieldKey["expiry" /* VtxoTreeExpiry */]
|
|
182
|
-
},
|
|
183
|
-
btcSigner.ScriptNum(6, true).encode(value.value === 0n ? 0n : value.value)
|
|
184
|
-
],
|
|
185
|
-
decode: (unknown) => nullIfCatch(() => {
|
|
186
|
-
if (!checkKeyMatch(unknown[0], "expiry" /* VtxoTreeExpiry */)) return null;
|
|
187
|
-
const v = btcSigner.ScriptNum(6, true).decode(unknown[1]);
|
|
188
|
-
if (!v) return null;
|
|
189
|
-
return sequenceToTimelock(Number(v));
|
|
190
|
-
})
|
|
191
|
-
};
|
|
192
|
-
var encodedPsbtFieldKey = Object.fromEntries(
|
|
193
|
-
Object.values(ArkPsbtFieldKey).map((key) => [key, new TextEncoder().encode(key)])
|
|
194
|
-
);
|
|
195
|
-
var nullIfCatch = (fn) => {
|
|
196
|
-
try {
|
|
197
|
-
return fn();
|
|
198
|
-
} catch {
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
function checkKeyMatch(key, arkPsbtFieldKey, prefixOnly = false) {
|
|
203
|
-
if (key.type !== ArkPsbtFieldKeyType) return false;
|
|
204
|
-
const expected = encodedPsbtFieldKey[arkPsbtFieldKey];
|
|
205
|
-
if (key.key.length < expected.length) return false;
|
|
206
|
-
if (!prefixOnly && key.key.length !== expected.length) return false;
|
|
207
|
-
for (let i = 0; i < expected.length; i++) {
|
|
208
|
-
if (key.key[i] !== expected[i]) return false;
|
|
209
|
-
}
|
|
210
|
-
return true;
|
|
211
|
-
}
|
|
212
39
|
var getNetwork = (network) => {
|
|
213
40
|
const found = networks[network];
|
|
214
41
|
if (!found) throw new Error(`Unsupported network: ${network}`);
|
|
@@ -345,6 +172,26 @@ var ArkAddress = class _ArkAddress {
|
|
|
345
172
|
return script_js.Script.encode(["RETURN", this.vtxoTaprootKey]);
|
|
346
173
|
}
|
|
347
174
|
};
|
|
175
|
+
function timelockToSequence(timelock) {
|
|
176
|
+
return bip68__namespace.encode(
|
|
177
|
+
timelock.type === "blocks" ? { blocks: Number(timelock.value) } : { seconds: Number(timelock.value) }
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
function sequenceToTimelock(sequence) {
|
|
181
|
+
const decoded = bip68__namespace.decode(sequence);
|
|
182
|
+
if ("blocks" in decoded && decoded.blocks !== void 0) {
|
|
183
|
+
return { type: "blocks", value: BigInt(decoded.blocks) };
|
|
184
|
+
}
|
|
185
|
+
if ("seconds" in decoded && decoded.seconds !== void 0) {
|
|
186
|
+
return { type: "seconds", value: BigInt(decoded.seconds) };
|
|
187
|
+
}
|
|
188
|
+
throw new Error(`Invalid BIP68 sequence: ${sequence}`);
|
|
189
|
+
}
|
|
190
|
+
function sequenceToCanonicalTimelock(sequence) {
|
|
191
|
+
if (sequence < 0n || sequence >= 0x80000000n) return void 0;
|
|
192
|
+
const timelock = sequenceToTimelock(Number(sequence));
|
|
193
|
+
return BigInt(timelockToSequence(timelock)) === sequence ? timelock : void 0;
|
|
194
|
+
}
|
|
348
195
|
var MinimalScriptNum = btcSigner.ScriptNum(void 0, true);
|
|
349
196
|
function decodeTapscript(script) {
|
|
350
197
|
const types = [
|
|
@@ -592,6 +439,16 @@ exports.CSVMultisigTapscript = void 0;
|
|
|
592
439
|
}
|
|
593
440
|
CSVMultisigTapscript2.isScriptValid = isScriptValid;
|
|
594
441
|
})(exports.CSVMultisigTapscript || (exports.CSVMultisigTapscript = {}));
|
|
442
|
+
function isConditionScriptValid(script) {
|
|
443
|
+
const asm = btcSigner.Script.decode(script);
|
|
444
|
+
if (asm.length < 1) {
|
|
445
|
+
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
446
|
+
}
|
|
447
|
+
if (asm.lastIndexOf("VERIFY") === -1) {
|
|
448
|
+
return new Error("Invalid script: missing VERIFY operation");
|
|
449
|
+
}
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
595
452
|
exports.ConditionCSVMultisigTapscript = void 0;
|
|
596
453
|
((ConditionCSVMultisigTapscript2) => {
|
|
597
454
|
function encode2(params) {
|
|
@@ -616,7 +473,7 @@ exports.ConditionCSVMultisigTapscript = void 0;
|
|
|
616
473
|
throw isValid;
|
|
617
474
|
}
|
|
618
475
|
const asm = btcSigner.Script.decode(script);
|
|
619
|
-
|
|
476
|
+
const verifyIndex = asm.lastIndexOf("VERIFY");
|
|
620
477
|
if (verifyIndex === -1) {
|
|
621
478
|
throw Error("Invalid script: missing VERIFY operation");
|
|
622
479
|
}
|
|
@@ -651,26 +508,8 @@ exports.ConditionCSVMultisigTapscript = void 0;
|
|
|
651
508
|
return tapscript.type === "condition-csv-multisig" /* ConditionCSVMultisig */;
|
|
652
509
|
}
|
|
653
510
|
ConditionCSVMultisigTapscript2.is = is;
|
|
654
|
-
function getVerifyIndex(asm) {
|
|
655
|
-
let verifyIndex = -1;
|
|
656
|
-
for (let i = asm.length - 1; i >= 0; i--) {
|
|
657
|
-
if (asm[i] === "VERIFY") {
|
|
658
|
-
verifyIndex = i;
|
|
659
|
-
return verifyIndex;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
return verifyIndex;
|
|
663
|
-
}
|
|
664
511
|
function isScriptValid(script) {
|
|
665
|
-
|
|
666
|
-
if (asm.length < 1) {
|
|
667
|
-
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
668
|
-
}
|
|
669
|
-
let verifyIndex = getVerifyIndex(asm);
|
|
670
|
-
if (verifyIndex === -1) {
|
|
671
|
-
return new Error("Invalid script: missing VERIFY operation");
|
|
672
|
-
}
|
|
673
|
-
return true;
|
|
512
|
+
return isConditionScriptValid(script);
|
|
674
513
|
}
|
|
675
514
|
ConditionCSVMultisigTapscript2.isScriptValid = isScriptValid;
|
|
676
515
|
})(exports.ConditionCSVMultisigTapscript || (exports.ConditionCSVMultisigTapscript = {}));
|
|
@@ -698,7 +537,7 @@ exports.ConditionMultisigTapscript = void 0;
|
|
|
698
537
|
throw isValid;
|
|
699
538
|
}
|
|
700
539
|
const asm = btcSigner.Script.decode(script);
|
|
701
|
-
|
|
540
|
+
const verifyIndex = asm.lastIndexOf("VERIFY");
|
|
702
541
|
if (verifyIndex === -1) {
|
|
703
542
|
throw Error("Invalid script: missing VERIFY operation");
|
|
704
543
|
}
|
|
@@ -733,26 +572,8 @@ exports.ConditionMultisigTapscript = void 0;
|
|
|
733
572
|
return tapscript.type === "condition-multisig" /* ConditionMultisig */;
|
|
734
573
|
}
|
|
735
574
|
ConditionMultisigTapscript2.is = is;
|
|
736
|
-
function getVerifyIndex(asm) {
|
|
737
|
-
let verifyIndex = -1;
|
|
738
|
-
for (let i = asm.length - 1; i >= 0; i--) {
|
|
739
|
-
if (asm[i] === "VERIFY") {
|
|
740
|
-
verifyIndex = i;
|
|
741
|
-
return verifyIndex;
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
return verifyIndex;
|
|
745
|
-
}
|
|
746
575
|
function isScriptValid(script) {
|
|
747
|
-
|
|
748
|
-
if (asm.length < 1) {
|
|
749
|
-
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
750
|
-
}
|
|
751
|
-
let verifyIndex = getVerifyIndex(asm);
|
|
752
|
-
if (verifyIndex === -1) {
|
|
753
|
-
return new Error("Invalid script: missing VERIFY operation");
|
|
754
|
-
}
|
|
755
|
-
return true;
|
|
576
|
+
return isConditionScriptValid(script);
|
|
756
577
|
}
|
|
757
578
|
ConditionMultisigTapscript2.isScriptValid = isScriptValid;
|
|
758
579
|
})(exports.ConditionMultisigTapscript || (exports.ConditionMultisigTapscript = {}));
|
|
@@ -877,7 +698,25 @@ function assembleBtcdTaprootTree(scripts) {
|
|
|
877
698
|
}
|
|
878
699
|
return branches[0];
|
|
879
700
|
}
|
|
880
|
-
|
|
701
|
+
function btcdLeafLayout(count) {
|
|
702
|
+
const placeholders = Array.from({ length: count }, () => new Uint8Array());
|
|
703
|
+
const indexOf = new Map(placeholders.map((script, index) => [script, index]));
|
|
704
|
+
const layout = [];
|
|
705
|
+
const walk = (node, depth) => {
|
|
706
|
+
if (Array.isArray(node)) {
|
|
707
|
+
walk(node[0], depth + 1);
|
|
708
|
+
walk(node[1], depth + 1);
|
|
709
|
+
} else {
|
|
710
|
+
layout.push({ index: indexOf.get(node.script), depth });
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
walk(assembleBtcdTaprootTree(placeholders), 0);
|
|
714
|
+
return layout;
|
|
715
|
+
}
|
|
716
|
+
var TapTreeCoder = P__namespace.array(
|
|
717
|
+
null,
|
|
718
|
+
P__namespace.struct({ depth: P__namespace.U8, version: P__namespace.U8, script: script_js.VarBytes })
|
|
719
|
+
);
|
|
881
720
|
function scriptFromTapLeafScript(leaf) {
|
|
882
721
|
return leaf[1].subarray(0, leaf[1].length - 1);
|
|
883
722
|
}
|
|
@@ -897,7 +736,7 @@ var VtxoScript = class _VtxoScript {
|
|
|
897
736
|
constructor(scripts) {
|
|
898
737
|
this.scripts = scripts;
|
|
899
738
|
const tapTree = assembleBtcdTaprootTree(scripts);
|
|
900
|
-
const payment = btcSigner.p2tr(btcSigner.
|
|
739
|
+
const payment = btcSigner.p2tr(btcSigner.taprootNumsKey(), tapTree, void 0, true);
|
|
901
740
|
if (!payment.tapLeafScript || payment.tapLeafScript.length !== scripts.length) {
|
|
902
741
|
throw new Error("invalid scripts");
|
|
903
742
|
}
|
|
@@ -912,15 +751,46 @@ var VtxoScript = class _VtxoScript {
|
|
|
912
751
|
/**
|
|
913
752
|
* Decode a virtual output script from an encoded TapTree.
|
|
914
753
|
*
|
|
754
|
+
* Leaves are normally read in construction order and their depths
|
|
755
|
+
* ignored: that covers the {@link encode} form (every depth 1) and the
|
|
756
|
+
* placeholder depths other writers use, such as arkd's. The exception is
|
|
757
|
+
* the BIP-371 form {@link toBIP371TapTree} writes, whose leaves are in the
|
|
758
|
+
* tree's DFS order: for some leaf counts (6, 7, 10, ...) that differs from
|
|
759
|
+
* construction order. A tree whose depths are exactly the shape
|
|
760
|
+
* `assembleBtcdTaprootTree` builds is that form, so its leaves are mapped
|
|
761
|
+
* back to construction order first. No construction-order writer produces
|
|
762
|
+
* that depth sequence when the two orders differ, so this never reorders
|
|
763
|
+
* a tree that decoded correctly before.
|
|
764
|
+
*
|
|
765
|
+
* Every leaf must carry the base tapscript version: the tree is rebuilt
|
|
766
|
+
* with {@link TAP_LEAF_VERSION} leaves, so any other version would
|
|
767
|
+
* silently derive a different taproot key.
|
|
768
|
+
*
|
|
915
769
|
* @param tapTree - Encoded TapTree bytes
|
|
916
770
|
* @returns Decoded virtual output script
|
|
917
771
|
* @throws Error if the TapTree cannot be decoded into a valid script set
|
|
772
|
+
* or a leaf carries a version other than {@link TAP_LEAF_VERSION}
|
|
918
773
|
* @see encode
|
|
919
774
|
*/
|
|
920
775
|
static decode(tapTree) {
|
|
921
776
|
const leaves = TapTreeCoder.decode(tapTree);
|
|
777
|
+
const foreign = leaves.find((leaf) => leaf.version !== payment_js.TAP_LEAF_VERSION);
|
|
778
|
+
if (foreign) {
|
|
779
|
+
throw new Error(`unsupported tap leaf version 0x${foreign.version.toString(16)}`);
|
|
780
|
+
}
|
|
922
781
|
const scripts = leaves.map((leaf) => leaf.script);
|
|
923
|
-
|
|
782
|
+
if (leaves.every((leaf) => leaf.depth === 1)) {
|
|
783
|
+
return new _VtxoScript(scripts);
|
|
784
|
+
}
|
|
785
|
+
const layout = btcdLeafLayout(leaves.length);
|
|
786
|
+
if (layout.some((slot, i) => slot.depth !== leaves[i].depth)) {
|
|
787
|
+
return new _VtxoScript(scripts);
|
|
788
|
+
}
|
|
789
|
+
const ordered = new Array(leaves.length);
|
|
790
|
+
layout.forEach((slot, i) => {
|
|
791
|
+
ordered[slot.index] = scripts[i];
|
|
792
|
+
});
|
|
793
|
+
return new _VtxoScript(ordered);
|
|
924
794
|
}
|
|
925
795
|
/**
|
|
926
796
|
* Encode the virtual output script to a TapTree byte representation.
|
|
@@ -1003,21 +873,323 @@ var VtxoScript = class _VtxoScript {
|
|
|
1003
873
|
return paths;
|
|
1004
874
|
}
|
|
1005
875
|
};
|
|
1006
|
-
function
|
|
1007
|
-
|
|
876
|
+
function toBIP371TapTree(tapTree) {
|
|
877
|
+
const scripts = TapTreeCoder.decode(tapTree).map((leaf) => leaf.script);
|
|
878
|
+
const vtxoScript = new VtxoScript(scripts);
|
|
879
|
+
return vtxoScript.leaves.map((leaf) => ({
|
|
880
|
+
depth: leaf[0].merklePath.length,
|
|
881
|
+
version: payment_js.TAP_LEAF_VERSION,
|
|
882
|
+
script: scriptFromTapLeafScript(leaf)
|
|
883
|
+
}));
|
|
884
|
+
}
|
|
885
|
+
function getSequence(tapLeafScript) {
|
|
886
|
+
let sequence = void 0;
|
|
887
|
+
try {
|
|
888
|
+
const scriptWithLeafVersion = tapLeafScript[1];
|
|
889
|
+
const script = scriptWithLeafVersion.subarray(0, scriptWithLeafVersion.length - 1);
|
|
890
|
+
try {
|
|
891
|
+
const params = exports.CSVMultisigTapscript.decode(script).params;
|
|
892
|
+
sequence = timelockToSequence(params.timelock);
|
|
893
|
+
} catch {
|
|
894
|
+
const params = exports.CLTVMultisigTapscript.decode(script).params;
|
|
895
|
+
sequence = Number(params.absoluteTimelock);
|
|
896
|
+
}
|
|
897
|
+
} catch {
|
|
898
|
+
}
|
|
899
|
+
return sequence;
|
|
900
|
+
}
|
|
901
|
+
var Transaction = class extends btcSigner.Transaction {
|
|
902
|
+
static ARK_TX_OPTS = {
|
|
903
|
+
unknown: "ignore",
|
|
904
|
+
allowUnknownOutputs: true,
|
|
905
|
+
allowUnknownInputs: true
|
|
906
|
+
};
|
|
907
|
+
constructor(opts) {
|
|
908
|
+
super(withArkOpts(opts));
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Decode a PSBT. PSBTs carrying a legacy `PSBT_OUT_TAP_TREE` (see
|
|
912
|
+
* {@link repairLegacyOutputTapTrees}) are repaired and decoded again
|
|
913
|
+
* instead of being rejected.
|
|
914
|
+
*/
|
|
915
|
+
static fromPSBT(psbt_, opts) {
|
|
916
|
+
try {
|
|
917
|
+
return btcSigner.Transaction.fromPSBT(psbt_, withArkOpts(opts));
|
|
918
|
+
} catch (err) {
|
|
919
|
+
const repaired = repairLegacyOutputTapTrees(psbt_);
|
|
920
|
+
if (!repaired) throw err;
|
|
921
|
+
return btcSigner.Transaction.fromPSBT(repaired, withArkOpts(opts));
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
static fromRaw(raw, opts) {
|
|
925
|
+
return btcSigner.Transaction.fromRaw(raw, withArkOpts(opts));
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
function withArkOpts(opts) {
|
|
929
|
+
return { ...Transaction.ARK_TX_OPTS, ...opts };
|
|
930
|
+
}
|
|
931
|
+
var PSBT_MAGIC = new Uint8Array([112, 115, 98, 116, 255]);
|
|
932
|
+
var PSBT_GLOBAL_UNSIGNED_TX = 0;
|
|
933
|
+
var PSBT_GLOBAL_INPUT_COUNT = 4;
|
|
934
|
+
var PSBT_OUT_TAP_TREE = 6;
|
|
935
|
+
function repairLegacyOutputTapTrees(psbt) {
|
|
936
|
+
let maps;
|
|
937
|
+
let inputsCount;
|
|
938
|
+
try {
|
|
939
|
+
maps = readPsbtMaps(psbt);
|
|
940
|
+
inputsCount = psbtInputsCount(maps[0]);
|
|
941
|
+
} catch {
|
|
942
|
+
return void 0;
|
|
943
|
+
}
|
|
944
|
+
let repaired = false;
|
|
945
|
+
for (const output of maps.slice(1 + inputsCount)) {
|
|
946
|
+
for (const kv of output) {
|
|
947
|
+
if (kv.key.length !== 1 || kv.key[0] !== PSBT_OUT_TAP_TREE) continue;
|
|
948
|
+
const value = legacyTapTreeToBIP371(kv.value);
|
|
949
|
+
if (!value) continue;
|
|
950
|
+
kv.value = value;
|
|
951
|
+
repaired = true;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
return repaired ? writePsbtMaps(maps) : void 0;
|
|
955
|
+
}
|
|
956
|
+
function legacyTapTreeToBIP371(value) {
|
|
957
|
+
try {
|
|
958
|
+
psbt_js.PSBTOutput.tapTree[2].decode(value);
|
|
959
|
+
return void 0;
|
|
960
|
+
} catch {
|
|
961
|
+
}
|
|
962
|
+
let leaves;
|
|
963
|
+
try {
|
|
964
|
+
leaves = TapTreeCoder.decode(value);
|
|
965
|
+
} catch {
|
|
966
|
+
return void 0;
|
|
967
|
+
}
|
|
968
|
+
if (leaves.length === 0 || leaves.some((leaf) => leaf.depth !== 1)) return void 0;
|
|
969
|
+
try {
|
|
970
|
+
return TapTreeCoder.encode(toBIP371TapTree(value));
|
|
971
|
+
} catch {
|
|
972
|
+
return void 0;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
function psbtInputsCount(global) {
|
|
976
|
+
for (const { key, value } of global) {
|
|
977
|
+
if (key.length !== 1) continue;
|
|
978
|
+
if (key[0] === PSBT_GLOBAL_UNSIGNED_TX) return btcSigner.RawTx.decode(value).inputs.length;
|
|
979
|
+
if (key[0] === PSBT_GLOBAL_INPUT_COUNT) return readCompactSize(value, 0)[0];
|
|
980
|
+
}
|
|
981
|
+
throw new Error("PSBT: missing input count");
|
|
982
|
+
}
|
|
983
|
+
function readPsbtMaps(psbt) {
|
|
984
|
+
for (let i = 0; i < PSBT_MAGIC.length; i++) {
|
|
985
|
+
if (psbt[i] !== PSBT_MAGIC[i]) throw new Error("PSBT: invalid magic");
|
|
986
|
+
}
|
|
987
|
+
const maps = [];
|
|
988
|
+
let pos = PSBT_MAGIC.length;
|
|
989
|
+
while (pos < psbt.length) {
|
|
990
|
+
const map = [];
|
|
991
|
+
for (; ; ) {
|
|
992
|
+
const [keyLen, afterKeyLen] = readCompactSize(psbt, pos);
|
|
993
|
+
pos = afterKeyLen;
|
|
994
|
+
if (keyLen === 0) break;
|
|
995
|
+
const key = readBytes(psbt, pos, keyLen);
|
|
996
|
+
pos += keyLen;
|
|
997
|
+
const [valueLen, afterValueLen] = readCompactSize(psbt, pos);
|
|
998
|
+
pos = afterValueLen;
|
|
999
|
+
const value = readBytes(psbt, pos, valueLen);
|
|
1000
|
+
pos += valueLen;
|
|
1001
|
+
map.push({ key, value });
|
|
1002
|
+
}
|
|
1003
|
+
maps.push(map);
|
|
1004
|
+
}
|
|
1005
|
+
if (maps.length === 0) throw new Error("PSBT: missing global map");
|
|
1006
|
+
return maps;
|
|
1007
|
+
}
|
|
1008
|
+
function writePsbtMaps(maps) {
|
|
1009
|
+
const parts = [PSBT_MAGIC];
|
|
1010
|
+
for (const map of maps) {
|
|
1011
|
+
for (const { key, value } of map) {
|
|
1012
|
+
parts.push(writeCompactSize(key.length), key, writeCompactSize(value.length), value);
|
|
1013
|
+
}
|
|
1014
|
+
parts.push(new Uint8Array([0]));
|
|
1015
|
+
}
|
|
1016
|
+
return utils_js.concatBytes(...parts);
|
|
1017
|
+
}
|
|
1018
|
+
function readBytes(data, pos, len) {
|
|
1019
|
+
if (pos + len > data.length) throw new Error("PSBT: unexpected end of data");
|
|
1020
|
+
return data.slice(pos, pos + len);
|
|
1021
|
+
}
|
|
1022
|
+
function readCompactSize(data, pos) {
|
|
1023
|
+
const first = readBytes(data, pos, 1)[0];
|
|
1024
|
+
if (first < 253) return [first, pos + 1];
|
|
1025
|
+
const width = first === 253 ? 2 : first === 254 ? 4 : 8;
|
|
1026
|
+
const bytes = readBytes(data, pos + 1, width);
|
|
1027
|
+
let value = 0;
|
|
1028
|
+
for (let i = width - 1; i >= 0; i--) value = value * 256 + bytes[i];
|
|
1029
|
+
if (!Number.isSafeInteger(value)) throw new Error("PSBT: compact size too large");
|
|
1030
|
+
return [value, pos + 1 + width];
|
|
1031
|
+
}
|
|
1032
|
+
function writeCompactSize(value) {
|
|
1033
|
+
if (value < 253) return new Uint8Array([value]);
|
|
1034
|
+
const width = value <= 65535 ? 2 : value <= 4294967295 ? 4 : 8;
|
|
1035
|
+
const out = new Uint8Array(1 + width);
|
|
1036
|
+
out[0] = width === 2 ? 253 : width === 4 ? 254 : 255;
|
|
1037
|
+
for (let i = 0, v = value; i < width; i++, v = Math.floor(v / 256)) out[1 + i] = v % 256;
|
|
1038
|
+
return out;
|
|
1039
|
+
}
|
|
1040
|
+
function formatSighash(type) {
|
|
1041
|
+
return `0x${type.toString(16).padStart(2, "0")}`;
|
|
1042
|
+
}
|
|
1043
|
+
function assertAllowedSighashTypes(tx, allowedSighashTypes = [btcSigner.SigHash.DEFAULT]) {
|
|
1044
|
+
for (let i = 0; i < tx.inputsLength; i++) {
|
|
1045
|
+
const declared = tx.getInput(i).sighashType;
|
|
1046
|
+
if (declared === void 0) continue;
|
|
1047
|
+
if (!allowedSighashTypes.includes(declared)) {
|
|
1048
|
+
throw new Error(`Unallowed sighash type ${formatSighash(declared)} for input ${i}.`);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// src/utils/time.ts
|
|
1054
|
+
function assertNonNegativeMs(name, ms) {
|
|
1055
|
+
if (ms !== void 0 && (!Number.isSafeInteger(ms) || ms < 0)) {
|
|
1056
|
+
throw new Error(`${name} must be a non-negative safe integer`);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
var MAX_TIMER_MS = 2 ** 31 - 1;
|
|
1060
|
+
function assertTimerMs(name, ms) {
|
|
1061
|
+
assertNonNegativeMs(name, ms);
|
|
1062
|
+
if (ms !== void 0 && ms > MAX_TIMER_MS) {
|
|
1063
|
+
throw new Error(`${name} must not exceed ${MAX_TIMER_MS} milliseconds`);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
var ArkPsbtFieldKey = /* @__PURE__ */ ((ArkPsbtFieldKey2) => {
|
|
1067
|
+
ArkPsbtFieldKey2["VtxoTaprootTree"] = "taptree";
|
|
1068
|
+
ArkPsbtFieldKey2["VtxoTreeExpiry"] = "expiry";
|
|
1069
|
+
ArkPsbtFieldKey2["Cosigner"] = "cosigner";
|
|
1070
|
+
ArkPsbtFieldKey2["ConditionWitness"] = "condition";
|
|
1071
|
+
ArkPsbtFieldKey2["PrevArkTx"] = "prevarktx";
|
|
1072
|
+
ArkPsbtFieldKey2["PrevoutTx"] = "prevouttx";
|
|
1073
|
+
return ArkPsbtFieldKey2;
|
|
1074
|
+
})(ArkPsbtFieldKey || {});
|
|
1075
|
+
var ArkPsbtFieldKeyType = 222;
|
|
1076
|
+
function setArkPsbtField(tx, inputIndex, coder, value) {
|
|
1077
|
+
tx.updateInput(inputIndex, {
|
|
1078
|
+
unknown: [...tx.getInput(inputIndex)?.unknown ?? [], coder.encode(value)]
|
|
1079
|
+
});
|
|
1080
|
+
}
|
|
1081
|
+
function getArkPsbtFields(tx, inputIndex, coder) {
|
|
1082
|
+
const unknown = tx.getInput(inputIndex)?.unknown ?? [];
|
|
1083
|
+
return unknown.map((u) => coder.decode(u)).filter((v) => v !== null);
|
|
1084
|
+
}
|
|
1085
|
+
var VtxoTaprootTree = {
|
|
1086
|
+
key: "taptree" /* VtxoTaprootTree */,
|
|
1087
|
+
encode: (value) => [
|
|
1088
|
+
{
|
|
1089
|
+
type: ArkPsbtFieldKeyType,
|
|
1090
|
+
key: encodedPsbtFieldKey["taptree" /* VtxoTaprootTree */]
|
|
1091
|
+
},
|
|
1092
|
+
value
|
|
1093
|
+
],
|
|
1094
|
+
decode: (value) => nullIfCatch(() => {
|
|
1095
|
+
if (!checkKeyMatch(value[0], "taptree" /* VtxoTaprootTree */)) return null;
|
|
1096
|
+
return value[1];
|
|
1097
|
+
})
|
|
1098
|
+
};
|
|
1099
|
+
var ConditionWitness = {
|
|
1100
|
+
key: "condition" /* ConditionWitness */,
|
|
1101
|
+
encode: (value) => [
|
|
1102
|
+
{
|
|
1103
|
+
type: ArkPsbtFieldKeyType,
|
|
1104
|
+
key: encodedPsbtFieldKey["condition" /* ConditionWitness */]
|
|
1105
|
+
},
|
|
1106
|
+
btcSigner.RawWitness.encode(value)
|
|
1107
|
+
],
|
|
1108
|
+
decode: (value) => nullIfCatch(() => {
|
|
1109
|
+
if (!checkKeyMatch(value[0], "condition" /* ConditionWitness */)) return null;
|
|
1110
|
+
return btcSigner.RawWitness.decode(value[1]);
|
|
1111
|
+
})
|
|
1112
|
+
};
|
|
1113
|
+
var PrevArkTxField = {
|
|
1114
|
+
key: "prevarktx" /* PrevArkTx */,
|
|
1115
|
+
encode: (value) => [
|
|
1116
|
+
{
|
|
1117
|
+
type: ArkPsbtFieldKeyType,
|
|
1118
|
+
key: encodedPsbtFieldKey["prevarktx" /* PrevArkTx */]
|
|
1119
|
+
},
|
|
1120
|
+
value
|
|
1121
|
+
],
|
|
1122
|
+
decode: (value) => nullIfCatch(() => {
|
|
1123
|
+
if (!checkKeyMatch(value[0], "prevarktx" /* PrevArkTx */)) return null;
|
|
1124
|
+
return value[1];
|
|
1125
|
+
})
|
|
1126
|
+
};
|
|
1127
|
+
var PrevoutTxField = {
|
|
1128
|
+
key: "prevouttx" /* PrevoutTx */,
|
|
1129
|
+
encode: (value) => [
|
|
1130
|
+
{
|
|
1131
|
+
type: ArkPsbtFieldKeyType,
|
|
1132
|
+
key: encodedPsbtFieldKey["prevouttx" /* PrevoutTx */]
|
|
1133
|
+
},
|
|
1134
|
+
value
|
|
1135
|
+
],
|
|
1136
|
+
decode: (value) => nullIfCatch(() => {
|
|
1137
|
+
if (!checkKeyMatch(value[0], "prevouttx" /* PrevoutTx */)) return null;
|
|
1138
|
+
return value[1];
|
|
1139
|
+
})
|
|
1140
|
+
};
|
|
1141
|
+
var CosignerPublicKey = {
|
|
1142
|
+
key: "cosigner" /* Cosigner */,
|
|
1143
|
+
encode: (value) => [
|
|
1144
|
+
{
|
|
1145
|
+
type: ArkPsbtFieldKeyType,
|
|
1146
|
+
key: new Uint8Array([...encodedPsbtFieldKey["cosigner" /* Cosigner */], value.index])
|
|
1147
|
+
},
|
|
1148
|
+
value.key
|
|
1149
|
+
],
|
|
1150
|
+
decode: (unknown) => nullIfCatch(() => {
|
|
1151
|
+
if (!checkKeyMatch(unknown[0], "cosigner" /* Cosigner */, true)) return null;
|
|
1152
|
+
return {
|
|
1153
|
+
index: unknown[0].key[unknown[0].key.length - 1],
|
|
1154
|
+
key: unknown[1]
|
|
1155
|
+
};
|
|
1156
|
+
})
|
|
1157
|
+
};
|
|
1158
|
+
var VtxoTreeExpiry = {
|
|
1159
|
+
key: "expiry" /* VtxoTreeExpiry */,
|
|
1160
|
+
encode: (value) => [
|
|
1161
|
+
{
|
|
1162
|
+
type: ArkPsbtFieldKeyType,
|
|
1163
|
+
key: encodedPsbtFieldKey["expiry" /* VtxoTreeExpiry */]
|
|
1164
|
+
},
|
|
1165
|
+
btcSigner.ScriptNum(6, true).encode(value.value)
|
|
1166
|
+
],
|
|
1167
|
+
decode: (unknown) => nullIfCatch(() => {
|
|
1168
|
+
if (!checkKeyMatch(unknown[0], "expiry" /* VtxoTreeExpiry */)) return null;
|
|
1169
|
+
const v = btcSigner.ScriptNum(6, true).decode(unknown[1]);
|
|
1170
|
+
if (!v) return null;
|
|
1171
|
+
return sequenceToTimelock(Number(v));
|
|
1172
|
+
})
|
|
1173
|
+
};
|
|
1174
|
+
var encodedPsbtFieldKey = Object.fromEntries(
|
|
1175
|
+
Object.values(ArkPsbtFieldKey).map((key) => [key, new TextEncoder().encode(key)])
|
|
1176
|
+
);
|
|
1177
|
+
var nullIfCatch = (fn) => {
|
|
1008
1178
|
try {
|
|
1009
|
-
|
|
1010
|
-
const script = scriptWithLeafVersion.subarray(0, scriptWithLeafVersion.length - 1);
|
|
1011
|
-
try {
|
|
1012
|
-
const params = exports.CSVMultisigTapscript.decode(script).params;
|
|
1013
|
-
sequence = timelockToSequence(params.timelock);
|
|
1014
|
-
} catch {
|
|
1015
|
-
const params = exports.CLTVMultisigTapscript.decode(script).params;
|
|
1016
|
-
sequence = Number(params.absoluteTimelock);
|
|
1017
|
-
}
|
|
1179
|
+
return fn();
|
|
1018
1180
|
} catch {
|
|
1181
|
+
return null;
|
|
1019
1182
|
}
|
|
1020
|
-
|
|
1183
|
+
};
|
|
1184
|
+
function checkKeyMatch(key, arkPsbtFieldKey, prefixOnly = false) {
|
|
1185
|
+
if (key.type !== ArkPsbtFieldKeyType) return false;
|
|
1186
|
+
const expected = encodedPsbtFieldKey[arkPsbtFieldKey];
|
|
1187
|
+
if (key.key.length < expected.length) return false;
|
|
1188
|
+
if (!prefixOnly && key.key.length !== expected.length) return false;
|
|
1189
|
+
for (let i = 0; i < expected.length; i++) {
|
|
1190
|
+
if (key.key[i] !== expected[i]) return false;
|
|
1191
|
+
}
|
|
1192
|
+
return true;
|
|
1021
1193
|
}
|
|
1022
1194
|
|
|
1023
1195
|
// src/providers/eventSource.ts
|
|
@@ -1045,11 +1217,15 @@ function resolveEventSource(override) {
|
|
|
1045
1217
|
}
|
|
1046
1218
|
|
|
1047
1219
|
// package.json
|
|
1048
|
-
var version = "0.5.0-rc.
|
|
1220
|
+
var version = "0.5.0-rc.20";
|
|
1049
1221
|
|
|
1050
1222
|
// src/utils/fetch.ts
|
|
1051
1223
|
var buildVersion = "0.9.9";
|
|
1052
1224
|
var sdkVersion = `ts-sdk/${version}`;
|
|
1225
|
+
var ARKADE_VERSION_HEADERS = {
|
|
1226
|
+
"X-Build-Version": buildVersion,
|
|
1227
|
+
"X-SDK-VERSION": sdkVersion
|
|
1228
|
+
};
|
|
1053
1229
|
var FetchError = class extends Error {
|
|
1054
1230
|
/** The request URL that failed, when derivable from the `fetch` input. */
|
|
1055
1231
|
url;
|
|
@@ -1062,38 +1238,48 @@ var FetchError = class extends Error {
|
|
|
1062
1238
|
this.method = options.method;
|
|
1063
1239
|
}
|
|
1064
1240
|
};
|
|
1241
|
+
var READ_TIMEOUT_MS = 3e4;
|
|
1242
|
+
var warnedNoTimeoutSupport = false;
|
|
1243
|
+
function readDeadline(input, init) {
|
|
1244
|
+
if (init?.signal || input instanceof Request) return void 0;
|
|
1245
|
+
const { method } = describeRequest(input, init);
|
|
1246
|
+
const verb = method.toUpperCase();
|
|
1247
|
+
if (verb !== "GET" && verb !== "HEAD") return void 0;
|
|
1248
|
+
if (typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function") {
|
|
1249
|
+
return AbortSignal.timeout(READ_TIMEOUT_MS);
|
|
1250
|
+
}
|
|
1251
|
+
if (typeof AbortController === "function") {
|
|
1252
|
+
const controller = new AbortController();
|
|
1253
|
+
const timer = setTimeout(() => controller.abort(), READ_TIMEOUT_MS);
|
|
1254
|
+
timer?.unref?.();
|
|
1255
|
+
return controller.signal;
|
|
1256
|
+
}
|
|
1257
|
+
if (!warnedNoTimeoutSupport) {
|
|
1258
|
+
warnedNoTimeoutSupport = true;
|
|
1259
|
+
console.warn(
|
|
1260
|
+
"Neither AbortSignal.timeout nor AbortController is available in this runtime: provider reads are UNBOUNDED and READ_TIMEOUT_MS is not being applied."
|
|
1261
|
+
);
|
|
1262
|
+
}
|
|
1263
|
+
return void 0;
|
|
1264
|
+
}
|
|
1065
1265
|
function baseFetch(input, init) {
|
|
1066
1266
|
if (typeof globalThis.fetch !== "function") {
|
|
1067
1267
|
throw new Error("Fetch API is not available in this environment.");
|
|
1068
1268
|
}
|
|
1069
|
-
|
|
1269
|
+
const signal = readDeadline(input, init);
|
|
1270
|
+
return globalThis.fetch(input, signal ? { ...init, signal } : init).catch((cause) => {
|
|
1070
1271
|
const { url, method } = describeRequest(input, init);
|
|
1071
1272
|
throw new FetchError(`Network request failed: ${method} ${url}`, { url, method, cause });
|
|
1072
1273
|
});
|
|
1073
1274
|
}
|
|
1074
1275
|
function fetch(input, init) {
|
|
1075
1276
|
const headers = new Headers(init?.headers);
|
|
1076
|
-
headers.set(
|
|
1077
|
-
headers.set("X-SDK-VERSION", sdkVersion);
|
|
1277
|
+
for (const [name, value] of Object.entries(ARKADE_VERSION_HEADERS)) headers.set(name, value);
|
|
1078
1278
|
return baseFetch(input, { ...init, headers });
|
|
1079
1279
|
}
|
|
1080
1280
|
function describeRequest(input, init) {
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
url = input;
|
|
1084
|
-
} else if (input instanceof URL) {
|
|
1085
|
-
url = input.href;
|
|
1086
|
-
} else {
|
|
1087
|
-
url = input.url;
|
|
1088
|
-
}
|
|
1089
|
-
let method;
|
|
1090
|
-
if (init?.method !== void 0) {
|
|
1091
|
-
method = init.method;
|
|
1092
|
-
} else if (input instanceof Request) {
|
|
1093
|
-
method = input.method;
|
|
1094
|
-
} else {
|
|
1095
|
-
method = "GET";
|
|
1096
|
-
}
|
|
1281
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
1282
|
+
const method = init?.method !== void 0 ? init.method : input instanceof Request ? input.method : "GET";
|
|
1097
1283
|
return { url, method };
|
|
1098
1284
|
}
|
|
1099
1285
|
|
|
@@ -1117,15 +1303,13 @@ var ArkErrorName = {
|
|
|
1117
1303
|
INVALID_TX_FILTER: "INVALID_TX_FILTER",
|
|
1118
1304
|
TX_FILTERS_LIMIT_EXCEEDED: "TX_FILTERS_LIMIT_EXCEEDED",
|
|
1119
1305
|
/**
|
|
1120
|
-
* A CLTV closure was spent before its absolute locktime matured.
|
|
1121
|
-
* `
|
|
1122
|
-
*
|
|
1123
|
-
*
|
|
1124
|
-
* Self-healing, so defer and retry rather than fail: the server matures a
|
|
1125
|
-
* seconds-locktime against the **chain tip block's timestamp**, not its wall clock,
|
|
1126
|
-
* so a spend attempted promptly at maturity is rejected until a later block lands.
|
|
1306
|
+
* A CLTV closure was spent before its absolute locktime matured. `submitTx` only, with
|
|
1307
|
+
* metadata `{ locktime, current_locktime, type: "height" | "time" }`. Self-healing, so defer
|
|
1308
|
+
* and retry: the server matures a seconds-locktime against the **chain tip block's
|
|
1309
|
+
* timestamp**, not wall clock, so a prompt spend is rejected until a later block lands.
|
|
1127
1310
|
*/
|
|
1128
|
-
FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED"
|
|
1311
|
+
FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED",
|
|
1312
|
+
INVALID_INTENT_PROOF: "INVALID_INTENT_PROOF"
|
|
1129
1313
|
};
|
|
1130
1314
|
function isArkError(error, name) {
|
|
1131
1315
|
return error instanceof ArkError && (name === void 0 || error.name === name);
|
|
@@ -1201,8 +1385,8 @@ exports.Intent = void 0;
|
|
|
1201
1385
|
}
|
|
1202
1386
|
if (ins.length == 0) throw new Error("intent proof requires at least one input");
|
|
1203
1387
|
const inputs = ins.map(prepareCoinAsIntentProofInput);
|
|
1204
|
-
|
|
1205
|
-
|
|
1388
|
+
validateInputs(inputs);
|
|
1389
|
+
validateOutputs(outputs);
|
|
1206
1390
|
const toSpend = craftToSpendTx(message, inputs[0].witnessUtxo.script);
|
|
1207
1391
|
return craftToSignTx(toSpend, inputs, outputs, message);
|
|
1208
1392
|
}
|
|
@@ -1257,7 +1441,6 @@ var OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([btcSigner.OP.RETURN]);
|
|
|
1257
1441
|
var ZERO_32 = new Uint8Array(32).fill(0);
|
|
1258
1442
|
var MAX_INDEX = 4294967295;
|
|
1259
1443
|
var TAG_INTENT_PROOF = "ark-intent-proof-message";
|
|
1260
|
-
var PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE = 9;
|
|
1261
1444
|
function validateInput(input) {
|
|
1262
1445
|
if (input.index === void 0) throw new Error("intent proof input requires index");
|
|
1263
1446
|
if (input.txid === void 0) throw new Error("intent proof input requires txid");
|
|
@@ -1267,7 +1450,6 @@ function validateInput(input) {
|
|
|
1267
1450
|
}
|
|
1268
1451
|
function validateInputs(inputs) {
|
|
1269
1452
|
inputs.forEach(validateInput);
|
|
1270
|
-
return true;
|
|
1271
1453
|
}
|
|
1272
1454
|
function validateOutput(output) {
|
|
1273
1455
|
if (output.amount === void 0) throw new Error("intent proof output requires amount");
|
|
@@ -1276,7 +1458,6 @@ function validateOutput(output) {
|
|
|
1276
1458
|
}
|
|
1277
1459
|
function validateOutputs(outputs) {
|
|
1278
1460
|
outputs.forEach(validateOutput);
|
|
1279
|
-
return true;
|
|
1280
1461
|
}
|
|
1281
1462
|
function craftToSpendTx(message, pkScript, tag = TAG_INTENT_PROOF) {
|
|
1282
1463
|
const messageHash = hashMessage(message, tag);
|
|
@@ -1304,8 +1485,9 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
|
|
|
1304
1485
|
version: 2,
|
|
1305
1486
|
lockTime: 0
|
|
1306
1487
|
});
|
|
1488
|
+
const { unknown: _, ...toSpendInput } = firstInput;
|
|
1307
1489
|
tx.addInput({
|
|
1308
|
-
...
|
|
1490
|
+
...toSpendInput,
|
|
1309
1491
|
txid: toSpend.id,
|
|
1310
1492
|
index: 0,
|
|
1311
1493
|
witnessUtxo: {
|
|
@@ -1339,14 +1521,7 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
|
|
|
1339
1521
|
script: output.script
|
|
1340
1522
|
});
|
|
1341
1523
|
}
|
|
1342
|
-
|
|
1343
|
-
global.unknown = [
|
|
1344
|
-
...global.unknown ?? [],
|
|
1345
|
-
[
|
|
1346
|
-
{ type: PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE, key: new Uint8Array() },
|
|
1347
|
-
new TextEncoder().encode(message)
|
|
1348
|
-
]
|
|
1349
|
-
];
|
|
1524
|
+
tx.global.genericSignedMessage = new TextEncoder().encode(message);
|
|
1350
1525
|
return tx;
|
|
1351
1526
|
}
|
|
1352
1527
|
function hashMessage(message, tag = TAG_INTENT_PROOF) {
|
|
@@ -1483,7 +1658,7 @@ var DEFAULT_MAX_CONCURRENT = 6;
|
|
|
1483
1658
|
var DEFAULT_COOLDOWN_MS = 5e3;
|
|
1484
1659
|
var MAX_COOLDOWN_MS = 6e4;
|
|
1485
1660
|
var DEFAULT_JITTER_MS = 500;
|
|
1486
|
-
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1661
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.min(ms, MAX_TIMER_MS)));
|
|
1487
1662
|
function parseRetryAfterMs(header) {
|
|
1488
1663
|
if (header === null || header === void 0) return void 0;
|
|
1489
1664
|
const trimmed = header.trim();
|
|
@@ -1516,6 +1691,9 @@ var OriginRateGate = class {
|
|
|
1516
1691
|
maxCooldownMs;
|
|
1517
1692
|
jitterMs;
|
|
1518
1693
|
constructor(options) {
|
|
1694
|
+
assertNonNegativeMs("defaultCooldownMs", options?.defaultCooldownMs);
|
|
1695
|
+
assertNonNegativeMs("maxCooldownMs", options?.maxCooldownMs);
|
|
1696
|
+
assertNonNegativeMs("jitterMs", options?.jitterMs);
|
|
1519
1697
|
this.maxConcurrent = options?.maxConcurrent ?? DEFAULT_MAX_CONCURRENT;
|
|
1520
1698
|
this.defaultCooldownMs = options?.defaultCooldownMs ?? DEFAULT_COOLDOWN_MS;
|
|
1521
1699
|
this.maxCooldownMs = options?.maxCooldownMs ?? MAX_COOLDOWN_MS;
|
|
@@ -1721,6 +1899,20 @@ var RestArkProvider = class {
|
|
|
1721
1899
|
"Arkade server reported a configuration digest mismatch; server info was refreshed. Rebuild and retry the request under the new server info."
|
|
1722
1900
|
);
|
|
1723
1901
|
}
|
|
1902
|
+
async postJson(url, body, failureMessage) {
|
|
1903
|
+
const response = await this.authedFetch(url, {
|
|
1904
|
+
method: "POST",
|
|
1905
|
+
headers: {
|
|
1906
|
+
"Content-Type": "application/json"
|
|
1907
|
+
},
|
|
1908
|
+
body: JSON.stringify(body)
|
|
1909
|
+
});
|
|
1910
|
+
if (!response.ok) {
|
|
1911
|
+
const errorText = await response.text();
|
|
1912
|
+
handleError(errorText, failureMessage(errorText, response));
|
|
1913
|
+
}
|
|
1914
|
+
return response;
|
|
1915
|
+
}
|
|
1724
1916
|
async getInfo() {
|
|
1725
1917
|
const url = `${this.serverUrl}/v1/info`;
|
|
1726
1918
|
const response = await rateGate.runHttp(
|
|
@@ -1786,20 +1978,14 @@ var RestArkProvider = class {
|
|
|
1786
1978
|
}
|
|
1787
1979
|
async submitTx(signedArkTx, checkpointTxs) {
|
|
1788
1980
|
const url = `${this.serverUrl}/v1/tx/submit`;
|
|
1789
|
-
const response = await this.
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
"Content-Type": "application/json"
|
|
1793
|
-
},
|
|
1794
|
-
body: JSON.stringify({
|
|
1981
|
+
const response = await this.postJson(
|
|
1982
|
+
url,
|
|
1983
|
+
{
|
|
1795
1984
|
signedArkTx,
|
|
1796
1985
|
checkpointTxs
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
const errorText = await response.text();
|
|
1801
|
-
handleError(errorText, `Failed to submit virtual transaction: ${errorText}`);
|
|
1802
|
-
}
|
|
1986
|
+
},
|
|
1987
|
+
(errorText) => `Failed to submit virtual transaction: ${errorText}`
|
|
1988
|
+
);
|
|
1803
1989
|
const data = await response.json();
|
|
1804
1990
|
return {
|
|
1805
1991
|
arkTxid: data.arkTxid,
|
|
@@ -1809,129 +1995,87 @@ var RestArkProvider = class {
|
|
|
1809
1995
|
}
|
|
1810
1996
|
async finalizeTx(arkTxid, finalCheckpointTxs) {
|
|
1811
1997
|
const url = `${this.serverUrl}/v1/tx/finalize`;
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
"Content-Type": "application/json"
|
|
1816
|
-
},
|
|
1817
|
-
body: JSON.stringify({
|
|
1998
|
+
await this.postJson(
|
|
1999
|
+
url,
|
|
2000
|
+
{
|
|
1818
2001
|
arkTxid,
|
|
1819
2002
|
finalCheckpointTxs
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
const errorText = await response.text();
|
|
1824
|
-
handleError(errorText, `Failed to finalize offchain transaction: ${errorText}`);
|
|
1825
|
-
}
|
|
2003
|
+
},
|
|
2004
|
+
(errorText) => `Failed to finalize offchain transaction: ${errorText}`
|
|
2005
|
+
);
|
|
1826
2006
|
}
|
|
1827
2007
|
async registerIntent(intent) {
|
|
1828
2008
|
const url = `${this.serverUrl}/v1/batch/registerIntent`;
|
|
1829
|
-
const response = await this.
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
"Content-Type": "application/json"
|
|
1833
|
-
},
|
|
1834
|
-
body: JSON.stringify({
|
|
2009
|
+
const response = await this.postJson(
|
|
2010
|
+
url,
|
|
2011
|
+
{
|
|
1835
2012
|
intent: {
|
|
1836
2013
|
proof: intent.proof,
|
|
1837
2014
|
message: exports.Intent.encodeMessage(intent.message)
|
|
1838
2015
|
}
|
|
1839
|
-
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
const errorText = await response.text();
|
|
1843
|
-
handleError(errorText, `Failed to register intent: ${errorText}`);
|
|
1844
|
-
}
|
|
2016
|
+
},
|
|
2017
|
+
(errorText) => `Failed to register intent: ${errorText}`
|
|
2018
|
+
);
|
|
1845
2019
|
const data = await response.json();
|
|
1846
2020
|
return data.intentId;
|
|
1847
2021
|
}
|
|
1848
2022
|
async deleteIntent(intent) {
|
|
1849
2023
|
const url = `${this.serverUrl}/v1/batch/deleteIntent`;
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
"Content-Type": "application/json"
|
|
1854
|
-
},
|
|
1855
|
-
body: JSON.stringify({
|
|
2024
|
+
await this.postJson(
|
|
2025
|
+
url,
|
|
2026
|
+
{
|
|
1856
2027
|
intent: {
|
|
1857
2028
|
proof: intent.proof,
|
|
1858
2029
|
message: exports.Intent.encodeMessage(intent.message)
|
|
1859
2030
|
}
|
|
1860
|
-
}
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
const errorText = await response.text();
|
|
1864
|
-
handleError(errorText, `Failed to delete intent: ${errorText}`);
|
|
1865
|
-
}
|
|
2031
|
+
},
|
|
2032
|
+
(errorText) => `Failed to delete intent: ${errorText}`
|
|
2033
|
+
);
|
|
1866
2034
|
}
|
|
1867
2035
|
async confirmRegistration(intentId) {
|
|
1868
2036
|
const url = `${this.serverUrl}/v1/batch/ack`;
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
"Content-Type": "application/json"
|
|
1873
|
-
},
|
|
1874
|
-
body: JSON.stringify({
|
|
2037
|
+
await this.postJson(
|
|
2038
|
+
url,
|
|
2039
|
+
{
|
|
1875
2040
|
intentId
|
|
1876
|
-
}
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
const errorText = await response.text();
|
|
1880
|
-
handleError(errorText, `Failed to confirm registration: ${errorText}`);
|
|
1881
|
-
}
|
|
2041
|
+
},
|
|
2042
|
+
(errorText) => `Failed to confirm registration: ${errorText}`
|
|
2043
|
+
);
|
|
1882
2044
|
}
|
|
1883
2045
|
async submitTreeNonces(batchId, pubkey, nonces) {
|
|
1884
2046
|
const url = `${this.serverUrl}/v1/batch/tree/submitNonces`;
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
"Content-Type": "application/json"
|
|
1889
|
-
},
|
|
1890
|
-
body: JSON.stringify({
|
|
2047
|
+
await this.postJson(
|
|
2048
|
+
url,
|
|
2049
|
+
{
|
|
1891
2050
|
batchId,
|
|
1892
2051
|
pubkey,
|
|
1893
2052
|
treeNonces: encodeMusig2Nonces(nonces)
|
|
1894
|
-
}
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
const errorText = await response.text();
|
|
1898
|
-
handleError(errorText, `Failed to submit tree nonces: ${errorText}`);
|
|
1899
|
-
}
|
|
2053
|
+
},
|
|
2054
|
+
(errorText) => `Failed to submit tree nonces: ${errorText}`
|
|
2055
|
+
);
|
|
1900
2056
|
}
|
|
1901
2057
|
async submitTreeSignatures(batchId, pubkey, signatures) {
|
|
1902
2058
|
const url = `${this.serverUrl}/v1/batch/tree/submitSignatures`;
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
"Content-Type": "application/json"
|
|
1907
|
-
},
|
|
1908
|
-
body: JSON.stringify({
|
|
2059
|
+
await this.postJson(
|
|
2060
|
+
url,
|
|
2061
|
+
{
|
|
1909
2062
|
batchId,
|
|
1910
2063
|
pubkey,
|
|
1911
2064
|
treeSignatures: encodeMusig2Signatures(signatures)
|
|
1912
|
-
}
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
const errorText = await response.text();
|
|
1916
|
-
handleError(errorText, `Failed to submit tree signatures: ${errorText}`);
|
|
1917
|
-
}
|
|
2065
|
+
},
|
|
2066
|
+
(errorText) => `Failed to submit tree signatures: ${errorText}`
|
|
2067
|
+
);
|
|
1918
2068
|
}
|
|
1919
2069
|
async submitSignedForfeitTxs(signedForfeitTxs, signedCommitmentTx) {
|
|
1920
2070
|
const url = `${this.serverUrl}/v1/batch/submitForfeitTxs`;
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
"Content-Type": "application/json"
|
|
1925
|
-
},
|
|
1926
|
-
body: JSON.stringify({
|
|
2071
|
+
await this.postJson(
|
|
2072
|
+
url,
|
|
2073
|
+
{
|
|
1927
2074
|
signedForfeitTxs,
|
|
1928
2075
|
signedCommitmentTx
|
|
1929
|
-
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
const errorText = await response.text();
|
|
1933
|
-
handleError(errorText, `Failed to submit forfeit transactions: ${response.statusText}`);
|
|
1934
|
-
}
|
|
2076
|
+
},
|
|
2077
|
+
(_, res) => `Failed to submit forfeit transactions: ${res.statusText}`
|
|
2078
|
+
);
|
|
1935
2079
|
}
|
|
1936
2080
|
getEventStream(signal, topics) {
|
|
1937
2081
|
const url = `${this.serverUrl}/v1/batch/events`;
|
|
@@ -2054,22 +2198,16 @@ var RestArkProvider = class {
|
|
|
2054
2198
|
}
|
|
2055
2199
|
async getPendingTxs(intent) {
|
|
2056
2200
|
const url = `${this.serverUrl}/v1/tx/pending`;
|
|
2057
|
-
const response = await this.
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
"Content-Type": "application/json"
|
|
2061
|
-
},
|
|
2062
|
-
body: JSON.stringify({
|
|
2201
|
+
const response = await this.postJson(
|
|
2202
|
+
url,
|
|
2203
|
+
{
|
|
2063
2204
|
intent: {
|
|
2064
2205
|
proof: intent.proof,
|
|
2065
2206
|
message: exports.Intent.encodeMessage(intent.message)
|
|
2066
2207
|
}
|
|
2067
|
-
}
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
const errorText = await response.text();
|
|
2071
|
-
handleError(errorText, `Failed to get pending transactions: ${errorText}`);
|
|
2072
|
-
}
|
|
2208
|
+
},
|
|
2209
|
+
(errorText) => `Failed to get pending transactions: ${errorText}`
|
|
2210
|
+
);
|
|
2073
2211
|
const data = await response.json();
|
|
2074
2212
|
return data.pendingTxs;
|
|
2075
2213
|
}
|
|
@@ -2289,60 +2427,23 @@ function parseWireExpiry(raw) {
|
|
|
2289
2427
|
if (ms >= EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(ms) };
|
|
2290
2428
|
return { expiresAtHeight: n };
|
|
2291
2429
|
}
|
|
2292
|
-
function toBatchExpiry(c) {
|
|
2293
|
-
if (c.expiresAt !== void 0) return c.expiresAt.getTime();
|
|
2294
|
-
if (c.expiresAtHeight !== void 0) return c.expiresAtHeight * 1e3;
|
|
2295
|
-
return void 0;
|
|
2296
|
-
}
|
|
2297
|
-
function parseLegacyExpiry(batchExpiry) {
|
|
2298
|
-
if (batchExpiry === void 0 || batchExpiry <= 0) return {};
|
|
2299
|
-
if (batchExpiry >= EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(batchExpiry) };
|
|
2300
|
-
return { expiresAtHeight: batchExpiry / 1e3 };
|
|
2301
|
-
}
|
|
2302
|
-
function toVirtualStatus(c) {
|
|
2303
|
-
return {
|
|
2304
|
-
// Precedence is load-bearing: consumers bucket on this label, so any other order silently
|
|
2305
|
-
// moves VTXOs between buckets.
|
|
2306
|
-
state: c.isSpent ? "spent" : c.isSwept ? "swept" : c.isPreconfirmed ? "preconfirmed" : "settled",
|
|
2307
|
-
commitmentTxIds: c.commitmentTxIds,
|
|
2308
|
-
batchExpiry: toBatchExpiry(c)
|
|
2309
|
-
};
|
|
2310
|
-
}
|
|
2311
2430
|
function normalizeVtxo(v) {
|
|
2312
|
-
const
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
// as `Date` but returns NaN from `.getTime()` — comparing false against everything.
|
|
2317
|
-
{
|
|
2318
|
-
expiresAt: v.expiresAt === void 0 ? void 0 : new Date(v.expiresAt),
|
|
2319
|
-
expiresAtHeight: v.expiresAtHeight
|
|
2320
|
-
}
|
|
2321
|
-
) : parseLegacyExpiry(v.virtualStatus?.batchExpiry);
|
|
2322
|
-
const isSpent = v.isSpent ?? state === "spent";
|
|
2323
|
-
const isSwept = v.isSwept ?? state === "swept";
|
|
2324
|
-
const isPreconfirmed = v.isPreconfirmed ?? state === "preconfirmed";
|
|
2325
|
-
const commitmentTxIds = v.commitmentTxIds ?? v.virtualStatus?.commitmentTxIds ?? [];
|
|
2431
|
+
const expiry = {
|
|
2432
|
+
expiresAt: v.expiresAt === void 0 ? void 0 : new Date(v.expiresAt),
|
|
2433
|
+
expiresAtHeight: v.expiresAtHeight
|
|
2434
|
+
};
|
|
2326
2435
|
return {
|
|
2327
2436
|
...v,
|
|
2328
|
-
isSpent,
|
|
2329
|
-
isSwept,
|
|
2330
|
-
isPreconfirmed,
|
|
2437
|
+
isSpent: v.isSpent ?? false,
|
|
2438
|
+
isSwept: v.isSwept ?? false,
|
|
2439
|
+
isPreconfirmed: v.isPreconfirmed ?? false,
|
|
2331
2440
|
spentBy: v.spentBy ?? "",
|
|
2332
|
-
commitmentTxIds,
|
|
2333
|
-
...expiry
|
|
2334
|
-
virtualStatus: v.virtualStatus ?? toVirtualStatus({ isSpent, isSwept, isPreconfirmed, commitmentTxIds, ...expiry })
|
|
2441
|
+
commitmentTxIds: v.commitmentTxIds ?? [],
|
|
2442
|
+
...expiry
|
|
2335
2443
|
};
|
|
2336
2444
|
}
|
|
2337
2445
|
function convertVtxo(vtxo) {
|
|
2338
2446
|
const expiry = parseWireExpiry(vtxo.expiresAt);
|
|
2339
|
-
const facts = {
|
|
2340
|
-
isSpent: vtxo.isSpent,
|
|
2341
|
-
isSwept: vtxo.isSwept,
|
|
2342
|
-
isPreconfirmed: vtxo.isPreconfirmed,
|
|
2343
|
-
commitmentTxIds: vtxo.commitmentTxids,
|
|
2344
|
-
...expiry
|
|
2345
|
-
};
|
|
2346
2447
|
return {
|
|
2347
2448
|
txid: vtxo.outpoint.txid,
|
|
2348
2449
|
vout: vtxo.outpoint.vout,
|
|
@@ -2351,8 +2452,11 @@ function convertVtxo(vtxo) {
|
|
|
2351
2452
|
confirmed: !vtxo.isSwept && !vtxo.isPreconfirmed,
|
|
2352
2453
|
isLeaf: !vtxo.isPreconfirmed
|
|
2353
2454
|
},
|
|
2354
|
-
|
|
2355
|
-
|
|
2455
|
+
isSpent: vtxo.isSpent,
|
|
2456
|
+
isSwept: vtxo.isSwept,
|
|
2457
|
+
isPreconfirmed: vtxo.isPreconfirmed,
|
|
2458
|
+
commitmentTxIds: vtxo.commitmentTxids,
|
|
2459
|
+
...expiry,
|
|
2356
2460
|
spentBy: vtxo.spentBy ?? "",
|
|
2357
2461
|
settledBy: vtxo.settledBy,
|
|
2358
2462
|
arkTxId: vtxo.arkTxid,
|
|
@@ -2369,11 +2473,16 @@ async function getNormalizedVtxos(provider, opts) {
|
|
|
2369
2473
|
const { vtxos, page } = await provider.getVtxos(opts);
|
|
2370
2474
|
return { vtxos: vtxos.map(normalizeVtxo), page };
|
|
2371
2475
|
}
|
|
2476
|
+
var SCRIPT_CHUNK_CONCURRENCY = 4;
|
|
2372
2477
|
async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
|
|
2373
2478
|
const { pageSize = DEFAULT_PAGE_SIZE, ...filters } = opts;
|
|
2374
2479
|
const all = [];
|
|
2480
|
+
const chunks = [];
|
|
2375
2481
|
for (let i = 0; i < scripts.length; i += SCRIPT_QUERY_CHUNK_SIZE) {
|
|
2376
|
-
|
|
2482
|
+
chunks.push(scripts.slice(i, i + SCRIPT_QUERY_CHUNK_SIZE));
|
|
2483
|
+
}
|
|
2484
|
+
const fetchChunk = async (chunk) => {
|
|
2485
|
+
const result = [];
|
|
2377
2486
|
let pageIndex = 0;
|
|
2378
2487
|
let hasMore = true;
|
|
2379
2488
|
while (hasMore) {
|
|
@@ -2383,11 +2492,18 @@ async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
|
|
|
2383
2492
|
pageIndex,
|
|
2384
2493
|
pageSize
|
|
2385
2494
|
});
|
|
2386
|
-
|
|
2495
|
+
result.push(...vtxos);
|
|
2387
2496
|
hasMore = page ? vtxos.length === pageSize : false;
|
|
2388
2497
|
pageIndex++;
|
|
2389
2498
|
if (hasMore) await new Promise((r) => setTimeout(r, 500));
|
|
2390
2499
|
}
|
|
2500
|
+
return result;
|
|
2501
|
+
};
|
|
2502
|
+
for (let i = 0; i < chunks.length; i += SCRIPT_CHUNK_CONCURRENCY) {
|
|
2503
|
+
const batch = await Promise.all(
|
|
2504
|
+
chunks.slice(i, i + SCRIPT_CHUNK_CONCURRENCY).map(fetchChunk)
|
|
2505
|
+
);
|
|
2506
|
+
for (const result of batch) all.push(...result);
|
|
2391
2507
|
}
|
|
2392
2508
|
return all;
|
|
2393
2509
|
}
|
|
@@ -2410,7 +2526,7 @@ async function fetchVtxoCreatedAtByTxid(provider, txids) {
|
|
|
2410
2526
|
}
|
|
2411
2527
|
return createdAt;
|
|
2412
2528
|
}
|
|
2413
|
-
function
|
|
2529
|
+
function isVtxoSpent(vtxo) {
|
|
2414
2530
|
const n = normalizeVtxo(vtxo);
|
|
2415
2531
|
return !!n.isSpent || !!n.spentBy || !!n.settledBy;
|
|
2416
2532
|
}
|
|
@@ -2421,41 +2537,34 @@ function isPastExpiry(vtxo, now) {
|
|
|
2421
2537
|
}
|
|
2422
2538
|
function canSpendOffchain(vtxo, now) {
|
|
2423
2539
|
const n = normalizeVtxo(vtxo);
|
|
2424
|
-
return !
|
|
2540
|
+
return !isVtxoSpent(n) && !n.isUnrolled && !(n.isSwept || isPastExpiry(n, now));
|
|
2425
2541
|
}
|
|
2426
2542
|
function canRecoverOnchain(vtxo, now) {
|
|
2427
2543
|
const n = normalizeVtxo(vtxo);
|
|
2428
|
-
return !
|
|
2544
|
+
return !isVtxoSpent(n) && !n.isUnrolled && (n.isSwept || isPastExpiry(n, now));
|
|
2429
2545
|
}
|
|
2430
2546
|
function canSweepOnchain(vtxo) {
|
|
2431
2547
|
const n = normalizeVtxo(vtxo);
|
|
2432
|
-
return !
|
|
2548
|
+
return !isVtxoSpent(n) && !!n.isUnrolled;
|
|
2549
|
+
}
|
|
2550
|
+
function requiresForfeit(vtxo) {
|
|
2551
|
+
const n = normalizeVtxo(vtxo);
|
|
2552
|
+
return !n.isSwept && !n.isUnrolled;
|
|
2433
2553
|
}
|
|
2434
2554
|
function toOffchainInputFeeParams(vtxo) {
|
|
2435
|
-
const batchExpiry = toBatchExpiry(vtxo);
|
|
2436
2555
|
return {
|
|
2437
2556
|
amount: BigInt(vtxo.value),
|
|
2438
2557
|
type: vtxo.isSwept ? "recoverable" : "vtxo",
|
|
2439
2558
|
weight: 0,
|
|
2440
2559
|
birth: vtxo.createdAt,
|
|
2441
|
-
expiry:
|
|
2560
|
+
expiry: vtxo.expiresAt
|
|
2442
2561
|
};
|
|
2443
2562
|
}
|
|
2444
2563
|
function isVirtualCoin(input) {
|
|
2445
2564
|
return typeof input === "object" && input !== null && typeof input.script === "string";
|
|
2446
2565
|
}
|
|
2447
|
-
function isSpendable(vtxo) {
|
|
2448
|
-
return !hasTerminalSpend(vtxo);
|
|
2449
|
-
}
|
|
2450
|
-
function isRecoverable(vtxo) {
|
|
2451
|
-
const n = normalizeVtxo(vtxo);
|
|
2452
|
-
return n.isSwept && !hasTerminalSpend(n);
|
|
2453
|
-
}
|
|
2454
|
-
function isExpired(vtxo) {
|
|
2455
|
-
const n = normalizeVtxo(vtxo);
|
|
2456
|
-
return n.isSwept || n.expiresAt !== void 0 && n.expiresAt.getTime() <= Date.now();
|
|
2457
|
-
}
|
|
2458
2566
|
|
|
2567
|
+
exports.ARKADE_VERSION_HEADERS = ARKADE_VERSION_HEADERS;
|
|
2459
2568
|
exports.ArkAddress = ArkAddress;
|
|
2460
2569
|
exports.ArkError = ArkError;
|
|
2461
2570
|
exports.ArkErrorName = ArkErrorName;
|
|
@@ -2469,6 +2578,7 @@ exports.DEFAULT_NETWORK = DEFAULT_NETWORK;
|
|
|
2469
2578
|
exports.DEFAULT_NETWORK_NAME = DEFAULT_NETWORK_NAME;
|
|
2470
2579
|
exports.DEFAULT_PAGE_SIZE = DEFAULT_PAGE_SIZE;
|
|
2471
2580
|
exports.DigestMismatchError = DigestMismatchError;
|
|
2581
|
+
exports.EXPIRY_MIN_PLAUSIBLE_MS = EXPIRY_MIN_PLAUSIBLE_MS;
|
|
2472
2582
|
exports.EventSourceUnavailableError = EventSourceUnavailableError;
|
|
2473
2583
|
exports.FetchError = FetchError;
|
|
2474
2584
|
exports.INFO_FETCH_TIMEOUT_MS = INFO_FETCH_TIMEOUT_MS;
|
|
@@ -2477,6 +2587,7 @@ exports.OP_RETURN_EMPTY_PKSCRIPT = OP_RETURN_EMPTY_PKSCRIPT;
|
|
|
2477
2587
|
exports.PrevArkTxField = PrevArkTxField;
|
|
2478
2588
|
exports.PrevoutTxField = PrevoutTxField;
|
|
2479
2589
|
exports.ProviderUnavailableError = ProviderUnavailableError;
|
|
2590
|
+
exports.READ_TIMEOUT_MS = READ_TIMEOUT_MS;
|
|
2480
2591
|
exports.REGTEST_EMULATOR_PUBKEY = REGTEST_EMULATOR_PUBKEY;
|
|
2481
2592
|
exports.RestArkProvider = RestArkProvider;
|
|
2482
2593
|
exports.SCRIPT_QUERY_CHUNK_SIZE = SCRIPT_QUERY_CHUNK_SIZE;
|
|
@@ -2487,8 +2598,11 @@ exports.Transaction = Transaction;
|
|
|
2487
2598
|
exports.VtxoScript = VtxoScript;
|
|
2488
2599
|
exports.VtxoTaprootTree = VtxoTaprootTree;
|
|
2489
2600
|
exports.VtxoTreeExpiry = VtxoTreeExpiry;
|
|
2601
|
+
exports.__export = __export;
|
|
2490
2602
|
exports.assembleBtcdTaprootTree = assembleBtcdTaprootTree;
|
|
2491
2603
|
exports.assertAllowedSighashTypes = assertAllowedSighashTypes;
|
|
2604
|
+
exports.assertNonNegativeMs = assertNonNegativeMs;
|
|
2605
|
+
exports.assertTimerMs = assertTimerMs;
|
|
2492
2606
|
exports.baseFetch = baseFetch;
|
|
2493
2607
|
exports.buildVersion = buildVersion;
|
|
2494
2608
|
exports.canRecoverOnchain = canRecoverOnchain;
|
|
@@ -2500,7 +2614,6 @@ exports.craftToSpendTx = craftToSpendTx;
|
|
|
2500
2614
|
exports.decodeTapscript = decodeTapscript;
|
|
2501
2615
|
exports.defaultEmulatorPubkey = defaultEmulatorPubkey;
|
|
2502
2616
|
exports.eventSourceIterator = eventSourceIterator;
|
|
2503
|
-
exports.fetch = fetch;
|
|
2504
2617
|
exports.fetchVtxoCreatedAtByTxid = fetchVtxoCreatedAtByTxid;
|
|
2505
2618
|
exports.formatSighash = formatSighash;
|
|
2506
2619
|
exports.getAllNormalizedVtxos = getAllNormalizedVtxos;
|
|
@@ -2509,35 +2622,32 @@ exports.getConfiguredEventSource = getConfiguredEventSource;
|
|
|
2509
2622
|
exports.getNetwork = getNetwork;
|
|
2510
2623
|
exports.getNormalizedVtxos = getNormalizedVtxos;
|
|
2511
2624
|
exports.getSequence = getSequence;
|
|
2512
|
-
exports.hasTerminalSpend = hasTerminalSpend;
|
|
2513
2625
|
exports.isArkError = isArkError;
|
|
2514
2626
|
exports.isEventSourceError = isEventSourceError;
|
|
2515
2627
|
exports.isEventSourceUnavailableError = isEventSourceUnavailableError;
|
|
2516
|
-
exports.isExpired = isExpired;
|
|
2517
2628
|
exports.isFetchTimeoutError = isFetchTimeoutError;
|
|
2518
2629
|
exports.isPastExpiry = isPastExpiry;
|
|
2519
|
-
exports.isRecoverable = isRecoverable;
|
|
2520
2630
|
exports.isRetryableProviderError = isRetryableProviderError;
|
|
2521
|
-
exports.isSpendable = isSpendable;
|
|
2522
2631
|
exports.isVirtualCoin = isVirtualCoin;
|
|
2632
|
+
exports.isVtxoSpent = isVtxoSpent;
|
|
2523
2633
|
exports.maybeArkError = maybeArkError;
|
|
2524
2634
|
exports.networkFromArkadeInfo = networkFromArkadeInfo;
|
|
2525
2635
|
exports.networks = networks;
|
|
2526
2636
|
exports.normalizeVtxo = normalizeVtxo;
|
|
2527
|
-
exports.parseLegacyExpiry = parseLegacyExpiry;
|
|
2528
2637
|
exports.rateGate = rateGate;
|
|
2638
|
+
exports.requiresForfeit = requiresForfeit;
|
|
2529
2639
|
exports.resolveEmulatorPubkey = resolveEmulatorPubkey;
|
|
2530
2640
|
exports.resolveEventSource = resolveEventSource;
|
|
2531
2641
|
exports.resolveTimeHeight = resolveTimeHeight;
|
|
2532
2642
|
exports.scriptFromTapLeafScript = scriptFromTapLeafScript;
|
|
2533
2643
|
exports.sdkVersion = sdkVersion;
|
|
2644
|
+
exports.sequenceToCanonicalTimelock = sequenceToCanonicalTimelock;
|
|
2534
2645
|
exports.sequenceToTimelock = sequenceToTimelock;
|
|
2535
2646
|
exports.setArkPsbtField = setArkPsbtField;
|
|
2536
2647
|
exports.throwIfHttpUnavailable = throwIfHttpUnavailable;
|
|
2537
2648
|
exports.timelockToSequence = timelockToSequence;
|
|
2538
|
-
exports.
|
|
2649
|
+
exports.toBIP371TapTree = toBIP371TapTree;
|
|
2539
2650
|
exports.toOffchainInputFeeParams = toOffchainInputFeeParams;
|
|
2540
2651
|
exports.toProviderUnavailable = toProviderUnavailable;
|
|
2541
|
-
|
|
2542
|
-
//# sourceMappingURL=chunk-
|
|
2543
|
-
//# sourceMappingURL=chunk-JZWLXNHV.cjs.map
|
|
2652
|
+
//# sourceMappingURL=chunk-T6N6B7HK.cjs.map
|
|
2653
|
+
//# sourceMappingURL=chunk-T6N6B7HK.cjs.map
|