@arkade-os/sdk 0.5.0-rc.9 → 0.5.1
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 +232 -51
- package/dist/adapters/expo.cjs +5 -5
- package/dist/adapters/expo.d.cts +5 -5
- package/dist/adapters/expo.d.ts +5 -5
- package/dist/adapters/expo.js +3 -3
- package/dist/{asyncStorageTaskQueue-DZYrAWN8.d.ts → asyncStorageTaskQueue-CdWheMqT.d.ts} +1 -1
- package/dist/{asyncStorageTaskQueue-ChKX-D51.d.cts → asyncStorageTaskQueue-DFt5LgW5.d.cts} +1 -1
- package/dist/{chunk-R4KRWX7R.js → chunk-3M22PJVB.js} +427 -1078
- package/dist/chunk-3M22PJVB.js.map +1 -0
- package/dist/{chunk-J2K7WWMJ.js → chunk-6MIGYYWB.js} +112 -243
- package/dist/chunk-6MIGYYWB.js.map +1 -0
- package/dist/{chunk-FQCMEAWN.js → chunk-FXVEOEYB.js} +32 -39
- package/dist/chunk-FXVEOEYB.js.map +1 -0
- package/dist/{chunk-7OL2P5TV.cjs → chunk-GQUFPTN7.cjs} +39 -46
- package/dist/chunk-GQUFPTN7.cjs.map +1 -0
- package/dist/{chunk-VMVHRKXM.cjs → chunk-GW42FS2X.cjs} +494 -1122
- package/dist/chunk-GW42FS2X.cjs.map +1 -0
- package/dist/{chunk-V4JZOFYT.cjs → chunk-HQNQ3CLQ.cjs} +124 -254
- package/dist/chunk-HQNQ3CLQ.cjs.map +1 -0
- package/dist/{chunk-PO2ZDZZC.cjs → chunk-JJ6QKTFZ.cjs} +12 -10
- package/dist/chunk-JJ6QKTFZ.cjs.map +1 -0
- package/dist/{chunk-3TCWQPAC.js → chunk-NKKJEA3Z.js} +5842 -4284
- package/dist/chunk-NKKJEA3Z.js.map +1 -0
- package/dist/{chunk-JFZBKPSV.js → chunk-QFB55EOZ.js} +541 -400
- package/dist/chunk-QFB55EOZ.js.map +1 -0
- package/dist/{chunk-PKD5VPYX.cjs → chunk-QKNSMVBW.cjs} +6143 -4565
- package/dist/chunk-QKNSMVBW.cjs.map +1 -0
- package/dist/{chunk-VTXMC4N7.cjs → chunk-XLHUGP3G.cjs} +548 -399
- package/dist/chunk-XLHUGP3G.cjs.map +1 -0
- package/dist/{chunk-Z3QM5XFY.js → chunk-XQRIY5K5.js} +7 -5
- package/dist/chunk-XQRIY5K5.js.map +1 -0
- package/dist/contracts/handlers/index.cjs +9 -9
- 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 -2
- package/dist/{delegate-CyBnNY9v.d.ts → delegate-BSbGQabI.d.ts} +1 -1
- package/dist/{delegate-Cyv2suFd.d.cts → delegate-CFCfrReG.d.cts} +1 -1
- package/dist/{index-BIL9boGL.d.ts → index-B3fRWO5i.d.cts} +1652 -2291
- package/dist/{index-BIL9boGL.d.cts → index-B3fRWO5i.d.ts} +1652 -2291
- package/dist/index-CzUVvIxA.d.ts +645 -0
- package/dist/index-Fpf4mQZr.d.cts +645 -0
- package/dist/index.cjs +399 -311
- package/dist/index.d.cts +957 -1124
- package/dist/index.d.ts +957 -1124
- package/dist/index.js +4 -4
- package/dist/repositories/realm/index.cjs +165 -103
- package/dist/repositories/realm/index.cjs.map +1 -1
- package/dist/repositories/realm/index.d.cts +18 -14
- package/dist/repositories/realm/index.d.ts +18 -14
- package/dist/repositories/realm/index.js +153 -91
- package/dist/repositories/realm/index.js.map +1 -1
- package/dist/repositories/sqlite/index.cjs +226 -184
- package/dist/repositories/sqlite/index.cjs.map +1 -1
- package/dist/repositories/sqlite/index.d.cts +22 -21
- package/dist/repositories/sqlite/index.d.ts +22 -21
- package/dist/repositories/sqlite/index.js +218 -176
- package/dist/repositories/sqlite/index.js.map +1 -1
- package/dist/{taskRunner-Cu4uO1to.d.ts → taskRunner-CdfoCMaw.d.ts} +1 -1
- package/dist/{taskRunner-DxpSuKmh.d.cts → taskRunner-Dk6oDAtd.d.cts} +1 -1
- package/dist/wallet/expo/background.cjs +14 -14
- 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 -6
- package/dist/wallet/expo/background.js.map +1 -1
- package/dist/wallet/expo/index.cjs +19 -14
- package/dist/wallet/expo/index.cjs.map +1 -1
- package/dist/wallet/expo/index.d.cts +8 -6
- package/dist/wallet/expo/index.d.ts +8 -6
- package/dist/wallet/expo/index.js +10 -5
- package/dist/wallet/expo/index.js.map +1 -1
- package/dist/wallet-BQHNgc_v.d.ts +1874 -0
- package/dist/wallet-D9dvXu-K.d.cts +1874 -0
- package/dist/worker/expo/index.cjs +9 -9
- 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 -5
- package/package.json +10 -11
- package/dist/chunk-3TCWQPAC.js.map +0 -1
- package/dist/chunk-7OL2P5TV.cjs.map +0 -1
- package/dist/chunk-FQCMEAWN.js.map +0 -1
- package/dist/chunk-J2K7WWMJ.js.map +0 -1
- package/dist/chunk-JFZBKPSV.js.map +0 -1
- package/dist/chunk-PKD5VPYX.cjs.map +0 -1
- package/dist/chunk-PO2ZDZZC.cjs.map +0 -1
- package/dist/chunk-R4KRWX7R.js.map +0 -1
- package/dist/chunk-V4JZOFYT.cjs.map +0 -1
- package/dist/chunk-VMVHRKXM.cjs.map +0 -1
- package/dist/chunk-VTXMC4N7.cjs.map +0 -1
- package/dist/chunk-Z3QM5XFY.js.map +0 -1
- package/dist/hdWalletCapable-D1ImQqlu.d.cts +0 -2214
- package/dist/hdWalletCapable-DvumVrKW.d.ts +0 -2214
- package/dist/index-DleNQcz5.d.cts +0 -850
- package/dist/index-QVhQgYvU.d.ts +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,191 +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
34
|
var __defProp = Object.defineProperty;
|
|
33
35
|
var __export = (target, all) => {
|
|
34
36
|
for (var name in all)
|
|
35
37
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
36
38
|
};
|
|
37
|
-
var Transaction = class extends btcSigner.Transaction {
|
|
38
|
-
static ARK_TX_OPTS = {
|
|
39
|
-
allowUnknown: true,
|
|
40
|
-
allowUnknownOutputs: true,
|
|
41
|
-
allowUnknownInputs: true
|
|
42
|
-
};
|
|
43
|
-
constructor(opts) {
|
|
44
|
-
super(withArkOpts(opts));
|
|
45
|
-
}
|
|
46
|
-
static fromPSBT(psbt_, opts) {
|
|
47
|
-
return btcSigner.Transaction.fromPSBT(psbt_, withArkOpts(opts));
|
|
48
|
-
}
|
|
49
|
-
static fromRaw(raw, opts) {
|
|
50
|
-
return btcSigner.Transaction.fromRaw(raw, withArkOpts(opts));
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
function withArkOpts(opts) {
|
|
54
|
-
return { ...Transaction.ARK_TX_OPTS, ...opts };
|
|
55
|
-
}
|
|
56
|
-
function formatSighash(type) {
|
|
57
|
-
return `0x${type.toString(16).padStart(2, "0")}`;
|
|
58
|
-
}
|
|
59
|
-
function assertAllowedSighashTypes(tx, allowedSighashTypes = [btcSigner.SigHash.DEFAULT]) {
|
|
60
|
-
for (let i = 0; i < tx.inputsLength; i++) {
|
|
61
|
-
const declared = tx.getInput(i).sighashType;
|
|
62
|
-
if (declared === void 0) continue;
|
|
63
|
-
if (!allowedSighashTypes.includes(declared)) {
|
|
64
|
-
throw new Error(`Unallowed sighash type ${formatSighash(declared)} for input ${i}.`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function timelockToSequence(timelock) {
|
|
69
|
-
return bip68__namespace.encode(
|
|
70
|
-
timelock.type === "blocks" ? { blocks: Number(timelock.value) } : { seconds: Number(timelock.value) }
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
function sequenceToTimelock(sequence) {
|
|
74
|
-
const decoded = bip68__namespace.decode(sequence);
|
|
75
|
-
if ("blocks" in decoded && decoded.blocks !== void 0) {
|
|
76
|
-
return { type: "blocks", value: BigInt(decoded.blocks) };
|
|
77
|
-
}
|
|
78
|
-
if ("seconds" in decoded && decoded.seconds !== void 0) {
|
|
79
|
-
return { type: "seconds", value: BigInt(decoded.seconds) };
|
|
80
|
-
}
|
|
81
|
-
throw new Error(`Invalid BIP68 sequence: ${sequence}`);
|
|
82
|
-
}
|
|
83
|
-
var ArkPsbtFieldKey = /* @__PURE__ */ ((ArkPsbtFieldKey2) => {
|
|
84
|
-
ArkPsbtFieldKey2["VtxoTaprootTree"] = "taptree";
|
|
85
|
-
ArkPsbtFieldKey2["VtxoTreeExpiry"] = "expiry";
|
|
86
|
-
ArkPsbtFieldKey2["Cosigner"] = "cosigner";
|
|
87
|
-
ArkPsbtFieldKey2["ConditionWitness"] = "condition";
|
|
88
|
-
ArkPsbtFieldKey2["PrevArkTx"] = "prevarktx";
|
|
89
|
-
ArkPsbtFieldKey2["PrevoutTx"] = "prevouttx";
|
|
90
|
-
return ArkPsbtFieldKey2;
|
|
91
|
-
})(ArkPsbtFieldKey || {});
|
|
92
|
-
var ArkPsbtFieldKeyType = 222;
|
|
93
|
-
function setArkPsbtField(tx, inputIndex, coder, value) {
|
|
94
|
-
tx.updateInput(inputIndex, {
|
|
95
|
-
unknown: [...tx.getInput(inputIndex)?.unknown ?? [], coder.encode(value)]
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
function getArkPsbtFields(tx, inputIndex, coder) {
|
|
99
|
-
const unknown = tx.getInput(inputIndex)?.unknown ?? [];
|
|
100
|
-
const fields = [];
|
|
101
|
-
for (const u of unknown) {
|
|
102
|
-
const v = coder.decode(u);
|
|
103
|
-
if (v !== null) fields.push(v);
|
|
104
|
-
}
|
|
105
|
-
return fields;
|
|
106
|
-
}
|
|
107
|
-
var VtxoTaprootTree = {
|
|
108
|
-
key: "taptree" /* VtxoTaprootTree */,
|
|
109
|
-
encode: (value) => [
|
|
110
|
-
{
|
|
111
|
-
type: ArkPsbtFieldKeyType,
|
|
112
|
-
key: encodedPsbtFieldKey["taptree" /* VtxoTaprootTree */]
|
|
113
|
-
},
|
|
114
|
-
value
|
|
115
|
-
],
|
|
116
|
-
decode: (value) => nullIfCatch(() => {
|
|
117
|
-
if (!checkKeyMatch(value[0], "taptree" /* VtxoTaprootTree */)) return null;
|
|
118
|
-
return value[1];
|
|
119
|
-
})
|
|
120
|
-
};
|
|
121
|
-
var ConditionWitness = {
|
|
122
|
-
key: "condition" /* ConditionWitness */,
|
|
123
|
-
encode: (value) => [
|
|
124
|
-
{
|
|
125
|
-
type: ArkPsbtFieldKeyType,
|
|
126
|
-
key: encodedPsbtFieldKey["condition" /* ConditionWitness */]
|
|
127
|
-
},
|
|
128
|
-
btcSigner.RawWitness.encode(value)
|
|
129
|
-
],
|
|
130
|
-
decode: (value) => nullIfCatch(() => {
|
|
131
|
-
if (!checkKeyMatch(value[0], "condition" /* ConditionWitness */)) return null;
|
|
132
|
-
return btcSigner.RawWitness.decode(value[1]);
|
|
133
|
-
})
|
|
134
|
-
};
|
|
135
|
-
var PrevArkTxField = {
|
|
136
|
-
key: "prevarktx" /* PrevArkTx */,
|
|
137
|
-
encode: (value) => [
|
|
138
|
-
{
|
|
139
|
-
type: ArkPsbtFieldKeyType,
|
|
140
|
-
key: encodedPsbtFieldKey["prevarktx" /* PrevArkTx */]
|
|
141
|
-
},
|
|
142
|
-
value
|
|
143
|
-
],
|
|
144
|
-
decode: (value) => nullIfCatch(() => {
|
|
145
|
-
if (!checkKeyMatch(value[0], "prevarktx" /* PrevArkTx */)) return null;
|
|
146
|
-
return value[1];
|
|
147
|
-
})
|
|
148
|
-
};
|
|
149
|
-
var PrevoutTxField = {
|
|
150
|
-
key: "prevouttx" /* PrevoutTx */,
|
|
151
|
-
encode: (value) => [
|
|
152
|
-
{
|
|
153
|
-
type: ArkPsbtFieldKeyType,
|
|
154
|
-
key: encodedPsbtFieldKey["prevouttx" /* PrevoutTx */]
|
|
155
|
-
},
|
|
156
|
-
value
|
|
157
|
-
],
|
|
158
|
-
decode: (value) => nullIfCatch(() => {
|
|
159
|
-
if (!checkKeyMatch(value[0], "prevouttx" /* PrevoutTx */)) return null;
|
|
160
|
-
return value[1];
|
|
161
|
-
})
|
|
162
|
-
};
|
|
163
|
-
var CosignerPublicKey = {
|
|
164
|
-
key: "cosigner" /* Cosigner */,
|
|
165
|
-
encode: (value) => [
|
|
166
|
-
{
|
|
167
|
-
type: ArkPsbtFieldKeyType,
|
|
168
|
-
key: new Uint8Array([...encodedPsbtFieldKey["cosigner" /* Cosigner */], value.index])
|
|
169
|
-
},
|
|
170
|
-
value.key
|
|
171
|
-
],
|
|
172
|
-
decode: (unknown) => nullIfCatch(() => {
|
|
173
|
-
if (!checkKeyMatch(unknown[0], "cosigner" /* Cosigner */, true)) return null;
|
|
174
|
-
return {
|
|
175
|
-
index: unknown[0].key[unknown[0].key.length - 1],
|
|
176
|
-
key: unknown[1]
|
|
177
|
-
};
|
|
178
|
-
})
|
|
179
|
-
};
|
|
180
|
-
var VtxoTreeExpiry = {
|
|
181
|
-
key: "expiry" /* VtxoTreeExpiry */,
|
|
182
|
-
encode: (value) => [
|
|
183
|
-
{
|
|
184
|
-
type: ArkPsbtFieldKeyType,
|
|
185
|
-
key: encodedPsbtFieldKey["expiry" /* VtxoTreeExpiry */]
|
|
186
|
-
},
|
|
187
|
-
btcSigner.ScriptNum(6, true).encode(value.value === 0n ? 0n : value.value)
|
|
188
|
-
],
|
|
189
|
-
decode: (unknown) => nullIfCatch(() => {
|
|
190
|
-
if (!checkKeyMatch(unknown[0], "expiry" /* VtxoTreeExpiry */)) return null;
|
|
191
|
-
const v = btcSigner.ScriptNum(6, true).decode(unknown[1]);
|
|
192
|
-
if (!v) return null;
|
|
193
|
-
return sequenceToTimelock(Number(v));
|
|
194
|
-
})
|
|
195
|
-
};
|
|
196
|
-
var encodedPsbtFieldKey = Object.fromEntries(
|
|
197
|
-
Object.values(ArkPsbtFieldKey).map((key) => [key, new TextEncoder().encode(key)])
|
|
198
|
-
);
|
|
199
|
-
var nullIfCatch = (fn) => {
|
|
200
|
-
try {
|
|
201
|
-
return fn();
|
|
202
|
-
} catch {
|
|
203
|
-
return null;
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
function checkKeyMatch(key, arkPsbtFieldKey, prefixOnly = false) {
|
|
207
|
-
if (key.type !== ArkPsbtFieldKeyType) return false;
|
|
208
|
-
const expected = encodedPsbtFieldKey[arkPsbtFieldKey];
|
|
209
|
-
if (key.key.length < expected.length) return false;
|
|
210
|
-
if (!prefixOnly && key.key.length !== expected.length) return false;
|
|
211
|
-
for (let i = 0; i < expected.length; i++) {
|
|
212
|
-
if (key.key[i] !== expected[i]) return false;
|
|
213
|
-
}
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
39
|
var getNetwork = (network) => {
|
|
217
40
|
const found = networks[network];
|
|
218
41
|
if (!found) throw new Error(`Unsupported network: ${network}`);
|
|
@@ -243,6 +66,7 @@ function withArkPrefix(network, prefix, name) {
|
|
|
243
66
|
};
|
|
244
67
|
}
|
|
245
68
|
var DEFAULT_ARKADE_SERVER_URL = "https://arkade.computer";
|
|
69
|
+
var DEFAULT_ARKADE_EMULATOR_URL = "https://emulator.arkade.computer";
|
|
246
70
|
var DEFAULT_NETWORK = networks.bitcoin;
|
|
247
71
|
var DEFAULT_NETWORK_NAME = "bitcoin";
|
|
248
72
|
var COMPRESSED_PUBKEY = /^0[23][0-9a-f]{64}$/;
|
|
@@ -349,6 +173,26 @@ var ArkAddress = class _ArkAddress {
|
|
|
349
173
|
return script_js.Script.encode(["RETURN", this.vtxoTaprootKey]);
|
|
350
174
|
}
|
|
351
175
|
};
|
|
176
|
+
function timelockToSequence(timelock) {
|
|
177
|
+
return bip68__namespace.encode(
|
|
178
|
+
timelock.type === "blocks" ? { blocks: Number(timelock.value) } : { seconds: Number(timelock.value) }
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
function sequenceToTimelock(sequence) {
|
|
182
|
+
const decoded = bip68__namespace.decode(sequence);
|
|
183
|
+
if ("blocks" in decoded && decoded.blocks !== void 0) {
|
|
184
|
+
return { type: "blocks", value: BigInt(decoded.blocks) };
|
|
185
|
+
}
|
|
186
|
+
if ("seconds" in decoded && decoded.seconds !== void 0) {
|
|
187
|
+
return { type: "seconds", value: BigInt(decoded.seconds) };
|
|
188
|
+
}
|
|
189
|
+
throw new Error(`Invalid BIP68 sequence: ${sequence}`);
|
|
190
|
+
}
|
|
191
|
+
function sequenceToCanonicalTimelock(sequence) {
|
|
192
|
+
if (sequence < 0n || sequence >= 0x80000000n) return void 0;
|
|
193
|
+
const timelock = sequenceToTimelock(Number(sequence));
|
|
194
|
+
return BigInt(timelockToSequence(timelock)) === sequence ? timelock : void 0;
|
|
195
|
+
}
|
|
352
196
|
var MinimalScriptNum = btcSigner.ScriptNum(void 0, true);
|
|
353
197
|
function decodeTapscript(script) {
|
|
354
198
|
const types = [
|
|
@@ -596,6 +440,16 @@ exports.CSVMultisigTapscript = void 0;
|
|
|
596
440
|
}
|
|
597
441
|
CSVMultisigTapscript2.isScriptValid = isScriptValid;
|
|
598
442
|
})(exports.CSVMultisigTapscript || (exports.CSVMultisigTapscript = {}));
|
|
443
|
+
function isConditionScriptValid(script) {
|
|
444
|
+
const asm = btcSigner.Script.decode(script);
|
|
445
|
+
if (asm.length < 1) {
|
|
446
|
+
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
447
|
+
}
|
|
448
|
+
if (asm.lastIndexOf("VERIFY") === -1) {
|
|
449
|
+
return new Error("Invalid script: missing VERIFY operation");
|
|
450
|
+
}
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
599
453
|
exports.ConditionCSVMultisigTapscript = void 0;
|
|
600
454
|
((ConditionCSVMultisigTapscript2) => {
|
|
601
455
|
function encode2(params) {
|
|
@@ -620,7 +474,7 @@ exports.ConditionCSVMultisigTapscript = void 0;
|
|
|
620
474
|
throw isValid;
|
|
621
475
|
}
|
|
622
476
|
const asm = btcSigner.Script.decode(script);
|
|
623
|
-
|
|
477
|
+
const verifyIndex = asm.lastIndexOf("VERIFY");
|
|
624
478
|
if (verifyIndex === -1) {
|
|
625
479
|
throw Error("Invalid script: missing VERIFY operation");
|
|
626
480
|
}
|
|
@@ -655,26 +509,8 @@ exports.ConditionCSVMultisigTapscript = void 0;
|
|
|
655
509
|
return tapscript.type === "condition-csv-multisig" /* ConditionCSVMultisig */;
|
|
656
510
|
}
|
|
657
511
|
ConditionCSVMultisigTapscript2.is = is;
|
|
658
|
-
function getVerifyIndex(asm) {
|
|
659
|
-
let verifyIndex = -1;
|
|
660
|
-
for (let i = asm.length - 1; i >= 0; i--) {
|
|
661
|
-
if (asm[i] === "VERIFY") {
|
|
662
|
-
verifyIndex = i;
|
|
663
|
-
return verifyIndex;
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
return verifyIndex;
|
|
667
|
-
}
|
|
668
512
|
function isScriptValid(script) {
|
|
669
|
-
|
|
670
|
-
if (asm.length < 1) {
|
|
671
|
-
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
672
|
-
}
|
|
673
|
-
let verifyIndex = getVerifyIndex(asm);
|
|
674
|
-
if (verifyIndex === -1) {
|
|
675
|
-
return new Error("Invalid script: missing VERIFY operation");
|
|
676
|
-
}
|
|
677
|
-
return true;
|
|
513
|
+
return isConditionScriptValid(script);
|
|
678
514
|
}
|
|
679
515
|
ConditionCSVMultisigTapscript2.isScriptValid = isScriptValid;
|
|
680
516
|
})(exports.ConditionCSVMultisigTapscript || (exports.ConditionCSVMultisigTapscript = {}));
|
|
@@ -702,7 +538,7 @@ exports.ConditionMultisigTapscript = void 0;
|
|
|
702
538
|
throw isValid;
|
|
703
539
|
}
|
|
704
540
|
const asm = btcSigner.Script.decode(script);
|
|
705
|
-
|
|
541
|
+
const verifyIndex = asm.lastIndexOf("VERIFY");
|
|
706
542
|
if (verifyIndex === -1) {
|
|
707
543
|
throw Error("Invalid script: missing VERIFY operation");
|
|
708
544
|
}
|
|
@@ -737,26 +573,8 @@ exports.ConditionMultisigTapscript = void 0;
|
|
|
737
573
|
return tapscript.type === "condition-multisig" /* ConditionMultisig */;
|
|
738
574
|
}
|
|
739
575
|
ConditionMultisigTapscript2.is = is;
|
|
740
|
-
function getVerifyIndex(asm) {
|
|
741
|
-
let verifyIndex = -1;
|
|
742
|
-
for (let i = asm.length - 1; i >= 0; i--) {
|
|
743
|
-
if (asm[i] === "VERIFY") {
|
|
744
|
-
verifyIndex = i;
|
|
745
|
-
return verifyIndex;
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
return verifyIndex;
|
|
749
|
-
}
|
|
750
576
|
function isScriptValid(script) {
|
|
751
|
-
|
|
752
|
-
if (asm.length < 1) {
|
|
753
|
-
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
754
|
-
}
|
|
755
|
-
let verifyIndex = getVerifyIndex(asm);
|
|
756
|
-
if (verifyIndex === -1) {
|
|
757
|
-
return new Error("Invalid script: missing VERIFY operation");
|
|
758
|
-
}
|
|
759
|
-
return true;
|
|
577
|
+
return isConditionScriptValid(script);
|
|
760
578
|
}
|
|
761
579
|
ConditionMultisigTapscript2.isScriptValid = isScriptValid;
|
|
762
580
|
})(exports.ConditionMultisigTapscript || (exports.ConditionMultisigTapscript = {}));
|
|
@@ -881,7 +699,25 @@ function assembleBtcdTaprootTree(scripts) {
|
|
|
881
699
|
}
|
|
882
700
|
return branches[0];
|
|
883
701
|
}
|
|
884
|
-
|
|
702
|
+
function btcdLeafLayout(count) {
|
|
703
|
+
const placeholders = Array.from({ length: count }, () => new Uint8Array());
|
|
704
|
+
const indexOf = new Map(placeholders.map((script, index) => [script, index]));
|
|
705
|
+
const layout = [];
|
|
706
|
+
const walk = (node, depth) => {
|
|
707
|
+
if (Array.isArray(node)) {
|
|
708
|
+
walk(node[0], depth + 1);
|
|
709
|
+
walk(node[1], depth + 1);
|
|
710
|
+
} else {
|
|
711
|
+
layout.push({ index: indexOf.get(node.script), depth });
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
walk(assembleBtcdTaprootTree(placeholders), 0);
|
|
715
|
+
return layout;
|
|
716
|
+
}
|
|
717
|
+
var TapTreeCoder = P__namespace.array(
|
|
718
|
+
null,
|
|
719
|
+
P__namespace.struct({ depth: P__namespace.U8, version: P__namespace.U8, script: script_js.VarBytes })
|
|
720
|
+
);
|
|
885
721
|
function scriptFromTapLeafScript(leaf) {
|
|
886
722
|
return leaf[1].subarray(0, leaf[1].length - 1);
|
|
887
723
|
}
|
|
@@ -901,7 +737,7 @@ var VtxoScript = class _VtxoScript {
|
|
|
901
737
|
constructor(scripts) {
|
|
902
738
|
this.scripts = scripts;
|
|
903
739
|
const tapTree = assembleBtcdTaprootTree(scripts);
|
|
904
|
-
const payment = btcSigner.p2tr(btcSigner.
|
|
740
|
+
const payment = btcSigner.p2tr(btcSigner.taprootNumsKey(), tapTree, void 0, true);
|
|
905
741
|
if (!payment.tapLeafScript || payment.tapLeafScript.length !== scripts.length) {
|
|
906
742
|
throw new Error("invalid scripts");
|
|
907
743
|
}
|
|
@@ -916,15 +752,46 @@ var VtxoScript = class _VtxoScript {
|
|
|
916
752
|
/**
|
|
917
753
|
* Decode a virtual output script from an encoded TapTree.
|
|
918
754
|
*
|
|
755
|
+
* Leaves are normally read in construction order and their depths
|
|
756
|
+
* ignored: that covers the {@link encode} form (every depth 1) and the
|
|
757
|
+
* placeholder depths other writers use, such as arkd's. The exception is
|
|
758
|
+
* the BIP-371 form {@link toBIP371TapTree} writes, whose leaves are in the
|
|
759
|
+
* tree's DFS order: for some leaf counts (6, 7, 10, ...) that differs from
|
|
760
|
+
* construction order. A tree whose depths are exactly the shape
|
|
761
|
+
* `assembleBtcdTaprootTree` builds is that form, so its leaves are mapped
|
|
762
|
+
* back to construction order first. No construction-order writer produces
|
|
763
|
+
* that depth sequence when the two orders differ, so this never reorders
|
|
764
|
+
* a tree that decoded correctly before.
|
|
765
|
+
*
|
|
766
|
+
* Every leaf must carry the base tapscript version: the tree is rebuilt
|
|
767
|
+
* with {@link TAP_LEAF_VERSION} leaves, so any other version would
|
|
768
|
+
* silently derive a different taproot key.
|
|
769
|
+
*
|
|
919
770
|
* @param tapTree - Encoded TapTree bytes
|
|
920
771
|
* @returns Decoded virtual output script
|
|
921
772
|
* @throws Error if the TapTree cannot be decoded into a valid script set
|
|
773
|
+
* or a leaf carries a version other than {@link TAP_LEAF_VERSION}
|
|
922
774
|
* @see encode
|
|
923
775
|
*/
|
|
924
776
|
static decode(tapTree) {
|
|
925
777
|
const leaves = TapTreeCoder.decode(tapTree);
|
|
778
|
+
const foreign = leaves.find((leaf) => leaf.version !== payment_js.TAP_LEAF_VERSION);
|
|
779
|
+
if (foreign) {
|
|
780
|
+
throw new Error(`unsupported tap leaf version 0x${foreign.version.toString(16)}`);
|
|
781
|
+
}
|
|
926
782
|
const scripts = leaves.map((leaf) => leaf.script);
|
|
927
|
-
|
|
783
|
+
if (leaves.every((leaf) => leaf.depth === 1)) {
|
|
784
|
+
return new _VtxoScript(scripts);
|
|
785
|
+
}
|
|
786
|
+
const layout = btcdLeafLayout(leaves.length);
|
|
787
|
+
if (layout.some((slot, i) => slot.depth !== leaves[i].depth)) {
|
|
788
|
+
return new _VtxoScript(scripts);
|
|
789
|
+
}
|
|
790
|
+
const ordered = new Array(leaves.length);
|
|
791
|
+
layout.forEach((slot, i) => {
|
|
792
|
+
ordered[slot.index] = scripts[i];
|
|
793
|
+
});
|
|
794
|
+
return new _VtxoScript(ordered);
|
|
928
795
|
}
|
|
929
796
|
/**
|
|
930
797
|
* Encode the virtual output script to a TapTree byte representation.
|
|
@@ -1007,21 +874,323 @@ var VtxoScript = class _VtxoScript {
|
|
|
1007
874
|
return paths;
|
|
1008
875
|
}
|
|
1009
876
|
};
|
|
1010
|
-
function
|
|
1011
|
-
|
|
877
|
+
function toBIP371TapTree(tapTree) {
|
|
878
|
+
const scripts = TapTreeCoder.decode(tapTree).map((leaf) => leaf.script);
|
|
879
|
+
const vtxoScript = new VtxoScript(scripts);
|
|
880
|
+
return vtxoScript.leaves.map((leaf) => ({
|
|
881
|
+
depth: leaf[0].merklePath.length,
|
|
882
|
+
version: payment_js.TAP_LEAF_VERSION,
|
|
883
|
+
script: scriptFromTapLeafScript(leaf)
|
|
884
|
+
}));
|
|
885
|
+
}
|
|
886
|
+
function getSequence(tapLeafScript) {
|
|
887
|
+
let sequence = void 0;
|
|
888
|
+
try {
|
|
889
|
+
const scriptWithLeafVersion = tapLeafScript[1];
|
|
890
|
+
const script = scriptWithLeafVersion.subarray(0, scriptWithLeafVersion.length - 1);
|
|
891
|
+
try {
|
|
892
|
+
const params = exports.CSVMultisigTapscript.decode(script).params;
|
|
893
|
+
sequence = timelockToSequence(params.timelock);
|
|
894
|
+
} catch {
|
|
895
|
+
const params = exports.CLTVMultisigTapscript.decode(script).params;
|
|
896
|
+
sequence = Number(params.absoluteTimelock);
|
|
897
|
+
}
|
|
898
|
+
} catch {
|
|
899
|
+
}
|
|
900
|
+
return sequence;
|
|
901
|
+
}
|
|
902
|
+
var Transaction = class extends btcSigner.Transaction {
|
|
903
|
+
static ARK_TX_OPTS = {
|
|
904
|
+
unknown: "ignore",
|
|
905
|
+
allowUnknownOutputs: true,
|
|
906
|
+
allowUnknownInputs: true
|
|
907
|
+
};
|
|
908
|
+
constructor(opts) {
|
|
909
|
+
super(withArkOpts(opts));
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Decode a PSBT. PSBTs carrying a legacy `PSBT_OUT_TAP_TREE` (see
|
|
913
|
+
* {@link repairLegacyOutputTapTrees}) are repaired and decoded again
|
|
914
|
+
* instead of being rejected.
|
|
915
|
+
*/
|
|
916
|
+
static fromPSBT(psbt_, opts) {
|
|
917
|
+
try {
|
|
918
|
+
return btcSigner.Transaction.fromPSBT(psbt_, withArkOpts(opts));
|
|
919
|
+
} catch (err) {
|
|
920
|
+
const repaired = repairLegacyOutputTapTrees(psbt_);
|
|
921
|
+
if (!repaired) throw err;
|
|
922
|
+
return btcSigner.Transaction.fromPSBT(repaired, withArkOpts(opts));
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
static fromRaw(raw, opts) {
|
|
926
|
+
return btcSigner.Transaction.fromRaw(raw, withArkOpts(opts));
|
|
927
|
+
}
|
|
928
|
+
};
|
|
929
|
+
function withArkOpts(opts) {
|
|
930
|
+
return { ...Transaction.ARK_TX_OPTS, ...opts };
|
|
931
|
+
}
|
|
932
|
+
var PSBT_MAGIC = new Uint8Array([112, 115, 98, 116, 255]);
|
|
933
|
+
var PSBT_GLOBAL_UNSIGNED_TX = 0;
|
|
934
|
+
var PSBT_GLOBAL_INPUT_COUNT = 4;
|
|
935
|
+
var PSBT_OUT_TAP_TREE = 6;
|
|
936
|
+
function repairLegacyOutputTapTrees(psbt) {
|
|
937
|
+
let maps;
|
|
938
|
+
let inputsCount;
|
|
939
|
+
try {
|
|
940
|
+
maps = readPsbtMaps(psbt);
|
|
941
|
+
inputsCount = psbtInputsCount(maps[0]);
|
|
942
|
+
} catch {
|
|
943
|
+
return void 0;
|
|
944
|
+
}
|
|
945
|
+
let repaired = false;
|
|
946
|
+
for (const output of maps.slice(1 + inputsCount)) {
|
|
947
|
+
for (const kv of output) {
|
|
948
|
+
if (kv.key.length !== 1 || kv.key[0] !== PSBT_OUT_TAP_TREE) continue;
|
|
949
|
+
const value = legacyTapTreeToBIP371(kv.value);
|
|
950
|
+
if (!value) continue;
|
|
951
|
+
kv.value = value;
|
|
952
|
+
repaired = true;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
return repaired ? writePsbtMaps(maps) : void 0;
|
|
956
|
+
}
|
|
957
|
+
function legacyTapTreeToBIP371(value) {
|
|
958
|
+
try {
|
|
959
|
+
psbt_js.PSBTOutput.tapTree[2].decode(value);
|
|
960
|
+
return void 0;
|
|
961
|
+
} catch {
|
|
962
|
+
}
|
|
963
|
+
let leaves;
|
|
964
|
+
try {
|
|
965
|
+
leaves = TapTreeCoder.decode(value);
|
|
966
|
+
} catch {
|
|
967
|
+
return void 0;
|
|
968
|
+
}
|
|
969
|
+
if (leaves.length === 0 || leaves.some((leaf) => leaf.depth !== 1)) return void 0;
|
|
970
|
+
try {
|
|
971
|
+
return TapTreeCoder.encode(toBIP371TapTree(value));
|
|
972
|
+
} catch {
|
|
973
|
+
return void 0;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
function psbtInputsCount(global) {
|
|
977
|
+
for (const { key, value } of global) {
|
|
978
|
+
if (key.length !== 1) continue;
|
|
979
|
+
if (key[0] === PSBT_GLOBAL_UNSIGNED_TX) return btcSigner.RawTx.decode(value).inputs.length;
|
|
980
|
+
if (key[0] === PSBT_GLOBAL_INPUT_COUNT) return readCompactSize(value, 0)[0];
|
|
981
|
+
}
|
|
982
|
+
throw new Error("PSBT: missing input count");
|
|
983
|
+
}
|
|
984
|
+
function readPsbtMaps(psbt) {
|
|
985
|
+
for (let i = 0; i < PSBT_MAGIC.length; i++) {
|
|
986
|
+
if (psbt[i] !== PSBT_MAGIC[i]) throw new Error("PSBT: invalid magic");
|
|
987
|
+
}
|
|
988
|
+
const maps = [];
|
|
989
|
+
let pos = PSBT_MAGIC.length;
|
|
990
|
+
while (pos < psbt.length) {
|
|
991
|
+
const map = [];
|
|
992
|
+
for (; ; ) {
|
|
993
|
+
const [keyLen, afterKeyLen] = readCompactSize(psbt, pos);
|
|
994
|
+
pos = afterKeyLen;
|
|
995
|
+
if (keyLen === 0) break;
|
|
996
|
+
const key = readBytes(psbt, pos, keyLen);
|
|
997
|
+
pos += keyLen;
|
|
998
|
+
const [valueLen, afterValueLen] = readCompactSize(psbt, pos);
|
|
999
|
+
pos = afterValueLen;
|
|
1000
|
+
const value = readBytes(psbt, pos, valueLen);
|
|
1001
|
+
pos += valueLen;
|
|
1002
|
+
map.push({ key, value });
|
|
1003
|
+
}
|
|
1004
|
+
maps.push(map);
|
|
1005
|
+
}
|
|
1006
|
+
if (maps.length === 0) throw new Error("PSBT: missing global map");
|
|
1007
|
+
return maps;
|
|
1008
|
+
}
|
|
1009
|
+
function writePsbtMaps(maps) {
|
|
1010
|
+
const parts = [PSBT_MAGIC];
|
|
1011
|
+
for (const map of maps) {
|
|
1012
|
+
for (const { key, value } of map) {
|
|
1013
|
+
parts.push(writeCompactSize(key.length), key, writeCompactSize(value.length), value);
|
|
1014
|
+
}
|
|
1015
|
+
parts.push(new Uint8Array([0]));
|
|
1016
|
+
}
|
|
1017
|
+
return utils_js.concatBytes(...parts);
|
|
1018
|
+
}
|
|
1019
|
+
function readBytes(data, pos, len) {
|
|
1020
|
+
if (pos + len > data.length) throw new Error("PSBT: unexpected end of data");
|
|
1021
|
+
return data.slice(pos, pos + len);
|
|
1022
|
+
}
|
|
1023
|
+
function readCompactSize(data, pos) {
|
|
1024
|
+
const first = readBytes(data, pos, 1)[0];
|
|
1025
|
+
if (first < 253) return [first, pos + 1];
|
|
1026
|
+
const width = first === 253 ? 2 : first === 254 ? 4 : 8;
|
|
1027
|
+
const bytes = readBytes(data, pos + 1, width);
|
|
1028
|
+
let value = 0;
|
|
1029
|
+
for (let i = width - 1; i >= 0; i--) value = value * 256 + bytes[i];
|
|
1030
|
+
if (!Number.isSafeInteger(value)) throw new Error("PSBT: compact size too large");
|
|
1031
|
+
return [value, pos + 1 + width];
|
|
1032
|
+
}
|
|
1033
|
+
function writeCompactSize(value) {
|
|
1034
|
+
if (value < 253) return new Uint8Array([value]);
|
|
1035
|
+
const width = value <= 65535 ? 2 : value <= 4294967295 ? 4 : 8;
|
|
1036
|
+
const out = new Uint8Array(1 + width);
|
|
1037
|
+
out[0] = width === 2 ? 253 : width === 4 ? 254 : 255;
|
|
1038
|
+
for (let i = 0, v = value; i < width; i++, v = Math.floor(v / 256)) out[1 + i] = v % 256;
|
|
1039
|
+
return out;
|
|
1040
|
+
}
|
|
1041
|
+
function formatSighash(type) {
|
|
1042
|
+
return `0x${type.toString(16).padStart(2, "0")}`;
|
|
1043
|
+
}
|
|
1044
|
+
function assertAllowedSighashTypes(tx, allowedSighashTypes = [btcSigner.SigHash.DEFAULT]) {
|
|
1045
|
+
for (let i = 0; i < tx.inputsLength; i++) {
|
|
1046
|
+
const declared = tx.getInput(i).sighashType;
|
|
1047
|
+
if (declared === void 0) continue;
|
|
1048
|
+
if (!allowedSighashTypes.includes(declared)) {
|
|
1049
|
+
throw new Error(`Unallowed sighash type ${formatSighash(declared)} for input ${i}.`);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
// src/utils/time.ts
|
|
1055
|
+
function assertNonNegativeMs(name, ms) {
|
|
1056
|
+
if (ms !== void 0 && (!Number.isSafeInteger(ms) || ms < 0)) {
|
|
1057
|
+
throw new Error(`${name} must be a non-negative safe integer`);
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
var MAX_TIMER_MS = 2 ** 31 - 1;
|
|
1061
|
+
function assertTimerMs(name, ms) {
|
|
1062
|
+
assertNonNegativeMs(name, ms);
|
|
1063
|
+
if (ms !== void 0 && ms > MAX_TIMER_MS) {
|
|
1064
|
+
throw new Error(`${name} must not exceed ${MAX_TIMER_MS} milliseconds`);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
var ArkPsbtFieldKey = /* @__PURE__ */ ((ArkPsbtFieldKey2) => {
|
|
1068
|
+
ArkPsbtFieldKey2["VtxoTaprootTree"] = "taptree";
|
|
1069
|
+
ArkPsbtFieldKey2["VtxoTreeExpiry"] = "expiry";
|
|
1070
|
+
ArkPsbtFieldKey2["Cosigner"] = "cosigner";
|
|
1071
|
+
ArkPsbtFieldKey2["ConditionWitness"] = "condition";
|
|
1072
|
+
ArkPsbtFieldKey2["PrevArkTx"] = "prevarktx";
|
|
1073
|
+
ArkPsbtFieldKey2["PrevoutTx"] = "prevouttx";
|
|
1074
|
+
return ArkPsbtFieldKey2;
|
|
1075
|
+
})(ArkPsbtFieldKey || {});
|
|
1076
|
+
var ArkPsbtFieldKeyType = 222;
|
|
1077
|
+
function setArkPsbtField(tx, inputIndex, coder, value) {
|
|
1078
|
+
tx.updateInput(inputIndex, {
|
|
1079
|
+
unknown: [...tx.getInput(inputIndex)?.unknown ?? [], coder.encode(value)]
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
function getArkPsbtFields(tx, inputIndex, coder) {
|
|
1083
|
+
const unknown = tx.getInput(inputIndex)?.unknown ?? [];
|
|
1084
|
+
return unknown.map((u) => coder.decode(u)).filter((v) => v !== null);
|
|
1085
|
+
}
|
|
1086
|
+
var VtxoTaprootTree = {
|
|
1087
|
+
key: "taptree" /* VtxoTaprootTree */,
|
|
1088
|
+
encode: (value) => [
|
|
1089
|
+
{
|
|
1090
|
+
type: ArkPsbtFieldKeyType,
|
|
1091
|
+
key: encodedPsbtFieldKey["taptree" /* VtxoTaprootTree */]
|
|
1092
|
+
},
|
|
1093
|
+
value
|
|
1094
|
+
],
|
|
1095
|
+
decode: (value) => nullIfCatch(() => {
|
|
1096
|
+
if (!checkKeyMatch(value[0], "taptree" /* VtxoTaprootTree */)) return null;
|
|
1097
|
+
return value[1];
|
|
1098
|
+
})
|
|
1099
|
+
};
|
|
1100
|
+
var ConditionWitness = {
|
|
1101
|
+
key: "condition" /* ConditionWitness */,
|
|
1102
|
+
encode: (value) => [
|
|
1103
|
+
{
|
|
1104
|
+
type: ArkPsbtFieldKeyType,
|
|
1105
|
+
key: encodedPsbtFieldKey["condition" /* ConditionWitness */]
|
|
1106
|
+
},
|
|
1107
|
+
btcSigner.RawWitness.encode(value)
|
|
1108
|
+
],
|
|
1109
|
+
decode: (value) => nullIfCatch(() => {
|
|
1110
|
+
if (!checkKeyMatch(value[0], "condition" /* ConditionWitness */)) return null;
|
|
1111
|
+
return btcSigner.RawWitness.decode(value[1]);
|
|
1112
|
+
})
|
|
1113
|
+
};
|
|
1114
|
+
var PrevArkTxField = {
|
|
1115
|
+
key: "prevarktx" /* PrevArkTx */,
|
|
1116
|
+
encode: (value) => [
|
|
1117
|
+
{
|
|
1118
|
+
type: ArkPsbtFieldKeyType,
|
|
1119
|
+
key: encodedPsbtFieldKey["prevarktx" /* PrevArkTx */]
|
|
1120
|
+
},
|
|
1121
|
+
value
|
|
1122
|
+
],
|
|
1123
|
+
decode: (value) => nullIfCatch(() => {
|
|
1124
|
+
if (!checkKeyMatch(value[0], "prevarktx" /* PrevArkTx */)) return null;
|
|
1125
|
+
return value[1];
|
|
1126
|
+
})
|
|
1127
|
+
};
|
|
1128
|
+
var PrevoutTxField = {
|
|
1129
|
+
key: "prevouttx" /* PrevoutTx */,
|
|
1130
|
+
encode: (value) => [
|
|
1131
|
+
{
|
|
1132
|
+
type: ArkPsbtFieldKeyType,
|
|
1133
|
+
key: encodedPsbtFieldKey["prevouttx" /* PrevoutTx */]
|
|
1134
|
+
},
|
|
1135
|
+
value
|
|
1136
|
+
],
|
|
1137
|
+
decode: (value) => nullIfCatch(() => {
|
|
1138
|
+
if (!checkKeyMatch(value[0], "prevouttx" /* PrevoutTx */)) return null;
|
|
1139
|
+
return value[1];
|
|
1140
|
+
})
|
|
1141
|
+
};
|
|
1142
|
+
var CosignerPublicKey = {
|
|
1143
|
+
key: "cosigner" /* Cosigner */,
|
|
1144
|
+
encode: (value) => [
|
|
1145
|
+
{
|
|
1146
|
+
type: ArkPsbtFieldKeyType,
|
|
1147
|
+
key: new Uint8Array([...encodedPsbtFieldKey["cosigner" /* Cosigner */], value.index])
|
|
1148
|
+
},
|
|
1149
|
+
value.key
|
|
1150
|
+
],
|
|
1151
|
+
decode: (unknown) => nullIfCatch(() => {
|
|
1152
|
+
if (!checkKeyMatch(unknown[0], "cosigner" /* Cosigner */, true)) return null;
|
|
1153
|
+
return {
|
|
1154
|
+
index: unknown[0].key[unknown[0].key.length - 1],
|
|
1155
|
+
key: unknown[1]
|
|
1156
|
+
};
|
|
1157
|
+
})
|
|
1158
|
+
};
|
|
1159
|
+
var VtxoTreeExpiry = {
|
|
1160
|
+
key: "expiry" /* VtxoTreeExpiry */,
|
|
1161
|
+
encode: (value) => [
|
|
1162
|
+
{
|
|
1163
|
+
type: ArkPsbtFieldKeyType,
|
|
1164
|
+
key: encodedPsbtFieldKey["expiry" /* VtxoTreeExpiry */]
|
|
1165
|
+
},
|
|
1166
|
+
btcSigner.ScriptNum(6, true).encode(value.value)
|
|
1167
|
+
],
|
|
1168
|
+
decode: (unknown) => nullIfCatch(() => {
|
|
1169
|
+
if (!checkKeyMatch(unknown[0], "expiry" /* VtxoTreeExpiry */)) return null;
|
|
1170
|
+
const v = btcSigner.ScriptNum(6, true).decode(unknown[1]);
|
|
1171
|
+
if (!v) return null;
|
|
1172
|
+
return sequenceToTimelock(Number(v));
|
|
1173
|
+
})
|
|
1174
|
+
};
|
|
1175
|
+
var encodedPsbtFieldKey = Object.fromEntries(
|
|
1176
|
+
Object.values(ArkPsbtFieldKey).map((key) => [key, new TextEncoder().encode(key)])
|
|
1177
|
+
);
|
|
1178
|
+
var nullIfCatch = (fn) => {
|
|
1012
1179
|
try {
|
|
1013
|
-
|
|
1014
|
-
const script = scriptWithLeafVersion.subarray(0, scriptWithLeafVersion.length - 1);
|
|
1015
|
-
try {
|
|
1016
|
-
const params = exports.CSVMultisigTapscript.decode(script).params;
|
|
1017
|
-
sequence = timelockToSequence(params.timelock);
|
|
1018
|
-
} catch {
|
|
1019
|
-
const params = exports.CLTVMultisigTapscript.decode(script).params;
|
|
1020
|
-
sequence = Number(params.absoluteTimelock);
|
|
1021
|
-
}
|
|
1180
|
+
return fn();
|
|
1022
1181
|
} catch {
|
|
1182
|
+
return null;
|
|
1023
1183
|
}
|
|
1024
|
-
|
|
1184
|
+
};
|
|
1185
|
+
function checkKeyMatch(key, arkPsbtFieldKey, prefixOnly = false) {
|
|
1186
|
+
if (key.type !== ArkPsbtFieldKeyType) return false;
|
|
1187
|
+
const expected = encodedPsbtFieldKey[arkPsbtFieldKey];
|
|
1188
|
+
if (key.key.length < expected.length) return false;
|
|
1189
|
+
if (!prefixOnly && key.key.length !== expected.length) return false;
|
|
1190
|
+
for (let i = 0; i < expected.length; i++) {
|
|
1191
|
+
if (key.key[i] !== expected[i]) return false;
|
|
1192
|
+
}
|
|
1193
|
+
return true;
|
|
1025
1194
|
}
|
|
1026
1195
|
|
|
1027
1196
|
// src/providers/eventSource.ts
|
|
@@ -1049,11 +1218,15 @@ function resolveEventSource(override) {
|
|
|
1049
1218
|
}
|
|
1050
1219
|
|
|
1051
1220
|
// package.json
|
|
1052
|
-
var version = "0.5.
|
|
1221
|
+
var version = "0.5.1";
|
|
1053
1222
|
|
|
1054
1223
|
// src/utils/fetch.ts
|
|
1055
1224
|
var buildVersion = "0.9.9";
|
|
1056
1225
|
var sdkVersion = `ts-sdk/${version}`;
|
|
1226
|
+
var ARKADE_VERSION_HEADERS = {
|
|
1227
|
+
"X-Build-Version": buildVersion,
|
|
1228
|
+
"X-SDK-VERSION": sdkVersion
|
|
1229
|
+
};
|
|
1057
1230
|
var FetchError = class extends Error {
|
|
1058
1231
|
/** The request URL that failed, when derivable from the `fetch` input. */
|
|
1059
1232
|
url;
|
|
@@ -1102,27 +1275,12 @@ function baseFetch(input, init) {
|
|
|
1102
1275
|
}
|
|
1103
1276
|
function fetch(input, init) {
|
|
1104
1277
|
const headers = new Headers(init?.headers);
|
|
1105
|
-
headers.set(
|
|
1106
|
-
headers.set("X-SDK-VERSION", sdkVersion);
|
|
1278
|
+
for (const [name, value] of Object.entries(ARKADE_VERSION_HEADERS)) headers.set(name, value);
|
|
1107
1279
|
return baseFetch(input, { ...init, headers });
|
|
1108
1280
|
}
|
|
1109
1281
|
function describeRequest(input, init) {
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
url = input;
|
|
1113
|
-
} else if (input instanceof URL) {
|
|
1114
|
-
url = input.href;
|
|
1115
|
-
} else {
|
|
1116
|
-
url = input.url;
|
|
1117
|
-
}
|
|
1118
|
-
let method;
|
|
1119
|
-
if (init?.method !== void 0) {
|
|
1120
|
-
method = init.method;
|
|
1121
|
-
} else if (input instanceof Request) {
|
|
1122
|
-
method = input.method;
|
|
1123
|
-
} else {
|
|
1124
|
-
method = "GET";
|
|
1125
|
-
}
|
|
1282
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
1283
|
+
const method = init?.method !== void 0 ? init.method : input instanceof Request ? input.method : "GET";
|
|
1126
1284
|
return { url, method };
|
|
1127
1285
|
}
|
|
1128
1286
|
|
|
@@ -1146,15 +1304,13 @@ var ArkErrorName = {
|
|
|
1146
1304
|
INVALID_TX_FILTER: "INVALID_TX_FILTER",
|
|
1147
1305
|
TX_FILTERS_LIMIT_EXCEEDED: "TX_FILTERS_LIMIT_EXCEEDED",
|
|
1148
1306
|
/**
|
|
1149
|
-
* A CLTV closure was spent before its absolute locktime matured.
|
|
1150
|
-
* `
|
|
1151
|
-
*
|
|
1152
|
-
*
|
|
1153
|
-
* Self-healing, so defer and retry rather than fail: the server matures a
|
|
1154
|
-
* seconds-locktime against the **chain tip block's timestamp**, not its wall clock,
|
|
1155
|
-
* so a spend attempted promptly at maturity is rejected until a later block lands.
|
|
1307
|
+
* A CLTV closure was spent before its absolute locktime matured. `submitTx` only, with
|
|
1308
|
+
* metadata `{ locktime, current_locktime, type: "height" | "time" }`. Self-healing, so defer
|
|
1309
|
+
* and retry: the server matures a seconds-locktime against the **chain tip block's
|
|
1310
|
+
* timestamp**, not wall clock, so a prompt spend is rejected until a later block lands.
|
|
1156
1311
|
*/
|
|
1157
|
-
FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED"
|
|
1312
|
+
FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED",
|
|
1313
|
+
INVALID_INTENT_PROOF: "INVALID_INTENT_PROOF"
|
|
1158
1314
|
};
|
|
1159
1315
|
function isArkError(error, name) {
|
|
1160
1316
|
return error instanceof ArkError && (name === void 0 || error.name === name);
|
|
@@ -1230,8 +1386,8 @@ exports.Intent = void 0;
|
|
|
1230
1386
|
}
|
|
1231
1387
|
if (ins.length == 0) throw new Error("intent proof requires at least one input");
|
|
1232
1388
|
const inputs = ins.map(prepareCoinAsIntentProofInput);
|
|
1233
|
-
|
|
1234
|
-
|
|
1389
|
+
validateInputs(inputs);
|
|
1390
|
+
validateOutputs(outputs);
|
|
1235
1391
|
const toSpend = craftToSpendTx(message, inputs[0].witnessUtxo.script);
|
|
1236
1392
|
return craftToSignTx(toSpend, inputs, outputs, message);
|
|
1237
1393
|
}
|
|
@@ -1286,7 +1442,6 @@ var OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([btcSigner.OP.RETURN]);
|
|
|
1286
1442
|
var ZERO_32 = new Uint8Array(32).fill(0);
|
|
1287
1443
|
var MAX_INDEX = 4294967295;
|
|
1288
1444
|
var TAG_INTENT_PROOF = "ark-intent-proof-message";
|
|
1289
|
-
var PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE = 9;
|
|
1290
1445
|
function validateInput(input) {
|
|
1291
1446
|
if (input.index === void 0) throw new Error("intent proof input requires index");
|
|
1292
1447
|
if (input.txid === void 0) throw new Error("intent proof input requires txid");
|
|
@@ -1296,7 +1451,6 @@ function validateInput(input) {
|
|
|
1296
1451
|
}
|
|
1297
1452
|
function validateInputs(inputs) {
|
|
1298
1453
|
inputs.forEach(validateInput);
|
|
1299
|
-
return true;
|
|
1300
1454
|
}
|
|
1301
1455
|
function validateOutput(output) {
|
|
1302
1456
|
if (output.amount === void 0) throw new Error("intent proof output requires amount");
|
|
@@ -1305,7 +1459,6 @@ function validateOutput(output) {
|
|
|
1305
1459
|
}
|
|
1306
1460
|
function validateOutputs(outputs) {
|
|
1307
1461
|
outputs.forEach(validateOutput);
|
|
1308
|
-
return true;
|
|
1309
1462
|
}
|
|
1310
1463
|
function craftToSpendTx(message, pkScript, tag = TAG_INTENT_PROOF) {
|
|
1311
1464
|
const messageHash = hashMessage(message, tag);
|
|
@@ -1333,8 +1486,9 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
|
|
|
1333
1486
|
version: 2,
|
|
1334
1487
|
lockTime: 0
|
|
1335
1488
|
});
|
|
1489
|
+
const { unknown: _, ...toSpendInput } = firstInput;
|
|
1336
1490
|
tx.addInput({
|
|
1337
|
-
...
|
|
1491
|
+
...toSpendInput,
|
|
1338
1492
|
txid: toSpend.id,
|
|
1339
1493
|
index: 0,
|
|
1340
1494
|
witnessUtxo: {
|
|
@@ -1368,14 +1522,7 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
|
|
|
1368
1522
|
script: output.script
|
|
1369
1523
|
});
|
|
1370
1524
|
}
|
|
1371
|
-
|
|
1372
|
-
global.unknown = [
|
|
1373
|
-
...global.unknown ?? [],
|
|
1374
|
-
[
|
|
1375
|
-
{ type: PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE, key: new Uint8Array() },
|
|
1376
|
-
new TextEncoder().encode(message)
|
|
1377
|
-
]
|
|
1378
|
-
];
|
|
1525
|
+
tx.global.genericSignedMessage = new TextEncoder().encode(message);
|
|
1379
1526
|
return tx;
|
|
1380
1527
|
}
|
|
1381
1528
|
function hashMessage(message, tag = TAG_INTENT_PROOF) {
|
|
@@ -1425,6 +1572,7 @@ function eventSourceIterator(eventSource) {
|
|
|
1425
1572
|
cleanedUp = true;
|
|
1426
1573
|
eventSource.removeEventListener("message", messageHandler);
|
|
1427
1574
|
eventSource.removeEventListener("error", errorHandler);
|
|
1575
|
+
eventSource.removeEventListener("failure", failureHandler);
|
|
1428
1576
|
};
|
|
1429
1577
|
const close = () => {
|
|
1430
1578
|
if (closed) return;
|
|
@@ -1451,10 +1599,8 @@ function eventSourceIterator(eventSource) {
|
|
|
1451
1599
|
messageQueue.push(event);
|
|
1452
1600
|
}
|
|
1453
1601
|
};
|
|
1454
|
-
const
|
|
1602
|
+
const rejectWith = (error) => {
|
|
1455
1603
|
if (closed) return;
|
|
1456
|
-
const error = new Error("EventSource error");
|
|
1457
|
-
error.name = "EventSourceError";
|
|
1458
1604
|
if (errorResolve) {
|
|
1459
1605
|
const reject = errorResolve;
|
|
1460
1606
|
messageResolve = null;
|
|
@@ -1464,8 +1610,11 @@ function eventSourceIterator(eventSource) {
|
|
|
1464
1610
|
errorQueue.push(error);
|
|
1465
1611
|
}
|
|
1466
1612
|
};
|
|
1613
|
+
const errorHandler = () => rejectWith(eventSourceError("EventSource error"));
|
|
1614
|
+
const failureHandler = (event) => rejectWith(streamFailureError(event.data));
|
|
1467
1615
|
eventSource.addEventListener("message", messageHandler);
|
|
1468
1616
|
eventSource.addEventListener("error", errorHandler);
|
|
1617
|
+
eventSource.addEventListener("failure", failureHandler);
|
|
1469
1618
|
const gen = (async function* () {
|
|
1470
1619
|
try {
|
|
1471
1620
|
while (!closed) {
|
|
@@ -1503,6 +1652,20 @@ function eventSourceIterator(eventSource) {
|
|
|
1503
1652
|
};
|
|
1504
1653
|
return managed;
|
|
1505
1654
|
}
|
|
1655
|
+
function eventSourceError(message) {
|
|
1656
|
+
const error = new Error(message);
|
|
1657
|
+
error.name = "EventSourceError";
|
|
1658
|
+
return error;
|
|
1659
|
+
}
|
|
1660
|
+
function streamFailureError(data) {
|
|
1661
|
+
let message = String(data);
|
|
1662
|
+
try {
|
|
1663
|
+
const parsed = typeof data === "string" ? JSON.parse(data) : data;
|
|
1664
|
+
if (typeof parsed?.message === "string") message = parsed.message;
|
|
1665
|
+
} catch {
|
|
1666
|
+
}
|
|
1667
|
+
return eventSourceError(`EventSource failure: ${message}`);
|
|
1668
|
+
}
|
|
1506
1669
|
function isEventSourceError(error) {
|
|
1507
1670
|
return error instanceof Error && error.name === "EventSourceError";
|
|
1508
1671
|
}
|
|
@@ -1512,7 +1675,7 @@ var DEFAULT_MAX_CONCURRENT = 6;
|
|
|
1512
1675
|
var DEFAULT_COOLDOWN_MS = 5e3;
|
|
1513
1676
|
var MAX_COOLDOWN_MS = 6e4;
|
|
1514
1677
|
var DEFAULT_JITTER_MS = 500;
|
|
1515
|
-
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1678
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.min(ms, MAX_TIMER_MS)));
|
|
1516
1679
|
function parseRetryAfterMs(header) {
|
|
1517
1680
|
if (header === null || header === void 0) return void 0;
|
|
1518
1681
|
const trimmed = header.trim();
|
|
@@ -1545,6 +1708,9 @@ var OriginRateGate = class {
|
|
|
1545
1708
|
maxCooldownMs;
|
|
1546
1709
|
jitterMs;
|
|
1547
1710
|
constructor(options) {
|
|
1711
|
+
assertNonNegativeMs("defaultCooldownMs", options?.defaultCooldownMs);
|
|
1712
|
+
assertNonNegativeMs("maxCooldownMs", options?.maxCooldownMs);
|
|
1713
|
+
assertNonNegativeMs("jitterMs", options?.jitterMs);
|
|
1548
1714
|
this.maxConcurrent = options?.maxConcurrent ?? DEFAULT_MAX_CONCURRENT;
|
|
1549
1715
|
this.defaultCooldownMs = options?.defaultCooldownMs ?? DEFAULT_COOLDOWN_MS;
|
|
1550
1716
|
this.maxCooldownMs = options?.maxCooldownMs ?? MAX_COOLDOWN_MS;
|
|
@@ -1750,6 +1916,20 @@ var RestArkProvider = class {
|
|
|
1750
1916
|
"Arkade server reported a configuration digest mismatch; server info was refreshed. Rebuild and retry the request under the new server info."
|
|
1751
1917
|
);
|
|
1752
1918
|
}
|
|
1919
|
+
async postJson(url, body, failureMessage) {
|
|
1920
|
+
const response = await this.authedFetch(url, {
|
|
1921
|
+
method: "POST",
|
|
1922
|
+
headers: {
|
|
1923
|
+
"Content-Type": "application/json"
|
|
1924
|
+
},
|
|
1925
|
+
body: JSON.stringify(body)
|
|
1926
|
+
});
|
|
1927
|
+
if (!response.ok) {
|
|
1928
|
+
const errorText = await response.text();
|
|
1929
|
+
handleError(errorText, failureMessage(errorText, response));
|
|
1930
|
+
}
|
|
1931
|
+
return response;
|
|
1932
|
+
}
|
|
1753
1933
|
async getInfo() {
|
|
1754
1934
|
const url = `${this.serverUrl}/v1/info`;
|
|
1755
1935
|
const response = await rateGate.runHttp(
|
|
@@ -1815,20 +1995,14 @@ var RestArkProvider = class {
|
|
|
1815
1995
|
}
|
|
1816
1996
|
async submitTx(signedArkTx, checkpointTxs) {
|
|
1817
1997
|
const url = `${this.serverUrl}/v1/tx/submit`;
|
|
1818
|
-
const response = await this.
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
"Content-Type": "application/json"
|
|
1822
|
-
},
|
|
1823
|
-
body: JSON.stringify({
|
|
1998
|
+
const response = await this.postJson(
|
|
1999
|
+
url,
|
|
2000
|
+
{
|
|
1824
2001
|
signedArkTx,
|
|
1825
2002
|
checkpointTxs
|
|
1826
|
-
}
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
const errorText = await response.text();
|
|
1830
|
-
handleError(errorText, `Failed to submit virtual transaction: ${errorText}`);
|
|
1831
|
-
}
|
|
2003
|
+
},
|
|
2004
|
+
(errorText) => `Failed to submit virtual transaction: ${errorText}`
|
|
2005
|
+
);
|
|
1832
2006
|
const data = await response.json();
|
|
1833
2007
|
return {
|
|
1834
2008
|
arkTxid: data.arkTxid,
|
|
@@ -1838,129 +2012,87 @@ var RestArkProvider = class {
|
|
|
1838
2012
|
}
|
|
1839
2013
|
async finalizeTx(arkTxid, finalCheckpointTxs) {
|
|
1840
2014
|
const url = `${this.serverUrl}/v1/tx/finalize`;
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
"Content-Type": "application/json"
|
|
1845
|
-
},
|
|
1846
|
-
body: JSON.stringify({
|
|
2015
|
+
await this.postJson(
|
|
2016
|
+
url,
|
|
2017
|
+
{
|
|
1847
2018
|
arkTxid,
|
|
1848
2019
|
finalCheckpointTxs
|
|
1849
|
-
}
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
const errorText = await response.text();
|
|
1853
|
-
handleError(errorText, `Failed to finalize offchain transaction: ${errorText}`);
|
|
1854
|
-
}
|
|
2020
|
+
},
|
|
2021
|
+
(errorText) => `Failed to finalize offchain transaction: ${errorText}`
|
|
2022
|
+
);
|
|
1855
2023
|
}
|
|
1856
2024
|
async registerIntent(intent) {
|
|
1857
2025
|
const url = `${this.serverUrl}/v1/batch/registerIntent`;
|
|
1858
|
-
const response = await this.
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
"Content-Type": "application/json"
|
|
1862
|
-
},
|
|
1863
|
-
body: JSON.stringify({
|
|
2026
|
+
const response = await this.postJson(
|
|
2027
|
+
url,
|
|
2028
|
+
{
|
|
1864
2029
|
intent: {
|
|
1865
2030
|
proof: intent.proof,
|
|
1866
2031
|
message: exports.Intent.encodeMessage(intent.message)
|
|
1867
2032
|
}
|
|
1868
|
-
}
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
const errorText = await response.text();
|
|
1872
|
-
handleError(errorText, `Failed to register intent: ${errorText}`);
|
|
1873
|
-
}
|
|
2033
|
+
},
|
|
2034
|
+
(errorText) => `Failed to register intent: ${errorText}`
|
|
2035
|
+
);
|
|
1874
2036
|
const data = await response.json();
|
|
1875
2037
|
return data.intentId;
|
|
1876
2038
|
}
|
|
1877
2039
|
async deleteIntent(intent) {
|
|
1878
2040
|
const url = `${this.serverUrl}/v1/batch/deleteIntent`;
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
"Content-Type": "application/json"
|
|
1883
|
-
},
|
|
1884
|
-
body: JSON.stringify({
|
|
2041
|
+
await this.postJson(
|
|
2042
|
+
url,
|
|
2043
|
+
{
|
|
1885
2044
|
intent: {
|
|
1886
2045
|
proof: intent.proof,
|
|
1887
2046
|
message: exports.Intent.encodeMessage(intent.message)
|
|
1888
2047
|
}
|
|
1889
|
-
}
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
const errorText = await response.text();
|
|
1893
|
-
handleError(errorText, `Failed to delete intent: ${errorText}`);
|
|
1894
|
-
}
|
|
2048
|
+
},
|
|
2049
|
+
(errorText) => `Failed to delete intent: ${errorText}`
|
|
2050
|
+
);
|
|
1895
2051
|
}
|
|
1896
2052
|
async confirmRegistration(intentId) {
|
|
1897
2053
|
const url = `${this.serverUrl}/v1/batch/ack`;
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
"Content-Type": "application/json"
|
|
1902
|
-
},
|
|
1903
|
-
body: JSON.stringify({
|
|
2054
|
+
await this.postJson(
|
|
2055
|
+
url,
|
|
2056
|
+
{
|
|
1904
2057
|
intentId
|
|
1905
|
-
}
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
const errorText = await response.text();
|
|
1909
|
-
handleError(errorText, `Failed to confirm registration: ${errorText}`);
|
|
1910
|
-
}
|
|
2058
|
+
},
|
|
2059
|
+
(errorText) => `Failed to confirm registration: ${errorText}`
|
|
2060
|
+
);
|
|
1911
2061
|
}
|
|
1912
2062
|
async submitTreeNonces(batchId, pubkey, nonces) {
|
|
1913
2063
|
const url = `${this.serverUrl}/v1/batch/tree/submitNonces`;
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
"Content-Type": "application/json"
|
|
1918
|
-
},
|
|
1919
|
-
body: JSON.stringify({
|
|
2064
|
+
await this.postJson(
|
|
2065
|
+
url,
|
|
2066
|
+
{
|
|
1920
2067
|
batchId,
|
|
1921
2068
|
pubkey,
|
|
1922
2069
|
treeNonces: encodeMusig2Nonces(nonces)
|
|
1923
|
-
}
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
const errorText = await response.text();
|
|
1927
|
-
handleError(errorText, `Failed to submit tree nonces: ${errorText}`);
|
|
1928
|
-
}
|
|
2070
|
+
},
|
|
2071
|
+
(errorText) => `Failed to submit tree nonces: ${errorText}`
|
|
2072
|
+
);
|
|
1929
2073
|
}
|
|
1930
2074
|
async submitTreeSignatures(batchId, pubkey, signatures) {
|
|
1931
2075
|
const url = `${this.serverUrl}/v1/batch/tree/submitSignatures`;
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
"Content-Type": "application/json"
|
|
1936
|
-
},
|
|
1937
|
-
body: JSON.stringify({
|
|
2076
|
+
await this.postJson(
|
|
2077
|
+
url,
|
|
2078
|
+
{
|
|
1938
2079
|
batchId,
|
|
1939
2080
|
pubkey,
|
|
1940
2081
|
treeSignatures: encodeMusig2Signatures(signatures)
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
const errorText = await response.text();
|
|
1945
|
-
handleError(errorText, `Failed to submit tree signatures: ${errorText}`);
|
|
1946
|
-
}
|
|
2082
|
+
},
|
|
2083
|
+
(errorText) => `Failed to submit tree signatures: ${errorText}`
|
|
2084
|
+
);
|
|
1947
2085
|
}
|
|
1948
2086
|
async submitSignedForfeitTxs(signedForfeitTxs, signedCommitmentTx) {
|
|
1949
2087
|
const url = `${this.serverUrl}/v1/batch/submitForfeitTxs`;
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
"Content-Type": "application/json"
|
|
1954
|
-
},
|
|
1955
|
-
body: JSON.stringify({
|
|
2088
|
+
await this.postJson(
|
|
2089
|
+
url,
|
|
2090
|
+
{
|
|
1956
2091
|
signedForfeitTxs,
|
|
1957
2092
|
signedCommitmentTx
|
|
1958
|
-
}
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
const errorText = await response.text();
|
|
1962
|
-
handleError(errorText, `Failed to submit forfeit transactions: ${response.statusText}`);
|
|
1963
|
-
}
|
|
2093
|
+
},
|
|
2094
|
+
(_, res) => `Failed to submit forfeit transactions: ${res.statusText}`
|
|
2095
|
+
);
|
|
1964
2096
|
}
|
|
1965
2097
|
getEventStream(signal, topics) {
|
|
1966
2098
|
const url = `${this.serverUrl}/v1/batch/events`;
|
|
@@ -2083,22 +2215,16 @@ var RestArkProvider = class {
|
|
|
2083
2215
|
}
|
|
2084
2216
|
async getPendingTxs(intent) {
|
|
2085
2217
|
const url = `${this.serverUrl}/v1/tx/pending`;
|
|
2086
|
-
const response = await this.
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
"Content-Type": "application/json"
|
|
2090
|
-
},
|
|
2091
|
-
body: JSON.stringify({
|
|
2218
|
+
const response = await this.postJson(
|
|
2219
|
+
url,
|
|
2220
|
+
{
|
|
2092
2221
|
intent: {
|
|
2093
2222
|
proof: intent.proof,
|
|
2094
2223
|
message: exports.Intent.encodeMessage(intent.message)
|
|
2095
2224
|
}
|
|
2096
|
-
}
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
const errorText = await response.text();
|
|
2100
|
-
handleError(errorText, `Failed to get pending transactions: ${errorText}`);
|
|
2101
|
-
}
|
|
2225
|
+
},
|
|
2226
|
+
(errorText) => `Failed to get pending transactions: ${errorText}`
|
|
2227
|
+
);
|
|
2102
2228
|
const data = await response.json();
|
|
2103
2229
|
return data.pendingTxs;
|
|
2104
2230
|
}
|
|
@@ -2364,11 +2490,16 @@ async function getNormalizedVtxos(provider, opts) {
|
|
|
2364
2490
|
const { vtxos, page } = await provider.getVtxos(opts);
|
|
2365
2491
|
return { vtxos: vtxos.map(normalizeVtxo), page };
|
|
2366
2492
|
}
|
|
2493
|
+
var SCRIPT_CHUNK_CONCURRENCY = 4;
|
|
2367
2494
|
async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
|
|
2368
2495
|
const { pageSize = DEFAULT_PAGE_SIZE, ...filters } = opts;
|
|
2369
2496
|
const all = [];
|
|
2497
|
+
const chunks = [];
|
|
2370
2498
|
for (let i = 0; i < scripts.length; i += SCRIPT_QUERY_CHUNK_SIZE) {
|
|
2371
|
-
|
|
2499
|
+
chunks.push(scripts.slice(i, i + SCRIPT_QUERY_CHUNK_SIZE));
|
|
2500
|
+
}
|
|
2501
|
+
const fetchChunk = async (chunk) => {
|
|
2502
|
+
const result = [];
|
|
2372
2503
|
let pageIndex = 0;
|
|
2373
2504
|
let hasMore = true;
|
|
2374
2505
|
while (hasMore) {
|
|
@@ -2378,11 +2509,18 @@ async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
|
|
|
2378
2509
|
pageIndex,
|
|
2379
2510
|
pageSize
|
|
2380
2511
|
});
|
|
2381
|
-
|
|
2512
|
+
result.push(...vtxos);
|
|
2382
2513
|
hasMore = page ? vtxos.length === pageSize : false;
|
|
2383
2514
|
pageIndex++;
|
|
2384
2515
|
if (hasMore) await new Promise((r) => setTimeout(r, 500));
|
|
2385
2516
|
}
|
|
2517
|
+
return result;
|
|
2518
|
+
};
|
|
2519
|
+
for (let i = 0; i < chunks.length; i += SCRIPT_CHUNK_CONCURRENCY) {
|
|
2520
|
+
const batch = await Promise.all(
|
|
2521
|
+
chunks.slice(i, i + SCRIPT_CHUNK_CONCURRENCY).map(fetchChunk)
|
|
2522
|
+
);
|
|
2523
|
+
for (const result of batch) all.push(...result);
|
|
2386
2524
|
}
|
|
2387
2525
|
return all;
|
|
2388
2526
|
}
|
|
@@ -2405,7 +2543,7 @@ async function fetchVtxoCreatedAtByTxid(provider, txids) {
|
|
|
2405
2543
|
}
|
|
2406
2544
|
return createdAt;
|
|
2407
2545
|
}
|
|
2408
|
-
function
|
|
2546
|
+
function isVtxoSpent(vtxo) {
|
|
2409
2547
|
const n = normalizeVtxo(vtxo);
|
|
2410
2548
|
return !!n.isSpent || !!n.spentBy || !!n.settledBy;
|
|
2411
2549
|
}
|
|
@@ -2416,15 +2554,19 @@ function isPastExpiry(vtxo, now) {
|
|
|
2416
2554
|
}
|
|
2417
2555
|
function canSpendOffchain(vtxo, now) {
|
|
2418
2556
|
const n = normalizeVtxo(vtxo);
|
|
2419
|
-
return !
|
|
2557
|
+
return !isVtxoSpent(n) && !n.isUnrolled && !(n.isSwept || isPastExpiry(n, now));
|
|
2420
2558
|
}
|
|
2421
2559
|
function canRecoverOnchain(vtxo, now) {
|
|
2422
2560
|
const n = normalizeVtxo(vtxo);
|
|
2423
|
-
return !
|
|
2561
|
+
return !isVtxoSpent(n) && !n.isUnrolled && (n.isSwept || isPastExpiry(n, now));
|
|
2424
2562
|
}
|
|
2425
2563
|
function canSweepOnchain(vtxo) {
|
|
2426
2564
|
const n = normalizeVtxo(vtxo);
|
|
2427
|
-
return !
|
|
2565
|
+
return !isVtxoSpent(n) && !!n.isUnrolled;
|
|
2566
|
+
}
|
|
2567
|
+
function requiresForfeit(vtxo) {
|
|
2568
|
+
const n = normalizeVtxo(vtxo);
|
|
2569
|
+
return !n.isSwept && !n.isUnrolled;
|
|
2428
2570
|
}
|
|
2429
2571
|
function toOffchainInputFeeParams(vtxo) {
|
|
2430
2572
|
return {
|
|
@@ -2439,6 +2581,7 @@ function isVirtualCoin(input) {
|
|
|
2439
2581
|
return typeof input === "object" && input !== null && typeof input.script === "string";
|
|
2440
2582
|
}
|
|
2441
2583
|
|
|
2584
|
+
exports.ARKADE_VERSION_HEADERS = ARKADE_VERSION_HEADERS;
|
|
2442
2585
|
exports.ArkAddress = ArkAddress;
|
|
2443
2586
|
exports.ArkError = ArkError;
|
|
2444
2587
|
exports.ArkErrorName = ArkErrorName;
|
|
@@ -2447,6 +2590,7 @@ exports.ArkPsbtFieldKeyType = ArkPsbtFieldKeyType;
|
|
|
2447
2590
|
exports.BITCOIN_EMULATOR_PUBKEY = BITCOIN_EMULATOR_PUBKEY;
|
|
2448
2591
|
exports.ConditionWitness = ConditionWitness;
|
|
2449
2592
|
exports.CosignerPublicKey = CosignerPublicKey;
|
|
2593
|
+
exports.DEFAULT_ARKADE_EMULATOR_URL = DEFAULT_ARKADE_EMULATOR_URL;
|
|
2450
2594
|
exports.DEFAULT_ARKADE_SERVER_URL = DEFAULT_ARKADE_SERVER_URL;
|
|
2451
2595
|
exports.DEFAULT_NETWORK = DEFAULT_NETWORK;
|
|
2452
2596
|
exports.DEFAULT_NETWORK_NAME = DEFAULT_NETWORK_NAME;
|
|
@@ -2475,6 +2619,8 @@ exports.VtxoTreeExpiry = VtxoTreeExpiry;
|
|
|
2475
2619
|
exports.__export = __export;
|
|
2476
2620
|
exports.assembleBtcdTaprootTree = assembleBtcdTaprootTree;
|
|
2477
2621
|
exports.assertAllowedSighashTypes = assertAllowedSighashTypes;
|
|
2622
|
+
exports.assertNonNegativeMs = assertNonNegativeMs;
|
|
2623
|
+
exports.assertTimerMs = assertTimerMs;
|
|
2478
2624
|
exports.baseFetch = baseFetch;
|
|
2479
2625
|
exports.buildVersion = buildVersion;
|
|
2480
2626
|
exports.canRecoverOnchain = canRecoverOnchain;
|
|
@@ -2486,7 +2632,6 @@ exports.craftToSpendTx = craftToSpendTx;
|
|
|
2486
2632
|
exports.decodeTapscript = decodeTapscript;
|
|
2487
2633
|
exports.defaultEmulatorPubkey = defaultEmulatorPubkey;
|
|
2488
2634
|
exports.eventSourceIterator = eventSourceIterator;
|
|
2489
|
-
exports.fetch = fetch;
|
|
2490
2635
|
exports.fetchVtxoCreatedAtByTxid = fetchVtxoCreatedAtByTxid;
|
|
2491
2636
|
exports.formatSighash = formatSighash;
|
|
2492
2637
|
exports.getAllNormalizedVtxos = getAllNormalizedVtxos;
|
|
@@ -2495,7 +2640,6 @@ exports.getConfiguredEventSource = getConfiguredEventSource;
|
|
|
2495
2640
|
exports.getNetwork = getNetwork;
|
|
2496
2641
|
exports.getNormalizedVtxos = getNormalizedVtxos;
|
|
2497
2642
|
exports.getSequence = getSequence;
|
|
2498
|
-
exports.hasTerminalSpend = hasTerminalSpend;
|
|
2499
2643
|
exports.isArkError = isArkError;
|
|
2500
2644
|
exports.isEventSourceError = isEventSourceError;
|
|
2501
2645
|
exports.isEventSourceUnavailableError = isEventSourceUnavailableError;
|
|
@@ -2503,21 +2647,26 @@ exports.isFetchTimeoutError = isFetchTimeoutError;
|
|
|
2503
2647
|
exports.isPastExpiry = isPastExpiry;
|
|
2504
2648
|
exports.isRetryableProviderError = isRetryableProviderError;
|
|
2505
2649
|
exports.isVirtualCoin = isVirtualCoin;
|
|
2650
|
+
exports.isVtxoSpent = isVtxoSpent;
|
|
2506
2651
|
exports.maybeArkError = maybeArkError;
|
|
2507
2652
|
exports.networkFromArkadeInfo = networkFromArkadeInfo;
|
|
2508
2653
|
exports.networks = networks;
|
|
2509
2654
|
exports.normalizeVtxo = normalizeVtxo;
|
|
2510
2655
|
exports.rateGate = rateGate;
|
|
2656
|
+
exports.requiresForfeit = requiresForfeit;
|
|
2511
2657
|
exports.resolveEmulatorPubkey = resolveEmulatorPubkey;
|
|
2512
2658
|
exports.resolveEventSource = resolveEventSource;
|
|
2513
2659
|
exports.resolveTimeHeight = resolveTimeHeight;
|
|
2514
2660
|
exports.scriptFromTapLeafScript = scriptFromTapLeafScript;
|
|
2515
2661
|
exports.sdkVersion = sdkVersion;
|
|
2662
|
+
exports.sequenceToCanonicalTimelock = sequenceToCanonicalTimelock;
|
|
2516
2663
|
exports.sequenceToTimelock = sequenceToTimelock;
|
|
2517
2664
|
exports.setArkPsbtField = setArkPsbtField;
|
|
2665
|
+
exports.streamFailureError = streamFailureError;
|
|
2518
2666
|
exports.throwIfHttpUnavailable = throwIfHttpUnavailable;
|
|
2519
2667
|
exports.timelockToSequence = timelockToSequence;
|
|
2668
|
+
exports.toBIP371TapTree = toBIP371TapTree;
|
|
2520
2669
|
exports.toOffchainInputFeeParams = toOffchainInputFeeParams;
|
|
2521
2670
|
exports.toProviderUnavailable = toProviderUnavailable;
|
|
2522
|
-
//# sourceMappingURL=chunk-
|
|
2523
|
-
//# sourceMappingURL=chunk-
|
|
2671
|
+
//# sourceMappingURL=chunk-XLHUGP3G.cjs.map
|
|
2672
|
+
//# sourceMappingURL=chunk-XLHUGP3G.cjs.map
|