@arkade-os/sdk 0.5.0-rc.3 → 0.5.0-rc.31

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.
Files changed (126) hide show
  1. package/README.md +223 -83
  2. package/dist/adapters/expo.cjs +5 -6
  3. package/dist/adapters/expo.d.cts +5 -5
  4. package/dist/adapters/expo.d.ts +5 -5
  5. package/dist/adapters/expo.js +3 -4
  6. package/dist/{asyncStorageTaskQueue-DAs_n1xr.d.ts → asyncStorageTaskQueue-DAVf4Fyy.d.ts} +2 -2
  7. package/dist/{asyncStorageTaskQueue-DqGRG66E.d.cts → asyncStorageTaskQueue-fkkUPrhz.d.cts} +2 -2
  8. package/dist/{chunk-BCT7DT2J.cjs → chunk-5XQNR5AK.cjs} +12 -10
  9. package/dist/chunk-5XQNR5AK.cjs.map +1 -0
  10. package/dist/{chunk-VQCDDGRW.js → chunk-6QKS7AJL.js} +6350 -4816
  11. package/dist/chunk-6QKS7AJL.js.map +1 -0
  12. package/dist/{chunk-UJTYUYY4.cjs → chunk-CUXM3LC5.cjs} +596 -467
  13. package/dist/chunk-CUXM3LC5.cjs.map +1 -0
  14. package/dist/{chunk-L4HZK4KK.cjs → chunk-GM6COBRW.cjs} +158 -263
  15. package/dist/chunk-GM6COBRW.cjs.map +1 -0
  16. package/dist/{chunk-UCSTNXB4.cjs → chunk-H5SOB5TL.cjs} +501 -1153
  17. package/dist/chunk-H5SOB5TL.cjs.map +1 -0
  18. package/dist/{chunk-G4UPMCKW.js → chunk-HRQAPER2.js} +33 -36
  19. package/dist/chunk-HRQAPER2.js.map +1 -0
  20. package/dist/{chunk-FSF2PGTR.cjs → chunk-MUKK2ETJ.cjs} +6736 -5189
  21. package/dist/chunk-MUKK2ETJ.cjs.map +1 -0
  22. package/dist/{chunk-ERUAQGYF.js → chunk-OQRIFUKZ.js} +146 -252
  23. package/dist/chunk-OQRIFUKZ.js.map +1 -0
  24. package/dist/{chunk-7W6FHWYN.js → chunk-PAAJWNX7.js} +434 -1109
  25. package/dist/chunk-PAAJWNX7.js.map +1 -0
  26. package/dist/{chunk-43XGA362.cjs → chunk-ZAAUE3MK.cjs} +40 -43
  27. package/dist/chunk-ZAAUE3MK.cjs.map +1 -0
  28. package/dist/{chunk-ROD5H7RX.js → chunk-ZIK5DLII.js} +7 -5
  29. package/dist/chunk-ZIK5DLII.js.map +1 -0
  30. package/dist/{chunk-HSG2GQTM.js → chunk-ZSP3UI5L.js} +586 -462
  31. package/dist/chunk-ZSP3UI5L.js.map +1 -0
  32. package/dist/contracts/handlers/index.cjs +9 -10
  33. package/dist/contracts/handlers/index.d.cts +5 -5
  34. package/dist/contracts/handlers/index.d.ts +5 -5
  35. package/dist/contracts/handlers/index.js +2 -3
  36. package/dist/{delegate-CZzIduW4.d.cts → delegate-BYoNu3lf.d.cts} +1 -1
  37. package/dist/{delegate-B9Bmrns7.d.ts → delegate-DsqzUVId.d.ts} +1 -1
  38. package/dist/index-CXNTURO_.d.cts +645 -0
  39. package/dist/{index-DnNIOqHS.d.ts → index-DhP68WBD.d.cts} +1698 -2402
  40. package/dist/{index-DnNIOqHS.d.cts → index-DhP68WBD.d.ts} +1698 -2402
  41. package/dist/index-pQr5y77P.d.ts +645 -0
  42. package/dist/index.cjs +407 -356
  43. package/dist/index.d.cts +1045 -1302
  44. package/dist/index.d.ts +1045 -1302
  45. package/dist/index.js +4 -5
  46. package/dist/repositories/realm/index.cjs +201 -106
  47. package/dist/repositories/realm/index.cjs.map +1 -1
  48. package/dist/repositories/realm/index.d.cts +28 -16
  49. package/dist/repositories/realm/index.d.ts +28 -16
  50. package/dist/repositories/realm/index.js +190 -95
  51. package/dist/repositories/realm/index.js.map +1 -1
  52. package/dist/repositories/sqlite/index.cjs +301 -189
  53. package/dist/repositories/sqlite/index.cjs.map +1 -1
  54. package/dist/repositories/sqlite/index.d.cts +32 -21
  55. package/dist/repositories/sqlite/index.d.ts +32 -21
  56. package/dist/repositories/sqlite/index.js +294 -182
  57. package/dist/repositories/sqlite/index.js.map +1 -1
  58. package/dist/{taskRunner-BDb5Ee2J.d.cts → taskRunner-C8H3bSsk.d.cts} +2 -2
  59. package/dist/{taskRunner-F7wNJcF3.d.ts → taskRunner-DKtBy8Yo.d.ts} +2 -2
  60. package/dist/wallet/expo/background.cjs +14 -15
  61. package/dist/wallet/expo/background.cjs.map +1 -1
  62. package/dist/wallet/expo/background.d.cts +10 -16
  63. package/dist/wallet/expo/background.d.ts +10 -16
  64. package/dist/wallet/expo/background.js +6 -7
  65. package/dist/wallet/expo/background.js.map +1 -1
  66. package/dist/wallet/expo/index.cjs +20 -23
  67. package/dist/wallet/expo/index.cjs.map +1 -1
  68. package/dist/wallet/expo/index.d.cts +8 -9
  69. package/dist/wallet/expo/index.d.ts +8 -9
  70. package/dist/wallet/expo/index.js +12 -15
  71. package/dist/wallet/expo/index.js.map +1 -1
  72. package/dist/wallet-BmAHDzK3.d.cts +1874 -0
  73. package/dist/wallet-C0W8EOnA.d.ts +1874 -0
  74. package/dist/worker/expo/index.cjs +9 -10
  75. package/dist/worker/expo/index.cjs.map +1 -1
  76. package/dist/worker/expo/index.d.cts +6 -6
  77. package/dist/worker/expo/index.d.ts +6 -6
  78. package/dist/worker/expo/index.js +5 -6
  79. package/dist/worker/expo/index.js.map +1 -1
  80. package/package.json +12 -51
  81. package/dist/adapters/asyncStorage.cjs +0 -48
  82. package/dist/adapters/asyncStorage.cjs.map +0 -1
  83. package/dist/adapters/asyncStorage.d.cts +0 -16
  84. package/dist/adapters/asyncStorage.d.ts +0 -16
  85. package/dist/adapters/asyncStorage.js +0 -46
  86. package/dist/adapters/asyncStorage.js.map +0 -1
  87. package/dist/adapters/fileSystem.cjs +0 -116
  88. package/dist/adapters/fileSystem.cjs.map +0 -1
  89. package/dist/adapters/fileSystem.d.cts +0 -17
  90. package/dist/adapters/fileSystem.d.ts +0 -17
  91. package/dist/adapters/fileSystem.js +0 -93
  92. package/dist/adapters/fileSystem.js.map +0 -1
  93. package/dist/adapters/indexedDB.cjs +0 -103
  94. package/dist/adapters/indexedDB.cjs.map +0 -1
  95. package/dist/adapters/indexedDB.d.cts +0 -18
  96. package/dist/adapters/indexedDB.d.ts +0 -18
  97. package/dist/adapters/indexedDB.js +0 -101
  98. package/dist/adapters/indexedDB.js.map +0 -1
  99. package/dist/adapters/localStorage.cjs +0 -50
  100. package/dist/adapters/localStorage.cjs.map +0 -1
  101. package/dist/adapters/localStorage.d.cts +0 -14
  102. package/dist/adapters/localStorage.d.ts +0 -14
  103. package/dist/adapters/localStorage.js +0 -48
  104. package/dist/adapters/localStorage.js.map +0 -1
  105. package/dist/chunk-43XGA362.cjs.map +0 -1
  106. package/dist/chunk-5BLDMQED.cjs +0 -18
  107. package/dist/chunk-5BLDMQED.cjs.map +0 -1
  108. package/dist/chunk-7W6FHWYN.js.map +0 -1
  109. package/dist/chunk-BCT7DT2J.cjs.map +0 -1
  110. package/dist/chunk-ERUAQGYF.js.map +0 -1
  111. package/dist/chunk-FSF2PGTR.cjs.map +0 -1
  112. package/dist/chunk-G4UPMCKW.js.map +0 -1
  113. package/dist/chunk-HSG2GQTM.js.map +0 -1
  114. package/dist/chunk-L4HZK4KK.cjs.map +0 -1
  115. package/dist/chunk-NSBPE2FW.js +0 -15
  116. package/dist/chunk-NSBPE2FW.js.map +0 -1
  117. package/dist/chunk-ROD5H7RX.js.map +0 -1
  118. package/dist/chunk-UCSTNXB4.cjs.map +0 -1
  119. package/dist/chunk-UJTYUYY4.cjs.map +0 -1
  120. package/dist/chunk-VQCDDGRW.js.map +0 -1
  121. package/dist/hdWalletCapable-BIl3yLVM.d.cts +0 -2232
  122. package/dist/hdWalletCapable-Cr5nGpK5.d.ts +0 -2232
  123. package/dist/index-C0IanN1m.d.cts +0 -11
  124. package/dist/index-C0IanN1m.d.ts +0 -11
  125. package/dist/index-Ci5MmNnK.d.cts +0 -850
  126. package/dist/index-DQ1Hb2w_.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,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
