@arkade-os/sdk 0.5.0-rc.24 → 0.5.0-rc.26

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 (80) hide show
  1. package/README.md +65 -0
  2. package/dist/adapters/expo.cjs +5 -5
  3. package/dist/adapters/expo.d.cts +3 -3
  4. package/dist/adapters/expo.d.ts +3 -3
  5. package/dist/adapters/expo.js +3 -3
  6. package/dist/{asyncStorageTaskQueue-DeXfxJp5.d.cts → asyncStorageTaskQueue-CFWscYpG.d.cts} +2 -2
  7. package/dist/{asyncStorageTaskQueue-C4ESykOx.d.ts → asyncStorageTaskQueue-DrFapzPg.d.ts} +2 -2
  8. package/dist/{chunk-PD5CVWPT.js → chunk-5JQ5EOYE.js} +25 -6
  9. package/dist/chunk-5JQ5EOYE.js.map +1 -0
  10. package/dist/{chunk-OIYVDV2N.cjs → chunk-B2YMUJD5.cjs} +1116 -657
  11. package/dist/chunk-B2YMUJD5.cjs.map +1 -0
  12. package/dist/{chunk-UV3IM6BG.cjs → chunk-CFOIHLON.cjs} +48 -48
  13. package/dist/{chunk-UV3IM6BG.cjs.map → chunk-CFOIHLON.cjs.map} +1 -1
  14. package/dist/{chunk-PAD5V653.cjs → chunk-FEBAG2K2.cjs} +40 -21
  15. package/dist/chunk-FEBAG2K2.cjs.map +1 -0
  16. package/dist/{chunk-RDJIT7RA.js → chunk-HPUKFTZV.js} +4 -4
  17. package/dist/{chunk-RDJIT7RA.js.map → chunk-HPUKFTZV.js.map} +1 -1
  18. package/dist/{chunk-HGOERMAY.js → chunk-HTCIPDVW.js} +23 -7
  19. package/dist/chunk-HTCIPDVW.js.map +1 -0
  20. package/dist/{chunk-O2WE7RWU.cjs → chunk-K2YTDYQF.cjs} +17 -17
  21. package/dist/chunk-K2YTDYQF.cjs.map +1 -0
  22. package/dist/{chunk-RFI6RO25.js → chunk-N2VM6V6K.js} +3 -3
  23. package/dist/{chunk-RFI6RO25.js.map → chunk-N2VM6V6K.js.map} +1 -1
  24. package/dist/{chunk-MJG2O6PT.cjs → chunk-QCD3SJOL.cjs} +10 -10
  25. package/dist/{chunk-MJG2O6PT.cjs.map → chunk-QCD3SJOL.cjs.map} +1 -1
  26. package/dist/{chunk-WXHMXKPV.js → chunk-U5ZRDVVB.js} +637 -181
  27. package/dist/chunk-U5ZRDVVB.js.map +1 -0
  28. package/dist/{chunk-65CTZR2O.cjs → chunk-VVFCCNU2.cjs} +23 -6
  29. package/dist/chunk-VVFCCNU2.cjs.map +1 -0
  30. package/dist/{chunk-2YGYHUBW.js → chunk-Y5VSJURH.js} +6 -6
  31. package/dist/chunk-Y5VSJURH.js.map +1 -0
  32. package/dist/contracts/handlers/index.cjs +9 -9
  33. package/dist/contracts/handlers/index.d.cts +3 -3
  34. package/dist/contracts/handlers/index.d.ts +3 -3
  35. package/dist/contracts/handlers/index.js +2 -2
  36. package/dist/{delegate-CJ34lCIK.d.ts → delegate-Cz8FnLqi.d.ts} +1 -1
  37. package/dist/{delegate-C1wtM1NZ.d.cts → delegate-r3jh7UcH.d.cts} +1 -1
  38. package/dist/{index-CH0tbuRp.d.ts → index-BfvbSL0W.d.cts} +81 -11
  39. package/dist/{index-CH0tbuRp.d.cts → index-BfvbSL0W.d.ts} +81 -11
  40. package/dist/{index-iD05fKPX.d.ts → index-Chgwl4dO.d.ts} +2 -2
  41. package/dist/{index-DhVOLSJN.d.cts → index-DOION7Ta.d.cts} +2 -2
  42. package/dist/index.cjs +328 -312
  43. package/dist/index.d.cts +129 -87
  44. package/dist/index.d.ts +129 -87
  45. package/dist/index.js +4 -4
  46. package/dist/repositories/realm/index.cjs +35 -35
  47. package/dist/repositories/realm/index.d.cts +2 -2
  48. package/dist/repositories/realm/index.d.ts +2 -2
  49. package/dist/repositories/realm/index.js +5 -5
  50. package/dist/repositories/sqlite/index.cjs +33 -33
  51. package/dist/repositories/sqlite/index.d.cts +2 -2
  52. package/dist/repositories/sqlite/index.d.ts +2 -2
  53. package/dist/repositories/sqlite/index.js +5 -5
  54. package/dist/{taskRunner-Ox7fjm1O.d.cts → taskRunner-BO8a-SQh.d.cts} +2 -2
  55. package/dist/{taskRunner-DGSSHZ6e.d.ts → taskRunner-CXAcjtdU.d.ts} +2 -2
  56. package/dist/wallet/expo/background.cjs +14 -14
  57. package/dist/wallet/expo/background.d.cts +3 -3
  58. package/dist/wallet/expo/background.d.ts +3 -3
  59. package/dist/wallet/expo/background.js +6 -6
  60. package/dist/wallet/expo/index.cjs +19 -15
  61. package/dist/wallet/expo/index.cjs.map +1 -1
  62. package/dist/wallet/expo/index.d.cts +6 -4
  63. package/dist/wallet/expo/index.d.ts +6 -4
  64. package/dist/wallet/expo/index.js +9 -5
  65. package/dist/wallet/expo/index.js.map +1 -1
  66. package/dist/{wallet-EWn1ivtK.d.cts → wallet-CFIfUlQP.d.ts} +72 -4
  67. package/dist/{wallet-DK71priz.d.ts → wallet-s90p-vIk.d.cts} +72 -4
  68. package/dist/worker/expo/index.cjs +9 -9
  69. package/dist/worker/expo/index.d.cts +4 -4
  70. package/dist/worker/expo/index.d.ts +4 -4
  71. package/dist/worker/expo/index.js +5 -5
  72. package/package.json +1 -1
  73. package/dist/chunk-2YGYHUBW.js.map +0 -1
  74. package/dist/chunk-65CTZR2O.cjs.map +0 -1
  75. package/dist/chunk-HGOERMAY.js.map +0 -1
  76. package/dist/chunk-O2WE7RWU.cjs.map +0 -1
  77. package/dist/chunk-OIYVDV2N.cjs.map +0 -1
  78. package/dist/chunk-PAD5V653.cjs.map +0 -1
  79. package/dist/chunk-PD5CVWPT.js.map +0 -1
  80. package/dist/chunk-WXHMXKPV.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkPAD5V653_cjs = require('./chunk-PAD5V653.cjs');
4
- var chunkUV3IM6BG_cjs = require('./chunk-UV3IM6BG.cjs');
5
- var chunk65CTZR2O_cjs = require('./chunk-65CTZR2O.cjs');
3
+ var chunkFEBAG2K2_cjs = require('./chunk-FEBAG2K2.cjs');
4
+ var chunkCFOIHLON_cjs = require('./chunk-CFOIHLON.cjs');
5
+ var chunkVVFCCNU2_cjs = require('./chunk-VVFCCNU2.cjs');
6
6
  var utils_js = require('@scure/btc-signer/utils.js');
7
7
  var btcSigner = require('@scure/btc-signer');
8
8
  var base = require('@scure/base');