- // src/utils/transaction.ts
33
- var Transaction = class extends btcSigner.Transaction {
34
- static ARK_TX_OPTS = {
35
- allowUnknown: true,
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
- }
48
- };
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
- })
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 });
175
38
  };
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}`);
@@ -239,6 +66,7 @@ function withArkPrefix(network, prefix, name) {
239
66
  };
240
67
  }
241
68
  var DEFAULT_ARKADE_SERVER_URL = "https://arkade.computer";
69
+ var DEFAULT_ARKADE_EMULATOR_URL = "https://emulator.arkade.computer";
242
70
  var DEFAULT_NETWORK = networks.bitcoin;
243
71
  var DEFAULT_NETWORK_NAME = "bitcoin";
244
72
  var COMPRESSED_PUBKEY = /^0[23][0-9a-f]{64}$/;
@@ -345,6 +173,26 @@ var ArkAddress = class _ArkAddress {
345
173
  return script_js.Script.encode(["RETURN", this.vtxoTaprootKey]);
346
174
  }
347
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
+ }
348
196
  var MinimalScriptNum = btcSigner.ScriptNum(void 0, true);
349
197
  function decodeTapscript(script) {
350
198
  const types = [
@@ -592,6 +440,16 @@ exports.CSVMultisigTapscript = void 0;
592
440
  }
593
441
  CSVMultisigTapscript2.isScriptValid = isScriptValid;
594
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
+ }
595
453
  exports.ConditionCSVMultisigTapscript = void 0;
596
454
  ((ConditionCSVMultisigTapscript2) => {
597
455
  function encode2(params) {
@@ -616,7 +474,7 @@ exports.ConditionCSVMultisigTapscript = void 0;
616
474
  throw isValid;
617
475
  }
618
476
  const asm = btcSigner.Script.decode(script);
619
- let verifyIndex = getVerifyIndex(asm);
477
+ const verifyIndex = asm.lastIndexOf("VERIFY");
620
478
  if (verifyIndex === -1) {
621
479
  throw Error("Invalid script: missing VERIFY operation");
622
480
  }
@@ -651,26 +509,8 @@ exports.ConditionCSVMultisigTapscript = void 0;
651
509
  return tapscript.type === "condition-csv-multisig" /* ConditionCSVMultisig */;
652
510
  }
653
511
  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
512
  function isScriptValid(script) {
665
- const asm = btcSigner.Script.decode(script);
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;
513
+ return isConditionScriptValid(script);
674
514
  }
675
515
  ConditionCSVMultisigTapscript2.isScriptValid = isScriptValid;
676
516
  })(exports.ConditionCSVMultisigTapscript || (exports.ConditionCSVMultisigTapscript = {}));
@@ -698,7 +538,7 @@ exports.ConditionMultisigTapscript = void 0;
698
538
  throw isValid;
699
539
  }
700
540
  const asm = btcSigner.Script.decode(script);
701
- let verifyIndex = getVerifyIndex(asm);
541
+ const verifyIndex = asm.lastIndexOf("VERIFY");
702
542
  if (verifyIndex === -1) {
703
543
  throw Error("Invalid script: missing VERIFY operation");
704
544
  }
@@ -733,26 +573,8 @@ exports.ConditionMultisigTapscript = void 0;
733
573
  return tapscript.type === "condition-multisig" /* ConditionMultisig */;
734
574
  }
735
575
  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
576
  function isScriptValid(script) {
747
- const asm = btcSigner.Script.decode(script);
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;
577
+ return isConditionScriptValid(script);
756
578
  }
757
579
  ConditionMultisigTapscript2.isScriptValid = isScriptValid;
758
580
  })(exports.ConditionMultisigTapscript || (exports.ConditionMultisigTapscript = {}));
@@ -877,7 +699,25 @@ function assembleBtcdTaprootTree(scripts) {
877
699
  }
878
700
  return branches[0];
879
701
  }
880
- var TapTreeCoder = psbt_js.PSBTOutput.tapTree[2];
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
+ );
881
721
  function scriptFromTapLeafScript(leaf) {
882
722
  return leaf[1].subarray(0, leaf[1].length - 1);
883
723
  }
@@ -897,7 +737,7 @@ var VtxoScript = class _VtxoScript {
897
737
  constructor(scripts) {
898
738
  this.scripts = scripts;
899
739
  const tapTree = assembleBtcdTaprootTree(scripts);
900
- const payment = btcSigner.p2tr(btcSigner.TAPROOT_UNSPENDABLE_KEY, tapTree, void 0, true);
740
+ const payment = btcSigner.p2tr(btcSigner.taprootNumsKey(), tapTree, void 0, true);
901
741
  if (!payment.tapLeafScript || payment.tapLeafScript.length !== scripts.length) {
902
742
  throw new Error("invalid scripts");
903
743
  }
@@ -912,15 +752,46 @@ var VtxoScript = class _VtxoScript {
912
752
  /**
913
753
  * Decode a virtual output script from an encoded TapTree.
914
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
+ *
915
770
  * @param tapTree - Encoded TapTree bytes
916
771
  * @returns Decoded virtual output script
917
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}
918
774
  * @see encode
919
775
  */
920
776
  static decode(tapTree) {
921
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
+ }
922
782
  const scripts = leaves.map((leaf) => leaf.script);
923
- return new _VtxoScript(scripts);
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);
924
795
  }
925
796
  /**
926
797
  * Encode the virtual output script to a TapTree byte representation.
@@ -1003,21 +874,323 @@ var VtxoScript = class _VtxoScript {
1003
874
  return paths;
1004
875
  }
1005
876
  };
1006
- function getSequence(tapLeafScript) {
1007
- let sequence = void 0;
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) => {
1008
1179
  try {
1009
- const scriptWithLeafVersion = tapLeafScript[1];
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
- }
1180
+ return fn();
1018
1181
  } catch {
1182
+ return null;
1019
1183
  }
1020
- return sequence;
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;
1021
1194
  }
1022
1195
 
1023
1196
  // src/providers/eventSource.ts
@@ -1045,11 +1218,15 @@ function resolveEventSource(override) {
1045
1218
  }
1046
1219
 
1047
1220
  // package.json
1048
- var version = "0.5.0-rc.3";
1221
+ var version = "0.5.0-rc.31";
1049
1222
 
1050
1223
  // src/utils/fetch.ts
1051
1224
  var buildVersion = "0.9.9";
1052
1225
  var sdkVersion = `ts-sdk/${version}`;
1226
+ var ARKADE_VERSION_HEADERS = {
1227
+ "X-Build-Version": buildVersion,
1228
+ "X-SDK-VERSION": sdkVersion
1229
+ };
1053
1230
  var FetchError = class extends Error {
1054
1231
  /** The request URL that failed, when derivable from the `fetch` input. */
1055
1232
  url;
@@ -1062,38 +1239,48 @@ var FetchError = class extends Error {
1062
1239
  this.method = options.method;
1063
1240
  }
1064
1241
  };
1242
+ var READ_TIMEOUT_MS = 3e4;
1243
+ var warnedNoTimeoutSupport = false;
1244
+ function readDeadline(input, init) {
1245
+ if (init?.signal || input instanceof Request) return void 0;
1246
+ const { method } = describeRequest(input, init);
1247
+ const verb = method.toUpperCase();
1248
+ if (verb !== "GET" && verb !== "HEAD") return void 0;
1249
+ if (typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function") {
1250
+ return AbortSignal.timeout(READ_TIMEOUT_MS);
1251
+ }
1252
+ if (typeof AbortController === "function") {
1253
+ const controller = new AbortController();
1254
+ const timer = setTimeout(() => controller.abort(), READ_TIMEOUT_MS);
1255
+ timer?.unref?.();
1256
+ return controller.signal;
1257
+ }
1258
+ if (!warnedNoTimeoutSupport) {
1259
+ warnedNoTimeoutSupport = true;
1260
+ console.warn(
1261
+ "Neither AbortSignal.timeout nor AbortController is available in this runtime: provider reads are UNBOUNDED and READ_TIMEOUT_MS is not being applied."
1262
+ );
1263
+ }
1264
+ return void 0;
1265
+ }
1065
1266
  function baseFetch(input, init) {
1066
1267
  if (typeof globalThis.fetch !== "function") {
1067
1268
  throw new Error("Fetch API is not available in this environment.");
1068
1269
  }
1069
- return globalThis.fetch(input, init).catch((cause) => {
1270
+ const signal = readDeadline(input, init);
1271
+ return globalThis.fetch(input, signal ? { ...init, signal } : init).catch((cause) => {
1070
1272
  const { url, method } = describeRequest(input, init);
1071
1273
  throw new FetchError(`Network request failed: ${method} ${url}`, { url, method, cause });
1072
1274
  });
1073
1275
  }
1074
1276
  function fetch(input, init) {
1075
1277
  const headers = new Headers(init?.headers);
1076
- headers.set("X-Build-Version", buildVersion);
1077
- headers.set("X-SDK-VERSION", sdkVersion);
1278
+ for (const [name, value] of Object.entries(ARKADE_VERSION_HEADERS)) headers.set(name, value);
1078
1279
  return baseFetch(input, { ...init, headers });
1079
1280
  }
1080
1281
  function describeRequest(input, init) {
1081
- let url;
1082
- if (typeof input === "string") {
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
- }
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";
1097
1284
  return { url, method };
1098
1285
  }
1099
1286
 
@@ -1117,15 +1304,13 @@ var ArkErrorName = {
1117
1304
  INVALID_TX_FILTER: "INVALID_TX_FILTER",
1118
1305
  TX_FILTERS_LIMIT_EXCEEDED: "TX_FILTERS_LIMIT_EXCEEDED",
1119
1306
  /**
1120
- * A CLTV closure was spent before its absolute locktime matured. Raised only by
1121
- * `submitTx` (never `finalizeTx`), with metadata
1122
- * `{ locktime, current_locktime, type: "height" | "time" }`.
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.
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.
1127
1311
  */
1128
- FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED"
1312
+ FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED",
1313
+ INVALID_INTENT_PROOF: "INVALID_INTENT_PROOF"
1129
1314
  };
1130
1315
  function isArkError(error, name) {
1131
1316
  return error instanceof ArkError && (name === void 0 || error.name === name);
@@ -1201,8 +1386,8 @@ exports.Intent = void 0;
1201
1386
  }
1202
1387
  if (ins.length == 0) throw new Error("intent proof requires at least one input");
1203
1388
  const inputs = ins.map(prepareCoinAsIntentProofInput);
1204
- if (!validateInputs(inputs)) ;
1205
- if (!validateOutputs(outputs)) ;
1389
+ validateInputs(inputs);
1390
+ validateOutputs(outputs);
1206
1391
  const toSpend = craftToSpendTx(message, inputs[0].witnessUtxo.script);
1207
1392
  return craftToSignTx(toSpend, inputs, outputs, message);
1208
1393
  }
@@ -1257,7 +1442,6 @@ var OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([btcSigner.OP.RETURN]);
1257
1442
  var ZERO_32 = new Uint8Array(32).fill(0);
1258
1443
  var MAX_INDEX = 4294967295;
1259
1444
  var TAG_INTENT_PROOF = "ark-intent-proof-message";
1260
- var PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE = 9;
1261
1445
  function validateInput(input) {
1262
1446
  if (input.index === void 0) throw new Error("intent proof input requires index");
1263
1447
  if (input.txid === void 0) throw new Error("intent proof input requires txid");
@@ -1267,7 +1451,6 @@ function validateInput(input) {
1267
1451
  }
1268
1452
  function validateInputs(inputs) {
1269
1453
  inputs.forEach(validateInput);
1270
- return true;
1271
1454
  }
1272
1455
  function validateOutput(output) {
1273
1456
  if (output.amount === void 0) throw new Error("intent proof output requires amount");
@@ -1276,7 +1459,6 @@ function validateOutput(output) {
1276
1459
  }
1277
1460
  function validateOutputs(outputs) {
1278
1461
  outputs.forEach(validateOutput);
1279
- return true;
1280
1462
  }
1281
1463
  function craftToSpendTx(message, pkScript, tag = TAG_INTENT_PROOF) {
1282
1464
  const messageHash = hashMessage(message, tag);
@@ -1304,8 +1486,9 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
1304
1486
  version: 2,
1305
1487
  lockTime: 0
1306
1488
  });
1489
+ const { unknown: _, ...toSpendInput } = firstInput;
1307
1490
  tx.addInput({
1308
- ...firstInput,
1491
+ ...toSpendInput,
1309
1492
  txid: toSpend.id,
1310
1493
  index: 0,
1311
1494
  witnessUtxo: {
@@ -1339,14 +1522,7 @@ function craftToSignTx(toSpend, inputs, outputs, message) {
1339
1522
  script: output.script
1340
1523
  });
1341
1524
  }
1342
- const global = tx.global;
1343
- global.unknown = [
1344
- ...global.unknown ?? [],
1345
- [
1346
- { type: PSBT_GLOBAL_GENERIC_SIGNED_MESSAGE, key: new Uint8Array() },
1347
- new TextEncoder().encode(message)
1348
- ]
1349
- ];
1525
+ tx.global.genericSignedMessage = new TextEncoder().encode(message);
1350
1526
  return tx;
1351
1527
  }
1352
1528
  function hashMessage(message, tag = TAG_INTENT_PROOF) {
@@ -1396,6 +1572,7 @@ function eventSourceIterator(eventSource) {
1396
1572
  cleanedUp = true;
1397
1573
  eventSource.removeEventListener("message", messageHandler);
1398
1574
  eventSource.removeEventListener("error", errorHandler);
1575
+ eventSource.removeEventListener("failure", failureHandler);
1399
1576
  };
1400
1577
  const close = () => {
1401
1578
  if (closed) return;
@@ -1422,10 +1599,8 @@ function eventSourceIterator(eventSource) {
1422
1599
  messageQueue.push(event);
1423
1600
  }
1424
1601
  };
1425
- const errorHandler = () => {
1602
+ const rejectWith = (error) => {
1426
1603
  if (closed) return;
1427
- const error = new Error("EventSource error");
1428
- error.name = "EventSourceError";
1429
1604
  if (errorResolve) {
1430
1605
  const reject = errorResolve;
1431
1606
  messageResolve = null;
@@ -1435,8 +1610,11 @@ function eventSourceIterator(eventSource) {
1435
1610
  errorQueue.push(error);
1436
1611
  }
1437
1612
  };
1613
+ const errorHandler = () => rejectWith(eventSourceError("EventSource error"));
1614
+ const failureHandler = (event) => rejectWith(streamFailureError(event.data));
1438
1615
  eventSource.addEventListener("message", messageHandler);
1439
1616
  eventSource.addEventListener("error", errorHandler);
1617
+ eventSource.addEventListener("failure", failureHandler);
1440
1618
  const gen = (async function* () {
1441
1619
  try {
1442
1620
  while (!closed) {
@@ -1474,6 +1652,20 @@ function eventSourceIterator(eventSource) {
1474
1652
  };
1475
1653
  return managed;
1476
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
+ }
1477
1669
  function isEventSourceError(error) {
1478
1670
  return error instanceof Error && error.name === "EventSourceError";
1479
1671
  }
@@ -1483,7 +1675,7 @@ var DEFAULT_MAX_CONCURRENT = 6;
1483
1675
  var DEFAULT_COOLDOWN_MS = 5e3;
1484
1676
  var MAX_COOLDOWN_MS = 6e4;
1485
1677
  var DEFAULT_JITTER_MS = 500;
1486
- var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
1678
+ var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.min(ms, MAX_TIMER_MS)));
1487
1679
  function parseRetryAfterMs(header) {
1488
1680
  if (header === null || header === void 0) return void 0;
1489
1681
  const trimmed = header.trim();
@@ -1516,6 +1708,9 @@ var OriginRateGate = class {
1516
1708
  maxCooldownMs;
1517
1709
  jitterMs;
1518
1710
  constructor(options) {
1711
+ assertNonNegativeMs("defaultCooldownMs", options?.defaultCooldownMs);
1712
+ assertNonNegativeMs("maxCooldownMs", options?.maxCooldownMs);
1713
+ assertNonNegativeMs("jitterMs", options?.jitterMs);
1519
1714
  this.maxConcurrent = options?.maxConcurrent ?? DEFAULT_MAX_CONCURRENT;
1520
1715
  this.defaultCooldownMs = options?.defaultCooldownMs ?? DEFAULT_COOLDOWN_MS;
1521
1716
  this.maxCooldownMs = options?.maxCooldownMs ?? MAX_COOLDOWN_MS;
@@ -1721,6 +1916,20 @@ var RestArkProvider = class {
1721
1916
  "Arkade server reported a configuration digest mismatch; server info was refreshed. Rebuild and retry the request under the new server info."
1722
1917
  );
1723
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
+ }
1724
1933
  async getInfo() {
1725
1934
  const url = `${this.serverUrl}/v1/info`;
1726
1935
  const response = await rateGate.runHttp(
@@ -1786,20 +1995,14 @@ var RestArkProvider = class {
1786
1995
  }
1787
1996
  async submitTx(signedArkTx, checkpointTxs) {
1788
1997
  const url = `${this.serverUrl}/v1/tx/submit`;
1789
- const response = await this.authedFetch(url, {
1790
- method: "POST",
1791
- headers: {
1792
- "Content-Type": "application/json"
1793
- },
1794
- body: JSON.stringify({
1998
+ const response = await this.postJson(
1999
+ url,
2000
+ {
1795
2001
  signedArkTx,
1796
2002
  checkpointTxs
1797
- })
1798
- });
1799
- if (!response.ok) {
1800
- const errorText = await response.text();
1801
- handleError(errorText, `Failed to submit virtual transaction: ${errorText}`);
1802
- }
2003
+ },
2004
+ (errorText) => `Failed to submit virtual transaction: ${errorText}`
2005
+ );
1803
2006
  const data = await response.json();
1804
2007
  return {
1805
2008
  arkTxid: data.arkTxid,
@@ -1809,129 +2012,87 @@ var RestArkProvider = class {
1809
2012
  }
1810
2013
  async finalizeTx(arkTxid, finalCheckpointTxs) {
1811
2014
  const url = `${this.serverUrl}/v1/tx/finalize`;
1812
- const response = await this.authedFetch(url, {
1813
- method: "POST",
1814
- headers: {
1815
- "Content-Type": "application/json"
1816
- },
1817
- body: JSON.stringify({
2015
+ await this.postJson(
2016
+ url,
2017
+ {
1818
2018
  arkTxid,
1819
2019
  finalCheckpointTxs
1820
- })
1821
- });
1822
- if (!response.ok) {
1823
- const errorText = await response.text();
1824
- handleError(errorText, `Failed to finalize offchain transaction: ${errorText}`);
1825
- }
2020
+ },
2021
+ (errorText) => `Failed to finalize offchain transaction: ${errorText}`
2022
+ );
1826
2023
  }
1827
2024
  async registerIntent(intent) {
1828
2025
  const url = `${this.serverUrl}/v1/batch/registerIntent`;
1829
- const response = await this.authedFetch(url, {
1830
- method: "POST",
1831
- headers: {
1832
- "Content-Type": "application/json"
1833
- },
1834
- body: JSON.stringify({
2026
+ const response = await this.postJson(
2027
+ url,
2028
+ {
1835
2029
  intent: {
1836
2030
  proof: intent.proof,
1837
2031
  message: exports.Intent.encodeMessage(intent.message)
1838
2032
  }
1839
- })
1840
- });
1841
- if (!response.ok) {
1842
- const errorText = await response.text();
1843
- handleError(errorText, `Failed to register intent: ${errorText}`);
1844
- }
2033
+ },
2034
+ (errorText) => `Failed to register intent: ${errorText}`
2035
+ );
1845
2036
  const data = await response.json();
1846
2037
  return data.intentId;
1847
2038
  }
1848
2039
  async deleteIntent(intent) {
1849
2040
  const url = `${this.serverUrl}/v1/batch/deleteIntent`;
1850
- const response = await this.authedFetch(url, {
1851
- method: "POST",
1852
- headers: {
1853
- "Content-Type": "application/json"
1854
- },
1855
- body: JSON.stringify({
2041
+ await this.postJson(
2042
+ url,
2043
+ {
1856
2044
  intent: {
1857
2045
  proof: intent.proof,
1858
2046
  message: exports.Intent.encodeMessage(intent.message)
1859
2047
  }
1860
- })
1861
- });
1862
- if (!response.ok) {
1863
- const errorText = await response.text();
1864
- handleError(errorText, `Failed to delete intent: ${errorText}`);
1865
- }
2048
+ },
2049
+ (errorText) => `Failed to delete intent: ${errorText}`
2050
+ );
1866
2051
  }
1867
2052
  async confirmRegistration(intentId) {
1868
2053
  const url = `${this.serverUrl}/v1/batch/ack`;
1869
- const response = await this.authedFetch(url, {
1870
- method: "POST",
1871
- headers: {
1872
- "Content-Type": "application/json"
1873
- },
1874
- body: JSON.stringify({
2054
+ await this.postJson(
2055
+ url,
2056
+ {
1875
2057
  intentId
1876
- })
1877
- });
1878
- if (!response.ok) {
1879
- const errorText = await response.text();
1880
- handleError(errorText, `Failed to confirm registration: ${errorText}`);
1881
- }
2058
+ },
2059
+ (errorText) => `Failed to confirm registration: ${errorText}`
2060
+ );
1882
2061
  }
1883
2062
  async submitTreeNonces(batchId, pubkey, nonces) {
1884
2063
  const url = `${this.serverUrl}/v1/batch/tree/submitNonces`;
1885
- const response = await this.authedFetch(url, {
1886
- method: "POST",
1887
- headers: {
1888
- "Content-Type": "application/json"
1889
- },
1890
- body: JSON.stringify({
2064
+ await this.postJson(
2065
+ url,
2066
+ {
1891
2067
  batchId,
1892
2068
  pubkey,
1893
2069
  treeNonces: encodeMusig2Nonces(nonces)
1894
- })
1895
- });
1896
- if (!response.ok) {
1897
- const errorText = await response.text();
1898
- handleError(errorText, `Failed to submit tree nonces: ${errorText}`);
1899
- }
2070
+ },
2071
+ (errorText) => `Failed to submit tree nonces: ${errorText}`
2072
+ );
1900
2073
  }
1901
2074
  async submitTreeSignatures(batchId, pubkey, signatures) {
1902
2075
  const url = `${this.serverUrl}/v1/batch/tree/submitSignatures`;
1903
- const response = await this.authedFetch(url, {
1904
- method: "POST",
1905
- headers: {
1906
- "Content-Type": "application/json"
1907
- },
1908
- body: JSON.stringify({
2076
+ await this.postJson(
2077
+ url,
2078
+ {
1909
2079
  batchId,
1910
2080
  pubkey,
1911
2081
  treeSignatures: encodeMusig2Signatures(signatures)
1912
- })
1913
- });
1914
- if (!response.ok) {
1915
- const errorText = await response.text();
1916
- handleError(errorText, `Failed to submit tree signatures: ${errorText}`);
1917
- }
2082
+ },
2083
+ (errorText) => `Failed to submit tree signatures: ${errorText}`
2084
+ );
1918
2085
  }
1919
2086
  async submitSignedForfeitTxs(signedForfeitTxs, signedCommitmentTx) {
1920
2087
  const url = `${this.serverUrl}/v1/batch/submitForfeitTxs`;
1921
- const response = await this.authedFetch(url, {
1922
- method: "POST",
1923
- headers: {
1924
- "Content-Type": "application/json"
1925
- },
1926
- body: JSON.stringify({
2088
+ await this.postJson(
2089
+ url,
2090
+ {
1927
2091
  signedForfeitTxs,
1928
2092
  signedCommitmentTx
1929
- })
1930
- });
1931
- if (!response.ok) {
1932
- const errorText = await response.text();
1933
- handleError(errorText, `Failed to submit forfeit transactions: ${response.statusText}`);
1934
- }
2093
+ },
2094
+ (_, res) => `Failed to submit forfeit transactions: ${res.statusText}`
2095
+ );
1935
2096
  }
1936
2097
  getEventStream(signal, topics) {
1937
2098
  const url = `${this.serverUrl}/v1/batch/events`;
@@ -2054,22 +2215,16 @@ var RestArkProvider = class {
2054
2215
  }
2055
2216
  async getPendingTxs(intent) {
2056
2217
  const url = `${this.serverUrl}/v1/tx/pending`;
2057
- const response = await this.authedFetch(url, {
2058
- method: "POST",
2059
- headers: {
2060
- "Content-Type": "application/json"
2061
- },
2062
- body: JSON.stringify({
2218
+ const response = await this.postJson(
2219
+ url,
2220
+ {
2063
2221
  intent: {
2064
2222
  proof: intent.proof,
2065
2223
  message: exports.Intent.encodeMessage(intent.message)
2066
2224
  }
2067
- })
2068
- });
2069
- if (!response.ok) {
2070
- const errorText = await response.text();
2071
- handleError(errorText, `Failed to get pending transactions: ${errorText}`);
2072
- }
2225
+ },
2226
+ (errorText) => `Failed to get pending transactions: ${errorText}`
2227
+ );
2073
2228
  const data = await response.json();
2074
2229
  return data.pendingTxs;
2075
2230
  }
@@ -2289,60 +2444,23 @@ function parseWireExpiry(raw) {
2289
2444
  if (ms >= EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(ms) };
2290
2445
  return { expiresAtHeight: n };
2291
2446
  }
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
2447
  function normalizeVtxo(v) {
2312
- const state = v.virtualStatus?.state;
2313
- const canonicalExpiry = v.expiresAt !== void 0 || v.expiresAtHeight !== void 0;
2314
- const expiry = canonicalExpiry ? (
2315
- // Coerce: a backend that persists through JSON hands back an ISO string, which typechecks
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 ?? [];
2448
+ const expiry = {
2449
+ expiresAt: v.expiresAt === void 0 ? void 0 : new Date(v.expiresAt),
2450
+ expiresAtHeight: v.expiresAtHeight
2451
+ };
2326
2452
  return {
2327
2453
  ...v,
2328
- isSpent,
2329
- isSwept,
2330
- isPreconfirmed,
2454
+ isSpent: v.isSpent ?? false,
2455
+ isSwept: v.isSwept ?? false,
2456
+ isPreconfirmed: v.isPreconfirmed ?? false,
2331
2457
  spentBy: v.spentBy ?? "",
2332
- commitmentTxIds,
2333
- ...expiry,
2334
- virtualStatus: v.virtualStatus ?? toVirtualStatus({ isSpent, isSwept, isPreconfirmed, commitmentTxIds, ...expiry })
2458
+ commitmentTxIds: v.commitmentTxIds ?? [],
2459
+ ...expiry
2335
2460
  };
2336
2461
  }
2337
2462
  function convertVtxo(vtxo) {
2338
2463
  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
2464
  return {
2347
2465
  txid: vtxo.outpoint.txid,
2348
2466
  vout: vtxo.outpoint.vout,
@@ -2351,8 +2469,11 @@ function convertVtxo(vtxo) {
2351
2469
  confirmed: !vtxo.isSwept && !vtxo.isPreconfirmed,
2352
2470
  isLeaf: !vtxo.isPreconfirmed
2353
2471
  },
2354
- ...facts,
2355
- virtualStatus: toVirtualStatus(facts),
2472
+ isSpent: vtxo.isSpent,
2473
+ isSwept: vtxo.isSwept,
2474
+ isPreconfirmed: vtxo.isPreconfirmed,
2475
+ commitmentTxIds: vtxo.commitmentTxids,
2476
+ ...expiry,
2356
2477
  spentBy: vtxo.spentBy ?? "",
2357
2478
  settledBy: vtxo.settledBy,
2358
2479
  arkTxId: vtxo.arkTxid,
@@ -2369,11 +2490,16 @@ async function getNormalizedVtxos(provider, opts) {
2369
2490
  const { vtxos, page } = await provider.getVtxos(opts);
2370
2491
  return { vtxos: vtxos.map(normalizeVtxo), page };
2371
2492
  }
2493
+ var SCRIPT_CHUNK_CONCURRENCY = 4;
2372
2494
  async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
2373
2495
  const { pageSize = DEFAULT_PAGE_SIZE, ...filters } = opts;
2374
2496
  const all = [];
2497
+ const chunks = [];
2375
2498
  for (let i = 0; i < scripts.length; i += SCRIPT_QUERY_CHUNK_SIZE) {
2376
- const chunk = scripts.slice(i, i + SCRIPT_QUERY_CHUNK_SIZE);
2499
+ chunks.push(scripts.slice(i, i + SCRIPT_QUERY_CHUNK_SIZE));
2500
+ }
2501
+ const fetchChunk = async (chunk) => {
2502
+ const result = [];
2377
2503
  let pageIndex = 0;
2378
2504
  let hasMore = true;
2379
2505
  while (hasMore) {
@@ -2383,11 +2509,18 @@ async function getAllNormalizedVtxos(provider, scripts, opts = {}) {
2383
2509
  pageIndex,
2384
2510
  pageSize
2385
2511
  });
2386
- all.push(...vtxos);
2512
+ result.push(...vtxos);
2387
2513
  hasMore = page ? vtxos.length === pageSize : false;
2388
2514
  pageIndex++;
2389
2515
  if (hasMore) await new Promise((r) => setTimeout(r, 500));
2390
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);
2391
2524
  }
2392
2525
  return all;
2393
2526
  }
@@ -2410,7 +2543,7 @@ async function fetchVtxoCreatedAtByTxid(provider, txids) {
2410
2543
  }
2411
2544
  return createdAt;
2412
2545
  }
2413
- function hasTerminalSpend(vtxo) {
2546
+ function isVtxoSpent(vtxo) {
2414
2547
  const n = normalizeVtxo(vtxo);
2415
2548
  return !!n.isSpent || !!n.spentBy || !!n.settledBy;
2416
2549
  }
@@ -2421,41 +2554,34 @@ function isPastExpiry(vtxo, now) {
2421
2554
  }
2422
2555
  function canSpendOffchain(vtxo, now) {
2423
2556
  const n = normalizeVtxo(vtxo);
2424
- return !hasTerminalSpend(n) && !n.isUnrolled && !(n.isSwept || isPastExpiry(n, now));
2557
+ return !isVtxoSpent(n) && !n.isUnrolled && !(n.isSwept || isPastExpiry(n, now));
2425
2558
  }
2426
2559
  function canRecoverOnchain(vtxo, now) {
2427
2560
  const n = normalizeVtxo(vtxo);
2428
- return !hasTerminalSpend(n) && !n.isUnrolled && (n.isSwept || isPastExpiry(n, now));
2561
+ return !isVtxoSpent(n) && !n.isUnrolled && (n.isSwept || isPastExpiry(n, now));
2429
2562
  }
2430
2563
  function canSweepOnchain(vtxo) {
2431
2564
  const n = normalizeVtxo(vtxo);
2432
- return !hasTerminalSpend(n) && !!n.isUnrolled;
2565
+ return !isVtxoSpent(n) && !!n.isUnrolled;
2566
+ }
2567
+ function requiresForfeit(vtxo) {
2568
+ const n = normalizeVtxo(vtxo);
2569
+ return !n.isSwept && !n.isUnrolled;
2433
2570
  }
2434
2571
  function toOffchainInputFeeParams(vtxo) {
2435
- const batchExpiry = toBatchExpiry(vtxo);
2436
2572
  return {
2437
2573
  amount: BigInt(vtxo.value),
2438
2574
  type: vtxo.isSwept ? "recoverable" : "vtxo",
2439
2575
  weight: 0,
2440
2576
  birth: vtxo.createdAt,
2441
- expiry: batchExpiry ? new Date(batchExpiry) : void 0
2577
+ expiry: vtxo.expiresAt
2442
2578
  };
2443
2579
  }
2444
2580
  function isVirtualCoin(input) {
2445
2581
  return typeof input === "object" && input !== null && typeof input.script === "string";
2446
2582
  }
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
2583
 
2584
+ exports.ARKADE_VERSION_HEADERS = ARKADE_VERSION_HEADERS;
2459
2585
  exports.ArkAddress = ArkAddress;
2460
2586
  exports.ArkError = ArkError;
2461
2587
  exports.ArkErrorName = ArkErrorName;
@@ -2464,11 +2590,13 @@ exports.ArkPsbtFieldKeyType = ArkPsbtFieldKeyType;
2464
2590
  exports.BITCOIN_EMULATOR_PUBKEY = BITCOIN_EMULATOR_PUBKEY;
2465
2591
  exports.ConditionWitness = ConditionWitness;
2466
2592
  exports.CosignerPublicKey = CosignerPublicKey;
2593
+ exports.DEFAULT_ARKADE_EMULATOR_URL = DEFAULT_ARKADE_EMULATOR_URL;
2467
2594
  exports.DEFAULT_ARKADE_SERVER_URL = DEFAULT_ARKADE_SERVER_URL;
2468
2595
  exports.DEFAULT_NETWORK = DEFAULT_NETWORK;
2469
2596
  exports.DEFAULT_NETWORK_NAME = DEFAULT_NETWORK_NAME;
2470
2597
  exports.DEFAULT_PAGE_SIZE = DEFAULT_PAGE_SIZE;
2471
2598
  exports.DigestMismatchError = DigestMismatchError;
2599
+ exports.EXPIRY_MIN_PLAUSIBLE_MS = EXPIRY_MIN_PLAUSIBLE_MS;
2472
2600
  exports.EventSourceUnavailableError = EventSourceUnavailableError;
2473
2601
  exports.FetchError = FetchError;
2474
2602
  exports.INFO_FETCH_TIMEOUT_MS = INFO_FETCH_TIMEOUT_MS;
@@ -2477,6 +2605,7 @@ exports.OP_RETURN_EMPTY_PKSCRIPT = OP_RETURN_EMPTY_PKSCRIPT;
2477
2605
  exports.PrevArkTxField = PrevArkTxField;
2478
2606
  exports.PrevoutTxField = PrevoutTxField;
2479
2607
  exports.ProviderUnavailableError = ProviderUnavailableError;
2608
+ exports.READ_TIMEOUT_MS = READ_TIMEOUT_MS;
2480
2609
  exports.REGTEST_EMULATOR_PUBKEY = REGTEST_EMULATOR_PUBKEY;
2481
2610
  exports.RestArkProvider = RestArkProvider;
2482
2611
  exports.SCRIPT_QUERY_CHUNK_SIZE = SCRIPT_QUERY_CHUNK_SIZE;
@@ -2487,8 +2616,11 @@ exports.Transaction = Transaction;
2487
2616
  exports.VtxoScript = VtxoScript;
2488
2617
  exports.VtxoTaprootTree = VtxoTaprootTree;
2489
2618
  exports.VtxoTreeExpiry = VtxoTreeExpiry;
2619
+ exports.__export = __export;
2490
2620
  exports.assembleBtcdTaprootTree = assembleBtcdTaprootTree;
2491
2621
  exports.assertAllowedSighashTypes = assertAllowedSighashTypes;
2622
+ exports.assertNonNegativeMs = assertNonNegativeMs;
2623
+ exports.assertTimerMs = assertTimerMs;
2492
2624
  exports.baseFetch = baseFetch;
2493
2625
  exports.buildVersion = buildVersion;
2494
2626
  exports.canRecoverOnchain = canRecoverOnchain;
@@ -2500,7 +2632,6 @@ exports.craftToSpendTx = craftToSpendTx;
2500
2632
  exports.decodeTapscript = decodeTapscript;
2501
2633
  exports.defaultEmulatorPubkey = defaultEmulatorPubkey;
2502
2634
  exports.eventSourceIterator = eventSourceIterator;
2503
- exports.fetch = fetch;
2504
2635
  exports.fetchVtxoCreatedAtByTxid = fetchVtxoCreatedAtByTxid;
2505
2636
  exports.formatSighash = formatSighash;
2506
2637
  exports.getAllNormalizedVtxos = getAllNormalizedVtxos;
@@ -2509,35 +2640,33 @@ exports.getConfiguredEventSource = getConfiguredEventSource;
2509
2640
  exports.getNetwork = getNetwork;
2510
2641
  exports.getNormalizedVtxos = getNormalizedVtxos;
2511
2642
  exports.getSequence = getSequence;
2512
- exports.hasTerminalSpend = hasTerminalSpend;
2513
2643
  exports.isArkError = isArkError;
2514
2644
  exports.isEventSourceError = isEventSourceError;
2515
2645
  exports.isEventSourceUnavailableError = isEventSourceUnavailableError;
2516
- exports.isExpired = isExpired;
2517
2646
  exports.isFetchTimeoutError = isFetchTimeoutError;
2518
2647
  exports.isPastExpiry = isPastExpiry;
2519
- exports.isRecoverable = isRecoverable;
2520
2648
  exports.isRetryableProviderError = isRetryableProviderError;
2521
- exports.isSpendable = isSpendable;
2522
2649
  exports.isVirtualCoin = isVirtualCoin;
2650
+ exports.isVtxoSpent = isVtxoSpent;
2523
2651
  exports.maybeArkError = maybeArkError;
2524
2652
  exports.networkFromArkadeInfo = networkFromArkadeInfo;
2525
2653
  exports.networks = networks;
2526
2654
  exports.normalizeVtxo = normalizeVtxo;
2527
- exports.parseLegacyExpiry = parseLegacyExpiry;
2528
2655
  exports.rateGate = rateGate;
2656
+ exports.requiresForfeit = requiresForfeit;
2529
2657
  exports.resolveEmulatorPubkey = resolveEmulatorPubkey;
2530
2658
  exports.resolveEventSource = resolveEventSource;
2531
2659
  exports.resolveTimeHeight = resolveTimeHeight;
2532
2660
  exports.scriptFromTapLeafScript = scriptFromTapLeafScript;
2533
2661
  exports.sdkVersion = sdkVersion;
2662
+ exports.sequenceToCanonicalTimelock = sequenceToCanonicalTimelock;
2534
2663
  exports.sequenceToTimelock = sequenceToTimelock;
2535
2664
  exports.setArkPsbtField = setArkPsbtField;
2665
+ exports.streamFailureError = streamFailureError;
2536
2666
  exports.throwIfHttpUnavailable = throwIfHttpUnavailable;
2537
2667
  exports.timelockToSequence = timelockToSequence;
2538
- exports.toBatchExpiry = toBatchExpiry;
2668
+ exports.toBIP371TapTree = toBIP371TapTree;
2539
2669
  exports.toOffchainInputFeeParams = toOffchainInputFeeParams;
2540
2670
  exports.toProviderUnavailable = toProviderUnavailable;
2541
- exports.toVirtualStatus = toVirtualStatus;
2542
- //# sourceMappingURL=chunk-UJTYUYY4.cjs.map
2543
- //# sourceMappingURL=chunk-UJTYUYY4.cjs.map
2671
+ //# sourceMappingURL=chunk-CUXM3LC5.cjs.map
2672
+ //# sourceMappingURL=chunk-CUXM3LC5.cjs.map