@@ -187,7 +187,7 @@ var TreeSignerSession = class _TreeSignerSession {
187
187
  noncesByPubkey.set(base.hex.encode(myPublicKey.subarray(1)), myNonce);
188
188
  const tx = this.graph.find(txid);
189
189
  if (!tx) throw new Error(`missing tx for txid ${txid}`);
190
- const cosigners = chunk65CTZR2O_cjs.getArkPsbtFields(tx.root, 0, chunk65CTZR2O_cjs.CosignerPublicKey).map(
190
+ const cosigners = chunkVVFCCNU2_cjs.getArkPsbtFields(tx.root, 0, chunkVVFCCNU2_cjs.CosignerPublicKey).map(
191
191
  (c) => base.hex.encode(c.key.subarray(1))
192
192
  // xonly pubkey
193
193
  );
@@ -239,7 +239,7 @@ var TreeSignerSession = class _TreeSignerSession {
239
239
  if (!aggNonce) throw new Error("missing aggregate nonce");
240
240
  const prevoutAmounts = [];
241
241
  const prevoutScripts = [];
242
- const cosigners = chunk65CTZR2O_cjs.getArkPsbtFields(g.root, 0, chunk65CTZR2O_cjs.CosignerPublicKey).map((c) => c.key);
242
+ const cosigners = chunkVVFCCNU2_cjs.getArkPsbtFields(g.root, 0, chunkVVFCCNU2_cjs.CosignerPublicKey).map((c) => c.key);
243
243
  const { finalKey } = aggregateKeys(cosigners, true, {
244
244
  taprootTweak: this.scriptRoot
245
245
  });
@@ -322,7 +322,7 @@ var SingleKey = class _SingleKey {
322
322
  async sign(tx, inputIndexes) {
323
323
  const txCpy = tx.clone();
324
324
  if (!inputIndexes) {
325
- chunk65CTZR2O_cjs.assertAllowedSighashTypes(txCpy, ALLOWED_SIGHASH);
325
+ chunkVVFCCNU2_cjs.assertAllowedSighashTypes(txCpy, ALLOWED_SIGHASH);
326
326
  try {
327
327
  if (!txCpy.sign(this.key, ALLOWED_SIGHASH)) {
328
328
  throw new Error("Failed to sign transaction");
@@ -422,7 +422,7 @@ var SeedIdentity = class _SeedIdentity {
422
422
  let network;
423
423
  if ("descriptor" in opts && typeof opts.descriptor === "string") {
424
424
  descriptor = opts.descriptor;
425
- network = chunkUV3IM6BG_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
425
+ network = chunkCFOIHLON_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
426
426
  } else {
427
427
  network = opts.isMainnet ?? true ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
428
428
  descriptor = descriptorsScure.scriptExpressions.trBIP32({
@@ -499,7 +499,7 @@ var SeedIdentity = class _SeedIdentity {
499
499
  }
500
500
  /** Returns true when `descriptor` is derived from this identity's seed. */
501
501
  ownsDescriptor(descriptor) {
502
- return chunkUV3IM6BG_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
502
+ return chunkCFOIHLON_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
503
503
  }
504
504
  /**
505
505
  * Signs each request with the key derived from its descriptor.
@@ -538,7 +538,7 @@ var SeedIdentity = class _SeedIdentity {
538
538
  }
539
539
  // ── internal helpers ─────────────────────────────────────────────
540
540
  derivePrivateKeyForDescriptor(descriptor) {
541
- const network = chunkUV3IM6BG_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
541
+ const network = chunkCFOIHLON_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
542
542
  const expansion = descriptorsScure.expand({ descriptor, network });
543
543
  if (expansion.isRanged) {
544
544
  throw new Error(
@@ -563,7 +563,7 @@ var SeedIdentity = class _SeedIdentity {
563
563
  signTxWithKey(tx, key, inputIndexes) {
564
564
  const txCpy = tx.clone();
565
565
  if (!inputIndexes) {
566
- chunk65CTZR2O_cjs.assertAllowedSighashTypes(txCpy, ALLOWED_SIGHASH2);
566
+ chunkVVFCCNU2_cjs.assertAllowedSighashTypes(txCpy, ALLOWED_SIGHASH2);
567
567
  try {
568
568
  if (!txCpy.sign(key, ALLOWED_SIGHASH2)) {
569
569
  throw new Error("Failed to sign transaction");
@@ -615,7 +615,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
615
615
  /** Wildcard account-descriptor template (e.g. `tr([fp/86'/0'/0']xpub/0/*)`). */
616
616
  descriptor;
617
617
  constructor(descriptor) {
618
- const network = chunkUV3IM6BG_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
618
+ const network = chunkCFOIHLON_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
619
619
  let expansion;
620
620
  try {
621
621
  expansion = descriptorsScure.expand({ descriptor, network, index: 0 });
@@ -650,7 +650,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
650
650
  }
651
651
  /** Returns true when `descriptor` derives from this identity's xpub. */
652
652
  ownsDescriptor(descriptor) {
653
- return chunkUV3IM6BG_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
653
+ return chunkCFOIHLON_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
654
654
  }
655
655
  };
656
656
  function serializeSeedOwnedSigningIdentity(identity) {
@@ -793,10 +793,10 @@ var DescriptorIdentity = class {
793
793
  this.base = base;
794
794
  }
795
795
  async xOnlyPublicKey() {
796
- return chunkUV3IM6BG_cjs.deriveDescriptorLeafPubKey(this.descriptor);
796
+ return chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(this.descriptor);
797
797
  }
798
798
  async compressedPublicKey() {
799
- return chunkUV3IM6BG_cjs.deriveDescriptorLeafCompressedPubKey(this.descriptor);
799
+ return chunkCFOIHLON_cjs.deriveDescriptorLeafCompressedPubKey(this.descriptor);
800
800
  }
801
801
  async sign(tx, inputIndexes) {
802
802
  const [signed] = await this.signer.signWithDescriptor([
@@ -856,8 +856,8 @@ var StaticDescriptorProvider = class _StaticDescriptorProvider {
856
856
  }
857
857
  isOurs(descriptor) {
858
858
  try {
859
- const normalized = chunkUV3IM6BG_cjs.normalizeToDescriptor(descriptor);
860
- const pubKey = chunkUV3IM6BG_cjs.extractPubKey(normalized);
859
+ const normalized = chunkCFOIHLON_cjs.normalizeToDescriptor(descriptor);
860
+ const pubKey = chunkCFOIHLON_cjs.extractPubKey(normalized);
861
861
  return pubKey.toLowerCase() === this.pubKeyHex.toLowerCase();
862
862
  } catch {
863
863
  return false;
@@ -1194,7 +1194,7 @@ function unwrapKeyring(provider) {
1194
1194
  }
1195
1195
  function keyOf(descriptor) {
1196
1196
  try {
1197
- return chunkUV3IM6BG_cjs.extractPubKey(chunkUV3IM6BG_cjs.normalizeToDescriptor(descriptor)).toLowerCase();
1197
+ return chunkCFOIHLON_cjs.extractPubKey(chunkCFOIHLON_cjs.normalizeToDescriptor(descriptor)).toLowerCase();
1198
1198
  } catch {
1199
1199
  return void 0;
1200
1200
  }
@@ -1285,12 +1285,12 @@ async function resolveDescriptorSigner(descriptor, identity, provider) {
1285
1285
  signMessageWithDescriptor: (ownedDescriptor, message, signatureType) => identity.signDescriptorMessage(ownedDescriptor, message, signatureType)
1286
1286
  } : void 0;
1287
1287
  const owner = providerOwner ?? identityOwner;
1288
- if (owner && chunkUV3IM6BG_cjs.parseHDDescriptor(descriptor)) {
1288
+ if (owner && chunkCFOIHLON_cjs.parseHDDescriptor(descriptor)) {
1289
1289
  return new DescriptorIdentity({ descriptor, signer: owner, base: identity });
1290
1290
  }
1291
1291
  let key;
1292
1292
  try {
1293
- key = chunkUV3IM6BG_cjs.deriveDescriptorLeafPubKey(descriptor);
1293
+ key = chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(descriptor);
1294
1294
  } catch {
1295
1295
  throw new ForeignDescriptorError(descriptor);
1296
1296
  }
@@ -1343,14 +1343,14 @@ function buildSaltedPreimageMessage(xonly, salt) {
1343
1343
  }
1344
1344
  var PREIMAGE_INDEX = 0;
1345
1345
  function isPerArtifactDescriptor(descriptor) {
1346
- return chunkUV3IM6BG_cjs.parseHDDescriptor(descriptor) !== null;
1346
+ return chunkCFOIHLON_cjs.parseHDDescriptor(descriptor) !== null;
1347
1347
  }
1348
1348
  async function provisionDescriptor(wallet) {
1349
1349
  const allocated = isHDAllocationCapable(wallet) ? await wallet.getNextSigningDescriptor() : void 0;
1350
- return allocated ?? await chunkUV3IM6BG_cjs.identityDescriptor(wallet.identity);
1350
+ return allocated ?? await chunkCFOIHLON_cjs.identityDescriptor(wallet.identity);
1351
1351
  }
1352
1352
  async function provisionRefundKey(wallet) {
1353
- const descriptor = await chunkUV3IM6BG_cjs.identityDescriptor(wallet.identity);
1353
+ const descriptor = await chunkCFOIHLON_cjs.identityDescriptor(wallet.identity);
1354
1354
  const signer = await contractSigner(wallet, descriptor);
1355
1355
  const pubkey = await signer.xOnlyPublicKey();
1356
1356
  const identityPubkey = await wallet.identity.xOnlyPublicKey();
@@ -1360,7 +1360,7 @@ async function provisionRefundKey(wallet) {
1360
1360
  );
1361
1361
  }
1362
1362
  const address = await wallet.getAddress();
1363
- const { pkScript } = chunk65CTZR2O_cjs.ArkAddress.decode(address);
1363
+ const { pkScript } = chunkVVFCCNU2_cjs.ArkAddress.decode(address);
1364
1364
  return { descriptor, pubkey, pkScript, address };
1365
1365
  }
1366
1366
  async function provisionClaimSecret(wallet, opts = {}) {
@@ -1406,7 +1406,7 @@ async function contractSigner(wallet, descriptor) {
1406
1406
  const signer = isHDWalletCapable(wallet) ? await wallet.signerForDescriptor(descriptor) : wallet.identity;
1407
1407
  let expected;
1408
1408
  try {
1409
- expected = chunkUV3IM6BG_cjs.deriveDescriptorLeafPubKey(descriptor);
1409
+ expected = chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(descriptor);
1410
1410
  } catch (cause) {
1411
1411
  throw new ForeignDescriptorError(descriptor, { cause });
1412
1412
  }
@@ -1488,7 +1488,7 @@ function debugLog(debug, ...args) {
1488
1488
  }
1489
1489
  function normalizeOptions(pathOrOptions) {
1490
1490
  const o = typeof pathOrOptions === "string" ? { path: pathOrOptions } : pathOrOptions;
1491
- chunk65CTZR2O_cjs.assertTimerMs("activationTimeoutMs", o.activationTimeoutMs);
1491
+ chunkVVFCCNU2_cjs.assertTimerMs("activationTimeoutMs", o.activationTimeoutMs);
1492
1492
  return {
1493
1493
  path: o.path,
1494
1494
  updateViaCache: o.updateViaCache ?? "none",
@@ -1611,14 +1611,14 @@ var RestDelegateProvider = class {
1611
1611
  */
1612
1612
  async delegate(intent, forfeitTxs, options) {
1613
1613
  const url = `${this.url}/v1/delegate`;
1614
- const response = await chunk65CTZR2O_cjs.baseFetch(url, {
1614
+ const response = await chunkVVFCCNU2_cjs.baseFetch(url, {
1615
1615
  method: "POST",
1616
1616
  headers: {
1617
1617
  "Content-Type": "application/json"
1618
1618
  },
1619
1619
  body: JSON.stringify({
1620
1620
  intent: {
1621
- message: chunk65CTZR2O_cjs.Intent.encodeMessage(intent.message),
1621
+ message: chunkVVFCCNU2_cjs.Intent.encodeMessage(intent.message),
1622
1622
  proof: intent.proof
1623
1623
  },
1624
1624
  forfeit_txs: forfeitTxs,
@@ -1637,7 +1637,7 @@ var RestDelegateProvider = class {
1637
1637
  */
1638
1638
  async getDelegateInfo() {
1639
1639
  const url = `${this.url}/v1/delegator/info`;
1640
- const response = await chunk65CTZR2O_cjs.rateGate.runHttp(url, () => chunk65CTZR2O_cjs.baseFetch(url));
1640
+ const response = await chunkVVFCCNU2_cjs.rateGate.runHttp(url, () => chunkVVFCCNU2_cjs.baseFetch(url));
1641
1641
  if (!response.ok) {
1642
1642
  const errorText2 = await response.text();
1643
1643
  throw new Error(`Failed to get delegate info: ${errorText2}`);
@@ -1693,7 +1693,7 @@ async function collectPages(read) {
1693
1693
  return items;
1694
1694
  }
1695
1695
  function scriptFromArkAddress(address) {
1696
- return base.hex.encode(chunk65CTZR2O_cjs.ArkAddress.decode(address).pkScript);
1696
+ return base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(address).pkScript);
1697
1697
  }
1698
1698
 
1699
1699
  // src/repositories/walletRepository.ts
@@ -1755,9 +1755,9 @@ async function collectScriptVtxos(repository, script, options) {
1755
1755
  return [...byOutpoint.values()].map((row) => row.vtxo);
1756
1756
  }
1757
1757
  function unspentScriptVtxos(rows, copies) {
1758
- const spent = copies.filter((copy) => chunk65CTZR2O_cjs.isVtxoSpent(copy.vtxo));
1758
+ const spent = copies.filter((copy) => chunkVVFCCNU2_cjs.isVtxoSpent(copy.vtxo));
1759
1759
  return rows.filter(
1760
- (row) => !chunk65CTZR2O_cjs.isVtxoSpent(row.vtxo) && !spent.some(
1760
+ (row) => !chunkVVFCCNU2_cjs.isVtxoSpent(row.vtxo) && !spent.some(
1761
1761
  (copy) => copy.address !== row.address && copy.vtxo.txid === row.vtxo.txid && copy.vtxo.vout === row.vtxo.vout && shouldReplaceScriptVtxo(row, copy)
1762
1762
  )
1763
1763
  );
@@ -1840,7 +1840,7 @@ var ESPLORA_URL = {
1840
1840
  regtest: "http://localhost:3000/api"
1841
1841
  };
1842
1842
  var EsploraProvider = class {
1843
- constructor(baseUrl = ESPLORA_URL[chunk65CTZR2O_cjs.DEFAULT_NETWORK_NAME], opts) {
1843
+ constructor(baseUrl = ESPLORA_URL[chunkVVFCCNU2_cjs.DEFAULT_NETWORK_NAME], opts) {
1844
1844
  this.baseUrl = baseUrl;
1845
1845
  this.pollingInterval = opts?.pollingInterval ?? 15e3;
1846
1846
  this.forcePolling = opts?.forcePolling ?? false;
@@ -1855,7 +1855,7 @@ var EsploraProvider = class {
1855
1855
  */
1856
1856
  addressWatches = /* @__PURE__ */ new Map();
1857
1857
  async getCoins(address) {
1858
- const response = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
1858
+ const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
1859
1859
  if (!response.ok) {
1860
1860
  throw new Error(`Failed to fetch UTXOs: ${response.statusText}`);
1861
1861
  }
@@ -1864,12 +1864,12 @@ var EsploraProvider = class {
1864
1864
  async getFeeRate() {
1865
1865
  let url = `${this.baseUrl}/fee-estimates`;
1866
1866
  let key = "1";
1867
- let response = await chunk65CTZR2O_cjs.baseFetch(url);
1867
+ let response = await chunkVVFCCNU2_cjs.baseFetch(url);
1868
1868
  if (response.status === 404) {
1869
1869
  await response.body?.cancel();
1870
1870
  url = `${this.baseUrl}/v1/fees/recommended`;
1871
1871
  key = "fastestFee";
1872
- response = await chunk65CTZR2O_cjs.baseFetch(url);
1872
+ response = await chunkVVFCCNU2_cjs.baseFetch(url);
1873
1873
  }
1874
1874
  if (response.status === 404) {
1875
1875
  await response.body?.cancel();
@@ -1906,7 +1906,7 @@ var EsploraProvider = class {
1906
1906
  }
1907
1907
  }
1908
1908
  async getTxOutspends(txid) {
1909
- const response = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
1909
+ const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
1910
1910
  if (!response.ok) {
1911
1911
  const error = await response.text();
1912
1912
  throw new Error(`Failed to get transaction outspends: ${error}`);
@@ -1914,7 +1914,7 @@ var EsploraProvider = class {
1914
1914
  return response.json();
1915
1915
  }
1916
1916
  async getTransactions(address) {
1917
- const response = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
1917
+ const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
1918
1918
  if (!response.ok) {
1919
1919
  const error = await response.text();
1920
1920
  throw new Error(`Failed to get transactions: ${error}`);
@@ -1923,14 +1923,14 @@ var EsploraProvider = class {
1923
1923
  }
1924
1924
  /** Orders of magnitude smaller than `/address/{addr}/txs`: the polling fallback's probe. */
1925
1925
  async getAddressStats(address) {
1926
- const response = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/address/${address}`);
1926
+ const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/address/${address}`);
1927
1927
  if (!response.ok) {
1928
1928
  throw new Error(`Failed to get address stats: ${response.statusText}`);
1929
1929
  }
1930
1930
  return response.json();
1931
1931
  }
1932
1932
  async getRawTransaction(txid) {
1933
- const response = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/hex`);
1933
+ const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/hex`);
1934
1934
  if (!response.ok) {
1935
1935
  const error = await response.text();
1936
1936
  throw new Error(`Failed to get raw transaction ${txid}: ${error}`);
@@ -1938,7 +1938,7 @@ var EsploraProvider = class {
1938
1938
  return base.hex.decode((await response.text()).trim());
1939
1939
  }
1940
1940
  async getTxStatus(txid) {
1941
- const txresponse = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
1941
+ const txresponse = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
1942
1942
  if (!txresponse.ok) {
1943
1943
  throw new Error(txresponse.statusText);
1944
1944
  }
@@ -1946,7 +1946,7 @@ var EsploraProvider = class {
1946
1946
  if (!tx.status.confirmed) {
1947
1947
  return { confirmed: false };
1948
1948
  }
1949
- const response = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
1949
+ const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
1950
1950
  if (!response.ok) {
1951
1951
  throw new Error(`Failed to get transaction status: ${response.statusText}`);
1952
1952
  }
@@ -2220,9 +2220,9 @@ var EsploraProvider = class {
2220
2220
  return { subscribers, teardown, started };
2221
2221
  }
2222
2222
  async getChainTip() {
2223
- let tipBlocks = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/blocks`);
2223
+ let tipBlocks = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/blocks`);
2224
2224
  if (tipBlocks.status === 404) {
2225
- tipBlocks = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/v1/blocks`);
2225
+ tipBlocks = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/v1/blocks`);
2226
2226
  }
2227
2227
  if (!tipBlocks.ok) {
2228
2228
  throw new Error(`Failed to get chain tip: ${tipBlocks.statusText}`);
@@ -2243,7 +2243,7 @@ var EsploraProvider = class {
2243
2243
  };
2244
2244
  }
2245
2245
  async broadcastPackage(parent, child) {
2246
- const response = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
2246
+ const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
2247
2247
  method: "POST",
2248
2248
  headers: {
2249
2249
  "Content-Type": "application/json"
@@ -2259,7 +2259,7 @@ var EsploraProvider = class {
2259
2259
  return result;
2260
2260
  }
2261
2261
  async broadcastTx(tx) {
2262
- const response = await chunk65CTZR2O_cjs.baseFetch(`${this.baseUrl}/tx`, {
2262
+ const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx`, {
2263
2263
  method: "POST",
2264
2264
  headers: {
2265
2265
  "Content-Type": "text/plain"
@@ -2431,7 +2431,7 @@ function findP2AOutput(tx) {
2431
2431
  var CHILD_DUST_AMOUNT = 546;
2432
2432
  function buildAnchorChild(params) {
2433
2433
  const { parent, feeRate, fundingCoins, changeAddress, tapInternalKey, network } = params;
2434
- const child = new chunk65CTZR2O_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
2434
+ const child = new chunkVVFCCNU2_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
2435
2435
  const anchor = findP2AOutput(parent);
2436
2436
  child.addInput(anchor);
2437
2437
  const estimator = TxWeightEstimator.create().addP2AInput();
@@ -2480,7 +2480,7 @@ function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
2480
2480
  );
2481
2481
  }
2482
2482
  function buildForfeitTxWithOutput(inputs, output, txLocktime) {
2483
- const tx = new chunk65CTZR2O_cjs.Transaction({
2483
+ const tx = new chunkVVFCCNU2_cjs.Transaction({
2484
2484
  version: 3,
2485
2485
  lockTime: txLocktime
2486
2486
  });
@@ -2507,7 +2507,7 @@ function validateConnectorsTxGraph(settlementTxB64, connectorsGraph) {
2507
2507
  connectorsGraph.validate();
2508
2508
  if (connectorsGraph.root.inputsLength !== 1) throw ErrNumberOfInputs;
2509
2509
  const rootInput = connectorsGraph.root.getInput(0);
2510
- const settlementTx = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(settlementTxB64));
2510
+ const settlementTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(settlementTxB64));
2511
2511
  if (settlementTx.outputsLength <= BATCH_OUTPUT_CONNECTORS_INDEX)
2512
2512
  throw ErrInvalidSettlementTxOutputs;
2513
2513
  const expectedRootTxid = settlementTx.id;
@@ -2556,7 +2556,7 @@ function validateVtxoTxGraph(graph, roundTransaction, sweepTapTreeRoot) {
2556
2556
  if (previousScriptKey.length !== 32) {
2557
2557
  throw new Error(`parent output ${childIndex} has invalid script`);
2558
2558
  }
2559
- const cosigners = chunk65CTZR2O_cjs.getArkPsbtFields(child.root, 0, chunk65CTZR2O_cjs.CosignerPublicKey);
2559
+ const cosigners = chunkVVFCCNU2_cjs.getArkPsbtFields(child.root, 0, chunkVVFCCNU2_cjs.CosignerPublicKey);
2560
2560
  if (cosigners.length === 0) {
2561
2561
  throw ErrMissingCosignersPublicKeys;
2562
2562
  }
@@ -2614,7 +2614,7 @@ var EmulatorPacket = class _EmulatorPacket {
2614
2614
  return new _EmulatorPacket(entries);
2615
2615
  }
2616
2616
  static fromBytes(data) {
2617
- const reader = new chunkPAD5V653_cjs.BufferReader(data);
2617
+ const reader = new chunkFEBAG2K2_cjs.BufferReader(data);
2618
2618
  const entryCount = reader.readCompactSize();
2619
2619
  const entries = [];
2620
2620
  for (let i = 0; i < entryCount; i++) {
@@ -2632,7 +2632,7 @@ var EmulatorPacket = class _EmulatorPacket {
2632
2632
  return _EmulatorPacket.PACKET_TYPE;
2633
2633
  }
2634
2634
  serialize() {
2635
- const writer = new chunkPAD5V653_cjs.BufferWriter();
2635
+ const writer = new chunkFEBAG2K2_cjs.BufferWriter();
2636
2636
  writer.writeCompactSize(this.entries.length);
2637
2637
  for (const entry of this.entries) {
2638
2638
  writer.writeUint16LE(entry.vin);
@@ -2719,7 +2719,7 @@ var Extension = class _Extension {
2719
2719
  `expected magic prefix ${base.hex.encode(ARKADE_MAGIC)}, got ${base.hex.encode(payload.slice(0, Math.min(payload.length, ARKADE_MAGIC.length)))}`
2720
2720
  );
2721
2721
  }
2722
- const reader = new chunkPAD5V653_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
2722
+ const reader = new chunkFEBAG2K2_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
2723
2723
  const packets = [];
2724
2724
  while (reader.remaining() > 0) {
2725
2725
  const packetType = reader.readByte();
@@ -2792,7 +2792,7 @@ var Extension = class _Extension {
2792
2792
  * getAssetPacket returns the embedded Packet, or null if not present.
2793
2793
  */
2794
2794
  getAssetPacket() {
2795
- return this.packets.find((p) => p instanceof chunkPAD5V653_cjs.Packet) ?? null;
2795
+ return this.packets.find((p) => p instanceof chunkFEBAG2K2_cjs.Packet) ?? null;
2796
2796
  }
2797
2797
  /**
2798
2798
  * getEmulatorPacket returns the embedded EmulatorPacket, or null if not present.
@@ -2816,8 +2816,8 @@ var Extension = class _Extension {
2816
2816
  };
2817
2817
  function parsePacket(packetType, data) {
2818
2818
  switch (packetType) {
2819
- case chunkPAD5V653_cjs.Packet.PACKET_TYPE:
2820
- return chunkPAD5V653_cjs.Packet.fromBytes(data);
2819
+ case chunkFEBAG2K2_cjs.Packet.PACKET_TYPE:
2820
+ return chunkFEBAG2K2_cjs.Packet.fromBytes(data);
2821
2821
  case EmulatorPacket.PACKET_TYPE:
2822
2822
  return EmulatorPacket.fromBytes(data);
2823
2823
  default:
@@ -2864,22 +2864,22 @@ function buildOpReturnScript(data) {
2864
2864
  }
2865
2865
  return script;
2866
2866
  }
2867
- var ErrOffchainOutputNotFound = (address) => new chunk65CTZR2O_cjs.ServerResponseMismatchError(`offchain send output not found: ${address}`);
2868
- var ErrInvalidAssetOutputAmount = (got, want, assetId) => new chunk65CTZR2O_cjs.ServerResponseMismatchError(
2867
+ var ErrOffchainOutputNotFound = (address) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(`offchain send output not found: ${address}`);
2868
+ var ErrInvalidAssetOutputAmount = (got, want, assetId) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
2869
2869
  `invalid asset output amount for ${assetId}: got ${got}, want ${want}`
2870
2870
  );
2871
- var ErrAssetGroupNotFound = (assetId) => new chunk65CTZR2O_cjs.ServerResponseMismatchError(`asset group not found in batch leaf: ${assetId}`);
2872
- var ErrAssetOutputNotFound = (assetId, outputIndex) => new chunk65CTZR2O_cjs.ServerResponseMismatchError(
2871
+ var ErrAssetGroupNotFound = (assetId) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(`asset group not found in batch leaf: ${assetId}`);
2872
+ var ErrAssetOutputNotFound = (assetId, outputIndex) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
2873
2873
  `asset output not found in asset group ${assetId} at index ${outputIndex}`
2874
2874
  );
2875
- var ErrOnchainOutputNotFound = (address) => new chunk65CTZR2O_cjs.ServerResponseMismatchError(`onchain output not found: ${address}`);
2876
- var ErrUnvalidatedOffchainOutput = (address) => new chunk65CTZR2O_cjs.ServerResponseMismatchError(
2875
+ var ErrOnchainOutputNotFound = (address) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(`onchain output not found: ${address}`);
2876
+ var ErrUnvalidatedOffchainOutput = (address) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
2877
2877
  `offchain output ${address} cannot be validated: virtual output tree signing did not run`
2878
2878
  );
2879
- var ErrIntentOutputNotFound = (index, kind) => new chunk65CTZR2O_cjs.ServerResponseMismatchError(
2879
+ var ErrIntentOutputNotFound = (index, kind) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
2880
2880
  `${kind} output ${index} of the intent proof is not present in what the server built`
2881
2881
  );
2882
- var ErrUnvalidatedIntentOutput = (index) => new chunk65CTZR2O_cjs.ServerResponseMismatchError(
2882
+ var ErrUnvalidatedIntentOutput = (index) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
2883
2883
  `offchain output ${index} of the intent proof cannot be validated: virtual output tree signing did not run`
2884
2884
  );
2885
2885
  var ErrInvalidOnchainOutputAmount = (address) => new Error(`invalid onchain output amount: ${address}`);
@@ -2888,7 +2888,7 @@ var ErrInvalidOffchainOutputAmount = (address) => new Error(`invalid offchain ou
2888
2888
  function assertFinalCommitmentMatchesValidated(finalCommitmentTx, validatedCommitmentTxid, context) {
2889
2889
  if (!validatedCommitmentTxid) return;
2890
2890
  if (finalCommitmentTx.id === validatedCommitmentTxid) return;
2891
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
2891
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
2892
2892
  `${context}: finalization commitment tx ${finalCommitmentTx.id} differs from the validated commitment tx ${validatedCommitmentTxid}`
2893
2893
  );
2894
2894
  }
@@ -2898,7 +2898,7 @@ function validateBatchRecipients(commitmentTx, vtxoTreeLeaves, recipients, netwo
2898
2898
  for (const recipient of recipients) {
2899
2899
  let arkAddress;
2900
2900
  try {
2901
- arkAddress = chunk65CTZR2O_cjs.ArkAddress.decode(recipient.address);
2901
+ arkAddress = chunkVVFCCNU2_cjs.ArkAddress.decode(recipient.address);
2902
2902
  } catch {
2903
2903
  validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
2904
2904
  continue;
@@ -2910,7 +2910,7 @@ function validateBatchRecipientsWithoutTree(commitmentTx, recipients, network) {
2910
2910
  const usedOnchainOutputs = /* @__PURE__ */ new Set();
2911
2911
  for (const recipient of recipients) {
2912
2912
  try {
2913
- chunk65CTZR2O_cjs.ArkAddress.decode(recipient.address);
2913
+ chunkVVFCCNU2_cjs.ArkAddress.decode(recipient.address);
2914
2914
  } catch {
2915
2915
  validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
2916
2916
  continue;
@@ -2919,7 +2919,7 @@ function validateBatchRecipientsWithoutTree(commitmentTx, recipients, network) {
2919
2919
  }
2920
2920
  }
2921
2921
  function declaredIntentOutputs(signedProof, onchainOutputIndexes) {
2922
- const proof = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(signedProof));
2922
+ const proof = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(signedProof));
2923
2923
  const onchain = new Set(onchainOutputIndexes);
2924
2924
  const declared = [];
2925
2925
  for (let i = 0; i < proof.outputsLength; i++) {
@@ -3211,7 +3211,7 @@ function assetMintResolver() {
3211
3211
  if (!tx.assets?.length || !tx.key.arkTxid) return void 0;
3212
3212
  const minted = tx.assets.filter((a) => {
3213
3213
  try {
3214
- return base.hex.encode(chunkPAD5V653_cjs.AssetId.fromString(a.assetId).txid) === tx.key.arkTxid;
3214
+ return base.hex.encode(chunkFEBAG2K2_cjs.AssetId.fromString(a.assetId).txid) === tx.key.arkTxid;
3215
3215
  } catch {
3216
3216
  return false;
3217
3217
  }
@@ -3288,7 +3288,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
3288
3288
  const existing = inputsByAssetId.get(asset.assetId);
3289
3289
  inputsByAssetId.set(asset.assetId, [
3290
3290
  ...existing ?? [],
3291
- chunkPAD5V653_cjs.AssetInput.create(inputIndex, asset.amount)
3291
+ chunkFEBAG2K2_cjs.AssetInput.create(inputIndex, asset.amount)
3292
3292
  ]);
3293
3293
  }
3294
3294
  }
@@ -3300,7 +3300,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
3300
3300
  const existing = outputsByAssetId.get(asset.assetId);
3301
3301
  outputsByAssetId.set(asset.assetId, [
3302
3302
  ...existing ?? [],
3303
- chunkPAD5V653_cjs.AssetOutput.create(outputIndex, asset.amount)
3303
+ chunkFEBAG2K2_cjs.AssetOutput.create(outputIndex, asset.amount)
3304
3304
  ]);
3305
3305
  }
3306
3306
  }
@@ -3311,7 +3311,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
3311
3311
  const existing = outputsByAssetId.get(asset.assetId);
3312
3312
  outputsByAssetId.set(asset.assetId, [
3313
3313
  ...existing ?? [],
3314
- chunkPAD5V653_cjs.AssetOutput.create(outputIndex, asset.amount)
3314
+ chunkFEBAG2K2_cjs.AssetOutput.create(outputIndex, asset.amount)
3315
3315
  ]);
3316
3316
  }
3317
3317
  }
@@ -3320,11 +3320,11 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
3320
3320
  for (const assetIdStr of allAssetIds) {
3321
3321
  const inputs = inputsByAssetId.get(assetIdStr);
3322
3322
  const outputs = outputsByAssetId.get(assetIdStr);
3323
- const assetId = chunkPAD5V653_cjs.AssetId.fromString(assetIdStr);
3324
- const group = chunkPAD5V653_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
3323
+ const assetId = chunkFEBAG2K2_cjs.AssetId.fromString(assetIdStr);
3324
+ const group = chunkFEBAG2K2_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
3325
3325
  groups.push(group);
3326
3326
  }
3327
- return chunkPAD5V653_cjs.Packet.create(groups);
3327
+ return chunkFEBAG2K2_cjs.Packet.create(groups);
3328
3328
  }
3329
3329
  function selectCoinsWithAsset(coins, assetId, requiredAmount) {
3330
3330
  const coinsWithAsset = coins.filter((coin) => coin.assets?.some((a) => a.assetId === assetId));
@@ -3408,7 +3408,7 @@ function meetsInputExpiryFloor(coin, floor) {
3408
3408
  }
3409
3409
  function toXOnlySignerHex(pubkeyHex) {
3410
3410
  const bytes = base.hex.decode(pubkeyHex);
3411
- if (bytes.length === 32 || bytes.length === 33) return base.hex.encode(chunkUV3IM6BG_cjs.toXOnly(bytes, "signer key"));
3411
+ if (bytes.length === 32 || bytes.length === 33) return base.hex.encode(chunkCFOIHLON_cjs.toXOnly(bytes, "signer key"));
3412
3412
  throw new Error(`invalid signer pubkey length: expected 32 or 33 bytes, got ${bytes.length}`);
3413
3413
  }
3414
3414
  function signerSetFromInfo(info) {
@@ -3455,13 +3455,13 @@ var toTimelock = (value) => ({
3455
3455
  var toSeconds = (t) => t.type === "seconds" ? t.value : t.value * NOMINAL_BLOCK_SECONDS;
3456
3456
  function assertTimelockInPolicy(timelock, policy, label, overrideOption) {
3457
3457
  if (policy.requireSeconds && timelock.type === "blocks") {
3458
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3458
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3459
3459
  `${label} rejected: block-typed timelocks are not accepted (got ${timelock.value})`
3460
3460
  );
3461
3461
  }
3462
3462
  const seconds = toSeconds(timelock);
3463
3463
  if (seconds < policy.minSeconds) {
3464
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3464
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3465
3465
  `${label} rejected: ${timelock.value} ${timelock.type} is below the ${policy.minSeconds}s floor; pass ${overrideOption}: ${seconds}n to Wallet.create to lower it`
3466
3466
  );
3467
3467
  }
@@ -3482,7 +3482,7 @@ function resolveBatchExpiryPolicy(network, overrides) {
3482
3482
  }
3483
3483
  function assertValidBatchExpiry(batchExpiry, policy) {
3484
3484
  if (policy.advertisedVtxoTreeExpiry !== void 0 && batchExpiry !== policy.advertisedVtxoTreeExpiry) {
3485
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3485
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3486
3486
  `batch expiry rejected: ${batchExpiry} does not match the advertised vtxoTreeExpiry ${policy.advertisedVtxoTreeExpiry}`
3487
3487
  );
3488
3488
  }
@@ -3512,21 +3512,21 @@ function resolveCheckpointExitDelayPolicy(network, overrides) {
3512
3512
  function assertValidServerUnrollScript(checkpointTapscript, policy) {
3513
3513
  let script;
3514
3514
  try {
3515
- script = chunk65CTZR2O_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
3515
+ script = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
3516
3516
  } catch (e) {
3517
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3517
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3518
3518
  `checkpoint exit delay rejected: invalid checkpointTapscript from server (${e instanceof Error ? e.message : String(e)})`
3519
3519
  );
3520
3520
  }
3521
3521
  if (policy.advertisedForfeitPubkey !== void 0) {
3522
3522
  const { pubkeys } = script.params;
3523
3523
  if (pubkeys.length !== 1) {
3524
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3524
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3525
3525
  `checkpoint exit delay rejected: checkpointTapscript must commit to exactly one pubkey, got ${pubkeys.length} [${pubkeys.map(base.hex.encode).join(", ")}]`
3526
3526
  );
3527
3527
  }
3528
3528
  if (!utils_js.equalBytes(pubkeys[0], policy.advertisedForfeitPubkey)) {
3529
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3529
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3530
3530
  `checkpoint exit delay rejected: checkpointTapscript pubkey ${base.hex.encode(pubkeys[0])} does not match the advertised forfeitPubkey ${base.hex.encode(policy.advertisedForfeitPubkey)}`
3531
3531
  );
3532
3532
  }
@@ -3570,8 +3570,8 @@ function buildOffchainTx(inputs, outputs, serverUnrollScript) {
3570
3570
  function buildVirtualTx(inputs, outputs) {
3571
3571
  let lockTime = 0n;
3572
3572
  for (const input of inputs) {
3573
- const tapscript = chunk65CTZR2O_cjs.decodeTapscript(chunk65CTZR2O_cjs.scriptFromTapLeafScript(input.tapLeafScript));
3574
- if (chunk65CTZR2O_cjs.CLTVMultisigTapscript.is(tapscript)) {
3573
+ const tapscript = chunkVVFCCNU2_cjs.decodeTapscript(chunkVVFCCNU2_cjs.scriptFromTapLeafScript(input.tapLeafScript));
3574
+ if (chunkVVFCCNU2_cjs.CLTVMultisigTapscript.is(tapscript)) {
3575
3575
  if (lockTime !== 0n) {
3576
3576
  if (isSeconds(lockTime) !== isSeconds(tapscript.params.absoluteTimelock)) {
3577
3577
  throw new Error("cannot mix seconds and blocks locktime");
@@ -3582,7 +3582,7 @@ function buildVirtualTx(inputs, outputs) {
3582
3582
  }
3583
3583
  }
3584
3584
  }
3585
- const tx = new chunk65CTZR2O_cjs.Transaction({
3585
+ const tx = new chunkVVFCCNU2_cjs.Transaction({
3586
3586
  version: 3,
3587
3587
  lockTime: Number(lockTime)
3588
3588
  });
@@ -3592,12 +3592,12 @@ function buildVirtualTx(inputs, outputs) {
3592
3592
  index: input.vout,
3593
3593
  sequence: lockTime ? btcSigner.DEFAULT_SEQUENCE - 1 : void 0,
3594
3594
  witnessUtxo: {
3595
- script: chunk65CTZR2O_cjs.VtxoScript.decode(input.tapTree).pkScript,
3595
+ script: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript,
3596
3596
  amount: BigInt(input.value)
3597
3597
  },
3598
3598
  tapLeafScript: [input.tapLeafScript]
3599
3599
  });
3600
- chunk65CTZR2O_cjs.setArkPsbtField(tx, i, chunk65CTZR2O_cjs.VtxoTaprootTree, input.tapTree);
3600
+ chunkVVFCCNU2_cjs.setArkPsbtField(tx, i, chunkVVFCCNU2_cjs.VtxoTaprootTree, input.tapTree);
3601
3601
  }
3602
3602
  for (const output of outputs) {
3603
3603
  tx.addOutput(output);
@@ -3608,8 +3608,8 @@ function buildVirtualTx(inputs, outputs) {
3608
3608
  return tx;
3609
3609
  }
3610
3610
  function buildCheckpointTx(vtxo, serverUnrollScript) {
3611
- const collaborativeClosure = chunk65CTZR2O_cjs.decodeTapscript(chunk65CTZR2O_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
3612
- const checkpointVtxoScript = new chunk65CTZR2O_cjs.VtxoScript([
3611
+ const collaborativeClosure = chunkVVFCCNU2_cjs.decodeTapscript(chunkVVFCCNU2_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
3612
+ const checkpointVtxoScript = new chunkVVFCCNU2_cjs.VtxoScript([
3613
3613
  serverUnrollScript.script,
3614
3614
  collaborativeClosure.script
3615
3615
  ]);
@@ -3685,7 +3685,7 @@ function verifyTapscriptSignatures(tx, inputIndex, requiredSigners, excludePubke
3685
3685
  const sighashType = signature.length === 65 ? signature[64] : btcSigner.SigHash.DEFAULT;
3686
3686
  const sig = signature.subarray(0, 64);
3687
3687
  if (!allowedSighashTypes.includes(sighashType)) {
3688
- const sighashName = chunk65CTZR2O_cjs.formatSighash(sighashType);
3688
+ const sighashName = chunkVVFCCNU2_cjs.formatSighash(sighashType);
3689
3689
  throw new Error(
3690
3690
  `Unallowed sighash type ${sighashName} for input ${inputIndex}, pubkey ${pubKeyHex}.`
3691
3691
  );
@@ -3759,7 +3759,7 @@ function combineTapscriptSigs(signedTx, originalTx) {
3759
3759
  }
3760
3760
  function isValidArkAddress(address) {
3761
3761
  try {
3762
- chunk65CTZR2O_cjs.ArkAddress.decode(address);
3762
+ chunkVVFCCNU2_cjs.ArkAddress.decode(address);
3763
3763
  return true;
3764
3764
  } catch (e) {
3765
3765
  return false;
@@ -3767,16 +3767,16 @@ function isValidArkAddress(address) {
3767
3767
  }
3768
3768
  function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, context) {
3769
3769
  if (serverCheckpointTxs.length !== expectedCheckpoints.length) {
3770
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3770
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3771
3771
  `${context} returned ${serverCheckpointTxs.length} checkpoints, expected ${expectedCheckpoints.length}`
3772
3772
  );
3773
3773
  }
3774
3774
  const byTxid = new Map(expectedCheckpoints.map((c) => [c.id, c]));
3775
3775
  return serverCheckpointTxs.map((encoded, index) => {
3776
- const server = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
3776
+ const server = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
3777
3777
  const local = byTxid.get(server.id);
3778
3778
  if (!local) {
3779
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3779
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3780
3780
  `${context} checkpoint ${index} txid ${server.id} does not match any submitted checkpoint`
3781
3781
  );
3782
3782
  }
@@ -3786,14 +3786,14 @@ function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, contex
3786
3786
  }
3787
3787
  function assertSubmittedArkTxid(response, signedArkTx, context) {
3788
3788
  if (response.arkTxid !== signedArkTx.id) {
3789
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3789
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3790
3790
  `${context} returned ark txid ${response.arkTxid}, expected ${signedArkTx.id}`
3791
3791
  );
3792
3792
  }
3793
3793
  if (response.finalArkTx === void 0) return;
3794
- const finalTxid = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx)).id;
3794
+ const finalTxid = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx)).id;
3795
3795
  if (finalTxid !== signedArkTx.id) {
3796
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3796
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3797
3797
  `${context} returned final ark tx ${finalTxid}, expected ${signedArkTx.id}`
3798
3798
  );
3799
3799
  }
@@ -3805,20 +3805,20 @@ function assertServerSignedLeaf(serverTx, localTx, inputIndex, serverPubkeys, co
3805
3805
  `${context}: input ${inputIndex} carries no spend leaf to verify the server signature against`
3806
3806
  );
3807
3807
  }
3808
- const script = chunk65CTZR2O_cjs.scriptFromTapLeafScript(leaf);
3808
+ const script = chunkVVFCCNU2_cjs.scriptFromTapLeafScript(leaf);
3809
3809
  let leafPubkeys;
3810
3810
  try {
3811
- leafPubkeys = chunk65CTZR2O_cjs.decodeTapscript(script).params.pubkeys.map(
3812
- (key) => base.hex.encode(chunkUV3IM6BG_cjs.toXOnly(key, "leaf key"))
3811
+ leafPubkeys = chunkVVFCCNU2_cjs.decodeTapscript(script).params.pubkeys.map(
3812
+ (key) => base.hex.encode(chunkCFOIHLON_cjs.toXOnly(key, "leaf key"))
3813
3813
  );
3814
3814
  } catch (error) {
3815
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3815
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3816
3816
  `${context}: input ${inputIndex} spend leaf cannot be decoded (${error instanceof Error ? error.message : String(error)})`
3817
3817
  );
3818
3818
  }
3819
3819
  const signer = leafPubkeys.find((key) => serverPubkeys.has(key));
3820
3820
  if (!signer) {
3821
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3821
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3822
3822
  `${context}: input ${inputIndex} spend leaf names no signer key the server advertises`
3823
3823
  );
3824
3824
  }
@@ -3832,7 +3832,7 @@ function assertServerSignedLeaf(serverTx, localTx, inputIndex, serverPubkeys, co
3832
3832
  payment_js.tapLeafHash(script)
3833
3833
  );
3834
3834
  } catch (error) {
3835
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3835
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3836
3836
  `${context}: input ${inputIndex} is not signed by the server on the leaf being spent (${error instanceof Error ? error.message : String(error)})`
3837
3837
  );
3838
3838
  }
@@ -3841,20 +3841,20 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
3841
3841
  const byOutpoint = new Map(inputs.map((input) => [`${input.txid}:${input.vout}`, input]));
3842
3842
  for (const [index, checkpoint] of checkpoints.entries()) {
3843
3843
  if (checkpoint.inputsLength !== 1) {
3844
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3844
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3845
3845
  `${context}: checkpoint ${index} spends ${checkpoint.inputsLength} inputs, expected 1`
3846
3846
  );
3847
3847
  }
3848
3848
  const spent = checkpoint.getInput(0);
3849
3849
  if (!spent.txid || spent.index === void 0) {
3850
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3850
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3851
3851
  `${context}: checkpoint ${index} has no input outpoint`
3852
3852
  );
3853
3853
  }
3854
3854
  const outpoint = `${base.hex.encode(spent.txid)}:${spent.index}`;
3855
3855
  const input = byOutpoint.get(outpoint);
3856
3856
  if (!input) {
3857
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3857
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3858
3858
  `${context}: checkpoint ${index} spends ${outpoint}, which is not one of the requested virtual outputs`
3859
3859
  );
3860
3860
  }
@@ -3862,7 +3862,7 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
3862
3862
  (unroll) => buildCheckpointTx(input, unroll).tx.id === checkpoint.id
3863
3863
  );
3864
3864
  if (!rebuilt) {
3865
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3865
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3866
3866
  `${context}: checkpoint ${index} txid ${checkpoint.id} differs from the checkpoint built locally for ${outpoint}`
3867
3867
  );
3868
3868
  }
@@ -3888,9 +3888,9 @@ async function submitOffchainTx(provider, offchainTx, signer, hooks, options) {
3888
3888
  const matched = matchServerCheckpoints(signedCheckpointTxs, offchainTx.checkpoints, "submitTx");
3889
3889
  matched.forEach(({ server }, index) => {
3890
3890
  try {
3891
- chunk65CTZR2O_cjs.assertAllowedSighashTypes(server);
3891
+ chunkVVFCCNU2_cjs.assertAllowedSighashTypes(server);
3892
3892
  } catch (error) {
3893
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3893
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3894
3894
  `submitTx checkpoint ${index}: ${error instanceof Error ? error.message : String(error)}`
3895
3895
  );
3896
3896
  }
@@ -3898,14 +3898,14 @@ async function submitOffchainTx(provider, offchainTx, signer, hooks, options) {
3898
3898
  const verify = options?.verifyServerSignatures;
3899
3899
  if (verify) {
3900
3900
  if (response.finalArkTx === void 0) {
3901
- throw new chunk65CTZR2O_cjs.ServerResponseMismatchError(
3901
+ throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
3902
3902
  "submitTx: server returned no final ark tx to verify its signatures against"
3903
3903
  );
3904
3904
  }
3905
- const finalArkTx = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx));
3905
+ const finalArkTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx));
3906
3906
  const serverPubkeys = new Set(
3907
3907
  [verify.serverPubkey, ...verify.deprecatedServerPubkeys ?? []].map(
3908
- (key) => base.hex.encode(chunkUV3IM6BG_cjs.toXOnly(key, "server key"))
3908
+ (key) => base.hex.encode(chunkCFOIHLON_cjs.toXOnly(key, "server key"))
3909
3909
  )
3910
3910
  );
3911
3911
  for (let i = 0; i < offchainTx.arkTx.inputsLength; i++) {
@@ -3953,16 +3953,36 @@ async function signAndSubmitOffchainTx(params) {
3953
3953
  });
3954
3954
  return arkTxid;
3955
3955
  }
3956
+ async function submitViaEmulator(emulator, offchainTx, signer, opts) {
3957
+ const { inputIndexes } = opts;
3958
+ let { arkTx, checkpoints } = offchainTx;
3959
+ if (inputIndexes.length > 0) {
3960
+ if (!signer) {
3961
+ throw new Error(`this spend requires an \`identity\` to sign inputs ${inputIndexes}`);
3962
+ }
3963
+ arkTx = await signer.sign(arkTx, inputIndexes);
3964
+ checkpoints = await Promise.all(
3965
+ checkpoints.map((c, i) => inputIndexes.includes(i) ? signer.sign(c, [0]) : c)
3966
+ );
3967
+ }
3968
+ const res = await emulator.submitTx(
3969
+ base.base64.encode(arkTx.toPSBT()),
3970
+ checkpoints.map((c) => base.base64.encode(c.toPSBT()))
3971
+ );
3972
+ const txid = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(res.signedArkTx)).id;
3973
+ assertSubmittedArkTxid({ arkTxid: txid }, arkTx, "emulator submitTx");
3974
+ return { txid, signedArkTx: res.signedArkTx, signedCheckpointTxs: res.signedCheckpointTxs };
3975
+ }
3956
3976
  function claimWithPreimageIdentity(identity, preimage) {
3957
3977
  return {
3958
3978
  ...identity,
3959
3979
  sign: async (tx, inputIndexes) => {
3960
- const signed = chunk65CTZR2O_cjs.Transaction.fromPSBT(
3980
+ const signed = chunkVVFCCNU2_cjs.Transaction.fromPSBT(
3961
3981
  (await identity.sign(tx.clone(), inputIndexes)).toPSBT()
3962
3982
  );
3963
3983
  const indexes = inputIndexes ?? Array.from({ length: signed.inputsLength }, (_, i) => i);
3964
3984
  for (const index of indexes) {
3965
- chunk65CTZR2O_cjs.setArkPsbtField(signed, index, chunk65CTZR2O_cjs.ConditionWitness, [preimage]);
3985
+ chunkVVFCCNU2_cjs.setArkPsbtField(signed, index, chunkVVFCCNU2_cjs.ConditionWitness, [preimage]);
3966
3986
  }
3967
3987
  return signed;
3968
3988
  }
@@ -4145,7 +4165,7 @@ function extendCoinWithTapscript(boardingTapscript, utxo) {
4145
4165
  };
4146
4166
  }
4147
4167
  function deriveContractTapscripts(contract) {
4148
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(contract.type);
4168
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
4149
4169
  if (!handler) {
4150
4170
  throw new Error(`No handler for contract type '${contract.type}'`);
4151
4171
  }
@@ -4214,6 +4234,18 @@ function getRandomId() {
4214
4234
  const randomValue = crypto.getRandomValues(new Uint8Array(16));
4215
4235
  return base.hex.encode(randomValue);
4216
4236
  }
4237
+ var sdkPicked = /* @__PURE__ */ new WeakSet();
4238
+ function markSdkPicked(params) {
4239
+ sdkPicked.add(params);
4240
+ return params;
4241
+ }
4242
+ function isSdkPicked(params) {
4243
+ return params !== void 0 && sdkPicked.has(params);
4244
+ }
4245
+ function getSelectableBoardingUtxos(wallet) {
4246
+ const selectable = wallet.getSelectableBoardingUtxos;
4247
+ return typeof selectable === "function" ? selectable.call(wallet) : wallet.getBoardingUtxos();
4248
+ }
4217
4249
  function assertRecipientArkadeAddress(encoded, address, context) {
4218
4250
  if (address.hrp !== context.hrp) {
4219
4251
  throw new Error(
@@ -4236,7 +4268,7 @@ function assertRecipientArkadeAddress(encoded, address, context) {
4236
4268
  function assertTapTreeDerivesAddress(encoded, tapTree, address) {
4237
4269
  let derived;
4238
4270
  try {
4239
- derived = chunk65CTZR2O_cjs.VtxoScript.decode(tapTree).pkScript;
4271
+ derived = chunkVVFCCNU2_cjs.VtxoScript.decode(tapTree).pkScript;
4240
4272
  } catch (e) {
4241
4273
  throw new Error(
4242
4274
  `Invalid tapTree for ${encoded}: ${e instanceof Error ? e.message : String(e)}`
@@ -4253,7 +4285,7 @@ function validateRecipients(recipients, dustAmount, context) {
4253
4285
  for (const recipient of recipients) {
4254
4286
  let address;
4255
4287
  try {
4256
- address = chunk65CTZR2O_cjs.ArkAddress.decode(recipient.address);
4288
+ address = chunkVVFCCNU2_cjs.ArkAddress.decode(recipient.address);
4257
4289
  } catch (e) {
4258
4290
  throw new Error(`Invalid Arkade address: ${recipient.address}`);
4259
4291
  }
@@ -4278,7 +4310,7 @@ function validateRecipients(recipients, dustAmount, context) {
4278
4310
 
4279
4311
  // src/contracts/spendability.ts
4280
4312
  function isContractGenericallySpendable(contract) {
4281
- return chunkUV3IM6BG_cjs.contractHandlers.get(contract.type)?.isGenericallySpendable?.(contract) === true;
4313
+ return chunkCFOIHLON_cjs.contractHandlers.get(contract.type)?.isGenericallySpendable?.(contract) === true;
4282
4314
  }
4283
4315
  function gatedContracts(contracts) {
4284
4316
  const gated = /* @__PURE__ */ new Map();
@@ -4300,7 +4332,7 @@ function gateExclusion(gated) {
4300
4332
  return (vtxo) => {
4301
4333
  const type = gatedTypeOf(vtxo, gated);
4302
4334
  if (type === void 0) return void 0;
4303
- if (!chunkUV3IM6BG_cjs.contractHandlers.has(type)) {
4335
+ if (!chunkCFOIHLON_cjs.contractHandlers.has(type)) {
4304
4336
  return `at ${vtxo.script} (contract type '${type}') has no handler registered in this build`;
4305
4337
  }
4306
4338
  return `at ${vtxo.script} (contract type '${type}') is not generically spendable`;
@@ -4336,7 +4368,7 @@ function selectPendingRecoveryOutpoints(contractsWithVtxos, signerSet, nowSecond
4336
4368
  continue;
4337
4369
  }
4338
4370
  for (const v of vtxos) {
4339
- if (!chunk65CTZR2O_cjs.isVtxoSpent(v) && !v.isSwept && !v.isUnrolled) {
4371
+ if (!chunkVVFCCNU2_cjs.isVtxoSpent(v) && !v.isSwept && !v.isUnrolled) {
4340
4372
  out.add(`${v.txid}:${v.vout}`);
4341
4373
  }
4342
4374
  }
@@ -4372,10 +4404,14 @@ function byValueDescending(vtxos) {
4372
4404
  return [...vtxos].sort((a, b) => b.value - a.value);
4373
4405
  }
4374
4406
  async function fetchTimeHeight(wallet) {
4375
- return chunk65CTZR2O_cjs.resolveTimeHeight(wallet.onchainProvider);
4407
+ return chunkVVFCCNU2_cjs.resolveTimeHeight(wallet.onchainProvider);
4408
+ }
4409
+ function heldVtxosOf(wallet) {
4410
+ const held = wallet.getHeldVtxos;
4411
+ return typeof held === "function" ? held.call(wallet) : Promise.resolve([]);
4376
4412
  }
4377
4413
  function canMigrateBySend(vtxo, now) {
4378
- if (!chunk65CTZR2O_cjs.canSpendOffchain(vtxo, now)) return false;
4414
+ if (!chunkVVFCCNU2_cjs.canSpendOffchain(vtxo, now)) return false;
4379
4415
  return vtxo.expiresAt !== void 0 || vtxo.expiresAtHeight !== void 0;
4380
4416
  }
4381
4417
  function byExpiryAscending(vtxos, now) {
@@ -4383,7 +4419,7 @@ function byExpiryAscending(vtxos, now) {
4383
4419
  if (vtxo.isSwept) return -Infinity;
4384
4420
  if (vtxo.expiresAt !== void 0) return vtxo.expiresAt.getTime();
4385
4421
  if (vtxo.expiresAtHeight !== void 0) {
4386
- return chunk65CTZR2O_cjs.isPastExpiry(vtxo, now) ? -Infinity : Infinity;
4422
+ return chunkVVFCCNU2_cjs.isPastExpiry(vtxo, now) ? -Infinity : Infinity;
4387
4423
  }
4388
4424
  return Infinity;
4389
4425
  };
@@ -4410,7 +4446,7 @@ function priceSettlementInputs(vtxos, estimator) {
4410
4446
  const payable = [];
4411
4447
  const net = /* @__PURE__ */ new Map();
4412
4448
  for (const vtxo of vtxos) {
4413
- const inputFee = estimator.evalOffchainInput(chunk65CTZR2O_cjs.toOffchainInputFeeParams(vtxo));
4449
+ const inputFee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo));
4414
4450
  if (inputFee.satoshis >= vtxo.value) {
4415
4451
  continue;
4416
4452
  }
@@ -4439,7 +4475,7 @@ function offchainOutputFee(amount, estimator, arkAddress) {
4439
4475
  }
4440
4476
  const outputFee = estimator.evalOffchainOutput({
4441
4477
  amount,
4442
- script: base.hex.encode(chunk65CTZR2O_cjs.ArkAddress.decode(arkAddress).pkScript)
4478
+ script: base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(arkAddress).pkScript)
4443
4479
  });
4444
4480
  return BigInt(outputFee.satoshis);
4445
4481
  }
@@ -4490,10 +4526,10 @@ var DEFAULT_SETTLEMENT_CONFIG = {
4490
4526
  };
4491
4527
  function getRecoverableVtxos(vtxos, dustAmount, now) {
4492
4528
  return vtxos.filter((vtxo) => {
4493
- if (chunk65CTZR2O_cjs.canRecoverOnchain(vtxo, now)) {
4529
+ if (chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now)) {
4494
4530
  return true;
4495
4531
  }
4496
- if (chunk65CTZR2O_cjs.canSpendOffchain(vtxo, now) && vtxo.isPreconfirmed && isSubdust(vtxo, dustAmount)) {
4532
+ if (chunkVVFCCNU2_cjs.canSpendOffchain(vtxo, now) && vtxo.isPreconfirmed && isSubdust(vtxo, dustAmount)) {
4497
4533
  return true;
4498
4534
  }
4499
4535
  return false;
@@ -4525,7 +4561,7 @@ function getRecoverableWithSubdust(vtxos, dustAmount, now) {
4525
4561
  function isVtxoExpiringSoon(vtxo, thresholdMs) {
4526
4562
  if (vtxo.isUnrolled) return false;
4527
4563
  const realThresholdMs = thresholdMs <= 100 ? DEFAULT_THRESHOLD_MS : thresholdMs;
4528
- const expiresAt = chunk65CTZR2O_cjs.normalizeVtxo(vtxo).expiresAt;
4564
+ const expiresAt = chunkVVFCCNU2_cjs.normalizeVtxo(vtxo).expiresAt;
4529
4565
  if (expiresAt === void 0) return false;
4530
4566
  const now = Date.now();
4531
4567
  const batchExpiry = expiresAt.getTime();
@@ -4536,7 +4572,7 @@ function getExpiringAndRecoverableVtxos(vtxos, thresholdMs, dustAmount, now) {
4536
4572
  return vtxos.filter(
4537
4573
  // The leading exclusion covers the `isSubdust` arm too, which is a value
4538
4574
  // property and would otherwise re-admit an exited coin on its own.
4539
- (vtxo) => !vtxo.isUnrolled && (isVtxoExpiringSoon(vtxo, thresholdMs) || chunk65CTZR2O_cjs.canRecoverOnchain(vtxo, now) || isSubdust(vtxo, dustAmount))
4575
+ (vtxo) => !vtxo.isUnrolled && (isVtxoExpiringSoon(vtxo, thresholdMs) || chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now) || isSubdust(vtxo, dustAmount))
4540
4576
  );
4541
4577
  }
4542
4578
  function isMigrationCapable(wallet) {
@@ -4596,7 +4632,7 @@ var VtxoManager = class _VtxoManager {
4596
4632
  constructor(wallet, settlementConfig) {
4597
4633
  this.wallet = wallet;
4598
4634
  if (settlementConfig !== false) {
4599
- chunk65CTZR2O_cjs.assertTimerMs("pollIntervalMs", settlementConfig?.pollIntervalMs);
4635
+ chunkVVFCCNU2_cjs.assertTimerMs("pollIntervalMs", settlementConfig?.pollIntervalMs);
4600
4636
  }
4601
4637
  this.settlementConfig = settlementConfig !== void 0 ? settlementConfig : { ...DEFAULT_SETTLEMENT_CONFIG };
4602
4638
  this.contractEventsSubscriptionReady = this.initializeSubscription();
@@ -4903,7 +4939,7 @@ var VtxoManager = class _VtxoManager {
4903
4939
  * {@link recoverImportedContracts}).
4904
4940
  */
4905
4941
  async recoverOneImportedContract(wallet, contract, vtxos, info, dustAmount) {
4906
- const recoverable = vtxos.filter((vtxo) => vtxo.isSwept && !chunk65CTZR2O_cjs.isVtxoSpent(vtxo));
4942
+ const recoverable = vtxos.filter((vtxo) => vtxo.isSwept && !chunkVVFCCNU2_cjs.isVtxoSpent(vtxo));
4907
4943
  const estimator = new Estimator(info?.fees.intentFee ?? {});
4908
4944
  const { payable, net } = priceSettlementInputs(recoverable, estimator);
4909
4945
  const vtxoMaxAmount = info?.vtxoMaxAmount ?? -1n;
@@ -4925,7 +4961,7 @@ var VtxoManager = class _VtxoManager {
4925
4961
  if (vtxos.length === 0) return;
4926
4962
  const spent = new Set(batch.map((vtxo) => `${vtxo.txid}:${vtxo.vout}`));
4927
4963
  const stillSpendable = vtxos.some(
4928
- (vtxo) => !chunk65CTZR2O_cjs.isVtxoSpent(vtxo) && !spent.has(`${vtxo.txid}:${vtxo.vout}`)
4964
+ (vtxo) => !chunkVVFCCNU2_cjs.isVtxoSpent(vtxo) && !spent.has(`${vtxo.txid}:${vtxo.vout}`)
4929
4965
  );
4930
4966
  if (!stillSpendable) {
4931
4967
  await wallet.removeRecoveryContract(contract.script);
@@ -4974,12 +5010,37 @@ var VtxoManager = class _VtxoManager {
4974
5010
  genericallySpendableOnly: true
4975
5011
  });
4976
5012
  const threshold = thresholdMs !== void 0 ? thresholdMs : this.configuredThresholdMs();
4977
- return getExpiringAndRecoverableVtxos(
4978
- vtxos,
4979
- threshold,
4980
- getDustAmount(this.wallet),
4981
- now ?? await fetchTimeHeight(this.wallet)
4982
- );
5013
+ const tip = now ?? await fetchTimeHeight(this.wallet);
5014
+ await this.warnHeldExpiring(threshold, tip);
5015
+ return getExpiringAndRecoverableVtxos(vtxos, threshold, getDustAmount(this.wallet), tip);
5016
+ }
5017
+ /** Outpoints {@link warnHeldExpiring} last reported, so each is reported once while held. */
5018
+ heldExpiringWarned = /* @__PURE__ */ new Set();
5019
+ /**
5020
+ * A hold outranks renewal: renewing would change the outpoint under the holder, whose spend
5021
+ * by name would then fail. So the VTXO is skipped, and only this warning says it is drifting
5022
+ * toward a sweep. Best-effort: a failed read never blocks renewal.
5023
+ */
5024
+ async warnHeldExpiring(threshold, now) {
5025
+ let keys;
5026
+ try {
5027
+ const held = await heldVtxosOf(this.wallet);
5028
+ keys = getExpiringAndRecoverableVtxos(
5029
+ held,
5030
+ threshold,
5031
+ getDustAmount(this.wallet),
5032
+ now
5033
+ ).map((vtxo) => `${vtxo.txid}:${vtxo.vout}`);
5034
+ } catch {
5035
+ return;
5036
+ }
5037
+ const fresh = keys.filter((key) => !this.heldExpiringWarned.has(key));
5038
+ this.heldExpiringWarned = new Set(keys);
5039
+ if (fresh.length > 0) {
5040
+ console.warn(
5041
+ `Renewal: ${fresh.length} VTXO(s) due for renewal are held by reserveVtxos and will not be renewed; spend or release them before they expire: ${fresh.join(", ")}`
5042
+ );
5043
+ }
4983
5044
  }
4984
5045
  /**
4985
5046
  * Renew expiring virtual outputs (including recoverable ones) by settling them back to the
@@ -5089,10 +5150,10 @@ var VtxoManager = class _VtxoManager {
5089
5150
  }
5090
5151
  }
5091
5152
  const txid = await this.wallet.settle(
5092
- {
5153
+ markSdkPicked({
5093
5154
  inputs: vtxos,
5094
5155
  outputs: amounts.map((amount) => ({ address: arkAddress, amount }))
5095
- },
5156
+ }),
5096
5157
  eventCallback
5097
5158
  );
5098
5159
  return txid;
@@ -5192,11 +5253,11 @@ var VtxoManager = class _VtxoManager {
5192
5253
  `Sweep not economical: output ${outputAmount} sats after ${fee} sats fee is below dust (${dustAmount} sats)`
5193
5254
  );
5194
5255
  }
5195
- const tx = new chunk65CTZR2O_cjs.Transaction();
5256
+ const tx = new chunkVVFCCNU2_cjs.Transaction();
5196
5257
  for (const utxo of expiredUtxos) {
5197
- const utxoScript = chunk65CTZR2O_cjs.VtxoScript.decode(utxo.tapTree);
5258
+ const utxoScript = chunkVVFCCNU2_cjs.VtxoScript.decode(utxo.tapTree);
5198
5259
  const utxoExitLeaf = utxoScript.leaves.find(
5199
- (leaf) => chunk65CTZR2O_cjs.CSVMultisigTapscript.isScriptValid(chunk65CTZR2O_cjs.scriptFromTapLeafScript(leaf)) === true
5260
+ (leaf) => chunkVVFCCNU2_cjs.CSVMultisigTapscript.isScriptValid(chunkVVFCCNU2_cjs.scriptFromTapLeafScript(leaf)) === true
5200
5261
  );
5201
5262
  if (!utxoExitLeaf) {
5202
5263
  throw new Error(
@@ -5211,7 +5272,7 @@ var VtxoManager = class _VtxoManager {
5211
5272
  amount: BigInt(utxo.value)
5212
5273
  },
5213
5274
  tapLeafScript: [utxoExitLeaf],
5214
- sequence: chunk65CTZR2O_cjs.getSequence(utxoExitLeaf)
5275
+ sequence: chunkVVFCCNU2_cjs.getSequence(utxoExitLeaf)
5215
5276
  });
5216
5277
  }
5217
5278
  tx.addOutputAddress(boardingAddress, outputAmount, this.getNetwork());
@@ -5437,8 +5498,8 @@ var VtxoManager = class _VtxoManager {
5437
5498
  const cls = classifyAgainstSignerSet(serverPubKey, signerSet, nowSeconds);
5438
5499
  if (cls.status === "CURRENT") continue;
5439
5500
  const live = vtxos.filter((v) => !v.isUnrolled);
5440
- const recoverable = live.filter((v) => v.isSwept && !chunk65CTZR2O_cjs.isVtxoSpent(v));
5441
- const spendable = live.filter((v) => !chunk65CTZR2O_cjs.isVtxoSpent(v) && !v.isSwept);
5501
+ const recoverable = live.filter((v) => v.isSwept && !chunkVVFCCNU2_cjs.isVtxoSpent(v));
5502
+ const spendable = live.filter((v) => !chunkVVFCCNU2_cjs.isVtxoSpent(v) && !v.isSwept);
5442
5503
  const value = spendable.reduce((sum, v) => sum + v.value, 0);
5443
5504
  let recoverableCount = 0;
5444
5505
  let recoverableValue = 0;
@@ -5678,7 +5739,7 @@ var VtxoManager = class _VtxoManager {
5678
5739
  }
5679
5740
  getBoardingTimelock() {
5680
5741
  const wallet = this.getSweepWallet();
5681
- const exitScript = chunk65CTZR2O_cjs.CSVMultisigTapscript.decode(
5742
+ const exitScript = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(
5682
5743
  base.hex.decode(wallet.boardingTapscript.exitScript)
5683
5744
  );
5684
5745
  return exitScript.params.timelock;
@@ -5728,7 +5789,7 @@ var VtxoManager = class _VtxoManager {
5728
5789
  if (e.message.includes("is below dust threshold")) {
5729
5790
  return;
5730
5791
  }
5731
- if (e.message.includes("VTXO_ALREADY_REGISTERED") || e.message.includes("duplicated input")) {
5792
+ if (e.name === "VtxoReservedError" || e.message.includes("VTXO_ALREADY_REGISTERED") || e.message.includes("duplicated input")) {
5732
5793
  return;
5733
5794
  }
5734
5795
  if (e.message.includes("VTXO_ALREADY_SPENT")) {
@@ -5786,8 +5847,8 @@ var VtxoManager = class _VtxoManager {
5786
5847
  }
5787
5848
  /** The outpoint a `VTXO_ALREADY_SPENT` error carries in `metadata.vtxo_outpoint`, if any. */
5788
5849
  extractSpentOutpoint(error) {
5789
- const ark = chunk65CTZR2O_cjs.maybeArkError(error);
5790
- if (!chunk65CTZR2O_cjs.isArkError(ark, chunk65CTZR2O_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
5850
+ const ark = chunkVVFCCNU2_cjs.maybeArkError(error);
5851
+ if (!chunkVVFCCNU2_cjs.isArkError(ark, chunkVVFCCNU2_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
5791
5852
  const raw = ark.metadata?.vtxo_outpoint;
5792
5853
  if (typeof raw !== "string") return void 0;
5793
5854
  const [txid, voutStr] = raw.split(":");
@@ -5856,7 +5917,7 @@ var VtxoManager = class _VtxoManager {
5856
5917
  let hadError = false;
5857
5918
  try {
5858
5919
  await runWithCrossInstanceLock(BOARDING_POLL_LOCK_NAME, async () => {
5859
- const boardingUtxos = await this.wallet.getBoardingUtxos();
5920
+ const boardingUtxos = await getSelectableBoardingUtxos(this.wallet);
5860
5921
  try {
5861
5922
  await this.runPeriodicSettle(boardingUtxos);
5862
5923
  } catch (e) {
@@ -5961,7 +6022,7 @@ var VtxoManager = class _VtxoManager {
5961
6022
  if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
5962
6023
  break;
5963
6024
  }
5964
- const inputFee = estimator.evalOffchainInput(chunk65CTZR2O_cjs.toOffchainInputFeeParams(v));
6025
+ const inputFee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(v));
5965
6026
  if (inputFee.satoshis >= v.value) {
5966
6027
  continue;
5967
6028
  }
@@ -5981,7 +6042,7 @@ var VtxoManager = class _VtxoManager {
5981
6042
  const arkAddress = await this.wallet.getAddress();
5982
6043
  const outputFee = estimator.evalOffchainOutput({
5983
6044
  amount: totalAmount,
5984
- script: base.hex.encode(chunk65CTZR2O_cjs.ArkAddress.decode(arkAddress).pkScript)
6045
+ script: base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(arkAddress).pkScript)
5985
6046
  });
5986
6047
  totalAmount -= BigInt(outputFee.satoshis);
5987
6048
  if (totalAmount < dustAmount) return;
@@ -5990,20 +6051,24 @@ var VtxoManager = class _VtxoManager {
5990
6051
  this.renewalInProgress = true;
5991
6052
  }
5992
6053
  let success = false;
5993
- let staleCacheSkip = false;
6054
+ let skipWithoutBackoff = false;
5994
6055
  try {
5995
6056
  try {
5996
- await this.wallet.settle({
5997
- inputs: [...filteredBoarding, ...filteredVtxos],
5998
- outputs: [{ address: arkAddress, amount: totalAmount }]
5999
- });
6057
+ await this.wallet.settle(
6058
+ markSdkPicked({
6059
+ inputs: [...filteredBoarding, ...filteredVtxos],
6060
+ outputs: [{ address: arkAddress, amount: totalAmount }]
6061
+ })
6062
+ );
6000
6063
  for (const u of filteredBoarding) {
6001
6064
  this.knownBoardingUtxos.add(`${u.txid}:${u.vout}`);
6002
6065
  }
6003
6066
  success = true;
6004
6067
  } catch (e) {
6005
- if (e instanceof Error && e.message.includes("VTXO_ALREADY_SPENT")) {
6006
- staleCacheSkip = true;
6068
+ if (e instanceof Error && e.name === "VtxoReservedError") {
6069
+ skipWithoutBackoff = true;
6070
+ } else if (e instanceof Error && e.message.includes("VTXO_ALREADY_SPENT")) {
6071
+ skipWithoutBackoff = true;
6007
6072
  void this.maybeRefreshAfterVtxoSpent(this.extractSpentOutpoint(e));
6008
6073
  } else {
6009
6074
  throw e;
@@ -6017,7 +6082,7 @@ var VtxoManager = class _VtxoManager {
6017
6082
  }
6018
6083
  if (success) {
6019
6084
  this.consecutivePeriodicSettleFailures = 0;
6020
- } else if (!staleCacheSkip) {
6085
+ } else if (!skipWithoutBackoff) {
6021
6086
  this.consecutivePeriodicSettleFailures++;
6022
6087
  }
6023
6088
  }
@@ -6061,7 +6126,7 @@ var ArkNote = class _ArkNote {
6061
6126
  this.value = value;
6062
6127
  this.HRP = HRP;
6063
6128
  const preimageHash = utils_js.sha256(this.preimage);
6064
- this.vtxoScript = new chunk65CTZR2O_cjs.VtxoScript([noteTapscript(preimageHash)]);
6129
+ this.vtxoScript = new chunkVVFCCNU2_cjs.VtxoScript([noteTapscript(preimageHash)]);
6065
6130
  const leaf = this.vtxoScript.leaves[0];
6066
6131
  this.txid = base.hex.encode(new Uint8Array(preimageHash).reverse());
6067
6132
  this.tapTree = this.vtxoScript.encode();
@@ -6234,7 +6299,7 @@ var ArkadeCash = class _ArkadeCash {
6234
6299
  const privateKey = data.slice(1, 33);
6235
6300
  const serverPubKey = data.slice(33, 65);
6236
6301
  const sequence = new DataView(data.buffer, data.byteOffset + 65, 4).getUint32(0, false);
6237
- const csvTimelock2 = chunk65CTZR2O_cjs.sequenceToTimelock(sequence);
6302
+ const csvTimelock2 = chunkVVFCCNU2_cjs.sequenceToTimelock(sequence);
6238
6303
  return new _ArkadeCash(privateKey, serverPubKey, csvTimelock2, decoded.prefix);
6239
6304
  }
6240
6305
  toString() {
@@ -6242,7 +6307,7 @@ var ArkadeCash = class _ArkadeCash {
6242
6307
  data[0] = _ArkadeCash.Version;
6243
6308
  data.set(this._privateKey, 1);
6244
6309
  data.set(this._serverPubKey, 33);
6245
- const sequence = chunk65CTZR2O_cjs.timelockToSequence(this.csvTimelock);
6310
+ const sequence = chunkVVFCCNU2_cjs.timelockToSequence(this.csvTimelock);
6246
6311
  new DataView(data.buffer, data.byteOffset + 65, 4).setUint32(0, sequence, false);
6247
6312
  const words = base.bech32m.toWords(data);
6248
6313
  return base.bech32m.encode(this.hrp, words, 1023);
@@ -6251,7 +6316,7 @@ var ArkadeCash = class _ArkadeCash {
6251
6316
  return SingleKey.fromPrivateKey(this._privateKey);
6252
6317
  }
6253
6318
  get vtxoScript() {
6254
- return new chunkUV3IM6BG_cjs.DefaultVtxo.Script({
6319
+ return new chunkCFOIHLON_cjs.DefaultVtxo.Script({
6255
6320
  pubKey: this._publicKey,
6256
6321
  serverPubKey: this._serverPubKey,
6257
6322
  csvTimelock: this.csvTimelock
@@ -6267,7 +6332,7 @@ var NON_TERMINAL_INTENT_STATES = ALL_INTENT_STATES.filter(
6267
6332
  (s) => !isTerminalIntentState(s)
6268
6333
  );
6269
6334
  function isConsumed(vtxo) {
6270
- return vtxo !== void 0 && chunk65CTZR2O_cjs.isVtxoSpent(vtxo);
6335
+ return vtxo !== void 0 && chunkVVFCCNU2_cjs.isVtxoSpent(vtxo);
6271
6336
  }
6272
6337
  async function classifyIntent(intent, vtxosByOutpoint, now) {
6273
6338
  if (isTerminalIntentState(intent.state)) return void 0;
@@ -6310,7 +6375,7 @@ async function reconcileIntents(deps) {
6310
6375
  let vtxosByOutpoint = /* @__PURE__ */ new Map();
6311
6376
  if (outpoints.length > 0) {
6312
6377
  try {
6313
- const { vtxos } = await chunk65CTZR2O_cjs.getNormalizedVtxos(deps.indexerProvider, { outpoints });
6378
+ const { vtxos } = await chunkVVFCCNU2_cjs.getNormalizedVtxos(deps.indexerProvider, { outpoints });
6314
6379
  vtxosByOutpoint = new Map(vtxos.map((v) => [outpointKey(v), v]));
6315
6380
  } catch (e) {
6316
6381
  console.error("reconcileIntents: failed to fetch input VTXO state", e);
@@ -6370,7 +6435,7 @@ async function releaseFromServer(intent, deps, now) {
6370
6435
  });
6371
6436
  }
6372
6437
  function isNoMatchingIntentsError(e) {
6373
- return chunk65CTZR2O_cjs.isArkError(e, chunk65CTZR2O_cjs.ArkErrorName.INVALID_INTENT_PROOF) && e.message.includes("no matching intents found");
6438
+ return chunkVVFCCNU2_cjs.isArkError(e, chunkVVFCCNU2_cjs.ArkErrorName.INVALID_INTENT_PROOF) && e.message.includes("no matching intents found");
6374
6439
  }
6375
6440
  function terminal(intent, state, now, patch) {
6376
6441
  return { ...intent, ...patch, state, updatedAt: now };
@@ -6589,7 +6654,7 @@ async function captureExitBranch(params) {
6589
6654
  const nonCommitment = ordered.filter((c) => chainTxTypeToChainedExit(c.type) !== 1 /* Commitment */).map((c) => c.txid);
6590
6655
  if (nonCommitment.length > 0) {
6591
6656
  for (const psbt of await resolver.getVirtualTxs(nonCommitment)) {
6592
- psbtByTxid.set(chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
6657
+ psbtByTxid.set(chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
6593
6658
  }
6594
6659
  }
6595
6660
  }
@@ -6632,10 +6697,10 @@ var IndexerExitDataSource = class {
6632
6697
  while (hasMore) {
6633
6698
  const { chain: page, page: meta } = await this.indexer.getVtxoChain(
6634
6699
  { txid: vtxo.txid, vout: vtxo.vout },
6635
- { pageIndex, pageSize: chunk65CTZR2O_cjs.DEFAULT_PAGE_SIZE }
6700
+ { pageIndex, pageSize: chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE }
6636
6701
  );
6637
6702
  chain.push(...page);
6638
- hasMore = meta ? page.length === chunk65CTZR2O_cjs.DEFAULT_PAGE_SIZE : false;
6703
+ hasMore = meta ? page.length === chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE : false;
6639
6704
  pageIndex++;
6640
6705
  }
6641
6706
  return chain;
@@ -6647,12 +6712,12 @@ var IndexerExitDataSource = class {
6647
6712
  while (hasMore) {
6648
6713
  const { txs, page } = await this.indexer.getVirtualTxs(txids, {
6649
6714
  pageIndex,
6650
- pageSize: chunk65CTZR2O_cjs.DEFAULT_PAGE_SIZE
6715
+ pageSize: chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE
6651
6716
  });
6652
6717
  for (const psbt of txs) {
6653
- out.set(chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
6718
+ out.set(chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
6654
6719
  }
6655
- hasMore = page ? txs.length === chunk65CTZR2O_cjs.DEFAULT_PAGE_SIZE : false;
6720
+ hasMore = page ? txs.length === chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE : false;
6656
6721
  pageIndex++;
6657
6722
  }
6658
6723
  return out;
@@ -6673,7 +6738,7 @@ function chainedTxTypeToChainTxType(t) {
6673
6738
  }
6674
6739
  }
6675
6740
  function psbtInputTxids(psbtBase64) {
6676
- return txInputTxids(chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64)));
6741
+ return txInputTxids(chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64)));
6677
6742
  }
6678
6743
  function txInputTxids(tx) {
6679
6744
  const ids = [];
@@ -6977,10 +7042,10 @@ async function resolveArkInfo(arkProvider, walletRepository, opts) {
6977
7042
  try {
6978
7043
  info = await arkProvider.getInfo();
6979
7044
  } catch (err) {
6980
- if (opts?.requireLive || !chunk65CTZR2O_cjs.isRetryableProviderError(err)) throw err;
7045
+ if (opts?.requireLive || !chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
6981
7046
  const snapshot = await loadArkInfoSnapshot(walletRepository);
6982
7047
  if (!snapshot) {
6983
- throw new chunk65CTZR2O_cjs.ProviderUnavailableError(
7048
+ throw new chunkVVFCCNU2_cjs.ProviderUnavailableError(
6984
7049
  "Arkade server info is unavailable and no cached snapshot exists",
6985
7050
  { cause: err }
6986
7051
  );
@@ -7172,7 +7237,7 @@ function buildGraph(rootTxid, chunksByTxid) {
7172
7237
  return new TxTree(rootTx, children);
7173
7238
  }
7174
7239
  function decodeNode(chunk) {
7175
- const tx = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(chunk.tx));
7240
+ const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(chunk.tx));
7176
7241
  return { tx, children: chunk.children };
7177
7242
  }
7178
7243
  exports.Batch = void 0;
@@ -7375,7 +7440,7 @@ function collectArkTxidsNeedingCreatedAt(vtxos, localCreatedAt) {
7375
7440
  return [...txids];
7376
7441
  }
7377
7442
  async function buildTransactionHistory(vtxos, allBoardingTxs, commitmentsToIgnore, resolveTxCreatedAt, gatedScripts = /* @__PURE__ */ new Map()) {
7378
- const normalized = vtxos.map(chunk65CTZR2O_cjs.normalizeVtxo).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
7443
+ const normalized = vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
7379
7444
  const localCreatedAt = localCreatedAtByTxid(normalized);
7380
7445
  const gatedVtxos = normalized.filter((vtxo) => isGatedVtxo(vtxo, gatedScripts));
7381
7446
  const ownVtxos = normalized.filter((vtxo) => !isGatedVtxo(vtxo, gatedScripts));
@@ -7542,6 +7607,9 @@ var AssetManager = class extends ReadonlyAssetManager {
7542
7607
  * ```
7543
7608
  */
7544
7609
  async issue(params) {
7610
+ return this.wallet.withSpendLock((submit) => this.issueWith(params, submit));
7611
+ }
7612
+ async issueWith(params, submit) {
7545
7613
  if (params.amount <= 0n) {
7546
7614
  throw new Error(`Issue amount must be greater than 0, got ${params.amount}`);
7547
7615
  }
@@ -7550,7 +7618,7 @@ var AssetManager = class extends ReadonlyAssetManager {
7550
7618
  withRecoverable: false,
7551
7619
  genericallySpendableOnly: true
7552
7620
  });
7553
- const controlAssetRef = params.controlAssetId ? chunkPAD5V653_cjs.AssetRef.fromId(chunkPAD5V653_cjs.AssetId.fromString(params.controlAssetId)) : null;
7621
+ const controlAssetRef = params.controlAssetId ? chunkFEBAG2K2_cjs.AssetRef.fromId(chunkFEBAG2K2_cjs.AssetId.fromString(params.controlAssetId)) : null;
7554
7622
  const coinSelection = selectVirtualCoins(virtualCoins, Number(this.wallet.dustAmount));
7555
7623
  let totalBtcSelected = 0n;
7556
7624
  const assetChanges = /* @__PURE__ */ new Map();
@@ -7563,8 +7631,8 @@ var AssetManager = class extends ReadonlyAssetManager {
7563
7631
  }
7564
7632
  }
7565
7633
  const groups = [];
7566
- const issuedAssetOutput = chunkPAD5V653_cjs.AssetOutput.create(0, params.amount);
7567
- const issuedAssetGroup = chunkPAD5V653_cjs.AssetGroup.create(
7634
+ const issuedAssetOutput = chunkFEBAG2K2_cjs.AssetOutput.create(0, params.amount);
7635
+ const issuedAssetGroup = chunkFEBAG2K2_cjs.AssetGroup.create(
7568
7636
  null,
7569
7637
  controlAssetRef,
7570
7638
  [],
@@ -7577,17 +7645,18 @@ var AssetManager = class extends ReadonlyAssetManager {
7577
7645
  for (const [assetId, amount] of assetChanges) {
7578
7646
  const changeInputs = inputsForAsset(assetInputs, assetId);
7579
7647
  groups.push(
7580
- chunkPAD5V653_cjs.AssetGroup.create(
7581
- chunkPAD5V653_cjs.AssetId.fromString(assetId),
7648
+ chunkFEBAG2K2_cjs.AssetGroup.create(
7649
+ chunkFEBAG2K2_cjs.AssetId.fromString(assetId),
7582
7650
  null,
7583
7651
  changeInputs,
7584
- [chunkPAD5V653_cjs.AssetOutput.create(0, amount)],
7652
+ [chunkFEBAG2K2_cjs.AssetOutput.create(0, amount)],
7585
7653
  []
7586
7654
  )
7587
7655
  );
7588
7656
  }
7589
7657
  }
7590
7658
  const arkTxid = await submitToSelf(
7659
+ submit,
7591
7660
  this.wallet,
7592
7661
  coinSelection.inputs,
7593
7662
  totalBtcSelected,
@@ -7595,7 +7664,7 @@ var AssetManager = class extends ReadonlyAssetManager {
7595
7664
  );
7596
7665
  return {
7597
7666
  arkTxId: arkTxid,
7598
- assetId: chunkPAD5V653_cjs.AssetId.create(arkTxid, 0).toString()
7667
+ assetId: chunkFEBAG2K2_cjs.AssetId.create(arkTxid, 0).toString()
7599
7668
  };
7600
7669
  }
7601
7670
  /**
@@ -7616,6 +7685,9 @@ var AssetManager = class extends ReadonlyAssetManager {
7616
7685
  * ```
7617
7686
  */
7618
7687
  async reissue(params) {
7688
+ return this.wallet.withSpendLock((submit) => this.reissueWith(params, submit));
7689
+ }
7690
+ async reissueWith(params, submit) {
7619
7691
  if (params.amount <= 0n) {
7620
7692
  throw new Error(`Reissuance amount must be greater than 0, got ${params.amount}`);
7621
7693
  }
@@ -7666,28 +7738,28 @@ var AssetManager = class extends ReadonlyAssetManager {
7666
7738
  const assetInputs = selectedCoinsToAssetInputs(selectedCoins);
7667
7739
  const reissueInputs = inputsForAsset(assetInputs, params.assetId);
7668
7740
  const totalAssetAmount = assetToReissueAmount + params.amount;
7669
- const reissueAssetIdObj = chunkPAD5V653_cjs.AssetId.fromString(params.assetId);
7670
- const reissueAssetGroup = chunkPAD5V653_cjs.AssetGroup.create(
7741
+ const reissueAssetIdObj = chunkFEBAG2K2_cjs.AssetId.fromString(params.assetId);
7742
+ const reissueAssetGroup = chunkFEBAG2K2_cjs.AssetGroup.create(
7671
7743
  reissueAssetIdObj,
7672
7744
  null,
7673
7745
  reissueInputs,
7674
- [chunkPAD5V653_cjs.AssetOutput.create(0, totalAssetAmount)],
7746
+ [chunkFEBAG2K2_cjs.AssetOutput.create(0, totalAssetAmount)],
7675
7747
  []
7676
7748
  );
7677
7749
  const groups = [reissueAssetGroup];
7678
7750
  for (const [assetId, amount] of assetChanges) {
7679
7751
  const changeInputs = inputsForAsset(assetInputs, assetId);
7680
7752
  groups.push(
7681
- chunkPAD5V653_cjs.AssetGroup.create(
7682
- chunkPAD5V653_cjs.AssetId.fromString(assetId),
7753
+ chunkFEBAG2K2_cjs.AssetGroup.create(
7754
+ chunkFEBAG2K2_cjs.AssetId.fromString(assetId),
7683
7755
  null,
7684
7756
  changeInputs,
7685
- [chunkPAD5V653_cjs.AssetOutput.create(0, amount)],
7757
+ [chunkFEBAG2K2_cjs.AssetOutput.create(0, amount)],
7686
7758
  []
7687
7759
  )
7688
7760
  );
7689
7761
  }
7690
- return submitToSelf(this.wallet, selectedCoins, totalBtcSelected, groups);
7762
+ return submitToSelf(submit, this.wallet, selectedCoins, totalBtcSelected, groups);
7691
7763
  }
7692
7764
  /**
7693
7765
  * Burn assets.
@@ -7705,6 +7777,9 @@ var AssetManager = class extends ReadonlyAssetManager {
7705
7777
  * ```
7706
7778
  */
7707
7779
  async burn(params) {
7780
+ return this.wallet.withSpendLock((submit) => this.burnWith(params, submit));
7781
+ }
7782
+ async burnWith(params, submit) {
7708
7783
  if (params.amount <= 0n) {
7709
7784
  throw new Error(`Burn amount must be greater than 0, got ${params.amount}`);
7710
7785
  }
@@ -7750,16 +7825,16 @@ var AssetManager = class extends ReadonlyAssetManager {
7750
7825
  for (const [assetId, amount] of assetChanges) {
7751
7826
  const changeInputs = inputsForAsset(assetInputs, assetId);
7752
7827
  groups.push(
7753
- chunkPAD5V653_cjs.AssetGroup.create(
7754
- chunkPAD5V653_cjs.AssetId.fromString(assetId),
7828
+ chunkFEBAG2K2_cjs.AssetGroup.create(
7829
+ chunkFEBAG2K2_cjs.AssetId.fromString(assetId),
7755
7830
  null,
7756
7831
  changeInputs,
7757
- amount > 0n ? [chunkPAD5V653_cjs.AssetOutput.create(0, amount)] : [],
7832
+ amount > 0n ? [chunkFEBAG2K2_cjs.AssetOutput.create(0, amount)] : [],
7758
7833
  []
7759
7834
  )
7760
7835
  );
7761
7836
  }
7762
- return submitToSelf(this.wallet, selectedCoins, totalBtcSelected, groups);
7837
+ return submitToSelf(submit, this.wallet, selectedCoins, totalBtcSelected, groups);
7763
7838
  }
7764
7839
  };
7765
7840
  function inputsForAsset(assetInputs, assetId) {
@@ -7767,18 +7842,18 @@ function inputsForAsset(assetInputs, assetId) {
7767
7842
  for (const [inputIndex, assets] of assetInputs) {
7768
7843
  for (const asset of assets) {
7769
7844
  if (asset.assetId !== assetId) continue;
7770
- inputs.push(chunkPAD5V653_cjs.AssetInput.create(inputIndex, asset.amount));
7845
+ inputs.push(chunkFEBAG2K2_cjs.AssetInput.create(inputIndex, asset.amount));
7771
7846
  }
7772
7847
  }
7773
7848
  return inputs;
7774
7849
  }
7775
- async function submitToSelf(wallet, inputs, amount, groups) {
7776
- const outputAddress = chunk65CTZR2O_cjs.ArkAddress.decode(await wallet.getAddress());
7850
+ async function submitToSelf(submit, wallet, inputs, amount, groups) {
7851
+ const outputAddress = chunkVVFCCNU2_cjs.ArkAddress.decode(await wallet.getAddress());
7777
7852
  const outputs = [
7778
7853
  { script: outputAddress.pkScript, amount: BigInt(amount) },
7779
- Extension.create([chunkPAD5V653_cjs.Packet.create(groups)]).txOut()
7854
+ Extension.create([chunkFEBAG2K2_cjs.Packet.create(groups)]).txOut()
7780
7855
  ];
7781
- const { arkTxid } = await wallet.buildAndSubmitOffchainTx(inputs, outputs);
7856
+ const { arkTxid } = await submit(inputs, outputs);
7782
7857
  return arkTxid;
7783
7858
  }
7784
7859
  function castMetadata(metadata) {
@@ -7800,7 +7875,7 @@ function castMetadata(metadata) {
7800
7875
  } else {
7801
7876
  throw new Error("Invalid metadata value type");
7802
7877
  }
7803
- md.push(chunkPAD5V653_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
7878
+ md.push(chunkFEBAG2K2_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
7804
7879
  }
7805
7880
  return md;
7806
7881
  }
@@ -7821,10 +7896,10 @@ var DelegateManagerImpl = class {
7821
7896
  if (vtxos.length === 0) {
7822
7897
  return { delegated: [], failed: [] };
7823
7898
  }
7824
- const destinationScript = chunk65CTZR2O_cjs.ArkAddress.decode(destination).pkScript;
7899
+ const destinationScript = chunkVVFCCNU2_cjs.ArkAddress.decode(destination).pkScript;
7825
7900
  const arkInfo = await this.arkInfoProvider.getInfo();
7826
7901
  const delegateInfo = await this.delegateProvider.getDelegateInfo();
7827
- const eligible = vtxos.map(chunk65CTZR2O_cjs.normalizeVtxo).filter(
7902
+ const eligible = vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo).filter(
7828
7903
  (v) => isAnnotated(v) && findDelegateTapLeaf(v, delegateInfo.pubkey) !== void 0
7829
7904
  );
7830
7905
  if (eligible.length === 0) {
@@ -7856,7 +7931,7 @@ var DelegateManagerImpl = class {
7856
7931
  const groupByExpiry = /* @__PURE__ */ new Map();
7857
7932
  let recoverableVtxos = [];
7858
7933
  for (const vtxo of eligible) {
7859
- if (chunk65CTZR2O_cjs.canRecoverOnchain(vtxo, now)) {
7934
+ if (chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now)) {
7860
7935
  recoverableVtxos.push(vtxo);
7861
7936
  continue;
7862
7937
  }
@@ -7908,7 +7983,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7908
7983
  }
7909
7984
  if (!delegateAt) {
7910
7985
  const now = { timestamp: /* @__PURE__ */ new Date() };
7911
- const expiryTimestamp = vtxos.filter((coin) => !chunk65CTZR2O_cjs.canRecoverOnchain(coin, now) && coin.expiresAt).reduce(
7986
+ const expiryTimestamp = vtxos.filter((coin) => !chunkVVFCCNU2_cjs.canRecoverOnchain(coin, now) && coin.expiresAt).reduce(
7912
7987
  (min, coin) => Math.min(min, coin.expiresAt.getTime()),
7913
7988
  Number.MAX_SAFE_INTEGER
7914
7989
  );
@@ -7935,7 +8010,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7935
8010
  let amount = 0n;
7936
8011
  for (const coin of vtxos) {
7937
8012
  const inputFee = estimator.evalOffchainInput({
7938
- ...chunk65CTZR2O_cjs.toOffchainInputFeeParams(coin),
8013
+ ...chunkVVFCCNU2_cjs.toOffchainInputFeeParams(coin),
7939
8014
  type: "vtxo"
7940
8015
  });
7941
8016
  if (inputFee.satoshis >= coin.value) {
@@ -7949,7 +8024,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7949
8024
  const delegateFee = BigInt(Number(fee));
7950
8025
  if (delegateFee > 0n) {
7951
8026
  outputs.push({
7952
- script: chunk65CTZR2O_cjs.ArkAddress.decode(delegateAddress).pkScript,
8027
+ script: chunkVVFCCNU2_cjs.ArkAddress.decode(delegateAddress).pkScript,
7953
8028
  amount: delegateFee
7954
8029
  });
7955
8030
  }
@@ -7982,10 +8057,10 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7982
8057
  destinationScript
7983
8058
  );
7984
8059
  const forfeitOutputScript = btcSigner.OutScript.encode(
7985
- btcSigner.Address(chunk65CTZR2O_cjs.getNetwork(network)).decode(forfeitAddress)
8060
+ btcSigner.Address(chunkVVFCCNU2_cjs.getNetwork(network)).decode(forfeitAddress)
7986
8061
  );
7987
8062
  const forfeits = await Promise.all(
7988
- vtxos.filter((v) => chunk65CTZR2O_cjs.requiresForfeit(v)).map(async (coin) => {
8063
+ vtxos.filter((v) => chunkVVFCCNU2_cjs.requiresForfeit(v)).map(async (coin) => {
7989
8064
  const forfeit = await makeDelegateForfeitTx(
7990
8065
  coin,
7991
8066
  dust,
@@ -8010,7 +8085,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
8010
8085
  index: input.vout,
8011
8086
  witnessUtxo: {
8012
8087
  amount: BigInt(input.value),
8013
- script: chunk65CTZR2O_cjs.VtxoScript.decode(input.tapTree).pkScript
8088
+ script: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
8014
8089
  },
8015
8090
  sighashType: btcSigner.SigHash.ALL_ANYONECANPAY,
8016
8091
  tapLeafScript: [delegateTapLeaf]
@@ -8068,7 +8143,7 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
8068
8143
  expire_at: 0,
8069
8144
  cosigners_public_keys: cosignerPubKeys
8070
8145
  };
8071
- const proof = chunk65CTZR2O_cjs.Intent.create(message, coins, outputs);
8146
+ const proof = chunkVVFCCNU2_cjs.Intent.create(message, coins, outputs);
8072
8147
  const signedProof = await identity.sign(proof);
8073
8148
  return {
8074
8149
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -8094,10 +8169,10 @@ function getDayTimestamp(timestamp) {
8094
8169
  function findDelegateTapLeaf(vtxo, delegatePubkey) {
8095
8170
  if (!vtxo.tapTree) return void 0;
8096
8171
  const pk = delegatePubkey.length === 66 ? delegatePubkey.slice(2) : delegatePubkey;
8097
- const vtxoScript = chunk65CTZR2O_cjs.VtxoScript.decode(vtxo.tapTree);
8172
+ const vtxoScript = chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree);
8098
8173
  return vtxoScript.leaves.find((tapLeaf) => {
8099
- const arkTapscript = chunk65CTZR2O_cjs.decodeTapscript(chunk65CTZR2O_cjs.scriptFromTapLeafScript(tapLeaf));
8100
- if (!chunk65CTZR2O_cjs.MultisigTapscript.is(arkTapscript)) return false;
8174
+ const arkTapscript = chunkVVFCCNU2_cjs.decodeTapscript(chunkVVFCCNU2_cjs.scriptFromTapLeafScript(tapLeaf));
8175
+ if (!chunkVVFCCNU2_cjs.MultisigTapscript.is(arkTapscript)) return false;
8101
8176
  return arkTapscript.params.pubkeys.map(base.hex.encode).includes(pk);
8102
8177
  });
8103
8178
  }
@@ -8653,8 +8728,8 @@ function checkSaveVtxosForScript(backend, key, vtxos) {
8653
8728
  }
8654
8729
  async function getVtxosForContract(repo, contract, options) {
8655
8730
  const vtxos = repo.getVtxosForScriptPage ? await collectScriptVtxos(repo, contract.script, options) : filterVtxosForScript(await collectVtxos(repo, contract.address), contract.script);
8656
- const normalized = vtxos.map(chunk65CTZR2O_cjs.normalizeVtxo);
8657
- return options?.unspentOnly ? normalized.filter((vtxo) => !chunk65CTZR2O_cjs.isVtxoSpent(vtxo)) : normalized;
8731
+ const normalized = vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
8732
+ return options?.unspentOnly ? normalized.filter((vtxo) => !chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)) : normalized;
8658
8733
  }
8659
8734
  async function hasVtxosForContract(repo, contract) {
8660
8735
  if (repo.getVtxosForScriptPage) {
@@ -8885,7 +8960,7 @@ function decodeArkContract(encoded) {
8885
8960
  }
8886
8961
  function contractFromArkContract(encoded, options = {}) {
8887
8962
  const parsed = decodeArkContract(encoded);
8888
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(parsed.type);
8963
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(parsed.type);
8889
8964
  if (!handler) {
8890
8965
  throw new Error(`No handler registered for contract type '${parsed.type}'`);
8891
8966
  }
@@ -8899,9 +8974,9 @@ function contractFromArkContract(encoded, options = {}) {
8899
8974
  metadata: options.metadata
8900
8975
  };
8901
8976
  }
8902
- function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunk65CTZR2O_cjs.DEFAULT_NETWORK.hrp, options = {}) {
8977
+ function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunkVVFCCNU2_cjs.DEFAULT_NETWORK.hrp, options = {}) {
8903
8978
  const parsed = decodeArkContract(encoded);
8904
- const handler = chunkUV3IM6BG_cjs.contractHandlers.getOrThrow(parsed.type);
8979
+ const handler = chunkCFOIHLON_cjs.contractHandlers.getOrThrow(parsed.type);
8905
8980
  const params = parsed.data;
8906
8981
  const vtxoScript = handler.createScript(params);
8907
8982
  return {
@@ -8927,8 +9002,9 @@ var DEFAULT_CONTRACT_WATCHER_CONFIG = {
8927
9002
  failsafePollIntervalMs: 2e4,
8928
9003
  reconnectDelayMs: 1e3,
8929
9004
  maxReconnectDelayMs: 5e3,
8930
- maxReconnectAttempts: 0
9005
+ maxReconnectAttempts: 0,
8931
9006
  // unlimited
9007
+ subscriptionRequestTimeoutMs: 3e4
8932
9008
  };
8933
9009
  var ContractWatcher = class {
8934
9010
  config;
@@ -8946,13 +9022,24 @@ var ContractWatcher = class {
8946
9022
  /** See {@link withCoalescedSubscription}. */
8947
9023
  subscriptionBatchDepth = 0;
8948
9024
  subscriptionUpdateDeferred = false;
9025
+ /** Subscription POSTs can fail while the event stream remains healthy. */
9026
+ subscriptionRetryTimeoutId;
9027
+ subscriptionRetryAttempts = 0;
9028
+ /** A failed update needs catch-up even when reconnect owns the next attempt. */
9029
+ subscriptionNeedsCatchUp = false;
9030
+ /** Serialize subscription creation and updates against the latest desired scripts. */
9031
+ subscriptionUpdate = Promise.resolve();
8949
9032
  /** See {@link reportEventSourceUnavailable} — said once, not per attempt. */
8950
9033
  eventSourceReported = false;
8951
9034
  /** @see ContractWatcherConfig */
8952
9035
  constructor(config) {
8953
- chunk65CTZR2O_cjs.assertTimerMs("failsafePollIntervalMs", config.failsafePollIntervalMs);
8954
- chunk65CTZR2O_cjs.assertTimerMs("reconnectDelayMs", config.reconnectDelayMs);
8955
- chunk65CTZR2O_cjs.assertTimerMs("maxReconnectDelayMs", config.maxReconnectDelayMs);
9036
+ chunkVVFCCNU2_cjs.assertTimerMs("failsafePollIntervalMs", config.failsafePollIntervalMs);
9037
+ chunkVVFCCNU2_cjs.assertTimerMs("reconnectDelayMs", config.reconnectDelayMs);
9038
+ chunkVVFCCNU2_cjs.assertTimerMs("maxReconnectDelayMs", config.maxReconnectDelayMs);
9039
+ chunkVVFCCNU2_cjs.assertTimerMs("subscriptionRequestTimeoutMs", config.subscriptionRequestTimeoutMs);
9040
+ if (config.subscriptionRequestTimeoutMs === 0) {
9041
+ throw new Error("subscriptionRequestTimeoutMs must be greater than 0");
9042
+ }
8956
9043
  this.config = {
8957
9044
  ...DEFAULT_CONTRACT_WATCHER_CONFIG,
8958
9045
  ...config
@@ -9112,9 +9199,12 @@ var ContractWatcher = class {
9112
9199
  }
9113
9200
  this.eventCallback = callback;
9114
9201
  this.isWatching = true;
9115
- this.abortController = new AbortController();
9202
+ const session = new AbortController();
9203
+ this.abortController = session;
9116
9204
  this.reconnectAttempts = 0;
9205
+ this.subscriptionUpdate = Promise.resolve();
9117
9206
  await this.connect();
9207
+ if (session.signal.aborted) return () => this.stopWatching();
9118
9208
  this.startFailsafePolling();
9119
9209
  return () => this.stopWatching();
9120
9210
  }
@@ -9122,6 +9212,9 @@ var ContractWatcher = class {
9122
9212
  this.isWatching = false;
9123
9213
  this.connectionState = "disconnected";
9124
9214
  this.abortController?.abort();
9215
+ this.cancelSubscriptionRetry();
9216
+ this.subscriptionRetryAttempts = 0;
9217
+ this.subscriptionNeedsCatchUp = false;
9125
9218
  if (this.reconnectTimeoutId) {
9126
9219
  clearTimeout(this.reconnectTimeoutId);
9127
9220
  this.reconnectTimeoutId = void 0;
@@ -9153,18 +9246,22 @@ var ContractWatcher = class {
9153
9246
  /** @param skipUpdate - The caller already established `subscriptionId`. */
9154
9247
  async connect(skipUpdate = false) {
9155
9248
  if (!this.isWatching) return;
9249
+ const signal = this.abortController?.signal;
9156
9250
  this.connectionState = "connecting";
9157
9251
  try {
9158
9252
  if (!skipUpdate) {
9159
9253
  await this.updateSubscription();
9160
9254
  }
9255
+ if (!this.isWatching || signal?.aborted) return;
9161
9256
  await this.pollAllContracts();
9257
+ if (!this.isWatching || signal?.aborted) return;
9162
9258
  this.connectionState = "connected";
9163
9259
  this.reconnectAttempts = 0;
9164
9260
  this.listenLoop().catch((e) => {
9165
- if (chunk65CTZR2O_cjs.isEventSourceError(e)) {
9261
+ if (!this.isWatching || signal?.aborted) return;
9262
+ if (chunkVVFCCNU2_cjs.isEventSourceError(e)) {
9166
9263
  console.debug("ContractWatcher subscription disconnected; reconnecting");
9167
- } else if (!chunk65CTZR2O_cjs.isEventSourceUnavailableError(e)) {
9264
+ } else if (!chunkVVFCCNU2_cjs.isEventSourceUnavailableError(e)) {
9168
9265
  console.error(e);
9169
9266
  }
9170
9267
  this.connectionState = "disconnected";
@@ -9173,7 +9270,8 @@ var ContractWatcher = class {
9173
9270
  this.scheduleReconnect();
9174
9271
  });
9175
9272
  } catch (error) {
9176
- if (!chunk65CTZR2O_cjs.isEventSourceUnavailableError(error)) {
9273
+ if (!this.isWatching || signal?.aborted) return;
9274
+ if (!chunkVVFCCNU2_cjs.isEventSourceUnavailableError(error)) {
9177
9275
  console.error("ContractWatcher connection failed:", error);
9178
9276
  }
9179
9277
  this.connectionState = "disconnected";
@@ -9189,7 +9287,7 @@ var ContractWatcher = class {
9189
9287
  * few seconds.
9190
9288
  */
9191
9289
  reportEventSourceUnavailable(error) {
9192
- if (!chunk65CTZR2O_cjs.isEventSourceUnavailableError(error)) return false;
9290
+ if (!chunkVVFCCNU2_cjs.isEventSourceUnavailableError(error)) return false;
9193
9291
  if (!this.eventSourceReported) {
9194
9292
  this.eventSourceReported = true;
9195
9293
  console.warn(
@@ -9200,6 +9298,7 @@ var ContractWatcher = class {
9200
9298
  }
9201
9299
  scheduleReconnect() {
9202
9300
  if (!this.isWatching) return;
9301
+ this.cancelSubscriptionRetry();
9203
9302
  if (this.config.maxReconnectAttempts > 0 && this.reconnectAttempts >= this.config.maxReconnectAttempts) {
9204
9303
  console.error(
9205
9304
  `ContractWatcher: Max reconnection attempts (${this.config.maxReconnectAttempts}) reached`
@@ -9253,7 +9352,7 @@ var ContractWatcher = class {
9253
9352
  const now = Date.now();
9254
9353
  let current;
9255
9354
  try {
9256
- current = await chunk65CTZR2O_cjs.getAllNormalizedVtxos(this.config.indexerProvider, scripts, {
9355
+ current = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(this.config.indexerProvider, scripts, {
9257
9356
  spendableOnly: true
9258
9357
  });
9259
9358
  } catch (error) {
@@ -9371,12 +9470,18 @@ var ContractWatcher = class {
9371
9470
  this.subscriptionUpdateDeferred = true;
9372
9471
  return;
9373
9472
  }
9473
+ const signal = this.abortController?.signal;
9374
9474
  const hadSubscription = this.subscriptionId !== void 0;
9375
9475
  try {
9376
9476
  await this.updateSubscription();
9377
9477
  } catch (error) {
9478
+ if (!signal?.aborted) {
9479
+ this.subscriptionNeedsCatchUp = true;
9480
+ this.scheduleSubscriptionRetry();
9481
+ }
9378
9482
  return;
9379
9483
  }
9484
+ if (!this.isWatching || signal?.aborted) return;
9380
9485
  const justGotSubscription = !hadSubscription && this.subscriptionId !== void 0;
9381
9486
  const listenerParked = this.connectionState === "disconnected" || this.connectionState === "reconnecting";
9382
9487
  if (this.isWatching && justGotSubscription && listenerParked) {
@@ -9390,8 +9495,47 @@ var ContractWatcher = class {
9390
9495
  });
9391
9496
  }
9392
9497
  }
9498
+ cancelSubscriptionRetry() {
9499
+ if (this.subscriptionRetryTimeoutId !== void 0) {
9500
+ clearTimeout(this.subscriptionRetryTimeoutId);
9501
+ this.subscriptionRetryTimeoutId = void 0;
9502
+ }
9503
+ }
9504
+ scheduleSubscriptionRetry() {
9505
+ if (!this.isWatching || this.reconnectTimeoutId !== void 0 || this.subscriptionRetryTimeoutId !== void 0)
9506
+ return;
9507
+ if (this.config.maxReconnectAttempts > 0 && this.subscriptionRetryAttempts >= this.config.maxReconnectAttempts)
9508
+ return;
9509
+ const delay = computeReconnectDelay(
9510
+ ++this.subscriptionRetryAttempts,
9511
+ this.config.reconnectDelayMs,
9512
+ this.config.maxReconnectDelayMs
9513
+ );
9514
+ this.subscriptionRetryTimeoutId = setTimeout(() => {
9515
+ this.subscriptionRetryTimeoutId = void 0;
9516
+ void this.tryUpdateSubscription();
9517
+ }, delay);
9518
+ }
9393
9519
  /** @see getSubscribedScripts */
9394
- async updateSubscription() {
9520
+ updateSubscription() {
9521
+ const signal = this.abortController?.signal;
9522
+ const update = this.subscriptionUpdate.then(async () => {
9523
+ if (!this.isWatching || !signal || signal.aborted) return;
9524
+ await this.sendSubscriptionUpdate(signal);
9525
+ if (signal.aborted) return;
9526
+ const recovered = this.subscriptionNeedsCatchUp;
9527
+ this.cancelSubscriptionRetry();
9528
+ this.subscriptionRetryAttempts = 0;
9529
+ this.subscriptionNeedsCatchUp = false;
9530
+ if (recovered) {
9531
+ this.emitConnectionReset();
9532
+ }
9533
+ });
9534
+ this.subscriptionUpdate = update.catch(() => {
9535
+ });
9536
+ return update;
9537
+ }
9538
+ async sendSubscriptionUpdate(signal) {
9395
9539
  const scriptsToWatch = this.getSubscribedScripts();
9396
9540
  if (scriptsToWatch.length === 0) {
9397
9541
  if (this.subscriptionId) {
@@ -9399,24 +9543,66 @@ var ContractWatcher = class {
9399
9543
  await this.config.indexerProvider.unsubscribeForScripts(this.subscriptionId);
9400
9544
  } catch {
9401
9545
  }
9546
+ if (signal.aborted) return;
9402
9547
  this.subscriptionId = void 0;
9403
9548
  }
9404
9549
  return;
9405
9550
  }
9551
+ let subscriptionId;
9406
9552
  try {
9407
- this.subscriptionId = await this.config.indexerProvider.subscribeForScripts(
9553
+ subscriptionId = await this.subscribeWithTimeout(
9408
9554
  scriptsToWatch,
9409
- this.subscriptionId
9555
+ this.subscriptionId,
9556
+ signal
9410
9557
  );
9411
9558
  } catch (error) {
9559
+ if (signal.aborted) return;
9412
9560
  const isStale = error instanceof Error && /subscription\b.*\bnot\s+found/i.test(error.message);
9413
9561
  if (this.subscriptionId && isStale) {
9414
9562
  this.subscriptionId = void 0;
9415
- this.subscriptionId = await this.config.indexerProvider.subscribeForScripts(scriptsToWatch);
9563
+ subscriptionId = await this.subscribeWithTimeout(scriptsToWatch, void 0, signal);
9416
9564
  } else {
9417
9565
  throw error;
9418
9566
  }
9419
9567
  }
9568
+ if (signal.aborted) {
9569
+ if (subscriptionId !== this.subscriptionId) {
9570
+ void this.config.indexerProvider.unsubscribeForScripts(subscriptionId).catch(() => {
9571
+ });
9572
+ }
9573
+ return;
9574
+ }
9575
+ this.subscriptionId = subscriptionId;
9576
+ }
9577
+ async subscribeWithTimeout(scripts, subscriptionId, sessionSignal) {
9578
+ if (sessionSignal.aborted) throw sessionSignal.reason;
9579
+ const request = new AbortController();
9580
+ let cancel;
9581
+ const cancelled = new Promise((_resolve, reject) => {
9582
+ cancel = (reason) => {
9583
+ reject(reason);
9584
+ request.abort(reason);
9585
+ };
9586
+ });
9587
+ const onStop = () => cancel(sessionSignal.reason);
9588
+ sessionSignal.addEventListener("abort", onStop, { once: true });
9589
+ const timer = setTimeout(
9590
+ () => cancel(new Error("Subscription request timed out")),
9591
+ this.config.subscriptionRequestTimeoutMs
9592
+ );
9593
+ try {
9594
+ const pending = this.config.indexerProvider.subscribeForScripts(scripts, subscriptionId, request.signal).then((id) => {
9595
+ if (request.signal.aborted && id !== subscriptionId && id !== this.subscriptionId) {
9596
+ void this.config.indexerProvider.unsubscribeForScripts(id).catch(() => {
9597
+ });
9598
+ }
9599
+ return id;
9600
+ });
9601
+ return await Promise.race([pending, cancelled]);
9602
+ } finally {
9603
+ clearTimeout(timer);
9604
+ sessionSignal.removeEventListener("abort", onStop);
9605
+ }
9420
9606
  }
9421
9607
  async listenLoop() {
9422
9608
  if (!this.subscriptionId || !this.abortController || !this.isWatching) {
@@ -9448,14 +9634,14 @@ var ContractWatcher = class {
9448
9634
  const timestamp = Date.now();
9449
9635
  if (update.newVtxos?.length) {
9450
9636
  this.processSubscriptionVtxos(
9451
- update.newVtxos.map(chunk65CTZR2O_cjs.normalizeVtxo),
9637
+ update.newVtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo),
9452
9638
  "vtxo_received",
9453
9639
  timestamp
9454
9640
  );
9455
9641
  }
9456
9642
  if (update.spentVtxos?.length) {
9457
9643
  this.processSubscriptionVtxos(
9458
- update.spentVtxos.map(chunk65CTZR2O_cjs.normalizeVtxo),
9644
+ update.spentVtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo),
9459
9645
  "vtxo_spent",
9460
9646
  timestamp
9461
9647
  );
@@ -9480,8 +9666,8 @@ var ContractWatcher = class {
9480
9666
  continue;
9481
9667
  }
9482
9668
  if (target === byWatchedScript && eventType === "vtxo_received") {
9483
- const n = chunk65CTZR2O_cjs.normalizeVtxo(vtxo);
9484
- if (chunk65CTZR2O_cjs.isVtxoSpent(n) || n.isSwept || chunk65CTZR2O_cjs.isPastExpiry(n, now)) continue;
9669
+ const n = chunkVVFCCNU2_cjs.normalizeVtxo(vtxo);
9670
+ if (chunkVVFCCNU2_cjs.isVtxoSpent(n) || n.isSwept || chunkVVFCCNU2_cjs.isPastExpiry(n, now)) continue;
9485
9671
  }
9486
9672
  let bucket = target.get(vtxo.script);
9487
9673
  if (!bucket) {
@@ -9618,7 +9804,7 @@ function annotatableIn(scriptToContract, vtxos, memo) {
9618
9804
  if (!contract) continue;
9619
9805
  try {
9620
9806
  const key = `${contract.type}\0${script}\0${JSON.stringify(contract.params)}`;
9621
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(contract.type);
9807
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
9622
9808
  const hit = memo?.get(script);
9623
9809
  let tapscripts;
9624
9810
  if (hit && hit.key === key && hit.handler === handler) {
@@ -9646,6 +9832,11 @@ function annotatableIn(scriptToContract, vtxos, memo) {
9646
9832
  }
9647
9833
  return { scripts, cache, failures };
9648
9834
  }
9835
+ function annotateAgainst(vtxos, byScript, tapscripts = /* @__PURE__ */ new Map()) {
9836
+ return vtxos.map(
9837
+ (vtxo) => extendVirtualCoinForContract(chunkVVFCCNU2_cjs.normalizeVtxo(vtxo), byScript, tapscripts)
9838
+ );
9839
+ }
9649
9840
  var SCAN_MAX_INDEX = 1e4;
9650
9841
  var DEFAULT_SCAN_BATCH = 10;
9651
9842
  var CHAIN_TIP_TTL_MS = 3e4;
@@ -9687,8 +9878,8 @@ var ContractManager = class _ContractManager {
9687
9878
  * `dispose()`, so it re-checks this at every await rather than run on a torn-down watcher. */
9688
9879
  disposed = false;
9689
9880
  constructor(config) {
9690
- chunk65CTZR2O_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", config.vtxoSyncMaxAgeMs);
9691
- chunk65CTZR2O_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", config.vtxoSyncOverlapMs);
9881
+ chunkVVFCCNU2_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", config.vtxoSyncMaxAgeMs);
9882
+ chunkVVFCCNU2_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", config.vtxoSyncOverlapMs);
9692
9883
  this.config = { ...config };
9693
9884
  this.watcher = new ContractWatcher({
9694
9885
  indexerProvider: config.indexerProvider,
@@ -9724,12 +9915,12 @@ var ContractManager = class _ContractManager {
9724
9915
  }
9725
9916
  /** @see ContractManagerConfig.vtxoSyncMaxAgeMs — for factory-built managers. */
9726
9917
  setVtxoSyncMaxAge(maxAgeMs) {
9727
- chunk65CTZR2O_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", maxAgeMs);
9918
+ chunkVVFCCNU2_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", maxAgeMs);
9728
9919
  this.config.vtxoSyncMaxAgeMs = maxAgeMs;
9729
9920
  }
9730
9921
  /** @see ContractManagerConfig.vtxoSyncOverlapMs — for factory-built managers. */
9731
9922
  setVtxoSyncOverlap(overlapMs) {
9732
- chunk65CTZR2O_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", overlapMs);
9923
+ chunkVVFCCNU2_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", overlapMs);
9733
9924
  this.config.vtxoSyncOverlapMs = overlapMs;
9734
9925
  }
9735
9926
  markSyncOnline() {
@@ -9777,7 +9968,7 @@ var ContractManager = class _ContractManager {
9777
9968
  this.markSyncOnline();
9778
9969
  return void 0;
9779
9970
  } catch (err) {
9780
- if (!chunk65CTZR2O_cjs.isRetryableProviderError(err)) throw err;
9971
+ if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
9781
9972
  this.markSyncDegraded(err);
9782
9973
  return err;
9783
9974
  }
@@ -9800,7 +9991,7 @@ var ContractManager = class _ContractManager {
9800
9991
  try {
9801
9992
  await this.scheduleLookAheadDrain();
9802
9993
  } catch (err) {
9803
- if (!chunk65CTZR2O_cjs.isRetryableProviderError(err)) throw err;
9994
+ if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
9804
9995
  this.lookAheadRefillOwed = true;
9805
9996
  this.markSyncDegraded(err);
9806
9997
  }
@@ -9863,7 +10054,7 @@ var ContractManager = class _ContractManager {
9863
10054
  /** No throw: construction returned long ago, so the state is the channel. */
9864
10055
  reportBackgroundFailure(stage, err) {
9865
10056
  this.markSyncDegraded(err);
9866
- if (!chunk65CTZR2O_cjs.isRetryableProviderError(err)) {
10057
+ if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) {
9867
10058
  console.error(`[contracts] background ${stage} failed`, err);
9868
10059
  }
9869
10060
  }
@@ -9965,7 +10156,7 @@ var ContractManager = class _ContractManager {
9965
10156
  const from = Math.max(0, watermark - lookAhead.size);
9966
10157
  const to = watermark + lookAhead.size;
9967
10158
  const deps = lookAhead.candidateDeps();
9968
- const handlers = chunkUV3IM6BG_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkUV3IM6BG_cjs.contractHandlers.get(t)).filter(hasCandidates);
10159
+ const handlers = chunkCFOIHLON_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkCFOIHLON_cjs.contractHandlers.get(t)).filter(hasCandidates);
9969
10160
  const band = /* @__PURE__ */ new Map();
9970
10161
  for (let index = from; index <= to; index++) {
9971
10162
  const descriptor = lookAhead.materialize(index);
@@ -9976,7 +10167,7 @@ var ContractManager = class _ContractManager {
9976
10167
  index,
9977
10168
  params: {
9978
10169
  ...candidate,
9979
- ...chunkUV3IM6BG_cjs.speculativeReceiveMetadata(descriptor)
10170
+ ...chunkCFOIHLON_cjs.speculativeReceiveMetadata(descriptor)
9980
10171
  }
9981
10172
  });
9982
10173
  }
@@ -10035,7 +10226,7 @@ var ContractManager = class _ContractManager {
10035
10226
  });
10036
10227
  for (const entry of pending) entry.catchUpPending = false;
10037
10228
  } catch (err) {
10038
- if (!chunk65CTZR2O_cjs.isRetryableProviderError(err)) throw err;
10229
+ if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
10039
10230
  this.markSyncDegraded(err);
10040
10231
  }
10041
10232
  }
@@ -10126,7 +10317,7 @@ var ContractManager = class _ContractManager {
10126
10317
  return result;
10127
10318
  }
10128
10319
  async upsertContractRow(params) {
10129
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(params.type);
10320
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(params.type);
10130
10321
  if (!handler) {
10131
10322
  throw new Error(`No handler registered for contract type '${params.type}'`);
10132
10323
  }
@@ -10194,7 +10385,7 @@ var ContractManager = class _ContractManager {
10194
10385
  `scanContracts: batchSize must be a positive integer (got ${String(opts.batchSize)})`
10195
10386
  );
10196
10387
  }
10197
- const registered = chunkUV3IM6BG_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkUV3IM6BG_cjs.contractHandlers.get(t)).filter(isDiscoverable);
10388
+ const registered = chunkCFOIHLON_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkCFOIHLON_cjs.contractHandlers.get(t)).filter(isDiscoverable);
10198
10389
  const discoverables = [
10199
10390
  ...registered.filter((h) => h.type === "boarding"),
10200
10391
  ...registered.filter((h) => h.type !== "boarding")
@@ -10320,7 +10511,7 @@ var ContractManager = class _ContractManager {
10320
10511
  return await collectContracts(this.config.contractRepository, dbFilter);
10321
10512
  }
10322
10513
  async getContractsWithVtxos(filter, pageSize, options) {
10323
- chunk65CTZR2O_cjs.assertNonNegativeMs("maxSyncAgeMs", options?.maxSyncAgeMs);
10514
+ chunkVVFCCNU2_cjs.assertNonNegativeMs("maxSyncAgeMs", options?.maxSyncAgeMs);
10324
10515
  const contracts = await this.getContracts(filter);
10325
10516
  if (this.syncedWithin(
10326
10517
  contracts,
@@ -10383,10 +10574,7 @@ var ContractManager = class _ContractManager {
10383
10574
  for (const contract of contracts) {
10384
10575
  byScript.set(contract.script, contract);
10385
10576
  }
10386
- const tapscriptCache = tapscripts ?? /* @__PURE__ */ new Map();
10387
- return vtxos.map(
10388
- (vtxo) => extendVirtualCoinForContract(chunk65CTZR2O_cjs.normalizeVtxo(vtxo), byScript, tapscriptCache)
10389
- );
10577
+ return annotateAgainst(vtxos, byScript, tapscripts);
10390
10578
  }
10391
10579
  /** @inheritdoc */
10392
10580
  async assertAnnotatable(vtxos) {
@@ -10430,14 +10618,14 @@ var ContractManager = class _ContractManager {
10430
10618
  const byScript = new Map(contracts.map((contract) => [contract.script, contract]));
10431
10619
  const asking = vtxos.filter((vtxo) => {
10432
10620
  const contract = byScript.get(vtxo.script);
10433
- return contract !== void 0 && chunkUV3IM6BG_cjs.contractHandlers.get(contract.type)?.assertSpendableNow !== void 0;
10621
+ return contract !== void 0 && chunkCFOIHLON_cjs.contractHandlers.get(contract.type)?.assertSpendableNow !== void 0;
10434
10622
  });
10435
10623
  if (asking.length === 0) return refused;
10436
10624
  const tip = await this.currentChainTip();
10437
10625
  const walletDescriptorValue = await walletDescriptor?.();
10438
10626
  for (const vtxo of asking) {
10439
10627
  const contract = byScript.get(vtxo.script);
10440
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(contract.type);
10628
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
10441
10629
  if (!handler?.assertSpendableNow) continue;
10442
10630
  const context = {
10443
10631
  collaborative: true,
@@ -10447,7 +10635,7 @@ var ContractManager = class _ContractManager {
10447
10635
  walletDescriptor: walletDescriptorValue,
10448
10636
  // `isVirtualCoin` only checks `script`, which every input has; `isCsvSpendable`
10449
10637
  // reads `vtxo.status.block_time` unguarded, so require `status` too.
10450
- vtxo: chunk65CTZR2O_cjs.isVirtualCoin(vtxo) && "status" in vtxo ? vtxo : void 0
10638
+ vtxo: chunkVVFCCNU2_cjs.isVirtualCoin(vtxo) && "status" in vtxo ? vtxo : void 0
10451
10639
  };
10452
10640
  try {
10453
10641
  await handler.assertSpendableNow(
@@ -10560,7 +10748,7 @@ var ContractManager = class _ContractManager {
10560
10748
  const { contractScript, collaborative = true, walletDescriptor, vtxo } = options;
10561
10749
  const [contract] = await this.getContracts({ script: contractScript });
10562
10750
  if (!contract) return [];
10563
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(contract.type);
10751
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
10564
10752
  if (!handler) return [];
10565
10753
  const script = handler.createScript(contract.params);
10566
10754
  const tip = await this.currentChainTip();
@@ -10582,7 +10770,7 @@ var ContractManager = class _ContractManager {
10582
10770
  const { contractScript, collaborative = true, walletDescriptor } = options;
10583
10771
  const [contract] = await this.getContracts({ script: contractScript });
10584
10772
  if (!contract) return [];
10585
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(contract.type);
10773
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
10586
10774
  if (!handler) return [];
10587
10775
  const script = handler.createScript(contract.params);
10588
10776
  const context = {
@@ -10628,7 +10816,7 @@ var ContractManager = class _ContractManager {
10628
10816
  }
10629
10817
  async refreshOutpoints(outpoints) {
10630
10818
  if (outpoints.length === 0) return;
10631
- const { vtxos } = await chunk65CTZR2O_cjs.getNormalizedVtxos(this.config.indexerProvider, {
10819
+ const { vtxos } = await chunkVVFCCNU2_cjs.getNormalizedVtxos(this.config.indexerProvider, {
10632
10820
  outpoints
10633
10821
  });
10634
10822
  if (vtxos.length === 0) return;
@@ -10637,9 +10825,15 @@ var ContractManager = class _ContractManager {
10637
10825
  script: scripts
10638
10826
  });
10639
10827
  const scriptToContract = new Map(contracts.map((c) => [c.script, c]));
10640
- const owned = vtxos.filter((v) => scriptToContract.has(v.script));
10828
+ const {
10829
+ scripts: annotatable,
10830
+ cache,
10831
+ failures
10832
+ } = annotatableIn(scriptToContract, vtxos, this.tapscriptMemo);
10833
+ this.recordAnnotationFailures(annotatable, failures);
10834
+ const owned = vtxos.filter((v) => annotatable.has(v.script));
10641
10835
  if (owned.length === 0) return;
10642
- const annotated = await this.annotateVtxos(owned);
10836
+ const annotated = annotateAgainst(owned, scriptToContract, cache);
10643
10837
  const byAddress = /* @__PURE__ */ new Map();
10644
10838
  for (const vtxo of annotated) {
10645
10839
  const contract = scriptToContract.get(vtxo.script);
@@ -10723,7 +10917,7 @@ var ContractManager = class _ContractManager {
10723
10917
  break;
10724
10918
  }
10725
10919
  } catch (err) {
10726
- if (!chunk65CTZR2O_cjs.isRetryableProviderError(err)) throw err;
10920
+ if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
10727
10921
  this.markSyncDegraded(err);
10728
10922
  synced = false;
10729
10923
  }
@@ -10811,7 +11005,7 @@ var ContractManager = class _ContractManager {
10811
11005
  */
10812
11006
  async reconcilePendingFrontier(contracts) {
10813
11007
  const scriptToContract = new Map(contracts.map((c) => [c.script, c]));
10814
- const vtxos = await chunk65CTZR2O_cjs.getAllNormalizedVtxos(
11008
+ const vtxos = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(
10815
11009
  this.config.indexerProvider,
10816
11010
  contracts.map((c) => c.script),
10817
11011
  { pendingOnly: true }
@@ -10826,7 +11020,7 @@ var ContractManager = class _ContractManager {
10826
11020
  } = annotatableIn(scriptToContract, vtxos, this.tapscriptMemo);
10827
11021
  this.recordAnnotationFailures(annotatable, failures);
10828
11022
  const owned = vtxos.filter((v) => annotatable.has(v.script));
10829
- const annotated = await this.annotateVtxos(owned, cache);
11023
+ const annotated = annotateAgainst(owned, scriptToContract, cache);
10830
11024
  const byContract = /* @__PURE__ */ new Map();
10831
11025
  const contractByAddress = /* @__PURE__ */ new Map();
10832
11026
  for (const vtxo of annotated) {
@@ -10885,7 +11079,7 @@ var ContractManager = class _ContractManager {
10885
11079
  }
10886
11080
  return result;
10887
11081
  }
10888
- async fetchContractVtxosBulk(contracts, pageSize = chunk65CTZR2O_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
11082
+ async fetchContractVtxosBulk(contracts, pageSize = chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
10889
11083
  if (contracts.length === 0) {
10890
11084
  return { vtxosByScript: /* @__PURE__ */ new Map(), promoted: /* @__PURE__ */ new Map() };
10891
11085
  }
@@ -10901,7 +11095,7 @@ var ContractManager = class _ContractManager {
10901
11095
  before: syncWindow.before
10902
11096
  }
10903
11097
  } : {};
10904
- const vtxos = await chunk65CTZR2O_cjs.getAllNormalizedVtxos(
11098
+ const vtxos = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(
10905
11099
  this.config.indexerProvider,
10906
11100
  contracts.map((c) => c.script),
10907
11101
  { ...windowOpts, pageSize }
@@ -10917,7 +11111,7 @@ var ContractManager = class _ContractManager {
10917
11111
  } = annotatableIn(scriptToContract, vtxos, this.tapscriptMemo);
10918
11112
  this.recordAnnotationFailures(annotatable, failures);
10919
11113
  const owned = vtxos.filter((v) => annotatable.has(v.script));
10920
- const annotated = await this.annotateVtxos(owned, cache);
11114
+ const annotated = annotateAgainst(owned, scriptToContract, cache);
10921
11115
  for (const vtxo of annotated) {
10922
11116
  result.get(vtxo.script).push({
10923
11117
  ...vtxo,
@@ -11003,7 +11197,7 @@ function parseLegacyExpiry(batchExpiry) {
11003
11197
  if (typeof batchExpiry !== "number" || !Number.isFinite(batchExpiry) || batchExpiry <= 0) {
11004
11198
  return {};
11005
11199
  }
11006
- if (batchExpiry >= chunk65CTZR2O_cjs.EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(batchExpiry) };
11200
+ if (batchExpiry >= chunkVVFCCNU2_cjs.EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(batchExpiry) };
11007
11201
  return { expiresAtHeight: batchExpiry / 1e3 };
11008
11202
  }
11009
11203
  function legacyVtxoFacts(status) {
@@ -11241,7 +11435,7 @@ function backfillContractWatchState(store) {
11241
11435
  };
11242
11436
  readPage();
11243
11437
  }
11244
- var unspentFlag = (vtxo) => chunk65CTZR2O_cjs.isVtxoSpent(vtxo) ? {} : { unspent: 1 };
11438
+ var unspentFlag = (vtxo) => chunkVVFCCNU2_cjs.isVtxoSpent(vtxo) ? {} : { unspent: 1 };
11245
11439
  function backfillVtxoIndexFields(transaction) {
11246
11440
  const store = transaction.objectStore(STORE_VTXOS);
11247
11441
  const pageSize = 1e3;
@@ -11272,7 +11466,7 @@ var DEFAULT_DB_NAME = "arkade-service-worker";
11272
11466
  var DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS = 1e4;
11273
11467
  function normalizeOptions2(pathOrOptions) {
11274
11468
  const o = typeof pathOrOptions === "string" ? { path: pathOrOptions } : pathOrOptions;
11275
- chunk65CTZR2O_cjs.assertTimerMs("activationTimeoutMs", o.activationTimeoutMs);
11469
+ chunkVVFCCNU2_cjs.assertTimerMs("activationTimeoutMs", o.activationTimeoutMs);
11276
11470
  return {
11277
11471
  path: o.path,
11278
11472
  activationTimeoutMs: o.activationTimeoutMs ?? DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS
@@ -11491,7 +11685,7 @@ var deserializeTapLeaf = (t) => {
11491
11685
  const s = base.hex.decode(t.s);
11492
11686
  return [cb, s];
11493
11687
  };
11494
- var deserializeVtxo = (o) => chunk65CTZR2O_cjs.normalizeVtxo({
11688
+ var deserializeVtxo = (o) => chunkVVFCCNU2_cjs.normalizeVtxo({
11495
11689
  ...o,
11496
11690
  createdAt: new Date(o.createdAt),
11497
11691
  tapTree: base.hex.decode(o.tapTree),
@@ -11915,7 +12109,7 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
11915
12109
  */
11916
12110
  materializeDescriptorAt(index) {
11917
12111
  const descriptor = this.identity.descriptor;
11918
- const network = chunkUV3IM6BG_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
12112
+ const network = chunkCFOIHLON_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
11919
12113
  const expansion = descriptorsScure.expand({ descriptor, network, index });
11920
12114
  const keyInfo = expansion.expansionMap?.["@0"];
11921
12115
  if (!keyInfo?.keyExpression) {
@@ -11983,7 +12177,7 @@ function signingDescriptorIndex(descriptor) {
11983
12177
  }
11984
12178
  function newestWalletReceiveContract(contracts, serverPubKeyHex) {
11985
12179
  return contracts.filter(
11986
- (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkUV3IM6BG_cjs.WALLET_RECEIVE_SOURCE
12180
+ (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkCFOIHLON_cjs.WALLET_RECEIVE_SOURCE
11987
12181
  ).sort((a, b) => {
11988
12182
  if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
11989
12183
  return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
@@ -12034,7 +12228,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
12034
12228
  const provider = await resolveDescriptorProvider(config, setup.walletRepository);
12035
12229
  if (!provider) return void 0;
12036
12230
  const allowSilentFallback = (config.walletMode ?? "auto") === "auto";
12037
- const expectedContractType = setup.offchainTapscript instanceof chunkUV3IM6BG_cjs.DelegateVtxo.Script ? "delegate" : "default";
12231
+ const expectedContractType = setup.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? "delegate" : "default";
12038
12232
  const factoryOpts = {
12039
12233
  walletRepository: setup.walletRepository,
12040
12234
  contractRepository: setup.contractRepository,
@@ -12191,7 +12385,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
12191
12385
  };
12192
12386
  function deriveLeafPubkey(descriptor) {
12193
12387
  try {
12194
- return chunkUV3IM6BG_cjs.deriveDescriptorLeafPubKey(descriptor);
12388
+ return chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(descriptor);
12195
12389
  } catch (e) {
12196
12390
  throw new NonRangeableDescriptorError(
12197
12391
  "Cannot derive leaf pubkey: descriptor is not a materialized, parsable tr(...) shape.",
@@ -12203,7 +12397,7 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
12203
12397
  const pubKey = deriveLeafPubkey(descriptor);
12204
12398
  const tapscript = rebuildTapscript(current, pubKey);
12205
12399
  const serverPubKey = tapscript.options.serverPubKey;
12206
- const csvTimelock2 = chunk65CTZR2O_cjs.timelockToSequence(tapscript.options.csvTimelock).toString();
12400
+ const csvTimelock2 = chunkVVFCCNU2_cjs.timelockToSequence(tapscript.options.csvTimelock).toString();
12207
12401
  const base$1 = {
12208
12402
  script: base.hex.encode(tapscript.pkScript),
12209
12403
  address: tapscript.address(hrp, serverPubKey).encode(),
@@ -12211,11 +12405,11 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
12211
12405
  // Read at sign time to route rotated-pubkey inputs through `signWithDescriptor`; without
12212
12406
  // it spends are rejected with `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
12213
12407
  metadata: {
12214
- ...tagSource && { source: chunkUV3IM6BG_cjs.WALLET_RECEIVE_SOURCE },
12408
+ ...tagSource && { source: chunkCFOIHLON_cjs.WALLET_RECEIVE_SOURCE },
12215
12409
  signingDescriptor: descriptor
12216
12410
  }
12217
12411
  };
12218
- const params = tapscript instanceof chunkUV3IM6BG_cjs.DelegateVtxo.Script ? {
12412
+ const params = tapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? {
12219
12413
  ...base$1,
12220
12414
  type: "delegate",
12221
12415
  params: {
@@ -12236,10 +12430,10 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
12236
12430
  return { tapscript, params };
12237
12431
  }
12238
12432
  function rebuildTapscript(current, pubKey) {
12239
- if (current instanceof chunkUV3IM6BG_cjs.DelegateVtxo.Script) {
12240
- return new chunkUV3IM6BG_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
12433
+ if (current instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script) {
12434
+ return new chunkCFOIHLON_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
12241
12435
  }
12242
- return new chunkUV3IM6BG_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
12436
+ return new chunkCFOIHLON_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
12243
12437
  }
12244
12438
  async function pickActiveReceive(contractRepository, serverPubKey, expectedType) {
12245
12439
  const candidates = await collectContracts(contractRepository, {
@@ -12280,12 +12474,13 @@ async function resolveDescriptorProvider(config, walletRepository) {
12280
12474
 
12281
12475
  // src/wallet/balance.ts
12282
12476
  function computeOffchainBalance(vtxos, caps) {
12283
- const { now, isPendingRecovery, isGenericallySpendable, isUnlocked, dustCarrier } = caps;
12477
+ const { now, isPendingRecovery, isGenericallySpendable, isUnlocked, isReserved, dustCarrier } = caps;
12284
12478
  let settled = 0;
12285
12479
  let preconfirmed = 0;
12286
12480
  let available = 0;
12287
12481
  let gated = 0;
12288
12482
  let intentLocked = 0;
12483
+ let reserved = 0;
12289
12484
  let recoverable = 0;
12290
12485
  let pendingRecovery = 0;
12291
12486
  let unrolled = 0;
@@ -12297,7 +12492,7 @@ function computeOffchainBalance(vtxos, caps) {
12297
12492
  }
12298
12493
  };
12299
12494
  for (const vtxo of vtxos) {
12300
- if (chunk65CTZR2O_cjs.isVtxoSpent(vtxo)) continue;
12495
+ if (chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)) continue;
12301
12496
  addAssets(owned, vtxo);
12302
12497
  if (vtxo.isUnrolled) {
12303
12498
  unrolled += vtxo.value;
@@ -12307,11 +12502,11 @@ function computeOffchainBalance(vtxos, caps) {
12307
12502
  pendingRecovery += vtxo.value;
12308
12503
  continue;
12309
12504
  }
12310
- if (chunk65CTZR2O_cjs.canRecoverOnchain(vtxo, now)) {
12505
+ if (chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now)) {
12311
12506
  recoverable += vtxo.value;
12312
12507
  continue;
12313
12508
  }
12314
- if (!chunk65CTZR2O_cjs.canSpendOffchain(vtxo, now)) continue;
12509
+ if (!chunkVVFCCNU2_cjs.canSpendOffchain(vtxo, now)) continue;
12315
12510
  if (vtxo.isPreconfirmed) {
12316
12511
  preconfirmed += vtxo.value;
12317
12512
  } else {
@@ -12321,6 +12516,8 @@ function computeOffchainBalance(vtxos, caps) {
12321
12516
  gated += vtxo.value;
12322
12517
  } else if (!isUnlocked(vtxo)) {
12323
12518
  intentLocked += vtxo.value;
12519
+ } else if (isReserved?.(vtxo)) {
12520
+ reserved += vtxo.value;
12324
12521
  } else {
12325
12522
  available += vtxo.value;
12326
12523
  addAssets(spendable, vtxo);
@@ -12336,6 +12533,7 @@ function computeOffchainBalance(vtxos, caps) {
12336
12533
  available,
12337
12534
  gated,
12338
12535
  intentLocked,
12536
+ reserved,
12339
12537
  recoverable,
12340
12538
  pendingRecovery,
12341
12539
  unrolled,
@@ -12366,6 +12564,7 @@ function toWalletBalance(boardingUtxos, offchain) {
12366
12564
  available: offchain.available,
12367
12565
  gated: offchain.gated,
12368
12566
  intentLocked: offchain.intentLocked,
12567
+ reserved: offchain.reserved,
12369
12568
  recoverable: offchain.recoverable,
12370
12569
  pendingRecovery: offchain.pendingRecovery,
12371
12570
  unrolled: offchain.unrolled,
@@ -12522,7 +12721,7 @@ function intentProofJobs(coins) {
12522
12721
  if (coins.length === 0) return [];
12523
12722
  const coinJobs = coins.map((coin, i) => ({
12524
12723
  index: i + 1,
12525
- lookupScript: chunk65CTZR2O_cjs.VtxoScript.decode(coin.tapTree).pkScript
12724
+ lookupScript: chunkVVFCCNU2_cjs.VtxoScript.decode(coin.tapTree).pkScript
12526
12725
  }));
12527
12726
  return [{ index: 0, lookupScript: coinJobs[0].lookupScript }, ...coinJobs];
12528
12727
  }
@@ -12548,7 +12747,7 @@ function dedupeTimelocks(timelocks) {
12548
12747
  const seen = /* @__PURE__ */ new Set();
12549
12748
  const deduped = [];
12550
12749
  for (const timelock of timelocks) {
12551
- const sequence = chunk65CTZR2O_cjs.timelockToSequence(timelock).toString();
12750
+ const sequence = chunkVVFCCNU2_cjs.timelockToSequence(timelock).toString();
12552
12751
  if (seen.has(sequence)) continue;
12553
12752
  seen.add(sequence);
12554
12753
  deduped.push(timelock);
@@ -12564,7 +12763,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
12564
12763
  if (!newest?.params.pubKey) return baseline;
12565
12764
  try {
12566
12765
  const pubKey = base.hex.decode(newest.params.pubKey);
12567
- return new chunkUV3IM6BG_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
12766
+ return new chunkCFOIHLON_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
12568
12767
  } catch (e) {
12569
12768
  console.warn("Skipping malformed boarding contract at boot", newest.script, e);
12570
12769
  return baseline;
@@ -12596,21 +12795,21 @@ function filterFlatVtxos(vtxos, filter, pendingSpendOutpoints) {
12596
12795
  if (vtxo.isUnrolled) {
12597
12796
  return !!f.withUnrolled;
12598
12797
  }
12599
- if (chunk65CTZR2O_cjs.isVtxoSpent(vtxo)) {
12798
+ if (chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)) {
12600
12799
  return false;
12601
12800
  }
12602
- if (!f.withRecoverable && chunk65CTZR2O_cjs.canRecoverOnchain(vtxo, now)) {
12801
+ if (!f.withRecoverable && chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now)) {
12603
12802
  return false;
12604
12803
  }
12605
12804
  return true;
12606
12805
  });
12607
12806
  }
12608
12807
  async function refreshSweptStateOfExpiredInputs(wallet, inputs) {
12609
- const candidates = inputs.filter(chunk65CTZR2O_cjs.isVirtualCoin).map(chunk65CTZR2O_cjs.normalizeVtxo).filter((v) => !v.isSwept);
12808
+ const candidates = inputs.filter(chunkVVFCCNU2_cjs.isVirtualCoin).map(chunkVVFCCNU2_cjs.normalizeVtxo).filter((v) => !v.isSwept);
12610
12809
  if (candidates.length === 0) return inputs;
12611
- const now = candidates.some((v) => v.expiresAtHeight !== void 0) ? await chunk65CTZR2O_cjs.resolveTimeHeight(wallet.onchainProvider) : { timestamp: /* @__PURE__ */ new Date() };
12810
+ const now = candidates.some((v) => v.expiresAtHeight !== void 0) ? await chunkVVFCCNU2_cjs.resolveTimeHeight(wallet.onchainProvider) : { timestamp: /* @__PURE__ */ new Date() };
12612
12811
  const suspects = candidates.filter(
12613
- (v) => chunk65CTZR2O_cjs.isPastExpiry(v, now) || v.expiresAtHeight !== void 0 && now.height === void 0
12812
+ (v) => chunkVVFCCNU2_cjs.isPastExpiry(v, now) || v.expiresAtHeight !== void 0 && now.height === void 0
12614
12813
  );
12615
12814
  if (suspects.length === 0) return inputs;
12616
12815
  let sweptNow;
@@ -12624,12 +12823,12 @@ async function refreshSweptStateOfExpiredInputs(wallet, inputs) {
12624
12823
  );
12625
12824
  } catch (e) {
12626
12825
  const message = "could not confirm the swept state of expired settlement inputs; retry the settlement";
12627
- throw chunk65CTZR2O_cjs.isRetryableProviderError(e) ? new chunk65CTZR2O_cjs.ProviderUnavailableError(message, { cause: e }) : new Error(message, { cause: e });
12826
+ throw chunkVVFCCNU2_cjs.isRetryableProviderError(e) ? new chunkVVFCCNU2_cjs.ProviderUnavailableError(message, { cause: e }) : new Error(message, { cause: e });
12628
12827
  }
12629
12828
  if (sweptNow.size === 0) return inputs;
12630
12829
  return inputs.map((input) => {
12631
- if (!chunk65CTZR2O_cjs.isVirtualCoin(input) || !sweptNow.has(`${input.txid}:${input.vout}`)) return input;
12632
- return { ...chunk65CTZR2O_cjs.normalizeVtxo(input), isSwept: true };
12830
+ if (!chunkVVFCCNU2_cjs.isVirtualCoin(input) || !sweptNow.has(`${input.txid}:${input.vout}`)) return input;
12831
+ return { ...chunkVVFCCNU2_cjs.normalizeVtxo(input), isSwept: true };
12633
12832
  });
12634
12833
  }
12635
12834
  var PENDING_RECOVERY_REASON = "is past its operator signer's rotation cutoff \u2014 the operator will not co-sign it until it recovers";
@@ -12641,6 +12840,9 @@ function omittedOutpoints(before, after) {
12641
12840
  before.map((vtxo) => `${vtxo.txid}:${vtxo.vout}`).filter((outpoint) => !kept.has(outpoint))
12642
12841
  );
12643
12842
  }
12843
+ function coinKeys(inputs) {
12844
+ return inputs.filter((input) => typeof input === "object" && input !== null).map((input) => `${input.txid}:${input.vout}`);
12845
+ }
12644
12846
  function excludeLockedOutpoints(vtxos, locked) {
12645
12847
  if (locked.length === 0) return vtxos;
12646
12848
  const lockedKeys = new Set(locked.map((o) => `${o.txid}:${o.vout}`));
@@ -12675,6 +12877,18 @@ var ArkadeCashCreateError = class extends Error {
12675
12877
  cash;
12676
12878
  cause;
12677
12879
  };
12880
+ var ArkadeCashOperatorMismatchError = class extends Error {
12881
+ constructor(cashSignerPubKey, activeSignerPubKey) {
12882
+ super(
12883
+ `ArkadeCash comes from another operator: its signer ${cashSignerPubKey} is not the active signer ${activeSignerPubKey} of the connected operator, and not one of its deprecated signers. Connect to the operator that issued it to claim it.`
12884
+ );
12885
+ this.cashSignerPubKey = cashSignerPubKey;
12886
+ this.activeSignerPubKey = activeSignerPubKey;
12887
+ this.name = "ArkadeCashOperatorMismatchError";
12888
+ }
12889
+ cashSignerPubKey;
12890
+ activeSignerPubKey;
12891
+ };
12678
12892
  var ReadonlyWallet = class _ReadonlyWallet {
12679
12893
  constructor(identity, network, onchainProvider, arkProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegateProvider, watcherConfig, walletContractTimelocks) {
12680
12894
  this.identity = identity;
@@ -12735,6 +12949,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12735
12949
  // Outpoints committed to an in-flight settle/send, filtered from getVtxos() so concurrent
12736
12950
  // callers can't reselect them. In-memory only: a stale entry only hides a VTXO.
12737
12951
  _pendingSpendOutpoints = /* @__PURE__ */ new Set();
12952
+ _heldOutpoints = /* @__PURE__ */ new Set();
12738
12953
  /** Activity resolvers consumed by {@link getActivityHistory}. */
12739
12954
  activity = createDefaultActivityRegistry();
12740
12955
  get assetManager() {
@@ -12902,7 +13117,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12902
13117
  async getArkadeReader() {
12903
13118
  const indexer = this.indexerProvider;
12904
13119
  return {
12905
- getVtxos: (opts) => chunk65CTZR2O_cjs.getNormalizedVtxos(indexer, opts),
13120
+ getVtxos: (opts) => chunkVVFCCNU2_cjs.getNormalizedVtxos(indexer, opts),
12906
13121
  getVirtualTxs: (txids, opts) => indexer.getVirtualTxs(txids, opts)
12907
13122
  };
12908
13123
  }
@@ -12937,7 +13152,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12937
13152
  }
12938
13153
  /** Shared setup for ReadonlyWallet.create() and Wallet.create(). */
12939
13154
  static async setupWalletConfig(config, pubKey) {
12940
- const arkProvider = config.arkProvider || new chunk65CTZR2O_cjs.RestArkProvider();
13155
+ const arkProvider = config.arkProvider || new chunkVVFCCNU2_cjs.RestArkProvider();
12941
13156
  let indexerProvider = config.indexerProvider;
12942
13157
  if (!indexerProvider) {
12943
13158
  const derived = extractArkProviderUrl(arkProvider);
@@ -12946,7 +13161,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12946
13161
  "indexerProvider is required when arkProvider is provided without a discoverable serverUrl"
12947
13162
  );
12948
13163
  }
12949
- indexerProvider = new chunkPAD5V653_cjs.RestIndexerProvider(derived ?? chunk65CTZR2O_cjs.DEFAULT_ARKADE_SERVER_URL);
13164
+ indexerProvider = new chunkFEBAG2K2_cjs.RestIndexerProvider(derived ?? chunkVVFCCNU2_cjs.DEFAULT_ARKADE_SERVER_URL);
12950
13165
  }
12951
13166
  const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
12952
13167
  const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
@@ -12955,7 +13170,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12955
13170
  source: serverInfoSource,
12956
13171
  lastOnlineAt: serverInfoLastOnlineAt
12957
13172
  } = await resolveArkInfo(arkProvider, walletRepository);
12958
- const network = chunk65CTZR2O_cjs.networkFromArkadeInfo(info);
13173
+ const network = chunkVVFCCNU2_cjs.networkFromArkadeInfo(info);
12959
13174
  if ("descriptor" in config.identity) {
12960
13175
  const descriptor = config.identity.descriptor;
12961
13176
  const identityIsMainnet = !descriptor.includes("tpub");
@@ -12991,18 +13206,18 @@ var ReadonlyWallet = class _ReadonlyWallet {
12991
13206
  }
12992
13207
  }
12993
13208
  const boardingTimelock = config.boardingTimelock ?? toTimelock(info.boardingExitDelay);
12994
- const serverPubKey = chunkUV3IM6BG_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
12995
- const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) => chunkUV3IM6BG_cjs.toXOnly(base.hex.decode(info2.pubkey), "delegate key")).catch(() => void 0) : void 0;
13209
+ const serverPubKey = chunkCFOIHLON_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
13210
+ const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) => chunkCFOIHLON_cjs.toXOnly(base.hex.decode(info2.pubkey), "delegate key")).catch(() => void 0) : void 0;
12996
13211
  const offchainOptions = {
12997
13212
  pubKey,
12998
13213
  serverPubKey,
12999
13214
  csvTimelock: exitTimelock
13000
13215
  };
13001
- const offchainTapscript = !delegatePubKey ? new chunkUV3IM6BG_cjs.DefaultVtxo.Script(offchainOptions) : new chunkUV3IM6BG_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
13002
- const boardingTapscript = chunkUV3IM6BG_cjs.BoardingContractHandler.createScript({
13216
+ const offchainTapscript = !delegatePubKey ? new chunkCFOIHLON_cjs.DefaultVtxo.Script(offchainOptions) : new chunkCFOIHLON_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
13217
+ const boardingTapscript = chunkCFOIHLON_cjs.BoardingContractHandler.createScript({
13003
13218
  pubKey: base.hex.encode(pubKey),
13004
13219
  serverPubKey: base.hex.encode(serverPubKey),
13005
- csvTimelock: chunk65CTZR2O_cjs.timelockToSequence(boardingTimelock).toString()
13220
+ csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(boardingTimelock).toString()
13006
13221
  });
13007
13222
  return {
13008
13223
  arkProvider,
@@ -13135,6 +13350,16 @@ var ReadonlyWallet = class _ReadonlyWallet {
13135
13350
  this._pendingSpendOutpoints
13136
13351
  );
13137
13352
  }
13353
+ /**
13354
+ * @internal The stored VTXOs {@link reserveVtxos} holds, minus any being spent: for renewal,
13355
+ * which skips them, to report the ones it would have renewed. No sync.
13356
+ */
13357
+ async getHeldVtxos() {
13358
+ if (this._heldOutpoints.size === 0) return [];
13359
+ return (await this.getStoredVtxos()).filter(
13360
+ (vtxo) => this._heldOutpoints.has(`${vtxo.txid}:${vtxo.vout}`)
13361
+ );
13362
+ }
13138
13363
  /** @inheritdoc */
13139
13364
  async getSpendableVtxos(filter) {
13140
13365
  const snapshot = await this.contractSnapshot(filter, {
@@ -13143,12 +13368,13 @@ var ReadonlyWallet = class _ReadonlyWallet {
13143
13368
  const vtxos = filterSnapshotVtxos(snapshot, filter, this._pendingSpendOutpoints);
13144
13369
  const { gated, pendingRecovery } = this.spendabilityView(snapshot);
13145
13370
  const selectable = vtxos.filter(
13146
- (vtxo) => !isGatedVtxo(vtxo, gated) && !pendingRecovery.has(`${vtxo.txid}:${vtxo.vout}`)
13371
+ (vtxo) => !isGatedVtxo(vtxo, gated) && !pendingRecovery.has(`${vtxo.txid}:${vtxo.vout}`) && !this._heldOutpoints.has(`${vtxo.txid}:${vtxo.vout}`)
13147
13372
  );
13148
13373
  const unlocked = await spendableVtxosExcludingLocked(selectable, this.intentRepository);
13149
13374
  logExcludedVtxos("getSpendableVtxos", vtxos, [
13150
13375
  gateExclusion(gated),
13151
13376
  outpointExclusion(pendingRecovery, PENDING_RECOVERY_REASON),
13377
+ outpointExclusion(this._heldOutpoints, "is held by reserveVtxos"),
13152
13378
  outpointExclusion(
13153
13379
  omittedOutpoints(selectable, unlocked),
13154
13380
  "is locked by an in-flight settlement intent"
@@ -13157,7 +13383,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13157
13383
  if (!filter?.withUnrolled) {
13158
13384
  logExcludedVtxos(
13159
13385
  "getSpendableVtxos",
13160
- snapshot.flatMap((contract) => contract.vtxos).filter((vtxo) => vtxo.isUnrolled && !chunk65CTZR2O_cjs.isVtxoSpent(vtxo)),
13386
+ snapshot.flatMap((contract) => contract.vtxos).filter((vtxo) => vtxo.isUnrolled && !chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)),
13161
13387
  [() => UNROLLED_REASON]
13162
13388
  );
13163
13389
  }
@@ -13241,7 +13467,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13241
13467
  }
13242
13468
  async contractSnapshotStored() {
13243
13469
  const contractManager = await this.getContractManager();
13244
- return contractManager.getStoredContractsWithVtxos ? contractManager.getStoredContractsWithVtxos() : contractManager.getContractsWithVtxos();
13470
+ return contractManager.getStoredContractsWithVtxos();
13245
13471
  }
13246
13472
  /**
13247
13473
  * The two exclusion sets the gate is made of, derived from one snapshot so
@@ -13266,6 +13492,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13266
13492
  isPendingRecovery: (vtxo) => pendingRecovery.has(`${vtxo.txid}:${vtxo.vout}`),
13267
13493
  isGenericallySpendable: (vtxo) => !isGatedVtxo(vtxo, gated),
13268
13494
  isUnlocked: (vtxo) => unlocked.has(`${vtxo.txid}:${vtxo.vout}`),
13495
+ isReserved: (vtxo) => this._heldOutpoints.has(`${vtxo.txid}:${vtxo.vout}`),
13269
13496
  dustCarrier: getDustAmount(this)
13270
13497
  };
13271
13498
  }
@@ -13299,7 +13526,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13299
13526
  this.getBoardingTxs()
13300
13527
  ]);
13301
13528
  const allVtxos = snapshot.flatMap((_) => _.vtxos);
13302
- const resolveTxCreatedAt = (txids) => chunk65CTZR2O_cjs.fetchVtxoCreatedAtByTxid(this.indexerProvider, txids);
13529
+ const resolveTxCreatedAt = (txids) => chunkVVFCCNU2_cjs.fetchVtxoCreatedAtByTxid(this.indexerProvider, txids);
13303
13530
  return buildTransactionHistory(
13304
13531
  allVtxos,
13305
13532
  boardingTxs,
@@ -13453,9 +13680,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
13453
13680
  async getBoardingTapscripts(allowedSigners) {
13454
13681
  const byScript = /* @__PURE__ */ new Map();
13455
13682
  const add = (s) => byScript.set(base.hex.encode(s.pkScript), s);
13456
- const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunkUV3IM6BG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13683
+ const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13457
13684
  add(
13458
- new chunkUV3IM6BG_cjs.DefaultVtxo.Script({
13685
+ new chunkCFOIHLON_cjs.DefaultVtxo.Script({
13459
13686
  pubKey: await this.identity.xOnlyPublicKey(),
13460
13687
  serverPubKey: this.boardingTapscript.options.serverPubKey,
13461
13688
  csvTimelock: boardingCsv
@@ -13470,7 +13697,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13470
13697
  for (const c of boardingContracts) {
13471
13698
  if (!allowed.has(toXOnlySignerHex(c.params.serverPubKey))) continue;
13472
13699
  try {
13473
- add(chunkUV3IM6BG_cjs.BoardingContractHandler.createScript(c.params));
13700
+ add(chunkCFOIHLON_cjs.BoardingContractHandler.createScript(c.params));
13474
13701
  } catch (e) {
13475
13702
  console.warn("Skipping malformed boarding contract", c.script, e);
13476
13703
  }
@@ -13499,7 +13726,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13499
13726
  // Per-row CSV delay decoded from THIS tapscript's exit leaf —
13500
13727
  // not the wallet's current boarding timelock, which a signer
13501
13728
  // rotation may have changed.
13502
- csvTimelock: chunk65CTZR2O_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
13729
+ csvTimelock: chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
13503
13730
  coins: utxos
13504
13731
  };
13505
13732
  })
@@ -13531,6 +13758,16 @@ var ReadonlyWallet = class _ReadonlyWallet {
13531
13758
  this.boardingLoaded = true;
13532
13759
  return groups.flatMap((g) => g.coins);
13533
13760
  }
13761
+ /**
13762
+ * @internal {@link getBoardingUtxos} minus those an in-flight settle is spending, for SDK
13763
+ * picks. The getter itself lists them: callers that mirror it (the worker's cache and
13764
+ * broadcasts, balances) must not see a settle's inputs vanish, and then stay gone if it fails.
13765
+ */
13766
+ async getSelectableBoardingUtxos() {
13767
+ return (await this.getBoardingUtxos()).filter(
13768
+ (coin) => !this._pendingSpendOutpoints.has(`${coin.txid}:${coin.vout}`)
13769
+ );
13770
+ }
13534
13771
  async getStoredBoardingUtxos() {
13535
13772
  const currentOnly = /* @__PURE__ */ new Set([
13536
13773
  toXOnlySignerHex(base.hex.encode(this.boardingTapscript.options.serverPubKey))
@@ -13645,7 +13882,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13645
13882
  /** Fetch Arkade transaction ids that are still pending final settlement. */
13646
13883
  async fetchPendingTxs() {
13647
13884
  const scripts = await this.getWalletScripts();
13648
- const vtxos = await chunk65CTZR2O_cjs.getAllNormalizedVtxos(this.indexerProvider, scripts);
13885
+ const vtxos = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(this.indexerProvider, scripts);
13649
13886
  return vtxos.filter(
13650
13887
  (vtxo) => (vtxo.isSpent || vtxo.isPreconfirmed && !vtxo.isSwept) && vtxo.arkTxId !== void 0
13651
13888
  ).map((_) => _.arkTxId);
@@ -13676,7 +13913,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13676
13913
  });
13677
13914
  for (const contract of contracts) {
13678
13915
  if (map.has(contract.script)) continue;
13679
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(contract.type);
13916
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
13680
13917
  if (handler) {
13681
13918
  const script = handler.createScript(contract.params);
13682
13919
  map.set(contract.script, script);
@@ -13788,7 +14025,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13788
14025
  }
13789
14026
  });
13790
14027
  const baselinePubkey = await this.identity.xOnlyPublicKey();
13791
- const delegatePubKey = this.offchainTapscript instanceof chunkUV3IM6BG_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
14028
+ const delegatePubKey = this.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
13792
14029
  const baselineSigners = [
13793
14030
  this.offchainTapscript.options.serverPubKey,
13794
14031
  ...[...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h))
@@ -13796,8 +14033,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
13796
14033
  const seenBaselineScripts = /* @__PURE__ */ new Set();
13797
14034
  for (const serverPubKey of baselineSigners) {
13798
14035
  for (const csvTimelock2 of this.walletContractTimelocks) {
13799
- const csvTimelockStr = chunk65CTZR2O_cjs.timelockToSequence(csvTimelock2).toString();
13800
- const defaultScript = new chunkUV3IM6BG_cjs.DefaultVtxo.Script({
14036
+ const csvTimelockStr = chunkVVFCCNU2_cjs.timelockToSequence(csvTimelock2).toString();
14037
+ const defaultScript = new chunkCFOIHLON_cjs.DefaultVtxo.Script({
13801
14038
  pubKey: baselinePubkey,
13802
14039
  serverPubKey,
13803
14040
  csvTimelock: csvTimelock2
@@ -13818,7 +14055,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13818
14055
  });
13819
14056
  }
13820
14057
  if (delegatePubKey) {
13821
- const delegateScript = new chunkUV3IM6BG_cjs.DelegateVtxo.Script({
14058
+ const delegateScript = new chunkCFOIHLON_cjs.DelegateVtxo.Script({
13822
14059
  pubKey: baselinePubkey,
13823
14060
  serverPubKey,
13824
14061
  delegatePubKey,
@@ -13842,9 +14079,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
13842
14079
  }
13843
14080
  }
13844
14081
  }
13845
- const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunkUV3IM6BG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
14082
+ const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13846
14083
  for (const serverPubKey of baselineSigners) {
13847
- const baselineBoarding = new chunkUV3IM6BG_cjs.DefaultVtxo.Script({
14084
+ const baselineBoarding = new chunkCFOIHLON_cjs.DefaultVtxo.Script({
13848
14085
  pubKey: baselinePubkey,
13849
14086
  serverPubKey,
13850
14087
  csvTimelock: boardingCsvTimelock
@@ -13857,7 +14094,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13857
14094
  params: {
13858
14095
  pubKey: base.hex.encode(baselineBoarding.options.pubKey),
13859
14096
  serverPubKey: base.hex.encode(serverPubKey),
13860
- csvTimelock: chunk65CTZR2O_cjs.timelockToSequence(boardingCsvTimelock).toString()
14097
+ csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(boardingCsvTimelock).toString()
13861
14098
  },
13862
14099
  script: boardingScriptHex,
13863
14100
  address: baselineBoarding.address(this.network.hrp, serverPubKey).encode(),
@@ -14044,7 +14281,7 @@ var Wallet2 = class extends ReadonlyWallet {
14044
14281
  serverPubKey: this.offchainTapscript.options.serverPubKey,
14045
14282
  deprecatedSignerPubKeys: [...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h)),
14046
14283
  csvTimelocks: this.walletContractTimelocks,
14047
- delegatePubKey: this.offchainTapscript instanceof chunkUV3IM6BG_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0
14284
+ delegatePubKey: this.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0
14048
14285
  };
14049
14286
  }
14050
14287
  _signerRouter;
@@ -14204,7 +14441,7 @@ var Wallet2 = class extends ReadonlyWallet {
14204
14441
  const [row] = await manager.getContracts({ script: base.hex.encode(display.pkScript) });
14205
14442
  const persisted = row?.metadata?.signingDescriptor;
14206
14443
  if (typeof persisted === "string") return persisted;
14207
- return chunkUV3IM6BG_cjs.identityDescriptor(this.identity);
14444
+ return chunkCFOIHLON_cjs.identityDescriptor(this.identity);
14208
14445
  }
14209
14446
  /**
14210
14447
  * Build, persist and shape one address of `type` owned by `descriptor`. The descriptor is the
@@ -14214,7 +14451,7 @@ var Wallet2 = class extends ReadonlyWallet {
14214
14451
  async mintAddress(manager, type, descriptor, tagSource, allocated) {
14215
14452
  if (type === "boarding") {
14216
14453
  const built2 = this.buildBoardingContract(
14217
- chunkUV3IM6BG_cjs.deriveDescriptorLeafPubKey(descriptor),
14454
+ chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(descriptor),
14218
14455
  descriptor,
14219
14456
  tagSource
14220
14457
  );
@@ -14251,11 +14488,11 @@ var Wallet2 = class extends ReadonlyWallet {
14251
14488
  * (offchain analogue: {@link buildReceiveContract}).
14252
14489
  */
14253
14490
  buildBoardingContract(pubKey, descriptor, tagSource) {
14254
- const tapscript = new chunkUV3IM6BG_cjs.DefaultVtxo.Script({
14491
+ const tapscript = new chunkCFOIHLON_cjs.DefaultVtxo.Script({
14255
14492
  ...this._boardingTapscript.options,
14256
14493
  pubKey
14257
14494
  });
14258
- const csvTimelock2 = tapscript.options.csvTimelock ?? chunkUV3IM6BG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
14495
+ const csvTimelock2 = tapscript.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
14259
14496
  return {
14260
14497
  tapscript,
14261
14498
  params: {
@@ -14263,13 +14500,13 @@ var Wallet2 = class extends ReadonlyWallet {
14263
14500
  params: {
14264
14501
  pubKey: base.hex.encode(pubKey),
14265
14502
  serverPubKey: base.hex.encode(tapscript.options.serverPubKey),
14266
- csvTimelock: chunk65CTZR2O_cjs.timelockToSequence(csvTimelock2).toString()
14503
+ csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(csvTimelock2).toString()
14267
14504
  },
14268
14505
  script: base.hex.encode(tapscript.pkScript),
14269
14506
  address: tapscript.address(this.network.hrp, this.arkServerPublicKey).encode(),
14270
14507
  state: "active",
14271
14508
  metadata: {
14272
- ...tagSource && { source: chunkUV3IM6BG_cjs.WALLET_RECEIVE_SOURCE },
14509
+ ...tagSource && { source: chunkCFOIHLON_cjs.WALLET_RECEIVE_SOURCE },
14273
14510
  signingDescriptor: descriptor
14274
14511
  }
14275
14512
  }
@@ -14291,7 +14528,7 @@ var Wallet2 = class extends ReadonlyWallet {
14291
14528
  if (this._hdProvider) {
14292
14529
  return (await this.getContractManager()).getNextSigningDescriptor();
14293
14530
  }
14294
- return chunkUV3IM6BG_cjs.identityDescriptor(this.identity);
14531
+ return chunkCFOIHLON_cjs.identityDescriptor(this.identity);
14295
14532
  }
14296
14533
  /**
14297
14534
  * @see HDAllocationCapable.advanceSigningDescriptorWatermark
@@ -14367,7 +14604,7 @@ var Wallet2 = class extends ReadonlyWallet {
14367
14604
  * the stable public API.
14368
14605
  */
14369
14606
  async rotateServerSigner(newServerPubKey, checkpointTapscript) {
14370
- const xonly = chunkUV3IM6BG_cjs.toXOnly(newServerPubKey, "ark signer key");
14607
+ const xonly = chunkCFOIHLON_cjs.toXOnly(newServerPubKey, "ark signer key");
14371
14608
  const newServerUnrollScript = assertValidServerUnrollScript(
14372
14609
  checkpointTapscript,
14373
14610
  resolveCheckpointExitDelayPolicy(this.network, this.checkpointExitDelayPolicy)
@@ -14396,21 +14633,21 @@ var Wallet2 = class extends ReadonlyWallet {
14396
14633
  const [currentBoardingRow] = await manager.getContracts({
14397
14634
  script: currentBoardingScript
14398
14635
  });
14399
- const newOffchain = this.offchainTapscript instanceof chunkUV3IM6BG_cjs.DelegateVtxo.Script ? new chunkUV3IM6BG_cjs.DelegateVtxo.Script({
14636
+ const newOffchain = this.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? new chunkCFOIHLON_cjs.DelegateVtxo.Script({
14400
14637
  ...this.offchainTapscript.options,
14401
14638
  serverPubKey: xonly
14402
- }) : new chunkUV3IM6BG_cjs.DefaultVtxo.Script({
14639
+ }) : new chunkCFOIHLON_cjs.DefaultVtxo.Script({
14403
14640
  ...this.offchainTapscript.options,
14404
14641
  serverPubKey: xonly
14405
14642
  });
14406
- const newBoarding = new chunkUV3IM6BG_cjs.DefaultVtxo.Script({
14643
+ const newBoarding = new chunkCFOIHLON_cjs.DefaultVtxo.Script({
14407
14644
  ...this._boardingTapscript.options,
14408
14645
  serverPubKey: xonly
14409
14646
  });
14410
- const offchainCsv = chunk65CTZR2O_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
14647
+ const offchainCsv = chunkVVFCCNU2_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
14411
14648
  const newOffchainScript = base.hex.encode(newOffchain.pkScript);
14412
14649
  const newOffchainAddress = newOffchain.address(this.network.hrp, xonly).encode();
14413
- if (newOffchain instanceof chunkUV3IM6BG_cjs.DelegateVtxo.Script) {
14650
+ if (newOffchain instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script) {
14414
14651
  await manager.createContract({
14415
14652
  type: "delegate",
14416
14653
  params: {
@@ -14438,13 +14675,13 @@ var Wallet2 = class extends ReadonlyWallet {
14438
14675
  metadata: currentOffchainRow?.metadata
14439
14676
  });
14440
14677
  }
14441
- const boardingCsv = newBoarding.options.csvTimelock ?? chunkUV3IM6BG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
14678
+ const boardingCsv = newBoarding.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
14442
14679
  await manager.createContract({
14443
14680
  type: "boarding",
14444
14681
  params: {
14445
14682
  pubKey: base.hex.encode(newBoarding.options.pubKey),
14446
14683
  serverPubKey: base.hex.encode(xonly),
14447
- csvTimelock: chunk65CTZR2O_cjs.timelockToSequence(boardingCsv).toString()
14684
+ csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(boardingCsv).toString()
14448
14685
  },
14449
14686
  script: base.hex.encode(newBoarding.pkScript),
14450
14687
  address: newBoarding.address(this.network.hrp, xonly).encode(),
@@ -14463,7 +14700,7 @@ var Wallet2 = class extends ReadonlyWallet {
14463
14700
  }
14464
14701
  /**
14465
14702
  * Serializes `settle`/`send` so VtxoManager's background renewal can't race user
14466
- * transactions for the same inputs.
14703
+ * transactions for the same inputs; with `concurrentSpending`, only until inputs are reserved.
14467
14704
  */
14468
14705
  _txLock = Promise.resolve();
14469
14706
  // Every input (boarding included) of an intent a live settle owns; reconciliation skips them.
@@ -14472,18 +14709,59 @@ var Wallet2 = class extends ReadonlyWallet {
14472
14709
  _restoreInFlight;
14473
14710
  _addPendingSpends(inputs) {
14474
14711
  for (const input of inputs) {
14475
- if (chunk65CTZR2O_cjs.isVirtualCoin(input)) {
14712
+ if (chunkVVFCCNU2_cjs.isVirtualCoin(input)) {
14476
14713
  this._pendingSpendOutpoints.add(`${input.txid}:${input.vout}`);
14477
14714
  }
14478
14715
  }
14479
14716
  }
14480
14717
  _removePendingSpends(inputs) {
14481
14718
  for (const input of inputs) {
14482
- if (chunk65CTZR2O_cjs.isVirtualCoin(input)) {
14719
+ if (chunkVVFCCNU2_cjs.isVirtualCoin(input)) {
14483
14720
  this._pendingSpendOutpoints.delete(`${input.txid}:${input.vout}`);
14484
14721
  }
14485
14722
  }
14486
14723
  }
14724
+ /**
14725
+ * Hold VTXOs so no SDK-chosen spend picks them; the holder still spends them by naming them.
14726
+ * All-or-nothing: throws {@link VtxoReservedError} if any is held or already being spent.
14727
+ * In-memory, for this `Wallet` instance only.
14728
+ */
14729
+ reserveVtxos(outpoints) {
14730
+ const keys = outpoints.map((o) => `${o.txid}:${o.vout}`);
14731
+ const inFlight = keys.filter((k) => this._pendingSpendOutpoints.has(k));
14732
+ if (inFlight.length > 0) throw new VtxoReservedError(inFlight, "in-flight");
14733
+ const held = keys.filter((k) => this._heldOutpoints.has(k));
14734
+ if (held.length > 0) throw new VtxoReservedError(held, "held");
14735
+ for (const k of keys) this._heldOutpoints.add(k);
14736
+ let released = false;
14737
+ return {
14738
+ outpoints: [...outpoints],
14739
+ release: () => {
14740
+ if (released) return;
14741
+ released = true;
14742
+ for (const k of keys) this._heldOutpoints.delete(k);
14743
+ }
14744
+ };
14745
+ }
14746
+ /**
14747
+ * @internal For `AssetManager`: reserves what `fn` submits, hiding it from other picks until
14748
+ * the submit ends. With `concurrentSpending`, `fn` runs under the wallet lock, released once
14749
+ * the inputs are reserved; otherwise `fn` runs unlocked and only the submit takes the lock.
14750
+ */
14751
+ withSpendLock(fn) {
14752
+ const run = (release) => fn(async (inputs, outputs) => {
14753
+ this._assertNotHeld(inputs);
14754
+ if (release) this._assertNotInFlight(inputs);
14755
+ this._addPendingSpends(inputs);
14756
+ release?.();
14757
+ try {
14758
+ return await (release ? this._buildAndSubmitOffchainTx(inputs, outputs, this.serverUnrollScript) : this.buildAndSubmitOffchainTx(inputs, outputs));
14759
+ } finally {
14760
+ this._removePendingSpends(inputs);
14761
+ }
14762
+ });
14763
+ return this._concurrentSpending ? this._withTxLock(run) : run();
14764
+ }
14487
14765
  _withTxLock(fn) {
14488
14766
  let release;
14489
14767
  const lock = new Promise((r) => release = r);
@@ -14491,12 +14769,22 @@ var Wallet2 = class extends ReadonlyWallet {
14491
14769
  this._txLock = lock;
14492
14770
  return prev.then(async () => {
14493
14771
  try {
14494
- return await fn();
14772
+ return await fn(release);
14495
14773
  } finally {
14496
14774
  release();
14497
14775
  }
14498
14776
  });
14499
14777
  }
14778
+ _assertNotInFlight(inputs) {
14779
+ const clashing = coinKeys(inputs).filter((key) => this._pendingSpendOutpoints.has(key));
14780
+ if (clashing.length > 0) throw new VtxoReservedError(clashing, "in-flight");
14781
+ }
14782
+ _assertNotHeld(inputs) {
14783
+ const held = coinKeys(inputs.filter(chunkVVFCCNU2_cjs.isVirtualCoin)).filter(
14784
+ (key) => this._heldOutpoints.has(key)
14785
+ );
14786
+ if (held.length > 0) throw new VtxoReservedError(held, "held");
14787
+ }
14500
14788
  /**
14501
14789
  * Explicitly recover this wallet's contracts and balance on a fresh repo: a gap-limit scan
14502
14790
  * for HD wallets, the single default pubkey otherwise. Throws on operational failure (a
@@ -14530,13 +14818,13 @@ var Wallet2 = class extends ReadonlyWallet {
14530
14818
  const manager = await this.getContractManager();
14531
14819
  const provider = this._hdProvider;
14532
14820
  const hd = provider !== void 0;
14533
- const staticDescriptor = hd ? void 0 : await chunkUV3IM6BG_cjs.identityDescriptor(this.identity);
14821
+ const staticDescriptor = hd ? void 0 : await chunkCFOIHLON_cjs.identityDescriptor(this.identity);
14534
14822
  const materialize = (index) => hd ? provider.materializeDescriptorAt(index) : staticDescriptor;
14535
- const delegatePubKey = this.offchainTapscript instanceof chunkUV3IM6BG_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
14823
+ const delegatePubKey = this.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
14536
14824
  const arkInfo = await this.arkProvider.getInfo();
14537
- const currentSignerPubKey = chunkUV3IM6BG_cjs.toXOnly(base.hex.decode(arkInfo.signerPubkey), "ark signer key");
14825
+ const currentSignerPubKey = chunkCFOIHLON_cjs.toXOnly(base.hex.decode(arkInfo.signerPubkey), "ark signer key");
14538
14826
  const deprecatedSignerPubKeys = arkInfo.deprecatedSigners.map(
14539
- (s) => chunkUV3IM6BG_cjs.toXOnly(base.hex.decode(s.pubkey), "deprecated signer key")
14827
+ (s) => chunkCFOIHLON_cjs.toXOnly(base.hex.decode(s.pubkey), "deprecated signer key")
14540
14828
  );
14541
14829
  const deps = {
14542
14830
  indexerProvider: this.indexerProvider,
@@ -14548,7 +14836,7 @@ var Wallet2 = class extends ReadonlyWallet {
14548
14836
  deprecatedSignerPubKeys,
14549
14837
  csvTimelocks: this.walletContractTimelocks,
14550
14838
  // Boarding-exit CSV, distinct from the unilateral-exit matrix.
14551
- boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunkUV3IM6BG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
14839
+ boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
14552
14840
  delegatePubKey
14553
14841
  };
14554
14842
  const result = await manager.scanContracts({
@@ -14579,6 +14867,12 @@ var Wallet2 = class extends ReadonlyWallet {
14579
14867
  }
14580
14868
  }
14581
14869
  settlementConfig;
14870
+ _concurrentSpending = false;
14871
+ _submitsAwaitingFinalize = 0;
14872
+ /** @see WalletConfig.concurrentSpending */
14873
+ get concurrentSpending() {
14874
+ return this._concurrentSpending;
14875
+ }
14582
14876
  /**
14583
14877
  * Broadcast access bound to this wallet's server, so a plugin needs only the wallet. Not on
14584
14878
  * {@link ReadonlyWallet}: a readonly wallet or `toReadonly()` view must not be able to submit.
@@ -14658,7 +14952,7 @@ var Wallet2 = class extends ReadonlyWallet {
14658
14952
  throw new Error("Invalid configured public key");
14659
14953
  }
14660
14954
  const setup = await ReadonlyWallet.setupWalletConfig(config, pubkey);
14661
- const forfeitPubkey = chunkUV3IM6BG_cjs.toXOnly(base.hex.decode(setup.info.forfeitPubkey), "forfeit key");
14955
+ const forfeitPubkey = chunkCFOIHLON_cjs.toXOnly(base.hex.decode(setup.info.forfeitPubkey), "forfeit key");
14662
14956
  const forfeitAddress = btcSigner.Address(setup.network).decode(setup.info.forfeitAddress);
14663
14957
  const forfeitOutputScript = btcSigner.OutScript.encode(forfeitAddress);
14664
14958
  const checkpointExitDelayOverrides = {
@@ -14744,6 +15038,7 @@ var Wallet2 = class extends ReadonlyWallet {
14744
15038
  wallet.intentRepository = config.storage?.intentRepository;
14745
15039
  wallet.virtualTxRepository = config.storage?.virtualTxRepository;
14746
15040
  wallet.exitDataCapture = config.storage?.exitDataCapture;
15041
+ wallet._concurrentSpending = config.concurrentSpending === true;
14747
15042
  await wallet.getVtxoManager();
14748
15043
  return wallet;
14749
15044
  }
@@ -14803,13 +15098,19 @@ var Wallet2 = class extends ReadonlyWallet {
14803
15098
  * @returns The finalized Arkade transaction id
14804
15099
  */
14805
15100
  async settle(params, eventCallback, hooks) {
14806
- return this._withTxLock(() => {
15101
+ return this._withTxLock((release) => {
14807
15102
  hooks?.onPhase?.("preparing");
14808
15103
  const onRegistrationAttempt = hooks?.onPhase ? () => hooks.onPhase?.("registration_attempt") : void 0;
14809
- return this._settleImpl(params, eventCallback, onRegistrationAttempt);
15104
+ return this._settleImpl(
15105
+ params,
15106
+ eventCallback,
15107
+ this._concurrentSpending ? release : void 0,
15108
+ onRegistrationAttempt
15109
+ );
14810
15110
  });
14811
15111
  }
14812
- async _settleImpl(params, eventCallback, onRegistrationAttempt) {
15112
+ async _settleImpl(params, eventCallback, onReserved, onRegistrationAttempt) {
15113
+ const picked = params === void 0 || isSdkPicked(params);
14813
15114
  if (params?.inputs) {
14814
15115
  for (const input of params.inputs) {
14815
15116
  if (typeof input === "string") {
@@ -14823,13 +15124,13 @@ var Wallet2 = class extends ReadonlyWallet {
14823
15124
  void this.logUngatedInputs("settle({ inputs })", params.inputs);
14824
15125
  }
14825
15126
  const offchainAddress = await this.getAddress();
14826
- const offchainPkScript = chunk65CTZR2O_cjs.ArkAddress.decode(offchainAddress).pkScript;
15127
+ const offchainPkScript = chunkVVFCCNU2_cjs.ArkAddress.decode(offchainAddress).pkScript;
14827
15128
  const offchainOutputScript = base.hex.encode(offchainPkScript);
14828
15129
  if (!params) {
14829
15130
  const { fees, vtxoMaxAmount } = await this.arkProvider.getInfo();
14830
15131
  const estimator = new Estimator(fees.intentFee);
14831
15132
  let amount = 0;
14832
- const exitScript = chunk65CTZR2O_cjs.CSVMultisigTapscript.decode(
15133
+ const exitScript = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(
14833
15134
  base.hex.decode(this.boardingTapscript.exitScript)
14834
15135
  );
14835
15136
  const boardingTimelock = exitScript.params.timelock;
@@ -14838,7 +15139,7 @@ var Wallet2 = class extends ReadonlyWallet {
14838
15139
  const tip = await this.onchainProvider.getChainTip();
14839
15140
  chainTipHeight = tip.height;
14840
15141
  }
14841
- const boardingUtxos = (await this.getBoardingUtxos()).filter(
15142
+ const boardingUtxos = (await this.getSelectableBoardingUtxos()).filter(
14842
15143
  (utxo) => utxo.status.confirmed && !hasBoardingTxExpired(utxo, boardingTimelock, chainTipHeight)
14843
15144
  );
14844
15145
  const filteredBoardingUtxos = [];
@@ -14861,7 +15162,7 @@ var Wallet2 = class extends ReadonlyWallet {
14861
15162
  if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
14862
15163
  break;
14863
15164
  }
14864
- const inputFee = estimator.evalOffchainInput(chunk65CTZR2O_cjs.toOffchainInputFeeParams(vtxo));
15165
+ const inputFee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo));
14865
15166
  if (inputFee.satoshis >= vtxo.value) {
14866
15167
  continue;
14867
15168
  }
@@ -14904,6 +15205,7 @@ var Wallet2 = class extends ReadonlyWallet {
14904
15205
  ...params,
14905
15206
  inputs: await refreshSweptStateOfExpiredInputs(this, params.inputs)
14906
15207
  };
15208
+ if (onReserved) this._assertNotInFlight(params.inputs);
14907
15209
  const onchainOutputIndexes = [];
14908
15210
  const outputs = [];
14909
15211
  let hasOffchainOutputs = false;
@@ -14912,7 +15214,7 @@ var Wallet2 = class extends ReadonlyWallet {
14912
15214
  let script;
14913
15215
  let arkAddress;
14914
15216
  try {
14915
- arkAddress = chunk65CTZR2O_cjs.ArkAddress.decode(output.address);
15217
+ arkAddress = chunkVVFCCNU2_cjs.ArkAddress.decode(output.address);
14916
15218
  } catch {
14917
15219
  arkAddress = void 0;
14918
15220
  }
@@ -14984,20 +15286,24 @@ var Wallet2 = class extends ReadonlyWallet {
14984
15286
  ]);
14985
15287
  let intentTxId;
14986
15288
  try {
14987
- intentTxId = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(intent.proof)).id;
15289
+ intentTxId = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(intent.proof)).id;
14988
15290
  } catch {
14989
15291
  intentTxId = params.inputs.map((i) => `${i.txid}:${i.vout}`).sort().join("|");
14990
15292
  }
14991
- const settleInputVtxos = params.inputs.filter(chunk65CTZR2O_cjs.isVirtualCoin);
15293
+ const settleInputVtxos = params.inputs.filter(chunkVVFCCNU2_cjs.isVirtualCoin);
14992
15294
  const contractManager = await this.getContractManager();
14993
15295
  await contractManager.assertAnnotatable(settleInputVtxos);
14994
15296
  await contractManager.assertSpendableNow?.(
14995
15297
  settleInputVtxos,
14996
15298
  async () => base.hex.encode(await this.identity.xOnlyPublicKey())
14997
15299
  );
15300
+ if (picked) this._assertNotHeld(params.inputs);
14998
15301
  this._addPendingSpends(params.inputs);
15302
+ const boardingKeys = onReserved ? coinKeys(params.inputs.filter((i) => !chunkVVFCCNU2_cjs.isVirtualCoin(i))) : [];
15303
+ for (const key of boardingKeys) this._pendingSpendOutpoints.add(key);
14999
15304
  const settlingKeys = params.inputs.map((i) => `${i.txid}:${i.vout}`);
15000
15305
  for (const key of settlingKeys) this._settlingOutpoints.add(key);
15306
+ onReserved?.();
15001
15307
  await this.persistIntentSnapshot(
15002
15308
  intentTxId,
15003
15309
  "waiting_to_submit",
@@ -15011,6 +15317,7 @@ var Wallet2 = class extends ReadonlyWallet {
15011
15317
  ];
15012
15318
  const abortController = new AbortController();
15013
15319
  let stream;
15320
+ let registering = false;
15014
15321
  let committedTxid;
15015
15322
  try {
15016
15323
  stream = this.arkProvider.getEventStream(abortController.signal, topics);
@@ -15024,6 +15331,7 @@ var Wallet2 = class extends ReadonlyWallet {
15024
15331
  }
15025
15332
  yield* stream;
15026
15333
  })();
15334
+ registering = true;
15027
15335
  onRegistrationAttempt?.();
15028
15336
  const intentId = await this.safeRegisterIntent(intent, params.inputs);
15029
15337
  await this.persistIntentSnapshot(
@@ -15064,12 +15372,15 @@ var Wallet2 = class extends ReadonlyWallet {
15064
15372
  throw error;
15065
15373
  }
15066
15374
  const inputIds = params.inputs.map((i) => `${i.txid}:${i.vout}`).join(",");
15067
- await this.arkProvider.deleteIntent(deleteIntent).catch((e) => {
15068
- console.warn(
15069
- `Failed to delete intent after settle failure for inputs [${inputIds}]; intent may linger on server and cause 'duplicated input' on next settle`,
15070
- e
15071
- );
15072
- });
15375
+ if (registering) {
15376
+ await this.arkProvider.deleteIntent(deleteIntent).catch((e) => {
15377
+ if (isNoMatchingIntentsError(e)) return;
15378
+ console.warn(
15379
+ `Failed to delete intent after settle failure for inputs [${inputIds}]; intent may linger on server and cause 'duplicated input' on next settle`,
15380
+ e
15381
+ );
15382
+ });
15383
+ }
15073
15384
  await this.persistIntentSnapshot(
15074
15385
  intentTxId,
15075
15386
  "cancelled",
@@ -15083,6 +15394,7 @@ var Wallet2 = class extends ReadonlyWallet {
15083
15394
  throw error;
15084
15395
  } finally {
15085
15396
  this._removePendingSpends(params.inputs);
15397
+ for (const key of boardingKeys) this._pendingSpendOutpoints.delete(key);
15086
15398
  for (const key of settlingKeys) this._settlingOutpoints.delete(key);
15087
15399
  abortController.abort();
15088
15400
  await stream?.return?.().catch(() => {
@@ -15098,7 +15410,7 @@ var Wallet2 = class extends ReadonlyWallet {
15098
15410
  async maybeRotateBoardingAfterBoard(inputs) {
15099
15411
  if (!this._descriptorProvider) return;
15100
15412
  const consumedBoarding = inputs.some(
15101
- (input) => typeof input !== "string" && !chunk65CTZR2O_cjs.isVirtualCoin(input)
15413
+ (input) => typeof input !== "string" && !chunkVVFCCNU2_cjs.isVirtualCoin(input)
15102
15414
  );
15103
15415
  if (!consumedBoarding) return;
15104
15416
  try {
@@ -15109,7 +15421,7 @@ var Wallet2 = class extends ReadonlyWallet {
15109
15421
  }
15110
15422
  async handleSettlementFinalizationEvent(event, inputs, forfeitOutputScript, expectedRecipients, connectorsGraph, validatedCommitmentTxid) {
15111
15423
  const signedForfeits = [];
15112
- let settlementPsbt = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
15424
+ let settlementPsbt = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
15113
15425
  assertFinalCommitmentMatchesValidated(
15114
15426
  settlementPsbt,
15115
15427
  validatedCommitmentTxid,
@@ -15122,7 +15434,7 @@ var Wallet2 = class extends ReadonlyWallet {
15122
15434
  let connectorIndex = 0;
15123
15435
  const connectorsLeaves = connectorsGraph?.leaves() || [];
15124
15436
  for (const input of inputs) {
15125
- if (!chunk65CTZR2O_cjs.isVirtualCoin(input)) {
15437
+ if (!chunkVVFCCNU2_cjs.isVirtualCoin(input)) {
15126
15438
  let matched = false;
15127
15439
  for (let i = 0; i < settlementPsbt.inputsLength; i++) {
15128
15440
  const settlementInput = settlementPsbt.getInput(i);
@@ -15160,7 +15472,7 @@ var Wallet2 = class extends ReadonlyWallet {
15160
15472
  }
15161
15473
  continue;
15162
15474
  }
15163
- if (!chunk65CTZR2O_cjs.requiresForfeit(input) || isSubdust({ value: input.value }, this.dustAmount)) {
15475
+ if (!chunkVVFCCNU2_cjs.requiresForfeit(input) || isSubdust({ value: input.value }, this.dustAmount)) {
15164
15476
  continue;
15165
15477
  }
15166
15478
  if (connectorsLeaves.length === 0) {
@@ -15188,7 +15500,7 @@ var Wallet2 = class extends ReadonlyWallet {
15188
15500
  index: input.vout,
15189
15501
  witnessUtxo: {
15190
15502
  amount: BigInt(input.value),
15191
- script: chunk65CTZR2O_cjs.VtxoScript.decode(input.tapTree).pkScript
15503
+ script: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
15192
15504
  },
15193
15505
  sighashType: btcSigner.SigHash.DEFAULT,
15194
15506
  tapLeafScript: [input.forfeitTapLeafScript]
@@ -15207,7 +15519,7 @@ var Wallet2 = class extends ReadonlyWallet {
15207
15519
  forfeitTx = await this._signerRouter.sign(forfeitTx, [
15208
15520
  {
15209
15521
  index: 0,
15210
- lookupScript: chunk65CTZR2O_cjs.VtxoScript.decode(input.tapTree).pkScript
15522
+ lookupScript: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
15211
15523
  }
15212
15524
  ]);
15213
15525
  signedForfeits.push(base.base64.encode(forfeitTx.toPSBT()));
@@ -15265,7 +15577,7 @@ var Wallet2 = class extends ReadonlyWallet {
15265
15577
  resolveBatchExpiryPolicy(this.network, this.batchExpiryPolicy)
15266
15578
  );
15267
15579
  await this.arkProvider.confirmRegistration(intentId);
15268
- const sweepTapscript = chunk65CTZR2O_cjs.CSVMultisigTapscript.encode({
15580
+ const sweepTapscript = chunkVVFCCNU2_cjs.CSVMultisigTapscript.encode({
15269
15581
  timelock,
15270
15582
  pubkeys: [this.forfeitPubkey]
15271
15583
  }).script;
@@ -15280,14 +15592,14 @@ var Wallet2 = class extends ReadonlyWallet {
15280
15592
  throw new Error("Sweep tap tree root not set");
15281
15593
  }
15282
15594
  const xOnlyPublicKeys = event.cosignersPublicKeys.map(
15283
- (k) => base.hex.encode(chunkUV3IM6BG_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
15595
+ (k) => base.hex.encode(chunkCFOIHLON_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
15284
15596
  );
15285
15597
  const signerPublicKey = await session.getPublicKey();
15286
- const xonlySignerPublicKey = chunkUV3IM6BG_cjs.toXOnly(signerPublicKey, "signer key");
15598
+ const xonlySignerPublicKey = chunkCFOIHLON_cjs.toXOnly(signerPublicKey, "signer key");
15287
15599
  if (!xOnlyPublicKeys.includes(base.hex.encode(xonlySignerPublicKey))) {
15288
15600
  return { skip: true };
15289
15601
  }
15290
- const commitmentTx = chunk65CTZR2O_cjs.Transaction.fromPSBT(
15602
+ const commitmentTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(
15291
15603
  base.base64.decode(event.unsignedCommitmentTx)
15292
15604
  );
15293
15605
  validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
@@ -15369,9 +15681,9 @@ var Wallet2 = class extends ReadonlyWallet {
15369
15681
  ...existing ?? {},
15370
15682
  intentTxId,
15371
15683
  registerProof: intent.proof,
15372
- registerProofMessage: chunk65CTZR2O_cjs.Intent.encodeMessage(intent.message),
15684
+ registerProofMessage: chunkVVFCCNU2_cjs.Intent.encodeMessage(intent.message),
15373
15685
  deleteProof: deleteIntent.proof,
15374
- deleteProofMessage: chunk65CTZR2O_cjs.Intent.encodeMessage(deleteIntent.message),
15686
+ deleteProofMessage: chunkVVFCCNU2_cjs.Intent.encodeMessage(deleteIntent.message),
15375
15687
  intentVtxos: inputs.map((i) => ({
15376
15688
  txid: i.txid,
15377
15689
  vout: i.vout
@@ -15404,7 +15716,7 @@ var Wallet2 = class extends ReadonlyWallet {
15404
15716
  try {
15405
15717
  return await this.arkProvider.registerIntent(intent);
15406
15718
  } catch (error) {
15407
- if (error instanceof chunk65CTZR2O_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
15719
+ if (error instanceof chunkVVFCCNU2_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
15408
15720
  const deleteIntent = await this.makeDeleteIntentSignature(inputs);
15409
15721
  await this.arkProvider.deleteIntent(deleteIntent);
15410
15722
  return this.arkProvider.registerIntent(intent);
@@ -15420,7 +15732,7 @@ var Wallet2 = class extends ReadonlyWallet {
15420
15732
  expire_at: 0,
15421
15733
  cosigners_public_keys: cosignerPubKeys
15422
15734
  };
15423
- const proof = chunk65CTZR2O_cjs.Intent.create(message, coins, outputs);
15735
+ const proof = chunkVVFCCNU2_cjs.Intent.create(message, coins, outputs);
15424
15736
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
15425
15737
  return {
15426
15738
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -15432,7 +15744,7 @@ var Wallet2 = class extends ReadonlyWallet {
15432
15744
  type: "delete",
15433
15745
  expire_at: 0
15434
15746
  };
15435
- const proof = chunk65CTZR2O_cjs.Intent.create(message, coins, []);
15747
+ const proof = chunkVVFCCNU2_cjs.Intent.create(message, coins, []);
15436
15748
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
15437
15749
  return {
15438
15750
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -15444,7 +15756,7 @@ var Wallet2 = class extends ReadonlyWallet {
15444
15756
  type: "get-pending-tx",
15445
15757
  expire_at: 0
15446
15758
  };
15447
- const proof = chunk65CTZR2O_cjs.Intent.create(message, coins, []);
15759
+ const proof = chunkVVFCCNU2_cjs.Intent.create(message, coins, []);
15448
15760
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
15449
15761
  return {
15450
15762
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -15465,7 +15777,7 @@ var Wallet2 = class extends ReadonlyWallet {
15465
15777
  if (!vtxos || vtxos.length === 0) {
15466
15778
  const scriptMap = await this.getScriptMap();
15467
15779
  const allExtended = [];
15468
- const fetchedVtxos = await chunk65CTZR2O_cjs.getAllNormalizedVtxos(this.indexerProvider, [
15780
+ const fetchedVtxos = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(this.indexerProvider, [
15469
15781
  ...scriptMap.keys()
15470
15782
  ]);
15471
15783
  for (const vtxo of fetchedVtxos) {
@@ -15508,8 +15820,8 @@ var Wallet2 = class extends ReadonlyWallet {
15508
15820
  batchPending.push(pendingTx.arkTxid);
15509
15821
  try {
15510
15822
  const checkpointTxs = pendingTx.signedCheckpointTxs.map((c) => {
15511
- const tx = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(c));
15512
- chunk65CTZR2O_cjs.assertAllowedSighashTypes(tx);
15823
+ const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(c));
15824
+ chunkVVFCCNU2_cjs.assertAllowedSighashTypes(tx);
15513
15825
  return tx;
15514
15826
  });
15515
15827
  assertCheckpointsMatchInputs(
@@ -15578,11 +15890,11 @@ var Wallet2 = class extends ReadonlyWallet {
15578
15890
  * and one per deprecated signer — else a pre-rotation tx would stay pending forever.
15579
15891
  */
15580
15892
  checkpointUnrollCandidates(info) {
15581
- const current = chunk65CTZR2O_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
15893
+ const current = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
15582
15894
  const candidates = [this._serverUnrollScript, current];
15583
15895
  for (const deprecated of signerSetFromInfo(info).deprecated.keys()) {
15584
15896
  candidates.push(
15585
- chunk65CTZR2O_cjs.CSVMultisigTapscript.encode({
15897
+ chunkVVFCCNU2_cjs.CSVMultisigTapscript.encode({
15586
15898
  ...current.params,
15587
15899
  pubkeys: [base.hex.decode(deprecated)]
15588
15900
  })
@@ -15664,6 +15976,12 @@ var Wallet2 = class extends ReadonlyWallet {
15664
15976
  */
15665
15977
  async claimCash(cashStr) {
15666
15978
  const cash = ArkadeCash.fromString(cashStr);
15979
+ const info = await this.arkProvider.getInfo();
15980
+ const signerSet = signerSetFromInfo(info);
15981
+ const signer = classifyAgainstSignerSet(base.hex.encode(cash.serverPubKey), signerSet);
15982
+ if (signer.status === "UNKNOWN_SIGNER") {
15983
+ throw new ArkadeCashOperatorMismatchError(signer.signerPubKey, signerSet.active);
15984
+ }
15667
15985
  const cashScript = cash.vtxoScript;
15668
15986
  const cashPkScript = base.hex.encode(cashScript.pkScript);
15669
15987
  const scripts = [cashPkScript];
@@ -15671,7 +15989,7 @@ var Wallet2 = class extends ReadonlyWallet {
15671
15989
  if (vtxos.length === 0) {
15672
15990
  throw new Error("No VTXOs found for this arkadeCash");
15673
15991
  }
15674
- const myPkScript = chunk65CTZR2O_cjs.ArkAddress.decode(await this.getAddress()).pkScript;
15992
+ const myPkScript = chunkVVFCCNU2_cjs.ArkAddress.decode(await this.getAddress()).pkScript;
15675
15993
  let { spendable, recoverable, unclaimed } = this.classifyCashVtxos(vtxos);
15676
15994
  let swept = 0;
15677
15995
  const drainable = vtxos.filter(
@@ -15699,7 +16017,6 @@ var Wallet2 = class extends ReadonlyWallet {
15699
16017
  }
15700
16018
  }
15701
16019
  if (spendable.length > 0) {
15702
- const info = await this.arkProvider.getInfo();
15703
16020
  const serverUnrollScript = assertValidServerUnrollScript(
15704
16021
  info.checkpointTapscript,
15705
16022
  resolveCheckpointExitDelayPolicy(this.network, this.checkpointExitDelayPolicy)
@@ -15798,7 +16115,7 @@ var Wallet2 = class extends ReadonlyWallet {
15798
16115
  params: {
15799
16116
  pubKey: base.hex.encode(cash.publicKey),
15800
16117
  serverPubKey: base.hex.encode(cash.serverPubKey),
15801
- csvTimelock: chunk65CTZR2O_cjs.timelockToSequence(cash.csvTimelock).toString()
16118
+ csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(cash.csvTimelock).toString()
15802
16119
  },
15803
16120
  script: base.hex.encode(cashScript.pkScript),
15804
16121
  address: cashAddress.encode(),
@@ -15879,7 +16196,7 @@ var Wallet2 = class extends ReadonlyWallet {
15879
16196
  const recoverable = [];
15880
16197
  const unclaimed = [];
15881
16198
  for (const vtxo of vtxos) {
15882
- if (chunk65CTZR2O_cjs.isVtxoSpent(vtxo)) {
16199
+ if (chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)) {
15883
16200
  unclaimed.push(cashReport(vtxo, "already-spent"));
15884
16201
  } else if (vtxo.isUnrolled) {
15885
16202
  unclaimed.push(cashReport(vtxo, "exited"));
@@ -15901,7 +16218,7 @@ var Wallet2 = class extends ReadonlyWallet {
15901
16218
  const all = [];
15902
16219
  const seen = /* @__PURE__ */ new Set();
15903
16220
  for (let pageIndex = 0; ; pageIndex++) {
15904
- const { vtxos, page } = await chunk65CTZR2O_cjs.getNormalizedVtxos(this.indexerProvider, {
16221
+ const { vtxos, page } = await chunkVVFCCNU2_cjs.getNormalizedVtxos(this.indexerProvider, {
15905
16222
  scripts,
15906
16223
  pageIndex,
15907
16224
  pageSize
@@ -15939,7 +16256,7 @@ var Wallet2 = class extends ReadonlyWallet {
15939
16256
  for (let i = 0; i < inputs.length; i += MAX_INPUTS_PER_INTENT) {
15940
16257
  const batch = inputs.slice(i, i + MAX_INPUTS_PER_INTENT);
15941
16258
  const message = { type: "get-pending-tx", expire_at: 0 };
15942
- const proof = chunk65CTZR2O_cjs.Intent.create(message, batch, []);
16259
+ const proof = chunkVVFCCNU2_cjs.Intent.create(message, batch, []);
15943
16260
  const signedProof = await identity.sign(
15944
16261
  proof,
15945
16262
  Array.from({ length: batch.length + 1 }, (_, j) => j)
@@ -15960,8 +16277,8 @@ var Wallet2 = class extends ReadonlyWallet {
15960
16277
  for (const pendingTx of pendingTxs) {
15961
16278
  try {
15962
16279
  const checkpointTxs = pendingTx.signedCheckpointTxs.map((checkpoint) => {
15963
- const tx = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(checkpoint));
15964
- chunk65CTZR2O_cjs.assertAllowedSighashTypes(tx);
16280
+ const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(checkpoint));
16281
+ chunkVVFCCNU2_cjs.assertAllowedSighashTypes(tx);
15965
16282
  return tx;
15966
16283
  });
15967
16284
  assertCheckpointsMatchInputs(
@@ -16001,7 +16318,7 @@ var Wallet2 = class extends ReadonlyWallet {
16001
16318
  }
16002
16319
  /** Sum the outputs of an ark tx PSBT that pay the given scriptPubKey. */
16003
16320
  arkTxAmountPaidTo(arkTxPsbt, pkScriptHex) {
16004
- const arkTx = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(arkTxPsbt));
16321
+ const arkTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(arkTxPsbt));
16005
16322
  let total = 0;
16006
16323
  for (let i = 0; i < arkTx.outputsLength; i++) {
16007
16324
  const output = arkTx.getOutput(i);
@@ -16039,9 +16356,16 @@ var Wallet2 = class extends ReadonlyWallet {
16039
16356
  const validUntil = captureSendDeadline(params.validUntil);
16040
16357
  const inputExpiryFloor = captureInputExpiryFloor(params.inputExpiryFloor);
16041
16358
  assertSendDeadline(validUntil);
16042
- return this._withTxLock(() => this._sendImpl(params, validUntil, inputExpiryFloor));
16359
+ return this._withTxLock(
16360
+ (release) => this._sendImpl(
16361
+ params,
16362
+ validUntil,
16363
+ inputExpiryFloor,
16364
+ this._concurrentSpending ? release : void 0
16365
+ )
16366
+ );
16043
16367
  }
16044
- async _sendImpl({ recipients: args, selectedVtxos, maxChangeFee }, validUntil, inputExpiryFloor) {
16368
+ async _sendImpl({ recipients: args, selectedVtxos, maxChangeFee }, validUntil, inputExpiryFloor, onReserved) {
16045
16369
  assertSendDeadline(validUntil);
16046
16370
  if (args.length === 0) {
16047
16371
  throw new Error("At least one receiver is required");
@@ -16053,7 +16377,7 @@ var Wallet2 = class extends ReadonlyWallet {
16053
16377
  throw new Error("send({ maxChangeFee }): expected a non-negative safe integer");
16054
16378
  }
16055
16379
  if (selectedVtxos) {
16056
- if (inputExpiryFloor) selectedVtxos = selectedVtxos.map(chunk65CTZR2O_cjs.normalizeVtxo);
16380
+ if (inputExpiryFloor) selectedVtxos = selectedVtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
16057
16381
  if (inputExpiryFloor && selectedVtxos.some((coin) => !meetsInputExpiryFloor(coin, inputExpiryFloor))) {
16058
16382
  throw new Error("send({ selectedVtxos }): input expiry floor not met");
16059
16383
  }
@@ -16188,7 +16512,7 @@ var Wallet2 = class extends ReadonlyWallet {
16188
16512
  script: recipient.script,
16189
16513
  amount: BigInt(recipient.amount),
16190
16514
  // Already checked against the recipient address in `validateRecipients`.
16191
- ...recipient.tapTree ? { tapTree: chunk65CTZR2O_cjs.toBIP371TapTree(recipient.tapTree) } : {}
16515
+ ...recipient.tapTree ? { tapTree: chunkVVFCCNU2_cjs.toBIP371TapTree(recipient.tapTree) } : {}
16192
16516
  }));
16193
16517
  const totalBtcOutput = outputs.reduce((sum, o) => sum + Number(o.amount), 0);
16194
16518
  let changeAmount = totalBtcSelected - totalBtcOutput;
@@ -16326,6 +16650,8 @@ var Wallet2 = class extends ReadonlyWallet {
16326
16650
  serverUnrollScript,
16327
16651
  changeAssets: changeReceiver?.assets
16328
16652
  },
16653
+ onReserved,
16654
+ !selectedVtxos,
16329
16655
  { validUntil }
16330
16656
  );
16331
16657
  }
@@ -16333,8 +16659,11 @@ var Wallet2 = class extends ReadonlyWallet {
16333
16659
  * Shared submit/persist tail of `send` and {@link sendSelectedVtxosToSelf}; callers own coin
16334
16660
  * selection, outputs and the synchronous epoch snapshot.
16335
16661
  */
16336
- async _submitOffchainSpend(inputs, outputs, persist, options) {
16662
+ async _submitOffchainSpend(inputs, outputs, persist, onReserved, picked = false, options) {
16663
+ if (picked) this._assertNotHeld(inputs);
16664
+ if (onReserved) this._assertNotInFlight(inputs);
16337
16665
  this._addPendingSpends(inputs);
16666
+ onReserved?.();
16338
16667
  try {
16339
16668
  const { arkTxid, signedCheckpointTxs } = await this._buildAndSubmitOffchainTx(
16340
16669
  inputs,
@@ -16370,15 +16699,15 @@ var Wallet2 = class extends ReadonlyWallet {
16370
16699
  if (inputs.length === 0) {
16371
16700
  throw new Error("sendSelectedVtxosToSelf: no inputs");
16372
16701
  }
16373
- return this._withTxLock(async () => {
16702
+ return this._withTxLock(async (release) => {
16374
16703
  const offchainTapscript = this.offchainTapscript;
16375
16704
  const serverPubKey = this.arkServerPublicKey;
16376
16705
  const serverUnrollScript = this.serverUnrollScript;
16377
16706
  const arkAddress = offchainTapscript.address(this.network.hrp, serverPubKey);
16378
- const normalizedInputs = inputs.map(chunk65CTZR2O_cjs.normalizeVtxo);
16379
- const at = now ?? await chunk65CTZR2O_cjs.resolveTimeHeight(this.onchainProvider);
16707
+ const normalizedInputs = inputs.map(chunkVVFCCNU2_cjs.normalizeVtxo);
16708
+ const at = now ?? await chunkVVFCCNU2_cjs.resolveTimeHeight(this.onchainProvider);
16380
16709
  for (const input of normalizedInputs) {
16381
- if (!chunk65CTZR2O_cjs.canSpendOffchain(input, at)) {
16710
+ if (!chunkVVFCCNU2_cjs.canSpendOffchain(input, at)) {
16382
16711
  throw new Error(
16383
16712
  `sendSelectedVtxosToSelf: input ${input.txid}:${input.vout} is not cooperatively spendable`
16384
16713
  );
@@ -16413,16 +16742,21 @@ var Wallet2 = class extends ReadonlyWallet {
16413
16742
  const packet = createAssetPacket(assetInputs, [], selfReceiver);
16414
16743
  outputs.push(Extension.create([packet]).txOut());
16415
16744
  }
16416
- return this._submitOffchainSpend(normalizedInputs, outputs, {
16417
- sentAmount: 0,
16418
- changeAmount: total,
16419
- changeVout: 0,
16420
- offchainTapscript,
16421
- serverPubKey,
16422
- changeAssets: selfAssets,
16423
- recordSentHistory: false,
16424
- serverUnrollScript
16425
- });
16745
+ return this._submitOffchainSpend(
16746
+ normalizedInputs,
16747
+ outputs,
16748
+ {
16749
+ sentAmount: 0,
16750
+ changeAmount: total,
16751
+ changeVout: 0,
16752
+ offchainTapscript,
16753
+ serverPubKey,
16754
+ changeAssets: selfAssets,
16755
+ recordSentHistory: false,
16756
+ serverUnrollScript
16757
+ },
16758
+ this._concurrentSpending ? release : void 0
16759
+ );
16426
16760
  });
16427
16761
  }
16428
16762
  /**
@@ -16457,7 +16791,7 @@ var Wallet2 = class extends ReadonlyWallet {
16457
16791
  );
16458
16792
  const arkTxJobs = inputs.map((input, index) => ({
16459
16793
  index,
16460
- lookupScript: chunk65CTZR2O_cjs.VtxoScript.decode(input.tapTree).pkScript
16794
+ lookupScript: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
16461
16795
  }));
16462
16796
  const identity = this.identity;
16463
16797
  const signer = {
@@ -16493,51 +16827,63 @@ var Wallet2 = class extends ReadonlyWallet {
16493
16827
  this.inputSigningJobsFromWitnessUtxos(checkpoint)
16494
16828
  )
16495
16829
  };
16496
- return submitOffchainTx(
16497
- this.arkProvider,
16498
- offchainTx,
16499
- signer,
16500
- {
16501
- // Mark pending before submitting — if we crash between submit and
16502
- // finalize, the next init recovers via finalizePendingTxs.
16503
- beforeSubmit: async () => {
16504
- const ownsPendingFlag = validUntil !== void 0 && !await this.hasPendingTxFlag();
16505
- await this.setPendingTxFlag(true);
16506
- try {
16507
- assertSendDeadline(validUntil);
16508
- } catch (error) {
16509
- if (ownsPendingFlag) {
16510
- try {
16511
- await this.setPendingTxFlag(false);
16512
- } catch (clearError) {
16513
- console.error(
16514
- "Failed to clear pending tx flag after deadline expiry:",
16515
- clearError
16516
- );
16830
+ let awaitingFinalize = false;
16831
+ try {
16832
+ return await submitOffchainTx(
16833
+ this.arkProvider,
16834
+ offchainTx,
16835
+ signer,
16836
+ {
16837
+ // Mark pending before submitting — if we crash between submit and
16838
+ // finalize, the next init recovers via finalizePendingTxs.
16839
+ beforeSubmit: async () => {
16840
+ const ownsPendingFlag = validUntil !== void 0 && !await this.hasPendingTxFlag();
16841
+ this._submitsAwaitingFinalize++;
16842
+ awaitingFinalize = true;
16843
+ await this.setPendingTxFlag(true);
16844
+ try {
16845
+ assertSendDeadline(validUntil);
16846
+ } catch (error) {
16847
+ this._submitsAwaitingFinalize--;
16848
+ awaitingFinalize = false;
16849
+ if (ownsPendingFlag && this._submitsAwaitingFinalize === 0) {
16850
+ try {
16851
+ await this.setPendingTxFlag(false);
16852
+ } catch (clearError) {
16853
+ console.error(
16854
+ "Failed to clear pending tx flag after deadline expiry:",
16855
+ clearError
16856
+ );
16857
+ }
16517
16858
  }
16859
+ throw error;
16860
+ }
16861
+ },
16862
+ afterFinalize: async () => {
16863
+ this._submitsAwaitingFinalize--;
16864
+ awaitingFinalize = false;
16865
+ if (this._submitsAwaitingFinalize > 0) return;
16866
+ try {
16867
+ await this.setPendingTxFlag(false);
16868
+ } catch (error) {
16869
+ console.error("Failed to clear pending tx flag:", error);
16518
16870
  }
16519
- throw error;
16520
16871
  }
16521
16872
  },
16522
- afterFinalize: async () => {
16523
- try {
16524
- await this.setPendingTxFlag(false);
16525
- } catch (error) {
16526
- console.error("Failed to clear pending tx flag:", error);
16873
+ {
16874
+ // Deprecated keys too: a vtxo built before a rotation is still
16875
+ // spent under the signer its leaf names.
16876
+ verifyServerSignatures: {
16877
+ serverPubkey: this._arkServerPublicKey,
16878
+ deprecatedServerPubkeys: [...this._deprecatedSigners.keys()].map(
16879
+ (h) => base.hex.decode(h)
16880
+ )
16527
16881
  }
16528
16882
  }
16529
- },
16530
- {
16531
- // Deprecated keys too: a vtxo built before a rotation is still
16532
- // spent under the signer its leaf names.
16533
- verifyServerSignatures: {
16534
- serverPubkey: this._arkServerPublicKey,
16535
- deprecatedServerPubkeys: [...this._deprecatedSigners.keys()].map(
16536
- (h) => base.hex.decode(h)
16537
- )
16538
- }
16539
- }
16540
- );
16883
+ );
16884
+ } finally {
16885
+ if (awaitingFinalize) this._submitsAwaitingFinalize--;
16886
+ }
16541
16887
  }
16542
16888
  // Mark inputs spent and save change. `offchainTapscript`/`serverPubKey` are the caller's epoch
16543
16889
  // snapshot, so the record matches what the server saw even if a rotation lands mid-flight.
@@ -16554,7 +16900,7 @@ var Wallet2 = class extends ReadonlyWallet {
16554
16900
  }
16555
16901
  const checkpointIdByOutpoint = /* @__PURE__ */ new Map();
16556
16902
  for (const encoded of signedCheckpointTxs) {
16557
- const checkpoint = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
16903
+ const checkpoint = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
16558
16904
  for (let i = 0; i < checkpoint.inputsLength; i++) {
16559
16905
  const input = checkpoint.getInput(i);
16560
16906
  if (!input.txid) continue;
@@ -16670,12 +17016,12 @@ var Wallet2 = class extends ReadonlyWallet {
16670
17016
  const spentVtxos = [];
16671
17017
  const inputArkTxIds = /* @__PURE__ */ new Set();
16672
17018
  const boardingRemovalsByAddress = /* @__PURE__ */ new Map();
16673
- const vtxoInputs = inputs.filter(chunk65CTZR2O_cjs.isVirtualCoin);
17019
+ const vtxoInputs = inputs.filter(chunkVVFCCNU2_cjs.isVirtualCoin);
16674
17020
  const cm = await this.getContractManager();
16675
17021
  const annotatedVtxos = await cm.annotateVtxos(vtxoInputs);
16676
17022
  const annotatedByKey = new Map(annotatedVtxos.map((v) => [`${v.txid}:${v.vout}`, v]));
16677
17023
  for (const input of inputs) {
16678
- if (chunk65CTZR2O_cjs.isVirtualCoin(input)) {
17024
+ if (chunkVVFCCNU2_cjs.isVirtualCoin(input)) {
16679
17025
  const outpoint = `${input.txid}:${input.vout}`;
16680
17026
  const vtxo = annotatedByKey.get(outpoint);
16681
17027
  if (!vtxo) {
@@ -16692,7 +17038,7 @@ var Wallet2 = class extends ReadonlyWallet {
16692
17038
  } else {
16693
17039
  let sourceAddress;
16694
17040
  try {
16695
- sourceAddress = chunk65CTZR2O_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
17041
+ sourceAddress = chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
16696
17042
  this.network
16697
17043
  );
16698
17044
  } catch {
@@ -16735,13 +17081,19 @@ var Wallet2 = class extends ReadonlyWallet {
16735
17081
  );
16736
17082
  }
16737
17083
  }
16738
- for (const [address, toRemove] of boardingRemovalsByAddress) {
16739
- const currentUtxos = await collectUtxos(this.walletRepository, address);
16740
- const filtered = currentUtxos.filter((u) => !toRemove.has(`${u.txid}:${u.vout}`));
16741
- await this.walletRepository.deleteUtxos(address);
16742
- if (filtered.length > 0) {
16743
- await this.walletRepository.saveUtxos(address, filtered);
16744
- }
17084
+ if (boardingRemovalsByAddress.size > 0) {
17085
+ await inVtxoWriteOrder(this.walletRepository, async () => {
17086
+ for (const [address, toRemove] of boardingRemovalsByAddress) {
17087
+ const currentUtxos = await collectUtxos(this.walletRepository, address);
17088
+ const filtered = currentUtxos.filter(
17089
+ (u) => !toRemove.has(`${u.txid}:${u.vout}`)
17090
+ );
17091
+ await this.walletRepository.deleteUtxos(address);
17092
+ if (filtered.length > 0) {
17093
+ await this.walletRepository.saveUtxos(address, filtered);
17094
+ }
17095
+ }
17096
+ });
16745
17097
  }
16746
17098
  } catch (e) {
16747
17099
  console.warn("error updating repository after settle", e);
@@ -16749,15 +17101,16 @@ var Wallet2 = class extends ReadonlyWallet {
16749
17101
  }
16750
17102
  }
16751
17103
  };
17104
+ function bySelectionOrder(a, b) {
17105
+ const expiryA = a.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
17106
+ const expiryB = b.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
17107
+ if (expiryA !== expiryB) {
17108
+ return expiryA - expiryB;
17109
+ }
17110
+ return b.value - a.value;
17111
+ }
16752
17112
  function selectVirtualCoins(coins, targetAmount) {
16753
- const sortedCoins = coins.map(chunk65CTZR2O_cjs.normalizeVtxo).sort((a, b) => {
16754
- const expiryA = a.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
16755
- const expiryB = b.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
16756
- if (expiryA !== expiryB) {
16757
- return expiryA - expiryB;
16758
- }
16759
- return b.value - a.value;
16760
- });
17113
+ const sortedCoins = coins.map(chunkVVFCCNU2_cjs.normalizeVtxo).sort(bySelectionOrder);
16761
17114
  const selectedCoins = [];
16762
17115
  let selectedAmount = 0;
16763
17116
  for (const coin of sortedCoins) {
@@ -16785,6 +17138,18 @@ var AbortError = class extends Error {
16785
17138
  this.name = "AbortError";
16786
17139
  }
16787
17140
  };
17141
+ var VtxoReservedError = class extends Error {
17142
+ constructor(outpoints, holder) {
17143
+ super(
17144
+ `${outpoints.join(", ")} ${holder === "held" ? "held by reserveVtxos" : "already being spent by another operation"}`
17145
+ );
17146
+ this.outpoints = outpoints;
17147
+ this.holder = holder;
17148
+ }
17149
+ outpoints;
17150
+ holder;
17151
+ name = "VtxoReservedError";
17152
+ };
16788
17153
  function abortReason(signal) {
16789
17154
  const { reason } = signal;
16790
17155
  if (reason instanceof Error) return reason;
@@ -16862,7 +17227,7 @@ function assertTimeoutMap(name, timeouts) {
16862
17227
  if (value === void 0) {
16863
17228
  throw new Error(`${name}.${key} must be a non-negative safe integer`);
16864
17229
  }
16865
- chunk65CTZR2O_cjs.assertTimerMs(`${name}.${key}`, value);
17230
+ chunkVVFCCNU2_cjs.assertTimerMs(`${name}.${key}`, value);
16866
17231
  }
16867
17232
  }
16868
17233
  var MessageBus = class {
@@ -16878,8 +17243,8 @@ var MessageBus = class {
16878
17243
  }) {
16879
17244
  this.walletRepository = walletRepository;
16880
17245
  this.contractRepository = contractRepository;
16881
- chunk65CTZR2O_cjs.assertTimerMs("tickIntervalMs", tickIntervalMs);
16882
- chunk65CTZR2O_cjs.assertTimerMs("messageTimeoutMs", messageTimeoutMs);
17246
+ chunkVVFCCNU2_cjs.assertTimerMs("tickIntervalMs", tickIntervalMs);
17247
+ chunkVVFCCNU2_cjs.assertTimerMs("messageTimeoutMs", messageTimeoutMs);
16883
17248
  assertTimeoutMap("messageTimeoutOverrides", messageTimeoutOverrides);
16884
17249
  this.intentRepository = intentRepository;
16885
17250
  this.handlers = new Map(messageHandlers.map((u) => [u.messageTag, u]));
@@ -17133,14 +17498,14 @@ var MessageBus = class {
17133
17498
  this.initialized = true;
17134
17499
  }
17135
17500
  async buildServices(config) {
17136
- const arkProvider = new chunk65CTZR2O_cjs.RestArkProvider(config.arkServer.url);
17501
+ const arkProvider = new chunkVVFCCNU2_cjs.RestArkProvider(config.arkServer.url);
17137
17502
  const storage = {
17138
17503
  walletRepository: this.walletRepository,
17139
17504
  contractRepository: this.contractRepository,
17140
17505
  ...this.intentRepository && { intentRepository: this.intentRepository }
17141
17506
  };
17142
17507
  const delegateProvider = config.delegateUrl ? new RestDelegateProvider(config.delegateUrl) : void 0;
17143
- const indexerProvider = new chunkPAD5V653_cjs.RestIndexerProvider(config.arkServer.url);
17508
+ const indexerProvider = new chunkFEBAG2K2_cjs.RestIndexerProvider(config.arkServer.url);
17144
17509
  const serialized = normalizeSerializedIdentity(config.wallet);
17145
17510
  if (isSigningSerialized(serialized)) {
17146
17511
  const identity2 = hydrateIdentity(serialized);
@@ -17152,6 +17517,7 @@ var MessageBus = class {
17152
17517
  storage,
17153
17518
  delegateProvider,
17154
17519
  settlementConfig: config.settlementConfig,
17520
+ concurrentSpending: config.concurrentSpending,
17155
17521
  walletMode: config.walletMode,
17156
17522
  lazyInitialization: config.lazyInitialization,
17157
17523
  watcherConfig: config.watcherConfig,
@@ -17480,7 +17846,7 @@ var offboardNetworkNames = [
17480
17846
  function offboardDestinationScript(destinationAddress) {
17481
17847
  for (const networkName of offboardNetworkNames) {
17482
17848
  try {
17483
- const network = chunk65CTZR2O_cjs.networks[networkName];
17849
+ const network = chunkVVFCCNU2_cjs.networks[networkName];
17484
17850
  const addr = btcSigner.Address(network).decode(destinationAddress);
17485
17851
  return btcSigner.OutScript.encode(addr);
17486
17852
  } catch {
@@ -17511,12 +17877,16 @@ function reportUngatedInputs(wallet, inputs) {
17511
17877
  const logger = wallet;
17512
17878
  void logger.logUngatedInputs("Ramps.offboard({ vtxos })", inputs);
17513
17879
  }
17880
+ var MAX_EXIT_PICKS = 3;
17881
+ function picksCovering(wallet) {
17882
+ return wallet.concurrentSpending === true;
17883
+ }
17514
17884
  function filterOffboardInputs(vtxos, feeInfo, named) {
17515
17885
  const estimator = new Estimator(feeInfo?.intentFee ?? {});
17516
17886
  const inputs = [];
17517
17887
  let subtotal = 0n;
17518
17888
  for (const vtxo of vtxos) {
17519
- const inputFee = estimator.evalOffchainInput(chunk65CTZR2O_cjs.toOffchainInputFeeParams(vtxo));
17889
+ const inputFee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo));
17520
17890
  if (inputFee.satoshis >= vtxo.value) {
17521
17891
  if (named) {
17522
17892
  throw new Error(
@@ -17574,7 +17944,7 @@ var Ramps = class {
17574
17944
  * ```
17575
17945
  */
17576
17946
  async onboard(feeInfo, boardingUtxos, amount, eventCallback) {
17577
- boardingUtxos = boardingUtxos ?? await this.wallet.getBoardingUtxos();
17947
+ boardingUtxos = boardingUtxos ?? await getSelectableBoardingUtxos(this.wallet);
17578
17948
  const estimator = new Estimator(feeInfo?.intentFee ?? {});
17579
17949
  const filteredBoardingUtxos = [];
17580
17950
  let totalAmount = 0n;
@@ -17613,7 +17983,7 @@ var Ramps = class {
17613
17983
  }
17614
17984
  amount = amount ?? totalAmount;
17615
17985
  const offchainAddress = await this.wallet.getAddress();
17616
- const offchainAddr = chunk65CTZR2O_cjs.ArkAddress.decode(offchainAddress);
17986
+ const offchainAddr = chunkVVFCCNU2_cjs.ArkAddress.decode(offchainAddress);
17617
17987
  const offchainScript = base.hex.encode(offchainAddr.pkScript);
17618
17988
  const outputFee = estimator.evalOffchainOutput({
17619
17989
  amount,
@@ -17668,29 +18038,39 @@ var Ramps = class {
17668
18038
  * ```
17669
18039
  */
17670
18040
  async offboard(destinationAddress, feeInfo, amount, eventCallback, vtxos) {
17671
- const { estimator, inputs, subtotal } = await this.offboardInputs(feeInfo, vtxos);
17672
- if (amount && amount > subtotal) {
17673
- throw new Error("Amount is greater than total amount of vtxos after fees");
17674
- }
17675
- const handed = amount || subtotal;
17676
- const { change, changeAddress } = await this.fundChange(
17677
- amount ? subtotal - handed : 0n,
17678
- estimator
17679
- );
17680
- const outputFee = estimator.evalOnchainOutput({
17681
- amount: handed,
17682
- script: base.hex.encode(offboardDestinationScript(destinationAddress))
17683
- });
17684
- if (BigInt(outputFee.satoshis) > handed) {
17685
- throw new Error(
17686
- `can't deduct fees from offboard amount (${outputFee.satoshis} > ${handed})`
18041
+ return this.withRepick(vtxos !== void 0, async () => {
18042
+ const {
18043
+ estimator,
18044
+ inputs: candidates,
18045
+ subtotal
18046
+ } = await this.offboardInputs(feeInfo, vtxos);
18047
+ if (amount && amount > subtotal) {
18048
+ throw new Error("Amount is greater than total amount of vtxos after fees");
18049
+ }
18050
+ const handed = amount || subtotal;
18051
+ const { inputs, change, changeAddress } = await this.fundExit(
18052
+ candidates,
18053
+ subtotal,
18054
+ handed,
18055
+ estimator,
18056
+ Boolean(amount) && vtxos === void 0
17687
18057
  );
17688
- }
17689
- const outputs = [
17690
- { address: destinationAddress, amount: handed - BigInt(outputFee.satoshis) }
17691
- ];
17692
- if (change > 0n) outputs.push({ address: changeAddress, amount: change });
17693
- return this.wallet.settle({ inputs, outputs }, eventCallback);
18058
+ const outputFee = estimator.evalOnchainOutput({
18059
+ amount: handed,
18060
+ script: base.hex.encode(offboardDestinationScript(destinationAddress))
18061
+ });
18062
+ if (BigInt(outputFee.satoshis) > handed) {
18063
+ throw new Error(
18064
+ `can't deduct fees from offboard amount (${outputFee.satoshis} > ${handed})`
18065
+ );
18066
+ }
18067
+ const outputs = [
18068
+ { address: destinationAddress, amount: handed - BigInt(outputFee.satoshis) }
18069
+ ];
18070
+ if (change > 0n) outputs.push({ address: changeAddress, amount: change });
18071
+ const params = { inputs, outputs };
18072
+ return this.wallet.settle(vtxos ? params : markSdkPicked(params), eventCallback);
18073
+ });
17694
18074
  }
17695
18075
  /**
17696
18076
  * Collaboratively exit with the DESTINATION paid exactly `amount`, pricing the
@@ -17703,23 +18083,36 @@ var Ramps = class {
17703
18083
  if (amount <= 0n) {
17704
18084
  throw new Error(`offboard amount must be positive, got ${amount}`);
17705
18085
  }
17706
- const { estimator, inputs, subtotal } = await this.offboardInputs(feeInfo, vtxos);
17707
- const outputFee = BigInt(
17708
- estimator.evalOnchainOutput({
17709
- amount,
17710
- script: base.hex.encode(offboardDestinationScript(destinationAddress))
17711
- }).satoshis
17712
- );
17713
- const needed = amount + outputFee;
17714
- if (needed > subtotal) {
17715
- throw new Error(
17716
- `selected vtxos net ${subtotal} sats, ${needed} needed to deliver ${amount} exactly (${amount} + a ${outputFee} sat exit fee)`
18086
+ return this.withRepick(vtxos !== void 0, async () => {
18087
+ const {
18088
+ estimator,
18089
+ inputs: candidates,
18090
+ subtotal
18091
+ } = await this.offboardInputs(feeInfo, vtxos);
18092
+ const outputFee = BigInt(
18093
+ estimator.evalOnchainOutput({
18094
+ amount,
18095
+ script: base.hex.encode(offboardDestinationScript(destinationAddress))
18096
+ }).satoshis
17717
18097
  );
17718
- }
17719
- const { change, changeAddress } = await this.fundChange(subtotal - needed, estimator);
17720
- const outputs = [{ address: destinationAddress, amount }];
17721
- if (change > 0n) outputs.push({ address: changeAddress, amount: change });
17722
- return this.wallet.settle({ inputs, outputs }, eventCallback);
18098
+ const needed = amount + outputFee;
18099
+ if (needed > subtotal) {
18100
+ throw new Error(
18101
+ `selected vtxos net ${subtotal} sats, ${needed} needed to deliver ${amount} exactly (${amount} + a ${outputFee} sat exit fee)`
18102
+ );
18103
+ }
18104
+ const { inputs, change, changeAddress } = await this.fundExit(
18105
+ candidates,
18106
+ subtotal,
18107
+ needed,
18108
+ estimator,
18109
+ vtxos === void 0
18110
+ );
18111
+ const outputs = [{ address: destinationAddress, amount }];
18112
+ if (change > 0n) outputs.push({ address: changeAddress, amount: change });
18113
+ const params2 = { inputs, outputs };
18114
+ return this.wallet.settle(vtxos ? params2 : markSdkPicked(params2), eventCallback);
18115
+ });
17723
18116
  }
17724
18117
  async offboardInputs(feeInfo, vtxos) {
17725
18118
  const named = vtxos !== void 0;
@@ -17732,12 +18125,49 @@ var Ramps = class {
17732
18125
  const estimator = new Estimator(feeInfo?.intentFee ?? {});
17733
18126
  return { estimator, ...filterOffboardInputs(spendable, feeInfo, named) };
17734
18127
  }
18128
+ /** Every candidate, or with `concurrentSpending` the shortest covering prefix in send order. */
18129
+ async fundExit(candidates, subtotal, needed, estimator, cover) {
18130
+ if (!cover || !picksCovering(this.wallet)) {
18131
+ return { inputs: candidates, ...await this.fundChange(subtotal - needed, estimator) };
18132
+ }
18133
+ const ordered = [...candidates].sort(bySelectionOrder);
18134
+ let covered = 0n;
18135
+ for (let i = 0; i < ordered.length && i < MAX_VTXOS_PER_SETTLEMENT; i++) {
18136
+ const fee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(ordered[i])).satoshis;
18137
+ covered += BigInt(ordered[i].value) - BigInt(fee);
18138
+ if (covered < needed) continue;
18139
+ try {
18140
+ return {
18141
+ inputs: ordered.slice(0, i + 1),
18142
+ ...await this.fundChange(covered - needed, estimator)
18143
+ };
18144
+ } catch (error) {
18145
+ if (!(error instanceof DustChangeError) || i + 1 === ordered.length) throw error;
18146
+ }
18147
+ }
18148
+ throw new Error(
18149
+ `this exit needs more than ${MAX_VTXOS_PER_SETTLEMENT} inputs; exit less, or consolidate first`
18150
+ );
18151
+ }
18152
+ /** Re-runs an SDK-picked exit that lost a coin to a concurrent spend. */
18153
+ async withRepick(named, exit) {
18154
+ for (let attempt = 1; ; attempt++) {
18155
+ try {
18156
+ return await exit();
18157
+ } catch (error) {
18158
+ const lostRace = error?.name === "VtxoReservedError";
18159
+ if (named || !lostRace || !picksCovering(this.wallet) || attempt >= MAX_EXIT_PICKS) {
18160
+ throw error;
18161
+ }
18162
+ }
18163
+ }
18164
+ }
17735
18165
  /** Fund the change output: pay its own fee, then judge it against both
17736
18166
  * server-side bounds. `0n` in is `0n` out — no change output at all. */
17737
18167
  async fundChange(left, estimator) {
17738
18168
  if (left <= 0n) return { change: 0n };
17739
18169
  const changeAddress = await this.wallet.getAddress();
17740
- const changeScript = base.hex.encode(chunk65CTZR2O_cjs.ArkAddress.decode(changeAddress).pkScript);
18170
+ const changeScript = base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(changeAddress).pkScript);
17741
18171
  const { change } = changeAfterOutputFee(
17742
18172
  left,
17743
18173
  (amount) => BigInt(estimator.evalOffchainOutput({ amount, script: changeScript }).satoshis)
@@ -18228,6 +18658,17 @@ var WalletMessageHandler = class {
18228
18658
  payload: { contracts, filterApplied: true }
18229
18659
  });
18230
18660
  }
18661
+ case "GET_STORED_CONTRACTS_WITH_VTXOS": {
18662
+ const manager = await this.readonlyWallet.getContractManager();
18663
+ const contracts = await manager.getStoredContractsWithVtxos(
18664
+ message.payload.filter
18665
+ );
18666
+ return this.tagged({
18667
+ id,
18668
+ type: "STORED_CONTRACTS_WITH_VTXOS",
18669
+ payload: { contracts }
18670
+ });
18671
+ }
18231
18672
  case "WATCH_SCRIPT": {
18232
18673
  const manager = await this.readonlyWallet.getContractManager();
18233
18674
  if (!manager.watchScript) throw unsupportedByManager("watchScript");
@@ -18651,7 +19092,7 @@ var WalletMessageHandler = class {
18651
19092
  this.lazyBoardingInit = payload.lazyBoarding ?? false;
18652
19093
  this.boardingEpoch++;
18653
19094
  this.boardingLoaded = false;
18654
- this.indexerProvider = new chunkPAD5V653_cjs.RestIndexerProvider(arkServerUrl);
19095
+ this.indexerProvider = new chunkFEBAG2K2_cjs.RestIndexerProvider(arkServerUrl);
18655
19096
  await this.onWalletInitialized();
18656
19097
  }
18657
19098
  /** @see RequestInitWallet.payload.lazyBoarding */
@@ -19073,7 +19514,7 @@ var WalletMessageHandler = class {
19073
19514
  this.readonlyWallet.getBoardingTxs()
19074
19515
  ]);
19075
19516
  const indexerProvider = this.indexerProvider;
19076
- const resolveTxCreatedAt = indexerProvider ? (txids) => chunk65CTZR2O_cjs.fetchVtxoCreatedAtByTxid(indexerProvider, txids) : void 0;
19517
+ const resolveTxCreatedAt = indexerProvider ? (txids) => chunkVVFCCNU2_cjs.fetchVtxoCreatedAtByTxid(indexerProvider, txids) : void 0;
19077
19518
  return buildTransactionHistory(
19078
19519
  vtxos,
19079
19520
  boardingTxs,
@@ -19142,7 +19583,7 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
19142
19583
  // budget so the worker's snapshot fallback stays reachable before this
19143
19584
  // page deadline fires — lowering it below the budget would time the page
19144
19585
  // out while the worker is still seconds from answering from cache.
19145
- GET_ARKADE_INFO: chunk65CTZR2O_cjs.INFO_FETCH_TIMEOUT_MS + 8e3,
19586
+ GET_ARKADE_INFO: chunkVVFCCNU2_cjs.INFO_FETCH_TIMEOUT_MS + 8e3,
19146
19587
  INDEXER_GET_VTXOS: 2e4,
19147
19588
  INDEXER_GET_VIRTUAL_TXS: 2e4,
19148
19589
  GET_VTXOS: 2e4,
@@ -19151,6 +19592,7 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
19151
19592
  GET_TRANSACTION_HISTORY: 2e4,
19152
19593
  GET_CONTRACTS: 2e4,
19153
19594
  GET_CONTRACTS_WITH_VTXOS: 2e4,
19595
+ GET_STORED_CONTRACTS_WITH_VTXOS: 2e4,
19154
19596
  GET_WATCHED_SCRIPTS: 1e4,
19155
19597
  ANNOTATE_VTXOS: 2e4,
19156
19598
  GET_SPENDABLE_PATHS: 2e4,
@@ -19220,6 +19662,7 @@ var DEDUPABLE_REQUEST_TYPES = /* @__PURE__ */ new Set([
19220
19662
  "GET_SPENDABLE_VTXOS",
19221
19663
  "GET_CONTRACTS",
19222
19664
  "GET_CONTRACTS_WITH_VTXOS",
19665
+ "GET_STORED_CONTRACTS_WITH_VTXOS",
19223
19666
  "GET_WATCHED_SCRIPTS",
19224
19667
  "ANNOTATE_VTXOS",
19225
19668
  "GET_SPENDABLE_PATHS",
@@ -19283,7 +19726,7 @@ var ServiceWorkerAssetManager = class extends ServiceWorkerReadonlyAssetManager
19283
19726
  }
19284
19727
  };
19285
19728
  var initializeMessageBus = (serviceWorker, config, timeoutMs = 2e3) => {
19286
- chunk65CTZR2O_cjs.assertTimerMs("messageBusTimeoutMs", timeoutMs);
19729
+ chunkVVFCCNU2_cjs.assertTimerMs("messageBusTimeoutMs", timeoutMs);
19287
19730
  const initCmd = {
19288
19731
  tag: "INITIALIZE_MESSAGE_BUS",
19289
19732
  id: getRandomId(),
@@ -19371,7 +19814,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19371
19814
  }
19372
19815
  /** Shared tail of both `create()` factories: boot the bus, INIT_WALLET, cache for reinit. */
19373
19816
  static async bootstrap(wallet, options, serializedWallet, busConfig) {
19374
- const arkServer = options.arkServer ?? { url: chunk65CTZR2O_cjs.DEFAULT_ARKADE_SERVER_URL };
19817
+ const arkServer = options.arkServer ?? { url: chunkVVFCCNU2_cjs.DEFAULT_ARKADE_SERVER_URL };
19375
19818
  const initWalletPayload = {
19376
19819
  lazyBoarding: options.lazyBoarding,
19377
19820
  arkServerUrl: arkServer.url,
@@ -19381,7 +19824,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19381
19824
  Object.entries(options.messageTimeouts ?? {}).filter(([, ms]) => ms !== void 0)
19382
19825
  );
19383
19826
  for (const [key, value] of Object.entries(overrides)) {
19384
- chunk65CTZR2O_cjs.assertTimerMs(`messageTimeouts.${key}`, value);
19827
+ chunkVVFCCNU2_cjs.assertTimerMs(`messageTimeouts.${key}`, value);
19385
19828
  }
19386
19829
  const messageTimeouts = {
19387
19830
  ...DEFAULT_MESSAGE_TIMEOUTS,
@@ -19721,7 +20164,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19721
20164
  try {
19722
20165
  const response = await this.sendMessage(message);
19723
20166
  const { vtxos, page } = response.payload;
19724
- return { vtxos: vtxos.map(chunk65CTZR2O_cjs.normalizeVtxo), page: page && { ...page } };
20167
+ return { vtxos: vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo), page: page && { ...page } };
19725
20168
  } catch (cause) {
19726
20169
  throw new Error(`Failed to get vtxos: ${cause}`, { cause });
19727
20170
  }
@@ -19825,7 +20268,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19825
20268
  };
19826
20269
  try {
19827
20270
  const response = await this.sendMessage(message);
19828
- return response.payload.vtxos.map(chunk65CTZR2O_cjs.normalizeVtxo);
20271
+ return response.payload.vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
19829
20272
  } catch (error) {
19830
20273
  throw new Error(`Failed to get vtxos: ${error}`);
19831
20274
  }
@@ -19856,7 +20299,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19856
20299
  "Service worker does not support the requested contract scope or freshness check"
19857
20300
  );
19858
20301
  }
19859
- return payload.vtxos.map(chunk65CTZR2O_cjs.normalizeVtxo);
20302
+ return payload.vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
19860
20303
  } catch (error) {
19861
20304
  throw new Error(`Failed to get spendable vtxos: ${error}`);
19862
20305
  }
@@ -19963,6 +20406,23 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19963
20406
  });
19964
20407
  }
19965
20408
  },
20409
+ async getStoredContractsWithVtxos(filter) {
20410
+ const message = {
20411
+ type: "GET_STORED_CONTRACTS_WITH_VTXOS",
20412
+ id: getRandomId(),
20413
+ tag: messageTag,
20414
+ payload: { filter }
20415
+ };
20416
+ try {
20417
+ const response = await sendContractMessage(message);
20418
+ await refreshSyncState();
20419
+ return response.payload.contracts;
20420
+ } catch (cause) {
20421
+ throw new Error(`Failed to get stored contracts with vtxos: ${cause}`, {
20422
+ cause
20423
+ });
20424
+ }
20425
+ },
19966
20426
  async watchScript(script, options) {
19967
20427
  const message = {
19968
20428
  type: "WATCH_SCRIPT",
@@ -20034,7 +20494,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
20034
20494
  };
20035
20495
  try {
20036
20496
  const response = await sendContractMessage(message);
20037
- return response.payload.vtxos.map(chunk65CTZR2O_cjs.normalizeVtxo);
20497
+ return response.payload.vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
20038
20498
  } catch (cause) {
20039
20499
  throw new Error(`Failed to annotate vtxos: ${cause}`, { cause });
20040
20500
  }
@@ -20237,6 +20697,11 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
20237
20697
  _assetManager;
20238
20698
  hasDelegate;
20239
20699
  _restoreInFlight;
20700
+ _concurrentSpending = false;
20701
+ /** @see WalletConfig.concurrentSpending */
20702
+ get concurrentSpending() {
20703
+ return this._concurrentSpending;
20704
+ }
20240
20705
  get assetManager() {
20241
20706
  return this._assetManager;
20242
20707
  }
@@ -20264,9 +20729,11 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
20264
20729
  messageTag,
20265
20730
  !!options.delegateUrl
20266
20731
  );
20732
+ wallet._concurrentSpending = options.concurrentSpending === true;
20267
20733
  return _ServiceWorkerWallet.bootstrap(wallet, options, serializedWallet, {
20268
20734
  delegateUrl: options.delegateUrl,
20269
20735
  settlementConfig: options.settlementConfig,
20736
+ concurrentSpending: options.concurrentSpending,
20270
20737
  walletMode: options.walletMode,
20271
20738
  lazyInitialization: options.lazyInitialization,
20272
20739
  watcherConfig: options.watcherConfig,
@@ -20460,6 +20927,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
20460
20927
  });
20461
20928
  return response.payload.txid;
20462
20929
  } catch (error) {
20930
+ if (error instanceof Error && error.name === "VtxoReservedError") throw error;
20463
20931
  throw new Error(`Settlement failed: ${error}`);
20464
20932
  }
20465
20933
  }
@@ -20550,6 +21018,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
20550
21018
  const response = await this.sendMessage(message);
20551
21019
  return response.payload.txid;
20552
21020
  } catch (error) {
21021
+ if (error instanceof Error && error.name === "VtxoReservedError") throw error;
20553
21022
  if (error instanceof SendDeadlineExceededError) throw error;
20554
21023
  throw new Error(`Send failed: ${error}`);
20555
21024
  }
@@ -20653,7 +21122,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
20653
21122
  };
20654
21123
  try {
20655
21124
  const response = await wallet.sendMessage(message);
20656
- return response.payload.vtxos.map(chunk65CTZR2O_cjs.normalizeVtxo);
21125
+ return response.payload.vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
20657
21126
  } catch (e) {
20658
21127
  throw new Error(`Failed to get expiring vtxos: ${e}`);
20659
21128
  }
@@ -20770,12 +21239,12 @@ var OnchainWallet = class _OnchainWallet {
20770
21239
  * @returns Configured onchain wallet
20771
21240
  * @throws Error if the configured identity cannot produce a valid x-only public key
20772
21241
  */
20773
- static async create(identity, networkName = chunk65CTZR2O_cjs.DEFAULT_NETWORK_NAME, provider) {
21242
+ static async create(identity, networkName = chunkVVFCCNU2_cjs.DEFAULT_NETWORK_NAME, provider) {
20774
21243
  const pubkey = await identity.xOnlyPublicKey();
20775
21244
  if (!pubkey) {
20776
21245
  throw new Error("Invalid configured public key");
20777
21246
  }
20778
- const network = chunk65CTZR2O_cjs.getNetwork(networkName);
21247
+ const network = chunkVVFCCNU2_cjs.getNetwork(networkName);
20779
21248
  const onchainProvider = provider || new EsploraProvider(ESPLORA_URL[networkName]);
20780
21249
  const onchainP2TR = btcSigner.p2tr(pubkey, void 0, network);
20781
21250
  return new _OnchainWallet(identity, network, onchainP2TR, onchainProvider);
@@ -20875,7 +21344,7 @@ var OnchainWallet = class _OnchainWallet {
20875
21344
  feeRate,
20876
21345
  params.address
20877
21346
  );
20878
- let tx = new chunk65CTZR2O_cjs.Transaction();
21347
+ let tx = new chunkVVFCCNU2_cjs.Transaction();
20879
21348
  for (const input of inputs) {
20880
21349
  tx.addInput({
20881
21350
  txid: input.txid,
@@ -20933,7 +21402,7 @@ var OnchainWallet = class _OnchainWallet {
20933
21402
  * @throws If the parent has no anchor, or funding cannot be selected/signed
20934
21403
  */
20935
21404
  async bumpAnchor(parentHex, feeRate) {
20936
- const parent = chunk65CTZR2O_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
21405
+ const parent = chunkVVFCCNU2_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
20937
21406
  const coins = (await this.getCoins()).filter((c) => c.status.confirmed);
20938
21407
  const child = await this.buildBumpPackage(parent, feeRate, coins);
20939
21408
  return [parent.hex, child.hex];
@@ -21749,7 +22218,7 @@ var CachingArkProvider = class {
21749
22218
  constructor(inner, ttlMs = DEFAULT_TTL_MS) {
21750
22219
  this.inner = inner;
21751
22220
  this.ttlMs = ttlMs;
21752
- chunk65CTZR2O_cjs.assertNonNegativeMs("ttlMs", ttlMs);
22221
+ chunkVVFCCNU2_cjs.assertNonNegativeMs("ttlMs", ttlMs);
21753
22222
  this.unsubscribe = inner.onServerInfoChanged?.((info) => {
21754
22223
  this.cached = info;
21755
22224
  this.expiresAt = Date.now() + this.ttlMs;
@@ -21841,7 +22310,7 @@ async function resolvePrevTxs(txids, source, onchain) {
21841
22310
  try {
21842
22311
  const { txs } = await source.getVirtualTxs(wanted);
21843
22312
  for (const psbt of txs) {
21844
- const tx = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(psbt));
22313
+ const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbt));
21845
22314
  resolved.set(tx.id, tx.toBytes());
21846
22315
  }
21847
22316
  } catch (err) {
@@ -21874,7 +22343,7 @@ async function resolvePrevTxs(txids, source, onchain) {
21874
22343
  async function attachPrevArkTxs(tx, txids, source, onchain) {
21875
22344
  const pending = [];
21876
22345
  for (let i = 0; i < tx.inputsLength; i++) {
21877
- if (chunk65CTZR2O_cjs.getArkPsbtFields(tx, i, chunk65CTZR2O_cjs.PrevArkTxField).length === 0) pending.push(i);
22346
+ if (chunkVVFCCNU2_cjs.getArkPsbtFields(tx, i, chunkVVFCCNU2_cjs.PrevArkTxField).length === 0) pending.push(i);
21878
22347
  }
21879
22348
  if (pending.length === 0) return;
21880
22349
  const resolved = await resolvePrevTxs(
@@ -21883,13 +22352,13 @@ async function attachPrevArkTxs(tx, txids, source, onchain) {
21883
22352
  onchain
21884
22353
  );
21885
22354
  for (const i of pending) {
21886
- chunk65CTZR2O_cjs.setArkPsbtField(tx, i, chunk65CTZR2O_cjs.PrevArkTxField, resolved.get(txidAt(txids, i)));
22355
+ chunkVVFCCNU2_cjs.setArkPsbtField(tx, i, chunkVVFCCNU2_cjs.PrevArkTxField, resolved.get(txidAt(txids, i)));
21887
22356
  }
21888
22357
  }
21889
22358
  async function attachPrevoutTxs(tx, source) {
21890
22359
  const pending = [];
21891
22360
  for (let i = 0; i < tx.inputsLength; i++) {
21892
- if (chunk65CTZR2O_cjs.getArkPsbtFields(tx, i, chunk65CTZR2O_cjs.PrevoutTxField).length > 0) continue;
22361
+ if (chunkVVFCCNU2_cjs.getArkPsbtFields(tx, i, chunkVVFCCNU2_cjs.PrevoutTxField).length > 0) continue;
21893
22362
  const input = tx.getInput(i);
21894
22363
  if (!input?.txid) throw new PrevTxUnavailableError(`input ${i} has no outpoint`);
21895
22364
  pending.push({ index: i, txid: base.hex.encode(input.txid) });
@@ -21900,7 +22369,7 @@ async function attachPrevoutTxs(tx, source) {
21900
22369
  resolved.set(txid, await source.getRawTransaction(txid));
21901
22370
  }
21902
22371
  for (const { index, txid } of pending) {
21903
- chunk65CTZR2O_cjs.setArkPsbtField(tx, index, chunk65CTZR2O_cjs.PrevoutTxField, resolved.get(txid));
22372
+ chunkVVFCCNU2_cjs.setArkPsbtField(tx, index, chunkVVFCCNU2_cjs.PrevoutTxField, resolved.get(txid));
21904
22373
  }
21905
22374
  }
21906
22375
  async function withPrevTxs(coins, source, onchain) {
@@ -21926,7 +22395,7 @@ exports.BIP322 = void 0;
21926
22395
  async function sign2(message, identity, network) {
21927
22396
  const xOnlyPubKey = await identity.xOnlyPublicKey();
21928
22397
  const payment = btcSigner.p2tr(xOnlyPubKey, void 0, network);
21929
- const toSpend = chunk65CTZR2O_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
22398
+ const toSpend = chunkVVFCCNU2_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
21930
22399
  const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
21931
22400
  const signed = await identity.sign(toSign, [0]);
21932
22401
  signed.finalizeIdx(0);
@@ -21984,7 +22453,7 @@ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
21984
22453
  if (sighashType !== btcSigner.SigHash.DEFAULT && sighashType !== btcSigner.SigHash.ALL) {
21985
22454
  return false;
21986
22455
  }
21987
- const toSpend = chunk65CTZR2O_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
22456
+ const toSpend = chunkVVFCCNU2_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
21988
22457
  const toSign = craftBIP322ToSignP2TR(toSpend, pkScript);
21989
22458
  const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
21990
22459
  const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
@@ -22005,7 +22474,7 @@ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
22005
22474
  }
22006
22475
  const sighashType = sigWithHash[sigWithHash.length - 1];
22007
22476
  const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
22008
- const toSpend = chunk65CTZR2O_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
22477
+ const toSpend = chunkVVFCCNU2_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
22009
22478
  const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
22010
22479
  const scriptCode = btcSigner.OutScript.encode({ type: "pkh", hash: addressHash });
22011
22480
  const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
@@ -22058,7 +22527,7 @@ function encodeCompactSize(n) {
22058
22527
  return buf;
22059
22528
  }
22060
22529
  function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
22061
- const tx = new chunk65CTZR2O_cjs.Transaction({ version: 0 });
22530
+ const tx = new chunkVVFCCNU2_cjs.Transaction({ version: 0 });
22062
22531
  tx.addInput({
22063
22532
  txid: toSpend.id,
22064
22533
  index: 0,
@@ -22072,12 +22541,12 @@ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
22072
22541
  });
22073
22542
  tx.addOutput({
22074
22543
  amount: 0n,
22075
- script: chunk65CTZR2O_cjs.OP_RETURN_EMPTY_PKSCRIPT
22544
+ script: chunkVVFCCNU2_cjs.OP_RETURN_EMPTY_PKSCRIPT
22076
22545
  });
22077
22546
  return tx;
22078
22547
  }
22079
22548
  function craftBIP322ToSignSimple(toSpend, pkScript) {
22080
- const tx = new chunk65CTZR2O_cjs.Transaction({ version: 0 });
22549
+ const tx = new chunkVVFCCNU2_cjs.Transaction({ version: 0 });
22081
22550
  tx.addInput({
22082
22551
  txid: toSpend.id,
22083
22552
  index: 0,
@@ -22089,7 +22558,7 @@ function craftBIP322ToSignSimple(toSpend, pkScript) {
22089
22558
  });
22090
22559
  tx.addOutput({
22091
22560
  amount: 0n,
22092
- script: chunk65CTZR2O_cjs.OP_RETURN_EMPTY_PKSCRIPT
22561
+ script: chunkVVFCCNU2_cjs.OP_RETURN_EMPTY_PKSCRIPT
22093
22562
  });
22094
22563
  return tx;
22095
22564
  }
@@ -22102,7 +22571,7 @@ var RestEmulatorProvider = class {
22102
22571
  serverUrl;
22103
22572
  async getInfo() {
22104
22573
  const url = `${this.serverUrl}/v1/info`;
22105
- const response = await chunk65CTZR2O_cjs.baseFetch(url);
22574
+ const response = await chunkVVFCCNU2_cjs.baseFetch(url);
22106
22575
  if (!response.ok) {
22107
22576
  const errorText2 = await response.text();
22108
22577
  throw new Error(`Failed to get emulator info: ${errorText2}`);
@@ -22220,7 +22689,7 @@ var RestEmulatorProvider = class {
22220
22689
  }
22221
22690
  };
22222
22691
  function finalizeVirtualTx(type, psbtBase64) {
22223
- const tx = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
22692
+ const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
22224
22693
  if (type === "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */) {
22225
22694
  const input = tx.getInput(0);
22226
22695
  if (!input) {
@@ -22247,14 +22716,14 @@ var ExitPathError = class extends Error {
22247
22716
  reason;
22248
22717
  };
22249
22718
  function delayWeight(sequence) {
22250
- const t = chunk65CTZR2O_cjs.sequenceToTimelock(sequence);
22719
+ const t = chunkVVFCCNU2_cjs.sequenceToTimelock(sequence);
22251
22720
  return t.type === "blocks" ? Number(t.value) : Number(t.value) / 600;
22252
22721
  }
22253
22722
  async function resolveUnilateralPath(params) {
22254
22723
  const { vtxo, scriptHex, contractRepository } = params;
22255
22724
  const contract = contractRepository ? (await collectContracts(contractRepository, { script: scriptHex }))[0] : void 0;
22256
22725
  if (contract) {
22257
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(contract.type);
22726
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
22258
22727
  if (!handler) {
22259
22728
  throw new ExitPathError(
22260
22729
  "no-handler",
@@ -22276,12 +22745,12 @@ async function resolveUnilateralPath(params) {
22276
22745
  paths.sort((a, b) => delayWeight(a.sequence) - delayWeight(b.sequence));
22277
22746
  return { selection: paths[0], label: `${contract.type}:unilateral` };
22278
22747
  }
22279
- const decoded = chunk65CTZR2O_cjs.VtxoScript.decode(vtxo.tapTree);
22748
+ const decoded = chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree);
22280
22749
  let best;
22281
22750
  for (const exit of decoded.exitPaths()) {
22282
22751
  const leaf = decoded.findLeaf(base.hex.encode(exit.script));
22283
22752
  if (!leaf) continue;
22284
- const sequence = chunk65CTZR2O_cjs.timelockToSequence(exit.params.timelock);
22753
+ const sequence = chunkVVFCCNU2_cjs.timelockToSequence(exit.params.timelock);
22285
22754
  const weight = delayWeight(sequence);
22286
22755
  if (!best || weight < best.weight) {
22287
22756
  best = { selection: { leaf, sequence }, weight };
@@ -22488,7 +22957,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
22488
22957
  const txWeightEstimator = TxWeightEstimator.create();
22489
22958
  const walletDescriptor = base.hex.encode(await wallet.identity.xOnlyPublicKey());
22490
22959
  for (const vtxo of vtxos) {
22491
- if (!chunk65CTZR2O_cjs.canSweepOnchain(vtxo)) {
22960
+ if (!chunkVVFCCNU2_cjs.canSweepOnchain(vtxo)) {
22492
22961
  throw new Error(
22493
22962
  `Vtxo ${vtxo.txid}:${vtxo.vout} cannot be swept onchain: it is not fully unrolled (use unroll first), or its exit output was already spent`
22494
22963
  );
@@ -22499,14 +22968,14 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
22499
22968
  }
22500
22969
  const resolved = await resolveUnilateralPath({
22501
22970
  vtxo,
22502
- scriptHex: base.hex.encode(chunk65CTZR2O_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
22971
+ scriptHex: base.hex.encode(chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
22503
22972
  contractRepository: wallet.contractRepository,
22504
22973
  walletDescriptor,
22505
22974
  currentTime: Date.now()
22506
22975
  });
22507
22976
  const spendingLeaf = resolved.selection.leaf;
22508
22977
  const sequence = resolved.selection.sequence;
22509
- const timelock = chunk65CTZR2O_cjs.sequenceToTimelock(sequence);
22978
+ const timelock = chunkVVFCCNU2_cjs.sequenceToTimelock(sequence);
22510
22979
  const elapsed = timelock.type === "blocks" ? chainTip.height >= txStatus.blockHeight + Number(timelock.value) : chainTip.time >= txStatus.blockTime + Number(timelock.value);
22511
22980
  if (!elapsed) {
22512
22981
  throw new Error(`no available exit path found for vtxo ${vtxo.txid}:${vtxo.vout}`);
@@ -22519,7 +22988,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
22519
22988
  sequence,
22520
22989
  witnessUtxo: {
22521
22990
  amount: BigInt(vtxo.value),
22522
- script: chunk65CTZR2O_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
22991
+ script: chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
22523
22992
  },
22524
22993
  sighashType: btcSigner.SigHash.DEFAULT
22525
22994
  });
@@ -22529,7 +22998,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
22529
22998
  btcSigner.TaprootControlBlock.encode(spendingLeaf[0]).length
22530
22999
  );
22531
23000
  }
22532
- const tx = new chunk65CTZR2O_cjs.Transaction({ version: 2 });
23001
+ const tx = new chunkVVFCCNU2_cjs.Transaction({ version: 2 });
22533
23002
  for (const input of inputs) {
22534
23003
  tx.addInput(input);
22535
23004
  }
@@ -22612,7 +23081,7 @@ async function buildSignedSweep(params) {
22612
23081
  `uneconomic vtxo ${vtxo.txid}:${vtxo.vout}: value ${vtxo.value} - fee ${fee} < dust`
22613
23082
  );
22614
23083
  }
22615
- const tx = new chunk65CTZR2O_cjs.Transaction({ version: 2 });
23084
+ const tx = new chunkVVFCCNU2_cjs.Transaction({ version: 2 });
22616
23085
  tx.addInput({
22617
23086
  txid: vtxo.txid,
22618
23087
  index: vtxo.vout,
@@ -22637,7 +23106,7 @@ async function buildSignedSweep(params) {
22637
23106
  finalScriptWitness: [
22638
23107
  tapScriptSig[0][1],
22639
23108
  ...path.extraWitness,
22640
- chunk65CTZR2O_cjs.scriptFromTapLeafScript(path.leaf),
23109
+ chunkVVFCCNU2_cjs.scriptFromTapLeafScript(path.leaf),
22641
23110
  btcSigner.TaprootControlBlock.encode(controlBlock)
22642
23111
  ]
22643
23112
  });
@@ -22667,7 +23136,7 @@ async function resolveFeeRate(opts) {
22667
23136
  }
22668
23137
  async function selectExitVtxos(opts) {
22669
23138
  if (!opts.vtxos) return opts.wallet.getVtxos();
22670
- const res = await chunk65CTZR2O_cjs.getNormalizedVtxos(opts.wallet.indexerProvider, { outpoints: opts.vtxos });
23139
+ const res = await chunkVVFCCNU2_cjs.getNormalizedVtxos(opts.wallet.indexerProvider, { outpoints: opts.vtxos });
22671
23140
  const tapTrees = /* @__PURE__ */ new Map();
22672
23141
  const out = [];
22673
23142
  for (const vtxo of res.vtxos) {
@@ -22682,7 +23151,7 @@ async function selectExitVtxos(opts) {
22682
23151
  `no contract registered for vtxo script ${vtxo.script} \u2014 register the contract before exiting`
22683
23152
  );
22684
23153
  }
22685
- const handler = chunkUV3IM6BG_cjs.contractHandlers.get(contract.type);
23154
+ const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
22686
23155
  if (!handler) {
22687
23156
  throw new Error(`no contract handler registered for type '${contract.type}'`);
22688
23157
  }
@@ -22712,7 +23181,7 @@ async function computeExitLayout(opts, feeRate) {
22712
23181
  if (pendingNodes.length > 0) {
22713
23182
  const txs = await resolver.getVirtualTxs(pendingNodes.map((n) => n.txid));
22714
23183
  for (const psbt of txs) {
22715
- psbts.set(chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
23184
+ psbts.set(chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
22716
23185
  }
22717
23186
  }
22718
23187
  const childVsize = Number(
@@ -22740,7 +23209,7 @@ async function computeExitLayout(opts, feeRate) {
22740
23209
  try {
22741
23210
  const resolved = await resolveUnilateralPath({
22742
23211
  vtxo,
22743
- scriptHex: base.hex.encode(chunk65CTZR2O_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
23212
+ scriptHex: base.hex.encode(chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
22744
23213
  contractRepository: wallet.contractRepository,
22745
23214
  walletDescriptor,
22746
23215
  currentTime: Date.now()
@@ -22759,7 +23228,7 @@ async function computeExitLayout(opts, feeRate) {
22759
23228
  });
22760
23229
  continue;
22761
23230
  }
22762
- const t = chunk65CTZR2O_cjs.sequenceToTimelock(resolved.selection.sequence);
23231
+ const t = chunkVVFCCNU2_cjs.sequenceToTimelock(resolved.selection.sequence);
22763
23232
  const delay = { type: t.type, value: Number(t.value) };
22764
23233
  infos.push({ outpoint, value: vtxo.value, sweepFee, path: resolved.label, delay });
22765
23234
  sweeps.push({ vtxo, resolved, sweepFee, delay });
@@ -22866,7 +23335,7 @@ var Executor = class {
22866
23335
  constructor(pkg, provider, opts) {
22867
23336
  this.pkg = pkg;
22868
23337
  this.provider = provider;
22869
- chunk65CTZR2O_cjs.assertTimerMs("pollIntervalMs", opts?.pollIntervalMs);
23338
+ chunkVVFCCNU2_cjs.assertTimerMs("pollIntervalMs", opts?.pollIntervalMs);
22870
23339
  this.pollIntervalMs = opts?.pollIntervalMs ?? 5e3;
22871
23340
  this.feeWallet = opts?.feeWallet;
22872
23341
  this.signal = opts?.signal;
@@ -23161,7 +23630,7 @@ async function prepare(opts) {
23161
23630
  txid: sweep.vtxo.txid,
23162
23631
  vout: sweep.vtxo.vout,
23163
23632
  value: sweep.vtxo.value,
23164
- pkScript: chunk65CTZR2O_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
23633
+ pkScript: chunkVVFCCNU2_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
23165
23634
  },
23166
23635
  path: sweep.resolved.selection,
23167
23636
  outputAddress: opts.sweepAddress,
@@ -23250,7 +23719,7 @@ async function prepare(opts) {
23250
23719
  if (newFee <= splitterFee) break;
23251
23720
  splitterFee = newFee;
23252
23721
  }
23253
- const splitter = new chunk65CTZR2O_cjs.Transaction({ version: 2 });
23722
+ const splitter = new chunkVVFCCNU2_cjs.Transaction({ version: 2 });
23254
23723
  for (const coin of selected.inputs) {
23255
23724
  splitter.addInput({
23256
23725
  txid: coin.txid,
@@ -23389,44 +23858,44 @@ var UnilateralExit = {
23389
23858
 
23390
23859
  // src/arkade/index.ts
23391
23860
  var arkade_exports = {};
23392
- chunk65CTZR2O_cjs.__export(arkade_exports, {
23393
- ARKADE_OP: () => chunkUV3IM6BG_cjs.ARKADE_OP,
23394
- ARKADE_OPCODES: () => chunkUV3IM6BG_cjs.ARKADE_OPCODES,
23395
- ARKADE_OPCODE_NAMES: () => chunkUV3IM6BG_cjs.ARKADE_OPCODE_NAMES,
23396
- ARKADE_OPCODE_VALUES: () => chunkUV3IM6BG_cjs.ARKADE_OPCODE_VALUES,
23397
- ARKADE_OPS: () => chunkUV3IM6BG_cjs.ARKADE_OPS,
23861
+ chunkVVFCCNU2_cjs.__export(arkade_exports, {
23862
+ ARKADE_OP: () => chunkCFOIHLON_cjs.ARKADE_OP,
23863
+ ARKADE_OPCODES: () => chunkCFOIHLON_cjs.ARKADE_OPCODES,
23864
+ ARKADE_OPCODE_NAMES: () => chunkCFOIHLON_cjs.ARKADE_OPCODE_NAMES,
23865
+ ARKADE_OPCODE_VALUES: () => chunkCFOIHLON_cjs.ARKADE_OPCODE_VALUES,
23866
+ ARKADE_OPS: () => chunkCFOIHLON_cjs.ARKADE_OPS,
23398
23867
  Arkade: () => Arkade,
23399
23868
  ArkadeContract: () => ArkadeContract,
23400
- ArkadeProgramScript: () => chunkUV3IM6BG_cjs.ArkadeProgramScript,
23401
- ArkadeScript: () => chunkUV3IM6BG_cjs.ArkadeScript,
23869
+ ArkadeProgramScript: () => chunkCFOIHLON_cjs.ArkadeProgramScript,
23870
+ ArkadeScript: () => chunkCFOIHLON_cjs.ArkadeScript,
23402
23871
  ArkadeTransactionBuilder: () => ArkadeTransactionBuilder,
23403
- BigNum: () => chunkUV3IM6BG_cjs.bignum_exports,
23872
+ BigNum: () => chunkCFOIHLON_cjs.bignum_exports,
23404
23873
  OP: () => btcSigner.OP,
23405
- OPCODE_NAMES: () => chunkUV3IM6BG_cjs.OPCODE_NAMES,
23406
- OPCODE_VALUES: () => chunkUV3IM6BG_cjs.OPCODE_VALUES,
23407
- SUPPORTED_PROGRAM_VERSION: () => chunkUV3IM6BG_cjs.SUPPORTED_PROGRAM_VERSION,
23874
+ OPCODE_NAMES: () => chunkCFOIHLON_cjs.OPCODE_NAMES,
23875
+ OPCODE_VALUES: () => chunkCFOIHLON_cjs.OPCODE_VALUES,
23876
+ SUPPORTED_PROGRAM_VERSION: () => chunkCFOIHLON_cjs.SUPPORTED_PROGRAM_VERSION,
23408
23877
  Script: () => btcSigner.Script,
23409
- arkadeScriptHash: () => chunkUV3IM6BG_cjs.arkadeScriptHash,
23410
- arkadeWitnessHash: () => chunkUV3IM6BG_cjs.arkadeWitnessHash,
23411
- asmToBytes: () => chunkUV3IM6BG_cjs.asmToBytes,
23412
- bytesToASM: () => chunkUV3IM6BG_cjs.bytesToASM,
23413
- computeArkadeScriptPublicKey: () => chunkUV3IM6BG_cjs.computeArkadeScriptPublicKey,
23878
+ arkadeScriptHash: () => chunkCFOIHLON_cjs.arkadeScriptHash,
23879
+ arkadeWitnessHash: () => chunkCFOIHLON_cjs.arkadeWitnessHash,
23880
+ asmToBytes: () => chunkCFOIHLON_cjs.asmToBytes,
23881
+ bytesToASM: () => chunkCFOIHLON_cjs.bytesToASM,
23882
+ computeArkadeScriptPublicKey: () => chunkCFOIHLON_cjs.computeArkadeScriptPublicKey,
23414
23883
  createArkadeBatchHandler: () => createArkadeBatchHandler,
23415
- deserializeArkadeContractParams: () => chunkUV3IM6BG_cjs.deserializeArkadeContractParams,
23416
- fromASM: () => chunkUV3IM6BG_cjs.fromASM,
23417
- getOpcodeName: () => chunkUV3IM6BG_cjs.getOpcodeName,
23418
- getOpcodeValue: () => chunkUV3IM6BG_cjs.getOpcodeValue,
23884
+ deserializeArkadeContractParams: () => chunkCFOIHLON_cjs.deserializeArkadeContractParams,
23885
+ fromASM: () => chunkCFOIHLON_cjs.fromASM,
23886
+ getOpcodeName: () => chunkCFOIHLON_cjs.getOpcodeName,
23887
+ getOpcodeValue: () => chunkCFOIHLON_cjs.getOpcodeValue,
23419
23888
  isContractArtifact: () => isContractArtifact,
23420
- parseArtifact: () => chunkUV3IM6BG_cjs.parseArtifact,
23889
+ parseArtifact: () => chunkCFOIHLON_cjs.parseArtifact,
23421
23890
  programFromArtifact: () => programFromArtifact,
23422
- resolveAsm: () => chunkUV3IM6BG_cjs.resolveAsm,
23423
- serializeArkadeContractParams: () => chunkUV3IM6BG_cjs.serializeArkadeContractParams,
23424
- stringifyArtifact: () => chunkUV3IM6BG_cjs.stringifyArtifact,
23425
- toASM: () => chunkUV3IM6BG_cjs.toASM,
23426
- validateProgram: () => chunkUV3IM6BG_cjs.validateProgram,
23427
- witnessRefToBytes: () => chunkUV3IM6BG_cjs.witnessRefToBytes
23891
+ resolveAsm: () => chunkCFOIHLON_cjs.resolveAsm,
23892
+ serializeArkadeContractParams: () => chunkCFOIHLON_cjs.serializeArkadeContractParams,
23893
+ stringifyArtifact: () => chunkCFOIHLON_cjs.stringifyArtifact,
23894
+ toASM: () => chunkCFOIHLON_cjs.toASM,
23895
+ validateProgram: () => chunkCFOIHLON_cjs.validateProgram,
23896
+ witnessRefToBytes: () => chunkCFOIHLON_cjs.witnessRefToBytes
23428
23897
  });
23429
- var isVtxoCoin = (input) => chunk65CTZR2O_cjs.isVirtualCoin(input);
23898
+ var isVtxoCoin = (input) => chunkVVFCCNU2_cjs.isVirtualCoin(input);
23430
23899
  function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message, session, arkProvider, emulator, network, recipients, batchExpiryPolicy) {
23431
23900
  let batchId;
23432
23901
  let sweepTapTreeRoot;
@@ -23447,23 +23916,23 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
23447
23916
  );
23448
23917
  await arkProvider.confirmRegistration(intentId);
23449
23918
  batchId = event.id;
23450
- const sweepTapscript = chunk65CTZR2O_cjs.CSVMultisigTapscript.encode({
23919
+ const sweepTapscript = chunkVVFCCNU2_cjs.CSVMultisigTapscript.encode({
23451
23920
  timelock,
23452
- pubkeys: [chunkUV3IM6BG_cjs.toXOnly(base.hex.decode(info.forfeitPubkey), "forfeit key")]
23921
+ pubkeys: [chunkCFOIHLON_cjs.toXOnly(base.hex.decode(info.forfeitPubkey), "forfeit key")]
23453
23922
  }).script;
23454
23923
  sweepTapTreeRoot = payment_js.tapLeafHash(sweepTapscript);
23455
23924
  return { skip: false };
23456
23925
  },
23457
23926
  onTreeSigningStarted: async (event, vtxoTree) => {
23458
23927
  const signerPubKey = await session.getPublicKey();
23459
- const xonlySignerPubKey = chunkUV3IM6BG_cjs.toXOnly(signerPubKey, "signer key");
23928
+ const xonlySignerPubKey = chunkCFOIHLON_cjs.toXOnly(signerPubKey, "signer key");
23460
23929
  const xOnlyPubkeys = event.cosignersPublicKeys.map(
23461
- (k) => base.hex.encode(chunkUV3IM6BG_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
23930
+ (k) => base.hex.encode(chunkCFOIHLON_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
23462
23931
  );
23463
23932
  if (!xOnlyPubkeys.includes(base.hex.encode(xonlySignerPubKey))) {
23464
23933
  return { skip: true };
23465
23934
  }
23466
- const commitmentTx = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(event.unsignedCommitmentTx));
23935
+ const commitmentTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(event.unsignedCommitmentTx));
23467
23936
  validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
23468
23937
  if (recipients && recipients.length > 0) {
23469
23938
  validateBatchRecipients(commitmentTx, vtxoTree.leaves(), recipients, network);
@@ -23501,7 +23970,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
23501
23970
  if (connectorTree) {
23502
23971
  validateConnectorsTxGraph(event.commitmentTx, connectorTree);
23503
23972
  }
23504
- let commitmentPsbt = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
23973
+ let commitmentPsbt = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
23505
23974
  assertFinalCommitmentMatchesValidated(
23506
23975
  commitmentPsbt,
23507
23976
  validatedCommitmentTxid,
@@ -23543,7 +24012,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
23543
24012
  boardingIndices.push(boardingIdx);
23544
24013
  continue;
23545
24014
  }
23546
- if (!chunk65CTZR2O_cjs.requiresForfeit(input) || isSubdust(input, info.dust)) {
24015
+ if (!chunkVVFCCNU2_cjs.requiresForfeit(input) || isSubdust(input, info.dust)) {
23547
24016
  continue;
23548
24017
  }
23549
24018
  if (connectorIndex >= connectorLeaves.length) {
@@ -23564,7 +24033,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
23564
24033
  index: input.vout,
23565
24034
  witnessUtxo: {
23566
24035
  amount: BigInt(input.value),
23567
- script: chunk65CTZR2O_cjs.VtxoScript.decode(input.tapTree).pkScript
24036
+ script: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
23568
24037
  },
23569
24038
  sighashType: btcSigner.SigHash.DEFAULT,
23570
24039
  tapLeafScript: [input.forfeitTapLeafScript]
@@ -23709,7 +24178,7 @@ function flatten(param, structs, stack = []) {
23709
24178
  function opcodeToken(token) {
23710
24179
  const base = token.slice(3);
23711
24180
  const name = base === "0" || /^([1-9]|1[0-6])$/.test(base) ? token : base;
23712
- if (!Object.hasOwn(chunkUV3IM6BG_cjs.ARKADE_OPS, name)) {
24181
+ if (!Object.hasOwn(chunkCFOIHLON_cjs.ARKADE_OPS, name)) {
23713
24182
  fail(`opcode '${token}' is not in this SDK's table`);
23714
24183
  }
23715
24184
  return name;
@@ -23756,7 +24225,7 @@ function providedWitness(witness) {
23756
24225
  }
23757
24226
  function csvTimelock(leafName, operand) {
23758
24227
  if (typeof operand === "string") return { type: "sequence", value: operand };
23759
- const timelock = chunk65CTZR2O_cjs.sequenceToCanonicalTimelock(operand);
24228
+ const timelock = chunkVVFCCNU2_cjs.sequenceToCanonicalTimelock(operand);
23760
24229
  if (!timelock) {
23761
24230
  fail(`leaf '${leafName}': CSV literal ${operand} is not a canonical BIP68 sequence`);
23762
24231
  }
@@ -23875,7 +24344,7 @@ function programFromArtifact(artifact) {
23875
24344
  const paramNames = /* @__PURE__ */ new Set();
23876
24345
  for (const param of params) claim(paramNames, param.name, "program parameter");
23877
24346
  return {
23878
- version: chunkUV3IM6BG_cjs.SUPPORTED_PROGRAM_VERSION,
24347
+ version: chunkCFOIHLON_cjs.SUPPORTED_PROGRAM_VERSION,
23879
24348
  name: artifact.contractName,
23880
24349
  params,
23881
24350
  functions
@@ -23916,16 +24385,16 @@ var Arkade = class _Arkade {
23916
24385
  /** Connect and resolve the server key, checkpoint closure and (if present) the co-signer key. */
23917
24386
  static async connect(opts) {
23918
24387
  const info = await opts.arkade.getInfo();
23919
- const serverKey = chunkUV3IM6BG_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
23920
- const checkpoint = chunk65CTZR2O_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
23921
- const network = opts.network ?? (Object.hasOwn(chunk65CTZR2O_cjs.networks, info.network) ? chunk65CTZR2O_cjs.getNetwork(info.network) : chunk65CTZR2O_cjs.DEFAULT_NETWORK);
24388
+ const serverKey = chunkCFOIHLON_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
24389
+ const checkpoint = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
24390
+ const network = opts.network ?? (Object.hasOwn(chunkVVFCCNU2_cjs.networks, info.network) ? chunkVVFCCNU2_cjs.getNetwork(info.network) : chunkVVFCCNU2_cjs.DEFAULT_NETWORK);
23922
24391
  let emulatorKey;
23923
24392
  if (opts.emulator) {
23924
- emulatorKey = base.hex.decode(chunk65CTZR2O_cjs.resolveEmulatorPubkey(network, opts.emulatorPubkey));
24393
+ emulatorKey = base.hex.decode(chunkVVFCCNU2_cjs.resolveEmulatorPubkey(network, opts.emulatorPubkey));
23925
24394
  }
23926
24395
  let userKey;
23927
24396
  if (opts.identity) {
23928
- userKey = chunkUV3IM6BG_cjs.toXOnly(await opts.identity.xOnlyPublicKey(), "identity key");
24397
+ userKey = chunkCFOIHLON_cjs.toXOnly(await opts.identity.xOnlyPublicKey(), "identity key");
23929
24398
  }
23930
24399
  return new _Arkade({
23931
24400
  arkProvider: opts.arkade,
@@ -23948,7 +24417,7 @@ var Arkade = class _Arkade {
23948
24417
  * explicit args win.
23949
24418
  */
23950
24419
  contract(program, args = {}) {
23951
- const declared = (program.params ?? []).map(chunkUV3IM6BG_cjs.inputName);
24420
+ const declared = (program.params ?? []).map(chunkCFOIHLON_cjs.inputName);
23952
24421
  if (declared.includes("server") && args.server === void 0) {
23953
24422
  args = { ...args, server: this.serverKey };
23954
24423
  }
@@ -23968,7 +24437,7 @@ var ArkadeContract = class _ArkadeContract {
23968
24437
  userKey: client.userKey,
23969
24438
  emulatorKey: client.emulatorKey
23970
24439
  };
23971
- this.vtxoScript = new chunkUV3IM6BG_cjs.ArkadeProgramScript(program, args, this.keys);
24440
+ this.vtxoScript = new chunkCFOIHLON_cjs.ArkadeProgramScript(program, args, this.keys);
23972
24441
  this.tapTree = this.vtxoScript.encode();
23973
24442
  this.compiled = this.vtxoScript.compiled;
23974
24443
  }
@@ -23993,7 +24462,7 @@ var ArkadeContract = class _ArkadeContract {
23993
24462
  `ArkadeContract.fromContract: expected contract type 'arkade', got '${contract.type}'`
23994
24463
  );
23995
24464
  }
23996
- const typed = chunkUV3IM6BG_cjs.deserializeArkadeContractParams(contract.params);
24465
+ const typed = chunkCFOIHLON_cjs.deserializeArkadeContractParams(contract.params);
23997
24466
  return new _ArkadeContract(client, typed.program, typed.args, {
23998
24467
  serverKey: typed.serverKey,
23999
24468
  userKey: typed.userKey,
@@ -24029,7 +24498,7 @@ var ArkadeContract = class _ArkadeContract {
24029
24498
  toContractParams() {
24030
24499
  return {
24031
24500
  type: "arkade",
24032
- params: chunkUV3IM6BG_cjs.serializeArkadeContractParams({
24501
+ params: chunkCFOIHLON_cjs.serializeArkadeContractParams({
24033
24502
  program: this.program,
24034
24503
  args: this.args,
24035
24504
  serverKey: this.keys.serverKey,
@@ -24069,17 +24538,17 @@ var ArkadeContract = class _ArkadeContract {
24069
24538
  const [registered] = await manager.getContracts({ script: scriptHex });
24070
24539
  if (registered) {
24071
24540
  const [withVtxos] = await manager.getContractsWithVtxos({ script: scriptHex });
24072
- return (withVtxos?.vtxos ?? []).filter((v) => !chunk65CTZR2O_cjs.isVtxoSpent(v) && !v.isUnrolled);
24541
+ return (withVtxos?.vtxos ?? []).filter((v) => !chunkVVFCCNU2_cjs.isVtxoSpent(v) && !v.isUnrolled);
24073
24542
  }
24074
24543
  }
24075
24544
  if (!this.client.indexer) {
24076
24545
  throw new Error("ArkadeContract.getUtxos: an indexer is required");
24077
24546
  }
24078
- const { vtxos } = await chunk65CTZR2O_cjs.getNormalizedVtxos(this.client.indexer, {
24547
+ const { vtxos } = await chunkVVFCCNU2_cjs.getNormalizedVtxos(this.client.indexer, {
24079
24548
  scripts: [scriptHex],
24080
24549
  spendableOnly: true
24081
24550
  });
24082
- return vtxos.filter((v) => !chunk65CTZR2O_cjs.isVtxoSpent(v) && !v.isUnrolled);
24551
+ return vtxos.filter((v) => !chunkVVFCCNU2_cjs.isVtxoSpent(v) && !v.isUnrolled);
24083
24552
  }
24084
24553
  /** Total spendable balance (requires an indexer). */
24085
24554
  async getBalance() {
@@ -24183,7 +24652,7 @@ var ArkadeTransactionBuilder = class {
24183
24652
  this.contract.client.checkpoint
24184
24653
  );
24185
24654
  if (coin.sourceTx) {
24186
- chunk65CTZR2O_cjs.setArkPsbtField(arkTx, 0, chunk65CTZR2O_cjs.PrevArkTxField, coin.sourceTx);
24655
+ chunkVVFCCNU2_cjs.setArkPsbtField(arkTx, 0, chunkVVFCCNU2_cjs.PrevArkTxField, coin.sourceTx);
24187
24656
  }
24188
24657
  if (this.fn.arkadeScript) {
24189
24658
  const indexer = this.contract.client.indexer;
@@ -24200,8 +24669,8 @@ var ArkadeTransactionBuilder = class {
24200
24669
  }
24201
24670
  const condition = (def.tapscript.witness ?? []).map((w) => this.witnessBytes(w));
24202
24671
  if (condition.length > 0) {
24203
- chunk65CTZR2O_cjs.setArkPsbtField(arkTx, 0, chunk65CTZR2O_cjs.ConditionWitness, condition);
24204
- chunk65CTZR2O_cjs.setArkPsbtField(checkpoints[0], 0, chunk65CTZR2O_cjs.ConditionWitness, condition);
24672
+ chunkVVFCCNU2_cjs.setArkPsbtField(arkTx, 0, chunkVVFCCNU2_cjs.ConditionWitness, condition);
24673
+ chunkVVFCCNU2_cjs.setArkPsbtField(checkpoints[0], 0, chunkVVFCCNU2_cjs.ConditionWitness, condition);
24205
24674
  }
24206
24675
  const packets = [];
24207
24676
  if (this.assetSpecs.length > 0) {
@@ -24231,22 +24700,9 @@ var ArkadeTransactionBuilder = class {
24231
24700
  if (!client.emulator) {
24232
24701
  throw new Error("covenant spends require an `emulator` on the Arkade client");
24233
24702
  }
24234
- const signedArk2 = await this.signArk(arkTx, userInputs);
24235
- const signedCps = userInputs.length > 0 ? await Promise.all(
24236
- checkpoints.map(
24237
- (c, i) => userInputs.includes(i) ? client.identity.sign(c, [0]) : c
24238
- )
24239
- ) : checkpoints;
24240
- const res2 = await client.emulator.submitTx(
24241
- base.base64.encode(signedArk2.toPSBT()),
24242
- signedCps.map((c) => base.base64.encode(c.toPSBT()))
24243
- );
24244
- const txid = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(res2.signedArkTx)).id;
24245
- return {
24246
- txid,
24247
- signedArkTx: res2.signedArkTx,
24248
- signedCheckpointTxs: res2.signedCheckpointTxs
24249
- };
24703
+ return submitViaEmulator(client.emulator, { arkTx, checkpoints }, client.identity, {
24704
+ inputIndexes: userInputs
24705
+ });
24250
24706
  }
24251
24707
  if (!client.identity) {
24252
24708
  throw new Error("a signing identity is required for non-covenant spends");
@@ -24306,23 +24762,23 @@ var ArkadeTransactionBuilder = class {
24306
24762
  }
24307
24763
  buildAssetPacket() {
24308
24764
  const groups = this.assetSpecs.map((s) => {
24309
- const id = typeof s.assetId === "string" ? chunkPAD5V653_cjs.AssetId.fromString(s.assetId) : chunkPAD5V653_cjs.AssetId.fromBytes(s.assetId);
24310
- return chunkPAD5V653_cjs.AssetGroup.create(
24765
+ const id = typeof s.assetId === "string" ? chunkFEBAG2K2_cjs.AssetId.fromString(s.assetId) : chunkFEBAG2K2_cjs.AssetId.fromBytes(s.assetId);
24766
+ return chunkFEBAG2K2_cjs.AssetGroup.create(
24311
24767
  id,
24312
24768
  null,
24313
- s.inputs.map((i) => chunkPAD5V653_cjs.AssetInput.create(i.vin, i.amount)),
24314
- s.outputs.map((o) => chunkPAD5V653_cjs.AssetOutput.create(o.vout, o.amount)),
24315
- (s.metadata ?? []).map((m) => chunkPAD5V653_cjs.Metadata.create(m.key, m.value))
24769
+ s.inputs.map((i) => chunkFEBAG2K2_cjs.AssetInput.create(i.vin, i.amount)),
24770
+ s.outputs.map((o) => chunkFEBAG2K2_cjs.AssetOutput.create(o.vout, o.amount)),
24771
+ (s.metadata ?? []).map((m) => chunkFEBAG2K2_cjs.Metadata.create(m.key, m.value))
24316
24772
  );
24317
24773
  });
24318
- return chunkPAD5V653_cjs.Packet.create(groups);
24774
+ return chunkFEBAG2K2_cjs.Packet.create(groups);
24319
24775
  }
24320
24776
  witnessBytes(ref) {
24321
- return chunkUV3IM6BG_cjs.witnessRefToBytes(ref, this.args, this.contract.args);
24777
+ return chunkCFOIHLON_cjs.witnessRefToBytes(ref, this.args, this.contract.args);
24322
24778
  }
24323
24779
  };
24324
24780
  function bindInputs(fn, callArgs) {
24325
- const names = (fn.def.inputs ?? []).map(chunkUV3IM6BG_cjs.inputName);
24781
+ const names = (fn.def.inputs ?? []).map(chunkCFOIHLON_cjs.inputName);
24326
24782
  if (callArgs.length !== names.length) {
24327
24783
  throw new Error(`${fn.name}: expected ${names.length} argument(s), got ${callArgs.length}`);
24328
24784
  }
@@ -24736,17 +25192,17 @@ var walletFeeSource = (wallet) => async () => (await wallet.arkProvider.getInfo(
24736
25192
  function offchainInputFees(vtxos, fees) {
24737
25193
  const estimator = new Estimator(fees?.intentFee ?? {});
24738
25194
  return vtxos.reduce(
24739
- (total, vtxo) => total + estimator.evalOffchainInput(chunk65CTZR2O_cjs.toOffchainInputFeeParams(vtxo)).satoshis,
25195
+ (total, vtxo) => total + estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo)).satoshis,
24740
25196
  0
24741
25197
  );
24742
25198
  }
24743
25199
  async function changeOutputFee(wallet, inputs, needed, fees) {
24744
25200
  const estimator = new Estimator(fees?.intentFee ?? {});
24745
25201
  const net = inputs.reduce(
24746
- (total, vtxo) => total + BigInt(vtxo.value) - BigInt(estimator.evalOffchainInput(chunk65CTZR2O_cjs.toOffchainInputFeeParams(vtxo)).satoshis),
25202
+ (total, vtxo) => total + BigInt(vtxo.value) - BigInt(estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo)).satoshis),
24747
25203
  0n
24748
25204
  );
24749
- const script = base.hex.encode(chunk65CTZR2O_cjs.ArkAddress.decode(await wallet.getAddress()).pkScript);
25205
+ const script = base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(await wallet.getAddress()).pkScript);
24750
25206
  return changeAfterOutputFee(
24751
25207
  net - needed,
24752
25208
  (amount) => BigInt(estimator.evalOffchainOutput({ amount, script }).satoshis)
@@ -24822,6 +25278,7 @@ exports.AmbiguousRouteError = AmbiguousRouteError;
24822
25278
  exports.ArkNote = ArkNote;
24823
25279
  exports.ArkadeCash = ArkadeCash;
24824
25280
  exports.ArkadeCashCreateError = ArkadeCashCreateError;
25281
+ exports.ArkadeCashOperatorMismatchError = ArkadeCashOperatorMismatchError;
24825
25282
  exports.AssetManager = AssetManager;
24826
25283
  exports.BIP21 = BIP21;
24827
25284
  exports.BIP21Error = BIP21Error;
@@ -24901,6 +25358,7 @@ exports.UnannotatableInputError = UnannotatableInputError;
24901
25358
  exports.UnilateralExit = UnilateralExit;
24902
25359
  exports.UnknownPacket = UnknownPacket;
24903
25360
  exports.VtxoManager = VtxoManager;
25361
+ exports.VtxoReservedError = VtxoReservedError;
24904
25362
  exports.Wallet = Wallet2;
24905
25363
  exports.WalletCannotAllocateAddressError = WalletCannotAllocateAddressError;
24906
25364
  exports.WalletCannotSignError = WalletCannotSignError;
@@ -25040,6 +25498,7 @@ exports.signAndSubmitOffchainTx = signAndSubmitOffchainTx;
25040
25498
  exports.signerSetFromInfo = signerSetFromInfo;
25041
25499
  exports.signingDescriptorIndex = signingDescriptorIndex;
25042
25500
  exports.strictSigningDescriptorIndex = strictSigningDescriptorIndex;
25501
+ exports.submitViaEmulator = submitViaEmulator;
25043
25502
  exports.toXOnlySignerHex = toXOnlySignerHex;
25044
25503
  exports.tryResolveSendAmount = tryResolveSendAmount;
25045
25504
  exports.utxoEntries = utxoEntries;
@@ -25051,5 +25510,5 @@ exports.waitForIncomingFunds = waitForIncomingFunds;
25051
25510
  exports.walletFeeSource = walletFeeSource;
25052
25511
  exports.warnAndFilterVtxosForScript = warnAndFilterVtxosForScript;
25053
25512
  exports.withPrevTxs = withPrevTxs;
25054
- //# sourceMappingURL=chunk-OIYVDV2N.cjs.map
25055
- //# sourceMappingURL=chunk-OIYVDV2N.cjs.map
25513
+ //# sourceMappingURL=chunk-B2YMUJD5.cjs.map
25514
+ //# sourceMappingURL=chunk-B2YMUJD5.cjs.map