@arkade-os/sdk 0.5.0-rc.21 → 0.5.0-rc.23

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 (72) hide show
  1. package/README.md +31 -0
  2. package/dist/adapters/expo.cjs +5 -5
  3. package/dist/adapters/expo.d.cts +2 -2
  4. package/dist/adapters/expo.d.ts +2 -2
  5. package/dist/adapters/expo.js +3 -3
  6. package/dist/{asyncStorageTaskQueue-x8ok3tJy.d.cts → asyncStorageTaskQueue-DUu3VwBE.d.cts} +2 -2
  7. package/dist/{asyncStorageTaskQueue-aL7K14e4.d.ts → asyncStorageTaskQueue-Dm71_6ID.d.ts} +2 -2
  8. package/dist/{chunk-LNJPVLIC.js → chunk-B4CZLBE6.js} +4 -4
  9. package/dist/{chunk-LNJPVLIC.js.map → chunk-B4CZLBE6.js.map} +1 -1
  10. package/dist/{chunk-EXFU6MTA.js → chunk-ENGV6VZF.js} +511 -89
  11. package/dist/chunk-ENGV6VZF.js.map +1 -0
  12. package/dist/{chunk-R5OFJ23O.cjs → chunk-H7W2KLN2.cjs} +990 -565
  13. package/dist/chunk-H7W2KLN2.cjs.map +1 -0
  14. package/dist/{chunk-VZMLADXQ.cjs → chunk-JETDFDWV.cjs} +10 -10
  15. package/dist/{chunk-VZMLADXQ.cjs.map → chunk-JETDFDWV.cjs.map} +1 -1
  16. package/dist/{chunk-5XBH5SAL.cjs → chunk-KR6FLFIH.cjs} +3 -3
  17. package/dist/{chunk-5XBH5SAL.cjs.map → chunk-KR6FLFIH.cjs.map} +1 -1
  18. package/dist/{chunk-GVF4OCTL.cjs → chunk-QLJXXVRO.cjs} +48 -48
  19. package/dist/{chunk-GVF4OCTL.cjs.map → chunk-QLJXXVRO.cjs.map} +1 -1
  20. package/dist/{chunk-JZAEFOE4.js → chunk-SPJA7XMU.js} +3 -3
  21. package/dist/{chunk-JZAEFOE4.js.map → chunk-SPJA7XMU.js.map} +1 -1
  22. package/dist/{chunk-CXHJGED6.js → chunk-UDQ3QE4C.js} +3 -3
  23. package/dist/{chunk-CXHJGED6.js.map → chunk-UDQ3QE4C.js.map} +1 -1
  24. package/dist/{chunk-S2WWOVFC.js → chunk-W2VYRZLB.js} +4 -4
  25. package/dist/{chunk-S2WWOVFC.js.map → chunk-W2VYRZLB.js.map} +1 -1
  26. package/dist/{chunk-4FDNOLBO.js → chunk-XZEQV5FE.js} +3 -3
  27. package/dist/{chunk-4FDNOLBO.js.map → chunk-XZEQV5FE.js.map} +1 -1
  28. package/dist/{chunk-Q7PC3NHX.cjs → chunk-YFHGGSII.cjs} +18 -18
  29. package/dist/{chunk-Q7PC3NHX.cjs.map → chunk-YFHGGSII.cjs.map} +1 -1
  30. package/dist/{chunk-HIZNPHB2.cjs → chunk-ZDLFQ7ZH.cjs} +15 -15
  31. package/dist/{chunk-HIZNPHB2.cjs.map → chunk-ZDLFQ7ZH.cjs.map} +1 -1
  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-BT5iON1T.d.ts → delegate-DATx5c2o.d.ts} +1 -1
  37. package/dist/{delegate-u6kXTtWY.d.cts → delegate-DRoyCz4n.d.cts} +1 -1
  38. package/dist/{index-CK5QbTmZ.d.ts → index-BKBoBSKX.d.cts} +83 -9
  39. package/dist/{index-CK5QbTmZ.d.cts → index-BKBoBSKX.d.ts} +83 -9
  40. package/dist/{index-D1D4cR-G.d.ts → index-BjDUwnH-.d.ts} +2 -2
  41. package/dist/{index-BCnhItOQ.d.cts → index-CLgF0km0.d.cts} +2 -2
  42. package/dist/index.cjs +321 -309
  43. package/dist/index.d.cts +78 -16
  44. package/dist/index.d.ts +78 -16
  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-BeYR6NpQ.d.ts → taskRunner-B78rNRXB.d.ts} +2 -2
  55. package/dist/{taskRunner-Csey3EYJ.d.cts → taskRunner-CoGRmz1U.d.cts} +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 +15 -15
  61. package/dist/wallet/expo/index.d.cts +4 -4
  62. package/dist/wallet/expo/index.d.ts +4 -4
  63. package/dist/wallet/expo/index.js +5 -5
  64. package/dist/{wallet-DzSLMxBZ.d.ts → wallet-CdUjdg15.d.cts} +23 -5
  65. package/dist/{wallet-DG3Qmbmt.d.cts → wallet-yKzfCUfY.d.ts} +23 -5
  66. package/dist/worker/expo/index.cjs +9 -9
  67. package/dist/worker/expo/index.d.cts +4 -4
  68. package/dist/worker/expo/index.d.ts +4 -4
  69. package/dist/worker/expo/index.js +5 -5
  70. package/package.json +1 -1
  71. package/dist/chunk-EXFU6MTA.js.map +0 -1
  72. package/dist/chunk-R5OFJ23O.cjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkQ7PC3NHX_cjs = require('./chunk-Q7PC3NHX.cjs');
4
- var chunkGVF4OCTL_cjs = require('./chunk-GVF4OCTL.cjs');
5
- var chunk5XBH5SAL_cjs = require('./chunk-5XBH5SAL.cjs');
3
+ var chunkYFHGGSII_cjs = require('./chunk-YFHGGSII.cjs');
4
+ var chunkQLJXXVRO_cjs = require('./chunk-QLJXXVRO.cjs');
5
+ var chunkKR6FLFIH_cjs = require('./chunk-KR6FLFIH.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 = chunk5XBH5SAL_cjs.getArkPsbtFields(tx.root, 0, chunk5XBH5SAL_cjs.CosignerPublicKey).map(
190
+ const cosigners = chunkKR6FLFIH_cjs.getArkPsbtFields(tx.root, 0, chunkKR6FLFIH_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 = chunk5XBH5SAL_cjs.getArkPsbtFields(g.root, 0, chunk5XBH5SAL_cjs.CosignerPublicKey).map((c) => c.key);
242
+ const cosigners = chunkKR6FLFIH_cjs.getArkPsbtFields(g.root, 0, chunkKR6FLFIH_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
- chunk5XBH5SAL_cjs.assertAllowedSighashTypes(txCpy, ALLOWED_SIGHASH);
325
+ chunkKR6FLFIH_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 = chunkGVF4OCTL_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
425
+ network = chunkQLJXXVRO_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 chunkGVF4OCTL_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
502
+ return chunkQLJXXVRO_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 = chunkGVF4OCTL_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
541
+ const network = chunkQLJXXVRO_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
- chunk5XBH5SAL_cjs.assertAllowedSighashTypes(txCpy, ALLOWED_SIGHASH2);
566
+ chunkKR6FLFIH_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 = chunkGVF4OCTL_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
618
+ const network = chunkQLJXXVRO_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 chunkGVF4OCTL_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
653
+ return chunkQLJXXVRO_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 chunkGVF4OCTL_cjs.deriveDescriptorLeafPubKey(this.descriptor);
796
+ return chunkQLJXXVRO_cjs.deriveDescriptorLeafPubKey(this.descriptor);
797
797
  }
798
798
  async compressedPublicKey() {
799
- return chunkGVF4OCTL_cjs.deriveDescriptorLeafCompressedPubKey(this.descriptor);
799
+ return chunkQLJXXVRO_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 = chunkGVF4OCTL_cjs.normalizeToDescriptor(descriptor);
860
- const pubKey = chunkGVF4OCTL_cjs.extractPubKey(normalized);
859
+ const normalized = chunkQLJXXVRO_cjs.normalizeToDescriptor(descriptor);
860
+ const pubKey = chunkQLJXXVRO_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 chunkGVF4OCTL_cjs.extractPubKey(chunkGVF4OCTL_cjs.normalizeToDescriptor(descriptor)).toLowerCase();
1197
+ return chunkQLJXXVRO_cjs.extractPubKey(chunkQLJXXVRO_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 && chunkGVF4OCTL_cjs.parseHDDescriptor(descriptor)) {
1288
+ if (owner && chunkQLJXXVRO_cjs.parseHDDescriptor(descriptor)) {
1289
1289
  return new DescriptorIdentity({ descriptor, signer: owner, base: identity });
1290
1290
  }
1291
1291
  let key;
1292
1292
  try {
1293
- key = chunkGVF4OCTL_cjs.deriveDescriptorLeafPubKey(descriptor);
1293
+ key = chunkQLJXXVRO_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 chunkGVF4OCTL_cjs.parseHDDescriptor(descriptor) !== null;
1346
+ return chunkQLJXXVRO_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 chunkGVF4OCTL_cjs.identityDescriptor(wallet.identity);
1350
+ return allocated ?? await chunkQLJXXVRO_cjs.identityDescriptor(wallet.identity);
1351
1351
  }
1352
1352
  async function provisionRefundKey(wallet) {
1353
- const descriptor = await chunkGVF4OCTL_cjs.identityDescriptor(wallet.identity);
1353
+ const descriptor = await chunkQLJXXVRO_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 } = chunk5XBH5SAL_cjs.ArkAddress.decode(address);
1363
+ const { pkScript } = chunkKR6FLFIH_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 = chunkGVF4OCTL_cjs.deriveDescriptorLeafPubKey(descriptor);
1409
+ expected = chunkQLJXXVRO_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
- chunk5XBH5SAL_cjs.assertTimerMs("activationTimeoutMs", o.activationTimeoutMs);
1491
+ chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(url, {
1614
+ const response = await chunkKR6FLFIH_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: chunk5XBH5SAL_cjs.Intent.encodeMessage(intent.message),
1621
+ message: chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.rateGate.runHttp(url, () => chunk5XBH5SAL_cjs.baseFetch(url));
1640
+ const response = await chunkKR6FLFIH_cjs.rateGate.runHttp(url, () => chunkKR6FLFIH_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(chunk5XBH5SAL_cjs.ArkAddress.decode(address).pkScript);
1696
+ return base.hex.encode(chunkKR6FLFIH_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) => chunk5XBH5SAL_cjs.isVtxoSpent(copy.vtxo));
1758
+ const spent = copies.filter((copy) => chunkKR6FLFIH_cjs.isVtxoSpent(copy.vtxo));
1759
1759
  return rows.filter(
1760
- (row) => !chunk5XBH5SAL_cjs.isVtxoSpent(row.vtxo) && !spent.some(
1760
+ (row) => !chunkKR6FLFIH_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[chunk5XBH5SAL_cjs.DEFAULT_NETWORK_NAME], opts) {
1843
+ constructor(baseUrl = ESPLORA_URL[chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
1858
+ const response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(url);
1867
+ let response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(url);
1872
+ response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
1909
+ const response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
1917
+ const response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/address/${address}`);
1926
+ const response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/hex`);
1933
+ const response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
1941
+ const txresponse = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
1949
+ const response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/blocks`);
2223
+ let tipBlocks = await chunkKR6FLFIH_cjs.baseFetch(`${this.baseUrl}/blocks`);
2224
2224
  if (tipBlocks.status === 404) {
2225
- tipBlocks = await chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/v1/blocks`);
2225
+ tipBlocks = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
2246
+ const response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.baseFetch(`${this.baseUrl}/tx`, {
2262
+ const response = await chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
2434
+ const child = new chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.Transaction({
2483
+ const tx = new chunkKR6FLFIH_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 = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(settlementTxB64));
2510
+ const settlementTx = chunkKR6FLFIH_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 = chunk5XBH5SAL_cjs.getArkPsbtFields(child.root, 0, chunk5XBH5SAL_cjs.CosignerPublicKey);
2559
+ const cosigners = chunkKR6FLFIH_cjs.getArkPsbtFields(child.root, 0, chunkKR6FLFIH_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 chunkQ7PC3NHX_cjs.BufferReader(data);
2617
+ const reader = new chunkYFHGGSII_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 chunkQ7PC3NHX_cjs.BufferWriter();
2635
+ const writer = new chunkYFHGGSII_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 chunkQ7PC3NHX_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
2722
+ const reader = new chunkYFHGGSII_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 chunkQ7PC3NHX_cjs.Packet) ?? null;
2795
+ return this.packets.find((p) => p instanceof chunkYFHGGSII_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 chunkQ7PC3NHX_cjs.Packet.PACKET_TYPE:
2820
- return chunkQ7PC3NHX_cjs.Packet.fromBytes(data);
2819
+ case chunkYFHGGSII_cjs.Packet.PACKET_TYPE:
2820
+ return chunkYFHGGSII_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 chunk5XBH5SAL_cjs.ServerResponseMismatchError(`offchain send output not found: ${address}`);
2868
- var ErrInvalidAssetOutputAmount = (got, want, assetId) => new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
2867
+ var ErrOffchainOutputNotFound = (address) => new chunkKR6FLFIH_cjs.ServerResponseMismatchError(`offchain send output not found: ${address}`);
2868
+ var ErrInvalidAssetOutputAmount = (got, want, assetId) => new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
2869
2869
  `invalid asset output amount for ${assetId}: got ${got}, want ${want}`
2870
2870
  );
2871
- var ErrAssetGroupNotFound = (assetId) => new chunk5XBH5SAL_cjs.ServerResponseMismatchError(`asset group not found in batch leaf: ${assetId}`);
2872
- var ErrAssetOutputNotFound = (assetId, outputIndex) => new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
2871
+ var ErrAssetGroupNotFound = (assetId) => new chunkKR6FLFIH_cjs.ServerResponseMismatchError(`asset group not found in batch leaf: ${assetId}`);
2872
+ var ErrAssetOutputNotFound = (assetId, outputIndex) => new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
2873
2873
  `asset output not found in asset group ${assetId} at index ${outputIndex}`
2874
2874
  );
2875
- var ErrOnchainOutputNotFound = (address) => new chunk5XBH5SAL_cjs.ServerResponseMismatchError(`onchain output not found: ${address}`);
2876
- var ErrUnvalidatedOffchainOutput = (address) => new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
2875
+ var ErrOnchainOutputNotFound = (address) => new chunkKR6FLFIH_cjs.ServerResponseMismatchError(`onchain output not found: ${address}`);
2876
+ var ErrUnvalidatedOffchainOutput = (address) => new chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.ServerResponseMismatchError(
2879
+ var ErrIntentOutputNotFound = (index, kind) => new chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.ServerResponseMismatchError(
2882
+ var ErrUnvalidatedIntentOutput = (index) => new chunkKR6FLFIH_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 chunk5XBH5SAL_cjs.ServerResponseMismatchError(
2891
+ throw new chunkKR6FLFIH_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 = chunk5XBH5SAL_cjs.ArkAddress.decode(recipient.address);
2901
+ arkAddress = chunkKR6FLFIH_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
- chunk5XBH5SAL_cjs.ArkAddress.decode(recipient.address);
2913
+ chunkKR6FLFIH_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 = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(signedProof));
2922
+ const proof = chunkKR6FLFIH_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(chunkQ7PC3NHX_cjs.AssetId.fromString(a.assetId).txid) === tx.key.arkTxid;
3214
+ return base.hex.encode(chunkYFHGGSII_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
- chunkQ7PC3NHX_cjs.AssetInput.create(inputIndex, asset.amount)
3291
+ chunkYFHGGSII_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
- chunkQ7PC3NHX_cjs.AssetOutput.create(outputIndex, asset.amount)
3303
+ chunkYFHGGSII_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
- chunkQ7PC3NHX_cjs.AssetOutput.create(outputIndex, asset.amount)
3314
+ chunkYFHGGSII_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 = chunkQ7PC3NHX_cjs.AssetId.fromString(assetIdStr);
3324
- const group = chunkQ7PC3NHX_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
3323
+ const assetId = chunkYFHGGSII_cjs.AssetId.fromString(assetIdStr);
3324
+ const group = chunkYFHGGSII_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
3325
3325
  groups.push(group);
3326
3326
  }
3327
- return chunkQ7PC3NHX_cjs.Packet.create(groups);
3327
+ return chunkYFHGGSII_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));
@@ -3359,9 +3359,56 @@ function selectedCoinsToAssetInputs(selectedCoins) {
3359
3359
  }
3360
3360
  return assetInputs;
3361
3361
  }
3362
+
3363
+ // src/wallet/sendDeadline.ts
3364
+ var SendDeadlineExceededError = class extends Error {
3365
+ constructor(validUntil) {
3366
+ super(`Send deadline ${validUntil} expired before provider submission`);
3367
+ this.name = "SendDeadlineExceededError";
3368
+ }
3369
+ };
3370
+ function captureSendDeadline(value, required = false) {
3371
+ if (value === void 0 && !required) return void 0;
3372
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0) {
3373
+ throw new TypeError("validUntil must be a positive safe integer UNIX timestamp in seconds");
3374
+ }
3375
+ return value;
3376
+ }
3377
+ function assertSendDeadline(validUntil) {
3378
+ if (validUntil !== void 0 && Date.now() / 1e3 >= validUntil) {
3379
+ throw new SendDeadlineExceededError(validUntil);
3380
+ }
3381
+ }
3382
+
3383
+ // src/wallet/sendInputExpiry.ts
3384
+ function captureInputExpiryFloor(value, required = false) {
3385
+ if (value === void 0 && !required) return void 0;
3386
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
3387
+ throw new TypeError(
3388
+ "inputExpiryFloor must specify a time or height and positive bigint value"
3389
+ );
3390
+ }
3391
+ const { kind, value: floor } = value;
3392
+ if (kind !== "time" && kind !== "height" || typeof floor !== "bigint" || floor <= 0n) {
3393
+ throw new TypeError(
3394
+ "inputExpiryFloor must specify a time or height and positive bigint value"
3395
+ );
3396
+ }
3397
+ return Object.freeze({ kind, value: floor });
3398
+ }
3399
+ function meetsInputExpiryFloor(coin, floor) {
3400
+ if (coin.expiresAt === void 0 === (coin.expiresAtHeight === void 0)) return false;
3401
+ if (floor.kind === "height") {
3402
+ const height = coin.expiresAtHeight;
3403
+ return typeof height === "number" && Number.isSafeInteger(height) && height > 0 && BigInt(height) >= floor.value;
3404
+ }
3405
+ if (!(coin.expiresAt instanceof Date)) return false;
3406
+ const milliseconds = coin.expiresAt.getTime();
3407
+ return Number.isSafeInteger(milliseconds) && milliseconds > 0 && BigInt(milliseconds) >= floor.value * 1000n;
3408
+ }
3362
3409
  function toXOnlySignerHex(pubkeyHex) {
3363
3410
  const bytes = base.hex.decode(pubkeyHex);
3364
- if (bytes.length === 32 || bytes.length === 33) return base.hex.encode(chunkGVF4OCTL_cjs.toXOnly(bytes, "signer key"));
3411
+ if (bytes.length === 32 || bytes.length === 33) return base.hex.encode(chunkQLJXXVRO_cjs.toXOnly(bytes, "signer key"));
3365
3412
  throw new Error(`invalid signer pubkey length: expected 32 or 33 bytes, got ${bytes.length}`);
3366
3413
  }
3367
3414
  function signerSetFromInfo(info) {
@@ -3408,13 +3455,13 @@ var toTimelock = (value) => ({
3408
3455
  var toSeconds = (t) => t.type === "seconds" ? t.value : t.value * NOMINAL_BLOCK_SECONDS;
3409
3456
  function assertTimelockInPolicy(timelock, policy, label, overrideOption) {
3410
3457
  if (policy.requireSeconds && timelock.type === "blocks") {
3411
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3458
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3412
3459
  `${label} rejected: block-typed timelocks are not accepted (got ${timelock.value})`
3413
3460
  );
3414
3461
  }
3415
3462
  const seconds = toSeconds(timelock);
3416
3463
  if (seconds < policy.minSeconds) {
3417
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3464
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3418
3465
  `${label} rejected: ${timelock.value} ${timelock.type} is below the ${policy.minSeconds}s floor; pass ${overrideOption}: ${seconds}n to Wallet.create to lower it`
3419
3466
  );
3420
3467
  }
@@ -3435,7 +3482,7 @@ function resolveBatchExpiryPolicy(network, overrides) {
3435
3482
  }
3436
3483
  function assertValidBatchExpiry(batchExpiry, policy) {
3437
3484
  if (policy.advertisedVtxoTreeExpiry !== void 0 && batchExpiry !== policy.advertisedVtxoTreeExpiry) {
3438
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3485
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3439
3486
  `batch expiry rejected: ${batchExpiry} does not match the advertised vtxoTreeExpiry ${policy.advertisedVtxoTreeExpiry}`
3440
3487
  );
3441
3488
  }
@@ -3465,21 +3512,21 @@ function resolveCheckpointExitDelayPolicy(network, overrides) {
3465
3512
  function assertValidServerUnrollScript(checkpointTapscript, policy) {
3466
3513
  let script;
3467
3514
  try {
3468
- script = chunk5XBH5SAL_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
3515
+ script = chunkKR6FLFIH_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
3469
3516
  } catch (e) {
3470
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3517
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3471
3518
  `checkpoint exit delay rejected: invalid checkpointTapscript from server (${e instanceof Error ? e.message : String(e)})`
3472
3519
  );
3473
3520
  }
3474
3521
  if (policy.advertisedForfeitPubkey !== void 0) {
3475
3522
  const { pubkeys } = script.params;
3476
3523
  if (pubkeys.length !== 1) {
3477
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3524
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3478
3525
  `checkpoint exit delay rejected: checkpointTapscript must commit to exactly one pubkey, got ${pubkeys.length} [${pubkeys.map(base.hex.encode).join(", ")}]`
3479
3526
  );
3480
3527
  }
3481
3528
  if (!utils_js.equalBytes(pubkeys[0], policy.advertisedForfeitPubkey)) {
3482
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3529
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3483
3530
  `checkpoint exit delay rejected: checkpointTapscript pubkey ${base.hex.encode(pubkeys[0])} does not match the advertised forfeitPubkey ${base.hex.encode(policy.advertisedForfeitPubkey)}`
3484
3531
  );
3485
3532
  }
@@ -3523,8 +3570,8 @@ function buildOffchainTx(inputs, outputs, serverUnrollScript) {
3523
3570
  function buildVirtualTx(inputs, outputs) {
3524
3571
  let lockTime = 0n;
3525
3572
  for (const input of inputs) {
3526
- const tapscript = chunk5XBH5SAL_cjs.decodeTapscript(chunk5XBH5SAL_cjs.scriptFromTapLeafScript(input.tapLeafScript));
3527
- if (chunk5XBH5SAL_cjs.CLTVMultisigTapscript.is(tapscript)) {
3573
+ const tapscript = chunkKR6FLFIH_cjs.decodeTapscript(chunkKR6FLFIH_cjs.scriptFromTapLeafScript(input.tapLeafScript));
3574
+ if (chunkKR6FLFIH_cjs.CLTVMultisigTapscript.is(tapscript)) {
3528
3575
  if (lockTime !== 0n) {
3529
3576
  if (isSeconds(lockTime) !== isSeconds(tapscript.params.absoluteTimelock)) {
3530
3577
  throw new Error("cannot mix seconds and blocks locktime");
@@ -3535,7 +3582,7 @@ function buildVirtualTx(inputs, outputs) {
3535
3582
  }
3536
3583
  }
3537
3584
  }
3538
- const tx = new chunk5XBH5SAL_cjs.Transaction({
3585
+ const tx = new chunkKR6FLFIH_cjs.Transaction({
3539
3586
  version: 3,
3540
3587
  lockTime: Number(lockTime)
3541
3588
  });
@@ -3545,12 +3592,12 @@ function buildVirtualTx(inputs, outputs) {
3545
3592
  index: input.vout,
3546
3593
  sequence: lockTime ? btcSigner.DEFAULT_SEQUENCE - 1 : void 0,
3547
3594
  witnessUtxo: {
3548
- script: chunk5XBH5SAL_cjs.VtxoScript.decode(input.tapTree).pkScript,
3595
+ script: chunkKR6FLFIH_cjs.VtxoScript.decode(input.tapTree).pkScript,
3549
3596
  amount: BigInt(input.value)
3550
3597
  },
3551
3598
  tapLeafScript: [input.tapLeafScript]
3552
3599
  });
3553
- chunk5XBH5SAL_cjs.setArkPsbtField(tx, i, chunk5XBH5SAL_cjs.VtxoTaprootTree, input.tapTree);
3600
+ chunkKR6FLFIH_cjs.setArkPsbtField(tx, i, chunkKR6FLFIH_cjs.VtxoTaprootTree, input.tapTree);
3554
3601
  }
3555
3602
  for (const output of outputs) {
3556
3603
  tx.addOutput(output);
@@ -3561,8 +3608,8 @@ function buildVirtualTx(inputs, outputs) {
3561
3608
  return tx;
3562
3609
  }
3563
3610
  function buildCheckpointTx(vtxo, serverUnrollScript) {
3564
- const collaborativeClosure = chunk5XBH5SAL_cjs.decodeTapscript(chunk5XBH5SAL_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
3565
- const checkpointVtxoScript = new chunk5XBH5SAL_cjs.VtxoScript([
3611
+ const collaborativeClosure = chunkKR6FLFIH_cjs.decodeTapscript(chunkKR6FLFIH_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
3612
+ const checkpointVtxoScript = new chunkKR6FLFIH_cjs.VtxoScript([
3566
3613
  serverUnrollScript.script,
3567
3614
  collaborativeClosure.script
3568
3615
  ]);
@@ -3638,7 +3685,7 @@ function verifyTapscriptSignatures(tx, inputIndex, requiredSigners, excludePubke
3638
3685
  const sighashType = signature.length === 65 ? signature[64] : btcSigner.SigHash.DEFAULT;
3639
3686
  const sig = signature.subarray(0, 64);
3640
3687
  if (!allowedSighashTypes.includes(sighashType)) {
3641
- const sighashName = chunk5XBH5SAL_cjs.formatSighash(sighashType);
3688
+ const sighashName = chunkKR6FLFIH_cjs.formatSighash(sighashType);
3642
3689
  throw new Error(
3643
3690
  `Unallowed sighash type ${sighashName} for input ${inputIndex}, pubkey ${pubKeyHex}.`
3644
3691
  );
@@ -3712,7 +3759,7 @@ function combineTapscriptSigs(signedTx, originalTx) {
3712
3759
  }
3713
3760
  function isValidArkAddress(address) {
3714
3761
  try {
3715
- chunk5XBH5SAL_cjs.ArkAddress.decode(address);
3762
+ chunkKR6FLFIH_cjs.ArkAddress.decode(address);
3716
3763
  return true;
3717
3764
  } catch (e) {
3718
3765
  return false;
@@ -3720,16 +3767,16 @@ function isValidArkAddress(address) {
3720
3767
  }
3721
3768
  function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, context) {
3722
3769
  if (serverCheckpointTxs.length !== expectedCheckpoints.length) {
3723
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3770
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3724
3771
  `${context} returned ${serverCheckpointTxs.length} checkpoints, expected ${expectedCheckpoints.length}`
3725
3772
  );
3726
3773
  }
3727
3774
  const byTxid = new Map(expectedCheckpoints.map((c) => [c.id, c]));
3728
3775
  return serverCheckpointTxs.map((encoded, index) => {
3729
- const server = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
3776
+ const server = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
3730
3777
  const local = byTxid.get(server.id);
3731
3778
  if (!local) {
3732
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3779
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3733
3780
  `${context} checkpoint ${index} txid ${server.id} does not match any submitted checkpoint`
3734
3781
  );
3735
3782
  }
@@ -3739,14 +3786,14 @@ function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, contex
3739
3786
  }
3740
3787
  function assertSubmittedArkTxid(response, signedArkTx, context) {
3741
3788
  if (response.arkTxid !== signedArkTx.id) {
3742
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3789
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3743
3790
  `${context} returned ark txid ${response.arkTxid}, expected ${signedArkTx.id}`
3744
3791
  );
3745
3792
  }
3746
3793
  if (response.finalArkTx === void 0) return;
3747
- const finalTxid = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx)).id;
3794
+ const finalTxid = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx)).id;
3748
3795
  if (finalTxid !== signedArkTx.id) {
3749
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3796
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3750
3797
  `${context} returned final ark tx ${finalTxid}, expected ${signedArkTx.id}`
3751
3798
  );
3752
3799
  }
@@ -3758,20 +3805,20 @@ function assertServerSignedLeaf(serverTx, localTx, inputIndex, serverPubkeys, co
3758
3805
  `${context}: input ${inputIndex} carries no spend leaf to verify the server signature against`
3759
3806
  );
3760
3807
  }
3761
- const script = chunk5XBH5SAL_cjs.scriptFromTapLeafScript(leaf);
3808
+ const script = chunkKR6FLFIH_cjs.scriptFromTapLeafScript(leaf);
3762
3809
  let leafPubkeys;
3763
3810
  try {
3764
- leafPubkeys = chunk5XBH5SAL_cjs.decodeTapscript(script).params.pubkeys.map(
3765
- (key) => base.hex.encode(chunkGVF4OCTL_cjs.toXOnly(key, "leaf key"))
3811
+ leafPubkeys = chunkKR6FLFIH_cjs.decodeTapscript(script).params.pubkeys.map(
3812
+ (key) => base.hex.encode(chunkQLJXXVRO_cjs.toXOnly(key, "leaf key"))
3766
3813
  );
3767
3814
  } catch (error) {
3768
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3815
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3769
3816
  `${context}: input ${inputIndex} spend leaf cannot be decoded (${error instanceof Error ? error.message : String(error)})`
3770
3817
  );
3771
3818
  }
3772
3819
  const signer = leafPubkeys.find((key) => serverPubkeys.has(key));
3773
3820
  if (!signer) {
3774
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3821
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3775
3822
  `${context}: input ${inputIndex} spend leaf names no signer key the server advertises`
3776
3823
  );
3777
3824
  }
@@ -3785,7 +3832,7 @@ function assertServerSignedLeaf(serverTx, localTx, inputIndex, serverPubkeys, co
3785
3832
  payment_js.tapLeafHash(script)
3786
3833
  );
3787
3834
  } catch (error) {
3788
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3835
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3789
3836
  `${context}: input ${inputIndex} is not signed by the server on the leaf being spent (${error instanceof Error ? error.message : String(error)})`
3790
3837
  );
3791
3838
  }
@@ -3794,20 +3841,20 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
3794
3841
  const byOutpoint = new Map(inputs.map((input) => [`${input.txid}:${input.vout}`, input]));
3795
3842
  for (const [index, checkpoint] of checkpoints.entries()) {
3796
3843
  if (checkpoint.inputsLength !== 1) {
3797
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3844
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3798
3845
  `${context}: checkpoint ${index} spends ${checkpoint.inputsLength} inputs, expected 1`
3799
3846
  );
3800
3847
  }
3801
3848
  const spent = checkpoint.getInput(0);
3802
3849
  if (!spent.txid || spent.index === void 0) {
3803
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3850
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3804
3851
  `${context}: checkpoint ${index} has no input outpoint`
3805
3852
  );
3806
3853
  }
3807
3854
  const outpoint = `${base.hex.encode(spent.txid)}:${spent.index}`;
3808
3855
  const input = byOutpoint.get(outpoint);
3809
3856
  if (!input) {
3810
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3857
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3811
3858
  `${context}: checkpoint ${index} spends ${outpoint}, which is not one of the requested virtual outputs`
3812
3859
  );
3813
3860
  }
@@ -3815,7 +3862,7 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
3815
3862
  (unroll) => buildCheckpointTx(input, unroll).tx.id === checkpoint.id
3816
3863
  );
3817
3864
  if (!rebuilt) {
3818
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3865
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3819
3866
  `${context}: checkpoint ${index} txid ${checkpoint.id} differs from the checkpoint built locally for ${outpoint}`
3820
3867
  );
3821
3868
  }
@@ -3841,9 +3888,9 @@ async function submitOffchainTx(provider, offchainTx, signer, hooks, options) {
3841
3888
  const matched = matchServerCheckpoints(signedCheckpointTxs, offchainTx.checkpoints, "submitTx");
3842
3889
  matched.forEach(({ server }, index) => {
3843
3890
  try {
3844
- chunk5XBH5SAL_cjs.assertAllowedSighashTypes(server);
3891
+ chunkKR6FLFIH_cjs.assertAllowedSighashTypes(server);
3845
3892
  } catch (error) {
3846
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3893
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3847
3894
  `submitTx checkpoint ${index}: ${error instanceof Error ? error.message : String(error)}`
3848
3895
  );
3849
3896
  }
@@ -3851,14 +3898,14 @@ async function submitOffchainTx(provider, offchainTx, signer, hooks, options) {
3851
3898
  const verify = options?.verifyServerSignatures;
3852
3899
  if (verify) {
3853
3900
  if (response.finalArkTx === void 0) {
3854
- throw new chunk5XBH5SAL_cjs.ServerResponseMismatchError(
3901
+ throw new chunkKR6FLFIH_cjs.ServerResponseMismatchError(
3855
3902
  "submitTx: server returned no final ark tx to verify its signatures against"
3856
3903
  );
3857
3904
  }
3858
- const finalArkTx = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx));
3905
+ const finalArkTx = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx));
3859
3906
  const serverPubkeys = new Set(
3860
3907
  [verify.serverPubkey, ...verify.deprecatedServerPubkeys ?? []].map(
3861
- (key) => base.hex.encode(chunkGVF4OCTL_cjs.toXOnly(key, "server key"))
3908
+ (key) => base.hex.encode(chunkQLJXXVRO_cjs.toXOnly(key, "server key"))
3862
3909
  )
3863
3910
  );
3864
3911
  for (let i = 0; i < offchainTx.arkTx.inputsLength; i++) {
@@ -3910,12 +3957,12 @@ function claimWithPreimageIdentity(identity, preimage) {
3910
3957
  return {
3911
3958
  ...identity,
3912
3959
  sign: async (tx, inputIndexes) => {
3913
- const signed = chunk5XBH5SAL_cjs.Transaction.fromPSBT(
3960
+ const signed = chunkKR6FLFIH_cjs.Transaction.fromPSBT(
3914
3961
  (await identity.sign(tx.clone(), inputIndexes)).toPSBT()
3915
3962
  );
3916
3963
  const indexes = inputIndexes ?? Array.from({ length: signed.inputsLength }, (_, i) => i);
3917
3964
  for (const index of indexes) {
3918
- chunk5XBH5SAL_cjs.setArkPsbtField(signed, index, chunk5XBH5SAL_cjs.ConditionWitness, [preimage]);
3965
+ chunkKR6FLFIH_cjs.setArkPsbtField(signed, index, chunkKR6FLFIH_cjs.ConditionWitness, [preimage]);
3919
3966
  }
3920
3967
  return signed;
3921
3968
  }
@@ -4098,7 +4145,7 @@ function extendCoinWithTapscript(boardingTapscript, utxo) {
4098
4145
  };
4099
4146
  }
4100
4147
  function deriveContractTapscripts(contract) {
4101
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(contract.type);
4148
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(contract.type);
4102
4149
  if (!handler) {
4103
4150
  throw new Error(`No handler for contract type '${contract.type}'`);
4104
4151
  }
@@ -4189,7 +4236,7 @@ function assertRecipientArkadeAddress(encoded, address, context) {
4189
4236
  function assertTapTreeDerivesAddress(encoded, tapTree, address) {
4190
4237
  let derived;
4191
4238
  try {
4192
- derived = chunk5XBH5SAL_cjs.VtxoScript.decode(tapTree).pkScript;
4239
+ derived = chunkKR6FLFIH_cjs.VtxoScript.decode(tapTree).pkScript;
4193
4240
  } catch (e) {
4194
4241
  throw new Error(
4195
4242
  `Invalid tapTree for ${encoded}: ${e instanceof Error ? e.message : String(e)}`
@@ -4206,7 +4253,7 @@ function validateRecipients(recipients, dustAmount, context) {
4206
4253
  for (const recipient of recipients) {
4207
4254
  let address;
4208
4255
  try {
4209
- address = chunk5XBH5SAL_cjs.ArkAddress.decode(recipient.address);
4256
+ address = chunkKR6FLFIH_cjs.ArkAddress.decode(recipient.address);
4210
4257
  } catch (e) {
4211
4258
  throw new Error(`Invalid Arkade address: ${recipient.address}`);
4212
4259
  }
@@ -4231,7 +4278,7 @@ function validateRecipients(recipients, dustAmount, context) {
4231
4278
 
4232
4279
  // src/contracts/spendability.ts
4233
4280
  function isContractGenericallySpendable(contract) {
4234
- return chunkGVF4OCTL_cjs.contractHandlers.get(contract.type)?.isGenericallySpendable?.(contract) === true;
4281
+ return chunkQLJXXVRO_cjs.contractHandlers.get(contract.type)?.isGenericallySpendable?.(contract) === true;
4235
4282
  }
4236
4283
  function gatedContracts(contracts) {
4237
4284
  const gated = /* @__PURE__ */ new Map();
@@ -4253,7 +4300,7 @@ function gateExclusion(gated) {
4253
4300
  return (vtxo) => {
4254
4301
  const type = gatedTypeOf(vtxo, gated);
4255
4302
  if (type === void 0) return void 0;
4256
- if (!chunkGVF4OCTL_cjs.contractHandlers.has(type)) {
4303
+ if (!chunkQLJXXVRO_cjs.contractHandlers.has(type)) {
4257
4304
  return `at ${vtxo.script} (contract type '${type}') has no handler registered in this build`;
4258
4305
  }
4259
4306
  return `at ${vtxo.script} (contract type '${type}') is not generically spendable`;
@@ -4289,7 +4336,7 @@ function selectPendingRecoveryOutpoints(contractsWithVtxos, signerSet, nowSecond
4289
4336
  continue;
4290
4337
  }
4291
4338
  for (const v of vtxos) {
4292
- if (!chunk5XBH5SAL_cjs.isVtxoSpent(v) && !v.isSwept && !v.isUnrolled) {
4339
+ if (!chunkKR6FLFIH_cjs.isVtxoSpent(v) && !v.isSwept && !v.isUnrolled) {
4293
4340
  out.add(`${v.txid}:${v.vout}`);
4294
4341
  }
4295
4342
  }
@@ -4325,10 +4372,10 @@ function byValueDescending(vtxos) {
4325
4372
  return [...vtxos].sort((a, b) => b.value - a.value);
4326
4373
  }
4327
4374
  async function fetchTimeHeight(wallet) {
4328
- return chunk5XBH5SAL_cjs.resolveTimeHeight(wallet.onchainProvider);
4375
+ return chunkKR6FLFIH_cjs.resolveTimeHeight(wallet.onchainProvider);
4329
4376
  }
4330
4377
  function canMigrateBySend(vtxo, now) {
4331
- if (!chunk5XBH5SAL_cjs.canSpendOffchain(vtxo, now)) return false;
4378
+ if (!chunkKR6FLFIH_cjs.canSpendOffchain(vtxo, now)) return false;
4332
4379
  return vtxo.expiresAt !== void 0 || vtxo.expiresAtHeight !== void 0;
4333
4380
  }
4334
4381
  function byExpiryAscending(vtxos, now) {
@@ -4336,7 +4383,7 @@ function byExpiryAscending(vtxos, now) {
4336
4383
  if (vtxo.isSwept) return -Infinity;
4337
4384
  if (vtxo.expiresAt !== void 0) return vtxo.expiresAt.getTime();
4338
4385
  if (vtxo.expiresAtHeight !== void 0) {
4339
- return chunk5XBH5SAL_cjs.isPastExpiry(vtxo, now) ? -Infinity : Infinity;
4386
+ return chunkKR6FLFIH_cjs.isPastExpiry(vtxo, now) ? -Infinity : Infinity;
4340
4387
  }
4341
4388
  return Infinity;
4342
4389
  };
@@ -4363,7 +4410,7 @@ function priceSettlementInputs(vtxos, estimator) {
4363
4410
  const payable = [];
4364
4411
  const net = /* @__PURE__ */ new Map();
4365
4412
  for (const vtxo of vtxos) {
4366
- const inputFee = estimator.evalOffchainInput(chunk5XBH5SAL_cjs.toOffchainInputFeeParams(vtxo));
4413
+ const inputFee = estimator.evalOffchainInput(chunkKR6FLFIH_cjs.toOffchainInputFeeParams(vtxo));
4367
4414
  if (inputFee.satoshis >= vtxo.value) {
4368
4415
  continue;
4369
4416
  }
@@ -4392,7 +4439,7 @@ function offchainOutputFee(amount, estimator, arkAddress) {
4392
4439
  }
4393
4440
  const outputFee = estimator.evalOffchainOutput({
4394
4441
  amount,
4395
- script: base.hex.encode(chunk5XBH5SAL_cjs.ArkAddress.decode(arkAddress).pkScript)
4442
+ script: base.hex.encode(chunkKR6FLFIH_cjs.ArkAddress.decode(arkAddress).pkScript)
4396
4443
  });
4397
4444
  return BigInt(outputFee.satoshis);
4398
4445
  }
@@ -4443,10 +4490,10 @@ var DEFAULT_SETTLEMENT_CONFIG = {
4443
4490
  };
4444
4491
  function getRecoverableVtxos(vtxos, dustAmount, now) {
4445
4492
  return vtxos.filter((vtxo) => {
4446
- if (chunk5XBH5SAL_cjs.canRecoverOnchain(vtxo, now)) {
4493
+ if (chunkKR6FLFIH_cjs.canRecoverOnchain(vtxo, now)) {
4447
4494
  return true;
4448
4495
  }
4449
- if (chunk5XBH5SAL_cjs.canSpendOffchain(vtxo, now) && vtxo.isPreconfirmed && isSubdust(vtxo, dustAmount)) {
4496
+ if (chunkKR6FLFIH_cjs.canSpendOffchain(vtxo, now) && vtxo.isPreconfirmed && isSubdust(vtxo, dustAmount)) {
4450
4497
  return true;
4451
4498
  }
4452
4499
  return false;
@@ -4478,7 +4525,7 @@ function getRecoverableWithSubdust(vtxos, dustAmount, now) {
4478
4525
  function isVtxoExpiringSoon(vtxo, thresholdMs) {
4479
4526
  if (vtxo.isUnrolled) return false;
4480
4527
  const realThresholdMs = thresholdMs <= 100 ? DEFAULT_THRESHOLD_MS : thresholdMs;
4481
- const expiresAt = chunk5XBH5SAL_cjs.normalizeVtxo(vtxo).expiresAt;
4528
+ const expiresAt = chunkKR6FLFIH_cjs.normalizeVtxo(vtxo).expiresAt;
4482
4529
  if (expiresAt === void 0) return false;
4483
4530
  const now = Date.now();
4484
4531
  const batchExpiry = expiresAt.getTime();
@@ -4489,7 +4536,7 @@ function getExpiringAndRecoverableVtxos(vtxos, thresholdMs, dustAmount, now) {
4489
4536
  return vtxos.filter(
4490
4537
  // The leading exclusion covers the `isSubdust` arm too, which is a value
4491
4538
  // property and would otherwise re-admit an exited coin on its own.
4492
- (vtxo) => !vtxo.isUnrolled && (isVtxoExpiringSoon(vtxo, thresholdMs) || chunk5XBH5SAL_cjs.canRecoverOnchain(vtxo, now) || isSubdust(vtxo, dustAmount))
4539
+ (vtxo) => !vtxo.isUnrolled && (isVtxoExpiringSoon(vtxo, thresholdMs) || chunkKR6FLFIH_cjs.canRecoverOnchain(vtxo, now) || isSubdust(vtxo, dustAmount))
4493
4540
  );
4494
4541
  }
4495
4542
  function isMigrationCapable(wallet) {
@@ -4549,7 +4596,7 @@ var VtxoManager = class _VtxoManager {
4549
4596
  constructor(wallet, settlementConfig) {
4550
4597
  this.wallet = wallet;
4551
4598
  if (settlementConfig !== false) {
4552
- chunk5XBH5SAL_cjs.assertTimerMs("pollIntervalMs", settlementConfig?.pollIntervalMs);
4599
+ chunkKR6FLFIH_cjs.assertTimerMs("pollIntervalMs", settlementConfig?.pollIntervalMs);
4553
4600
  }
4554
4601
  this.settlementConfig = settlementConfig !== void 0 ? settlementConfig : { ...DEFAULT_SETTLEMENT_CONFIG };
4555
4602
  this.contractEventsSubscriptionReady = this.initializeSubscription();
@@ -4856,7 +4903,7 @@ var VtxoManager = class _VtxoManager {
4856
4903
  * {@link recoverImportedContracts}).
4857
4904
  */
4858
4905
  async recoverOneImportedContract(wallet, contract, vtxos, info, dustAmount) {
4859
- const recoverable = vtxos.filter((vtxo) => vtxo.isSwept && !chunk5XBH5SAL_cjs.isVtxoSpent(vtxo));
4906
+ const recoverable = vtxos.filter((vtxo) => vtxo.isSwept && !chunkKR6FLFIH_cjs.isVtxoSpent(vtxo));
4860
4907
  const estimator = new Estimator(info?.fees.intentFee ?? {});
4861
4908
  const { payable, net } = priceSettlementInputs(recoverable, estimator);
4862
4909
  const vtxoMaxAmount = info?.vtxoMaxAmount ?? -1n;
@@ -4878,7 +4925,7 @@ var VtxoManager = class _VtxoManager {
4878
4925
  if (vtxos.length === 0) return;
4879
4926
  const spent = new Set(batch.map((vtxo) => `${vtxo.txid}:${vtxo.vout}`));
4880
4927
  const stillSpendable = vtxos.some(
4881
- (vtxo) => !chunk5XBH5SAL_cjs.isVtxoSpent(vtxo) && !spent.has(`${vtxo.txid}:${vtxo.vout}`)
4928
+ (vtxo) => !chunkKR6FLFIH_cjs.isVtxoSpent(vtxo) && !spent.has(`${vtxo.txid}:${vtxo.vout}`)
4882
4929
  );
4883
4930
  if (!stillSpendable) {
4884
4931
  await wallet.removeRecoveryContract(contract.script);
@@ -5145,11 +5192,11 @@ var VtxoManager = class _VtxoManager {
5145
5192
  `Sweep not economical: output ${outputAmount} sats after ${fee} sats fee is below dust (${dustAmount} sats)`
5146
5193
  );
5147
5194
  }
5148
- const tx = new chunk5XBH5SAL_cjs.Transaction();
5195
+ const tx = new chunkKR6FLFIH_cjs.Transaction();
5149
5196
  for (const utxo of expiredUtxos) {
5150
- const utxoScript = chunk5XBH5SAL_cjs.VtxoScript.decode(utxo.tapTree);
5197
+ const utxoScript = chunkKR6FLFIH_cjs.VtxoScript.decode(utxo.tapTree);
5151
5198
  const utxoExitLeaf = utxoScript.leaves.find(
5152
- (leaf) => chunk5XBH5SAL_cjs.CSVMultisigTapscript.isScriptValid(chunk5XBH5SAL_cjs.scriptFromTapLeafScript(leaf)) === true
5199
+ (leaf) => chunkKR6FLFIH_cjs.CSVMultisigTapscript.isScriptValid(chunkKR6FLFIH_cjs.scriptFromTapLeafScript(leaf)) === true
5153
5200
  );
5154
5201
  if (!utxoExitLeaf) {
5155
5202
  throw new Error(
@@ -5164,7 +5211,7 @@ var VtxoManager = class _VtxoManager {
5164
5211
  amount: BigInt(utxo.value)
5165
5212
  },
5166
5213
  tapLeafScript: [utxoExitLeaf],
5167
- sequence: chunk5XBH5SAL_cjs.getSequence(utxoExitLeaf)
5214
+ sequence: chunkKR6FLFIH_cjs.getSequence(utxoExitLeaf)
5168
5215
  });
5169
5216
  }
5170
5217
  tx.addOutputAddress(boardingAddress, outputAmount, this.getNetwork());
@@ -5390,8 +5437,8 @@ var VtxoManager = class _VtxoManager {
5390
5437
  const cls = classifyAgainstSignerSet(serverPubKey, signerSet, nowSeconds);
5391
5438
  if (cls.status === "CURRENT") continue;
5392
5439
  const live = vtxos.filter((v) => !v.isUnrolled);
5393
- const recoverable = live.filter((v) => v.isSwept && !chunk5XBH5SAL_cjs.isVtxoSpent(v));
5394
- const spendable = live.filter((v) => !chunk5XBH5SAL_cjs.isVtxoSpent(v) && !v.isSwept);
5440
+ const recoverable = live.filter((v) => v.isSwept && !chunkKR6FLFIH_cjs.isVtxoSpent(v));
5441
+ const spendable = live.filter((v) => !chunkKR6FLFIH_cjs.isVtxoSpent(v) && !v.isSwept);
5395
5442
  const value = spendable.reduce((sum, v) => sum + v.value, 0);
5396
5443
  let recoverableCount = 0;
5397
5444
  let recoverableValue = 0;
@@ -5631,7 +5678,7 @@ var VtxoManager = class _VtxoManager {
5631
5678
  }
5632
5679
  getBoardingTimelock() {
5633
5680
  const wallet = this.getSweepWallet();
5634
- const exitScript = chunk5XBH5SAL_cjs.CSVMultisigTapscript.decode(
5681
+ const exitScript = chunkKR6FLFIH_cjs.CSVMultisigTapscript.decode(
5635
5682
  base.hex.decode(wallet.boardingTapscript.exitScript)
5636
5683
  );
5637
5684
  return exitScript.params.timelock;
@@ -5739,8 +5786,8 @@ var VtxoManager = class _VtxoManager {
5739
5786
  }
5740
5787
  /** The outpoint a `VTXO_ALREADY_SPENT` error carries in `metadata.vtxo_outpoint`, if any. */
5741
5788
  extractSpentOutpoint(error) {
5742
- const ark = chunk5XBH5SAL_cjs.maybeArkError(error);
5743
- if (!chunk5XBH5SAL_cjs.isArkError(ark, chunk5XBH5SAL_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
5789
+ const ark = chunkKR6FLFIH_cjs.maybeArkError(error);
5790
+ if (!chunkKR6FLFIH_cjs.isArkError(ark, chunkKR6FLFIH_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
5744
5791
  const raw = ark.metadata?.vtxo_outpoint;
5745
5792
  if (typeof raw !== "string") return void 0;
5746
5793
  const [txid, voutStr] = raw.split(":");
@@ -5914,7 +5961,7 @@ var VtxoManager = class _VtxoManager {
5914
5961
  if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
5915
5962
  break;
5916
5963
  }
5917
- const inputFee = estimator.evalOffchainInput(chunk5XBH5SAL_cjs.toOffchainInputFeeParams(v));
5964
+ const inputFee = estimator.evalOffchainInput(chunkKR6FLFIH_cjs.toOffchainInputFeeParams(v));
5918
5965
  if (inputFee.satoshis >= v.value) {
5919
5966
  continue;
5920
5967
  }
@@ -5934,7 +5981,7 @@ var VtxoManager = class _VtxoManager {
5934
5981
  const arkAddress = await this.wallet.getAddress();
5935
5982
  const outputFee = estimator.evalOffchainOutput({
5936
5983
  amount: totalAmount,
5937
- script: base.hex.encode(chunk5XBH5SAL_cjs.ArkAddress.decode(arkAddress).pkScript)
5984
+ script: base.hex.encode(chunkKR6FLFIH_cjs.ArkAddress.decode(arkAddress).pkScript)
5938
5985
  });
5939
5986
  totalAmount -= BigInt(outputFee.satoshis);
5940
5987
  if (totalAmount < dustAmount) return;
@@ -6014,7 +6061,7 @@ var ArkNote = class _ArkNote {
6014
6061
  this.value = value;
6015
6062
  this.HRP = HRP;
6016
6063
  const preimageHash = utils_js.sha256(this.preimage);
6017
- this.vtxoScript = new chunk5XBH5SAL_cjs.VtxoScript([noteTapscript(preimageHash)]);
6064
+ this.vtxoScript = new chunkKR6FLFIH_cjs.VtxoScript([noteTapscript(preimageHash)]);
6018
6065
  const leaf = this.vtxoScript.leaves[0];
6019
6066
  this.txid = base.hex.encode(new Uint8Array(preimageHash).reverse());
6020
6067
  this.tapTree = this.vtxoScript.encode();
@@ -6187,7 +6234,7 @@ var ArkadeCash = class _ArkadeCash {
6187
6234
  const privateKey = data.slice(1, 33);
6188
6235
  const serverPubKey = data.slice(33, 65);
6189
6236
  const sequence = new DataView(data.buffer, data.byteOffset + 65, 4).getUint32(0, false);
6190
- const csvTimelock2 = chunk5XBH5SAL_cjs.sequenceToTimelock(sequence);
6237
+ const csvTimelock2 = chunkKR6FLFIH_cjs.sequenceToTimelock(sequence);
6191
6238
  return new _ArkadeCash(privateKey, serverPubKey, csvTimelock2, decoded.prefix);
6192
6239
  }
6193
6240
  toString() {
@@ -6195,7 +6242,7 @@ var ArkadeCash = class _ArkadeCash {
6195
6242
  data[0] = _ArkadeCash.Version;
6196
6243
  data.set(this._privateKey, 1);
6197
6244
  data.set(this._serverPubKey, 33);
6198
- const sequence = chunk5XBH5SAL_cjs.timelockToSequence(this.csvTimelock);
6245
+ const sequence = chunkKR6FLFIH_cjs.timelockToSequence(this.csvTimelock);
6199
6246
  new DataView(data.buffer, data.byteOffset + 65, 4).setUint32(0, sequence, false);
6200
6247
  const words = base.bech32m.toWords(data);
6201
6248
  return base.bech32m.encode(this.hrp, words, 1023);
@@ -6204,7 +6251,7 @@ var ArkadeCash = class _ArkadeCash {
6204
6251
  return SingleKey.fromPrivateKey(this._privateKey);
6205
6252
  }
6206
6253
  get vtxoScript() {
6207
- return new chunkGVF4OCTL_cjs.DefaultVtxo.Script({
6254
+ return new chunkQLJXXVRO_cjs.DefaultVtxo.Script({
6208
6255
  pubKey: this._publicKey,
6209
6256
  serverPubKey: this._serverPubKey,
6210
6257
  csvTimelock: this.csvTimelock
@@ -6220,7 +6267,7 @@ var NON_TERMINAL_INTENT_STATES = ALL_INTENT_STATES.filter(
6220
6267
  (s) => !isTerminalIntentState(s)
6221
6268
  );
6222
6269
  function isConsumed(vtxo) {
6223
- return vtxo !== void 0 && chunk5XBH5SAL_cjs.isVtxoSpent(vtxo);
6270
+ return vtxo !== void 0 && chunkKR6FLFIH_cjs.isVtxoSpent(vtxo);
6224
6271
  }
6225
6272
  async function classifyIntent(intent, vtxosByOutpoint, now) {
6226
6273
  if (isTerminalIntentState(intent.state)) return void 0;
@@ -6263,7 +6310,7 @@ async function reconcileIntents(deps) {
6263
6310
  let vtxosByOutpoint = /* @__PURE__ */ new Map();
6264
6311
  if (outpoints.length > 0) {
6265
6312
  try {
6266
- const { vtxos } = await chunk5XBH5SAL_cjs.getNormalizedVtxos(deps.indexerProvider, { outpoints });
6313
+ const { vtxos } = await chunkKR6FLFIH_cjs.getNormalizedVtxos(deps.indexerProvider, { outpoints });
6267
6314
  vtxosByOutpoint = new Map(vtxos.map((v) => [outpointKey(v), v]));
6268
6315
  } catch (e) {
6269
6316
  console.error("reconcileIntents: failed to fetch input VTXO state", e);
@@ -6323,7 +6370,7 @@ async function releaseFromServer(intent, deps, now) {
6323
6370
  });
6324
6371
  }
6325
6372
  function isNoMatchingIntentsError(e) {
6326
- return chunk5XBH5SAL_cjs.isArkError(e, chunk5XBH5SAL_cjs.ArkErrorName.INVALID_INTENT_PROOF) && e.message.includes("no matching intents found");
6373
+ return chunkKR6FLFIH_cjs.isArkError(e, chunkKR6FLFIH_cjs.ArkErrorName.INVALID_INTENT_PROOF) && e.message.includes("no matching intents found");
6327
6374
  }
6328
6375
  function terminal(intent, state, now, patch) {
6329
6376
  return { ...intent, ...patch, state, updatedAt: now };
@@ -6542,7 +6589,7 @@ async function captureExitBranch(params) {
6542
6589
  const nonCommitment = ordered.filter((c) => chainTxTypeToChainedExit(c.type) !== 1 /* Commitment */).map((c) => c.txid);
6543
6590
  if (nonCommitment.length > 0) {
6544
6591
  for (const psbt of await resolver.getVirtualTxs(nonCommitment)) {
6545
- psbtByTxid.set(chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
6592
+ psbtByTxid.set(chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
6546
6593
  }
6547
6594
  }
6548
6595
  }
@@ -6585,10 +6632,10 @@ var IndexerExitDataSource = class {
6585
6632
  while (hasMore) {
6586
6633
  const { chain: page, page: meta } = await this.indexer.getVtxoChain(
6587
6634
  { txid: vtxo.txid, vout: vtxo.vout },
6588
- { pageIndex, pageSize: chunk5XBH5SAL_cjs.DEFAULT_PAGE_SIZE }
6635
+ { pageIndex, pageSize: chunkKR6FLFIH_cjs.DEFAULT_PAGE_SIZE }
6589
6636
  );
6590
6637
  chain.push(...page);
6591
- hasMore = meta ? page.length === chunk5XBH5SAL_cjs.DEFAULT_PAGE_SIZE : false;
6638
+ hasMore = meta ? page.length === chunkKR6FLFIH_cjs.DEFAULT_PAGE_SIZE : false;
6592
6639
  pageIndex++;
6593
6640
  }
6594
6641
  return chain;
@@ -6600,12 +6647,12 @@ var IndexerExitDataSource = class {
6600
6647
  while (hasMore) {
6601
6648
  const { txs, page } = await this.indexer.getVirtualTxs(txids, {
6602
6649
  pageIndex,
6603
- pageSize: chunk5XBH5SAL_cjs.DEFAULT_PAGE_SIZE
6650
+ pageSize: chunkKR6FLFIH_cjs.DEFAULT_PAGE_SIZE
6604
6651
  });
6605
6652
  for (const psbt of txs) {
6606
- out.set(chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
6653
+ out.set(chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
6607
6654
  }
6608
- hasMore = page ? txs.length === chunk5XBH5SAL_cjs.DEFAULT_PAGE_SIZE : false;
6655
+ hasMore = page ? txs.length === chunkKR6FLFIH_cjs.DEFAULT_PAGE_SIZE : false;
6609
6656
  pageIndex++;
6610
6657
  }
6611
6658
  return out;
@@ -6626,7 +6673,7 @@ function chainedTxTypeToChainTxType(t) {
6626
6673
  }
6627
6674
  }
6628
6675
  function psbtInputTxids(psbtBase64) {
6629
- return txInputTxids(chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64)));
6676
+ return txInputTxids(chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64)));
6630
6677
  }
6631
6678
  function txInputTxids(tx) {
6632
6679
  const ids = [];
@@ -6930,10 +6977,10 @@ async function resolveArkInfo(arkProvider, walletRepository, opts) {
6930
6977
  try {
6931
6978
  info = await arkProvider.getInfo();
6932
6979
  } catch (err) {
6933
- if (opts?.requireLive || !chunk5XBH5SAL_cjs.isRetryableProviderError(err)) throw err;
6980
+ if (opts?.requireLive || !chunkKR6FLFIH_cjs.isRetryableProviderError(err)) throw err;
6934
6981
  const snapshot = await loadArkInfoSnapshot(walletRepository);
6935
6982
  if (!snapshot) {
6936
- throw new chunk5XBH5SAL_cjs.ProviderUnavailableError(
6983
+ throw new chunkKR6FLFIH_cjs.ProviderUnavailableError(
6937
6984
  "Arkade server info is unavailable and no cached snapshot exists",
6938
6985
  { cause: err }
6939
6986
  );
@@ -7125,7 +7172,7 @@ function buildGraph(rootTxid, chunksByTxid) {
7125
7172
  return new TxTree(rootTx, children);
7126
7173
  }
7127
7174
  function decodeNode(chunk) {
7128
- const tx = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(chunk.tx));
7175
+ const tx = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(chunk.tx));
7129
7176
  return { tx, children: chunk.children };
7130
7177
  }
7131
7178
  exports.Batch = void 0;
@@ -7328,7 +7375,7 @@ function collectArkTxidsNeedingCreatedAt(vtxos, localCreatedAt) {
7328
7375
  return [...txids];
7329
7376
  }
7330
7377
  async function buildTransactionHistory(vtxos, allBoardingTxs, commitmentsToIgnore, resolveTxCreatedAt, gatedScripts = /* @__PURE__ */ new Map()) {
7331
- const normalized = vtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
7378
+ const normalized = vtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
7332
7379
  const localCreatedAt = localCreatedAtByTxid(normalized);
7333
7380
  const gatedVtxos = normalized.filter((vtxo) => isGatedVtxo(vtxo, gatedScripts));
7334
7381
  const ownVtxos = normalized.filter((vtxo) => !isGatedVtxo(vtxo, gatedScripts));
@@ -7503,7 +7550,7 @@ var AssetManager = class extends ReadonlyAssetManager {
7503
7550
  withRecoverable: false,
7504
7551
  genericallySpendableOnly: true
7505
7552
  });
7506
- const controlAssetRef = params.controlAssetId ? chunkQ7PC3NHX_cjs.AssetRef.fromId(chunkQ7PC3NHX_cjs.AssetId.fromString(params.controlAssetId)) : null;
7553
+ const controlAssetRef = params.controlAssetId ? chunkYFHGGSII_cjs.AssetRef.fromId(chunkYFHGGSII_cjs.AssetId.fromString(params.controlAssetId)) : null;
7507
7554
  const coinSelection = selectVirtualCoins(virtualCoins, Number(this.wallet.dustAmount));
7508
7555
  let totalBtcSelected = 0n;
7509
7556
  const assetChanges = /* @__PURE__ */ new Map();
@@ -7516,8 +7563,8 @@ var AssetManager = class extends ReadonlyAssetManager {
7516
7563
  }
7517
7564
  }
7518
7565
  const groups = [];
7519
- const issuedAssetOutput = chunkQ7PC3NHX_cjs.AssetOutput.create(0, params.amount);
7520
- const issuedAssetGroup = chunkQ7PC3NHX_cjs.AssetGroup.create(
7566
+ const issuedAssetOutput = chunkYFHGGSII_cjs.AssetOutput.create(0, params.amount);
7567
+ const issuedAssetGroup = chunkYFHGGSII_cjs.AssetGroup.create(
7521
7568
  null,
7522
7569
  controlAssetRef,
7523
7570
  [],
@@ -7530,11 +7577,11 @@ var AssetManager = class extends ReadonlyAssetManager {
7530
7577
  for (const [assetId, amount] of assetChanges) {
7531
7578
  const changeInputs = inputsForAsset(assetInputs, assetId);
7532
7579
  groups.push(
7533
- chunkQ7PC3NHX_cjs.AssetGroup.create(
7534
- chunkQ7PC3NHX_cjs.AssetId.fromString(assetId),
7580
+ chunkYFHGGSII_cjs.AssetGroup.create(
7581
+ chunkYFHGGSII_cjs.AssetId.fromString(assetId),
7535
7582
  null,
7536
7583
  changeInputs,
7537
- [chunkQ7PC3NHX_cjs.AssetOutput.create(0, amount)],
7584
+ [chunkYFHGGSII_cjs.AssetOutput.create(0, amount)],
7538
7585
  []
7539
7586
  )
7540
7587
  );
@@ -7548,7 +7595,7 @@ var AssetManager = class extends ReadonlyAssetManager {
7548
7595
  );
7549
7596
  return {
7550
7597
  arkTxId: arkTxid,
7551
- assetId: chunkQ7PC3NHX_cjs.AssetId.create(arkTxid, 0).toString()
7598
+ assetId: chunkYFHGGSII_cjs.AssetId.create(arkTxid, 0).toString()
7552
7599
  };
7553
7600
  }
7554
7601
  /**
@@ -7619,23 +7666,23 @@ var AssetManager = class extends ReadonlyAssetManager {
7619
7666
  const assetInputs = selectedCoinsToAssetInputs(selectedCoins);
7620
7667
  const reissueInputs = inputsForAsset(assetInputs, params.assetId);
7621
7668
  const totalAssetAmount = assetToReissueAmount + params.amount;
7622
- const reissueAssetIdObj = chunkQ7PC3NHX_cjs.AssetId.fromString(params.assetId);
7623
- const reissueAssetGroup = chunkQ7PC3NHX_cjs.AssetGroup.create(
7669
+ const reissueAssetIdObj = chunkYFHGGSII_cjs.AssetId.fromString(params.assetId);
7670
+ const reissueAssetGroup = chunkYFHGGSII_cjs.AssetGroup.create(
7624
7671
  reissueAssetIdObj,
7625
7672
  null,
7626
7673
  reissueInputs,
7627
- [chunkQ7PC3NHX_cjs.AssetOutput.create(0, totalAssetAmount)],
7674
+ [chunkYFHGGSII_cjs.AssetOutput.create(0, totalAssetAmount)],
7628
7675
  []
7629
7676
  );
7630
7677
  const groups = [reissueAssetGroup];
7631
7678
  for (const [assetId, amount] of assetChanges) {
7632
7679
  const changeInputs = inputsForAsset(assetInputs, assetId);
7633
7680
  groups.push(
7634
- chunkQ7PC3NHX_cjs.AssetGroup.create(
7635
- chunkQ7PC3NHX_cjs.AssetId.fromString(assetId),
7681
+ chunkYFHGGSII_cjs.AssetGroup.create(
7682
+ chunkYFHGGSII_cjs.AssetId.fromString(assetId),
7636
7683
  null,
7637
7684
  changeInputs,
7638
- [chunkQ7PC3NHX_cjs.AssetOutput.create(0, amount)],
7685
+ [chunkYFHGGSII_cjs.AssetOutput.create(0, amount)],
7639
7686
  []
7640
7687
  )
7641
7688
  );
@@ -7703,11 +7750,11 @@ var AssetManager = class extends ReadonlyAssetManager {
7703
7750
  for (const [assetId, amount] of assetChanges) {
7704
7751
  const changeInputs = inputsForAsset(assetInputs, assetId);
7705
7752
  groups.push(
7706
- chunkQ7PC3NHX_cjs.AssetGroup.create(
7707
- chunkQ7PC3NHX_cjs.AssetId.fromString(assetId),
7753
+ chunkYFHGGSII_cjs.AssetGroup.create(
7754
+ chunkYFHGGSII_cjs.AssetId.fromString(assetId),
7708
7755
  null,
7709
7756
  changeInputs,
7710
- amount > 0n ? [chunkQ7PC3NHX_cjs.AssetOutput.create(0, amount)] : [],
7757
+ amount > 0n ? [chunkYFHGGSII_cjs.AssetOutput.create(0, amount)] : [],
7711
7758
  []
7712
7759
  )
7713
7760
  );
@@ -7720,16 +7767,16 @@ function inputsForAsset(assetInputs, assetId) {
7720
7767
  for (const [inputIndex, assets] of assetInputs) {
7721
7768
  for (const asset of assets) {
7722
7769
  if (asset.assetId !== assetId) continue;
7723
- inputs.push(chunkQ7PC3NHX_cjs.AssetInput.create(inputIndex, asset.amount));
7770
+ inputs.push(chunkYFHGGSII_cjs.AssetInput.create(inputIndex, asset.amount));
7724
7771
  }
7725
7772
  }
7726
7773
  return inputs;
7727
7774
  }
7728
7775
  async function submitToSelf(wallet, inputs, amount, groups) {
7729
- const outputAddress = chunk5XBH5SAL_cjs.ArkAddress.decode(await wallet.getAddress());
7776
+ const outputAddress = chunkKR6FLFIH_cjs.ArkAddress.decode(await wallet.getAddress());
7730
7777
  const outputs = [
7731
7778
  { script: outputAddress.pkScript, amount: BigInt(amount) },
7732
- Extension.create([chunkQ7PC3NHX_cjs.Packet.create(groups)]).txOut()
7779
+ Extension.create([chunkYFHGGSII_cjs.Packet.create(groups)]).txOut()
7733
7780
  ];
7734
7781
  const { arkTxid } = await wallet.buildAndSubmitOffchainTx(inputs, outputs);
7735
7782
  return arkTxid;
@@ -7753,7 +7800,7 @@ function castMetadata(metadata) {
7753
7800
  } else {
7754
7801
  throw new Error("Invalid metadata value type");
7755
7802
  }
7756
- md.push(chunkQ7PC3NHX_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
7803
+ md.push(chunkYFHGGSII_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
7757
7804
  }
7758
7805
  return md;
7759
7806
  }
@@ -7774,10 +7821,10 @@ var DelegateManagerImpl = class {
7774
7821
  if (vtxos.length === 0) {
7775
7822
  return { delegated: [], failed: [] };
7776
7823
  }
7777
- const destinationScript = chunk5XBH5SAL_cjs.ArkAddress.decode(destination).pkScript;
7824
+ const destinationScript = chunkKR6FLFIH_cjs.ArkAddress.decode(destination).pkScript;
7778
7825
  const arkInfo = await this.arkInfoProvider.getInfo();
7779
7826
  const delegateInfo = await this.delegateProvider.getDelegateInfo();
7780
- const eligible = vtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo).filter(
7827
+ const eligible = vtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo).filter(
7781
7828
  (v) => isAnnotated(v) && findDelegateTapLeaf(v, delegateInfo.pubkey) !== void 0
7782
7829
  );
7783
7830
  if (eligible.length === 0) {
@@ -7809,7 +7856,7 @@ var DelegateManagerImpl = class {
7809
7856
  const groupByExpiry = /* @__PURE__ */ new Map();
7810
7857
  let recoverableVtxos = [];
7811
7858
  for (const vtxo of eligible) {
7812
- if (chunk5XBH5SAL_cjs.canRecoverOnchain(vtxo, now)) {
7859
+ if (chunkKR6FLFIH_cjs.canRecoverOnchain(vtxo, now)) {
7813
7860
  recoverableVtxos.push(vtxo);
7814
7861
  continue;
7815
7862
  }
@@ -7861,7 +7908,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7861
7908
  }
7862
7909
  if (!delegateAt) {
7863
7910
  const now = { timestamp: /* @__PURE__ */ new Date() };
7864
- const expiryTimestamp = vtxos.filter((coin) => !chunk5XBH5SAL_cjs.canRecoverOnchain(coin, now) && coin.expiresAt).reduce(
7911
+ const expiryTimestamp = vtxos.filter((coin) => !chunkKR6FLFIH_cjs.canRecoverOnchain(coin, now) && coin.expiresAt).reduce(
7865
7912
  (min, coin) => Math.min(min, coin.expiresAt.getTime()),
7866
7913
  Number.MAX_SAFE_INTEGER
7867
7914
  );
@@ -7888,7 +7935,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7888
7935
  let amount = 0n;
7889
7936
  for (const coin of vtxos) {
7890
7937
  const inputFee = estimator.evalOffchainInput({
7891
- ...chunk5XBH5SAL_cjs.toOffchainInputFeeParams(coin),
7938
+ ...chunkKR6FLFIH_cjs.toOffchainInputFeeParams(coin),
7892
7939
  type: "vtxo"
7893
7940
  });
7894
7941
  if (inputFee.satoshis >= coin.value) {
@@ -7902,7 +7949,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7902
7949
  const delegateFee = BigInt(Number(fee));
7903
7950
  if (delegateFee > 0n) {
7904
7951
  outputs.push({
7905
- script: chunk5XBH5SAL_cjs.ArkAddress.decode(delegateAddress).pkScript,
7952
+ script: chunkKR6FLFIH_cjs.ArkAddress.decode(delegateAddress).pkScript,
7906
7953
  amount: delegateFee
7907
7954
  });
7908
7955
  }
@@ -7935,10 +7982,10 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7935
7982
  destinationScript
7936
7983
  );
7937
7984
  const forfeitOutputScript = btcSigner.OutScript.encode(
7938
- btcSigner.Address(chunk5XBH5SAL_cjs.getNetwork(network)).decode(forfeitAddress)
7985
+ btcSigner.Address(chunkKR6FLFIH_cjs.getNetwork(network)).decode(forfeitAddress)
7939
7986
  );
7940
7987
  const forfeits = await Promise.all(
7941
- vtxos.filter((v) => chunk5XBH5SAL_cjs.requiresForfeit(v)).map(async (coin) => {
7988
+ vtxos.filter((v) => chunkKR6FLFIH_cjs.requiresForfeit(v)).map(async (coin) => {
7942
7989
  const forfeit = await makeDelegateForfeitTx(
7943
7990
  coin,
7944
7991
  dust,
@@ -7963,7 +8010,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
7963
8010
  index: input.vout,
7964
8011
  witnessUtxo: {
7965
8012
  amount: BigInt(input.value),
7966
- script: chunk5XBH5SAL_cjs.VtxoScript.decode(input.tapTree).pkScript
8013
+ script: chunkKR6FLFIH_cjs.VtxoScript.decode(input.tapTree).pkScript
7967
8014
  },
7968
8015
  sighashType: btcSigner.SigHash.ALL_ANYONECANPAY,
7969
8016
  tapLeafScript: [delegateTapLeaf]
@@ -8021,7 +8068,7 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
8021
8068
  expire_at: 0,
8022
8069
  cosigners_public_keys: cosignerPubKeys
8023
8070
  };
8024
- const proof = chunk5XBH5SAL_cjs.Intent.create(message, coins, outputs);
8071
+ const proof = chunkKR6FLFIH_cjs.Intent.create(message, coins, outputs);
8025
8072
  const signedProof = await identity.sign(proof);
8026
8073
  return {
8027
8074
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -8047,10 +8094,10 @@ function getDayTimestamp(timestamp) {
8047
8094
  function findDelegateTapLeaf(vtxo, delegatePubkey) {
8048
8095
  if (!vtxo.tapTree) return void 0;
8049
8096
  const pk = delegatePubkey.length === 66 ? delegatePubkey.slice(2) : delegatePubkey;
8050
- const vtxoScript = chunk5XBH5SAL_cjs.VtxoScript.decode(vtxo.tapTree);
8097
+ const vtxoScript = chunkKR6FLFIH_cjs.VtxoScript.decode(vtxo.tapTree);
8051
8098
  return vtxoScript.leaves.find((tapLeaf) => {
8052
- const arkTapscript = chunk5XBH5SAL_cjs.decodeTapscript(chunk5XBH5SAL_cjs.scriptFromTapLeafScript(tapLeaf));
8053
- if (!chunk5XBH5SAL_cjs.MultisigTapscript.is(arkTapscript)) return false;
8099
+ const arkTapscript = chunkKR6FLFIH_cjs.decodeTapscript(chunkKR6FLFIH_cjs.scriptFromTapLeafScript(tapLeaf));
8100
+ if (!chunkKR6FLFIH_cjs.MultisigTapscript.is(arkTapscript)) return false;
8054
8101
  return arkTapscript.params.pubkeys.map(base.hex.encode).includes(pk);
8055
8102
  });
8056
8103
  }
@@ -8606,8 +8653,8 @@ function checkSaveVtxosForScript(backend, key, vtxos) {
8606
8653
  }
8607
8654
  async function getVtxosForContract(repo, contract, options) {
8608
8655
  const vtxos = repo.getVtxosForScriptPage ? await collectScriptVtxos(repo, contract.script, options) : filterVtxosForScript(await collectVtxos(repo, contract.address), contract.script);
8609
- const normalized = vtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo);
8610
- return options?.unspentOnly ? normalized.filter((vtxo) => !chunk5XBH5SAL_cjs.isVtxoSpent(vtxo)) : normalized;
8656
+ const normalized = vtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo);
8657
+ return options?.unspentOnly ? normalized.filter((vtxo) => !chunkKR6FLFIH_cjs.isVtxoSpent(vtxo)) : normalized;
8611
8658
  }
8612
8659
  async function hasVtxosForContract(repo, contract) {
8613
8660
  if (repo.getVtxosForScriptPage) {
@@ -8838,7 +8885,7 @@ function decodeArkContract(encoded) {
8838
8885
  }
8839
8886
  function contractFromArkContract(encoded, options = {}) {
8840
8887
  const parsed = decodeArkContract(encoded);
8841
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(parsed.type);
8888
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(parsed.type);
8842
8889
  if (!handler) {
8843
8890
  throw new Error(`No handler registered for contract type '${parsed.type}'`);
8844
8891
  }
@@ -8852,9 +8899,9 @@ function contractFromArkContract(encoded, options = {}) {
8852
8899
  metadata: options.metadata
8853
8900
  };
8854
8901
  }
8855
- function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunk5XBH5SAL_cjs.DEFAULT_NETWORK.hrp, options = {}) {
8902
+ function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunkKR6FLFIH_cjs.DEFAULT_NETWORK.hrp, options = {}) {
8856
8903
  const parsed = decodeArkContract(encoded);
8857
- const handler = chunkGVF4OCTL_cjs.contractHandlers.getOrThrow(parsed.type);
8904
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.getOrThrow(parsed.type);
8858
8905
  const params = parsed.data;
8859
8906
  const vtxoScript = handler.createScript(params);
8860
8907
  return {
@@ -8903,9 +8950,9 @@ var ContractWatcher = class {
8903
8950
  eventSourceReported = false;
8904
8951
  /** @see ContractWatcherConfig */
8905
8952
  constructor(config) {
8906
- chunk5XBH5SAL_cjs.assertTimerMs("failsafePollIntervalMs", config.failsafePollIntervalMs);
8907
- chunk5XBH5SAL_cjs.assertTimerMs("reconnectDelayMs", config.reconnectDelayMs);
8908
- chunk5XBH5SAL_cjs.assertTimerMs("maxReconnectDelayMs", config.maxReconnectDelayMs);
8953
+ chunkKR6FLFIH_cjs.assertTimerMs("failsafePollIntervalMs", config.failsafePollIntervalMs);
8954
+ chunkKR6FLFIH_cjs.assertTimerMs("reconnectDelayMs", config.reconnectDelayMs);
8955
+ chunkKR6FLFIH_cjs.assertTimerMs("maxReconnectDelayMs", config.maxReconnectDelayMs);
8909
8956
  this.config = {
8910
8957
  ...DEFAULT_CONTRACT_WATCHER_CONFIG,
8911
8958
  ...config
@@ -9107,9 +9154,9 @@ var ContractWatcher = class {
9107
9154
  this.connectionState = "connected";
9108
9155
  this.reconnectAttempts = 0;
9109
9156
  this.listenLoop().catch((e) => {
9110
- if (chunk5XBH5SAL_cjs.isEventSourceError(e)) {
9157
+ if (chunkKR6FLFIH_cjs.isEventSourceError(e)) {
9111
9158
  console.debug("ContractWatcher subscription disconnected; reconnecting");
9112
- } else if (!chunk5XBH5SAL_cjs.isEventSourceUnavailableError(e)) {
9159
+ } else if (!chunkKR6FLFIH_cjs.isEventSourceUnavailableError(e)) {
9113
9160
  console.error(e);
9114
9161
  }
9115
9162
  this.connectionState = "disconnected";
@@ -9121,7 +9168,7 @@ var ContractWatcher = class {
9121
9168
  this.scheduleReconnect();
9122
9169
  });
9123
9170
  } catch (error) {
9124
- if (!chunk5XBH5SAL_cjs.isEventSourceUnavailableError(error)) {
9171
+ if (!chunkKR6FLFIH_cjs.isEventSourceUnavailableError(error)) {
9125
9172
  console.error("ContractWatcher connection failed:", error);
9126
9173
  }
9127
9174
  this.connectionState = "disconnected";
@@ -9140,7 +9187,7 @@ var ContractWatcher = class {
9140
9187
  * few seconds.
9141
9188
  */
9142
9189
  reportEventSourceUnavailable(error) {
9143
- if (!chunk5XBH5SAL_cjs.isEventSourceUnavailableError(error)) return false;
9190
+ if (!chunkKR6FLFIH_cjs.isEventSourceUnavailableError(error)) return false;
9144
9191
  if (!this.eventSourceReported) {
9145
9192
  this.eventSourceReported = true;
9146
9193
  console.warn(
@@ -9204,7 +9251,7 @@ var ContractWatcher = class {
9204
9251
  const now = Date.now();
9205
9252
  let current;
9206
9253
  try {
9207
- current = await chunk5XBH5SAL_cjs.getAllNormalizedVtxos(this.config.indexerProvider, scripts, {
9254
+ current = await chunkKR6FLFIH_cjs.getAllNormalizedVtxos(this.config.indexerProvider, scripts, {
9208
9255
  spendableOnly: true
9209
9256
  });
9210
9257
  } catch (error) {
@@ -9393,14 +9440,14 @@ var ContractWatcher = class {
9393
9440
  const timestamp = Date.now();
9394
9441
  if (update.newVtxos?.length) {
9395
9442
  this.processSubscriptionVtxos(
9396
- update.newVtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo),
9443
+ update.newVtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo),
9397
9444
  "vtxo_received",
9398
9445
  timestamp
9399
9446
  );
9400
9447
  }
9401
9448
  if (update.spentVtxos?.length) {
9402
9449
  this.processSubscriptionVtxos(
9403
- update.spentVtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo),
9450
+ update.spentVtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo),
9404
9451
  "vtxo_spent",
9405
9452
  timestamp
9406
9453
  );
@@ -9425,8 +9472,8 @@ var ContractWatcher = class {
9425
9472
  continue;
9426
9473
  }
9427
9474
  if (target === byWatchedScript && eventType === "vtxo_received") {
9428
- const n = chunk5XBH5SAL_cjs.normalizeVtxo(vtxo);
9429
- if (chunk5XBH5SAL_cjs.isVtxoSpent(n) || n.isSwept || chunk5XBH5SAL_cjs.isPastExpiry(n, now)) continue;
9475
+ const n = chunkKR6FLFIH_cjs.normalizeVtxo(vtxo);
9476
+ if (chunkKR6FLFIH_cjs.isVtxoSpent(n) || n.isSwept || chunkKR6FLFIH_cjs.isPastExpiry(n, now)) continue;
9430
9477
  }
9431
9478
  let bucket = target.get(vtxo.script);
9432
9479
  if (!bucket) {
@@ -9532,7 +9579,7 @@ function annotatableIn(scriptToContract, vtxos, memo) {
9532
9579
  if (!contract) continue;
9533
9580
  try {
9534
9581
  const key = `${contract.type}\0${script}\0${JSON.stringify(contract.params)}`;
9535
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(contract.type);
9582
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(contract.type);
9536
9583
  const hit = memo?.get(script);
9537
9584
  let tapscripts;
9538
9585
  if (hit && hit.key === key && hit.handler === handler) {
@@ -9572,11 +9619,18 @@ var ContractManager = class _ContractManager {
9572
9619
  initialized = false;
9573
9620
  eventCallbacks = /* @__PURE__ */ new Set();
9574
9621
  stopWatcherFn;
9622
+ /** Watcher events still being handled. They write VTXO rows, so {@link dispose} waits for them. */
9623
+ inFlightEvents = /* @__PURE__ */ new Set();
9575
9624
  /** `undefined` while online; the failure reason once a sync degrades. */
9576
9625
  syncDegradedReason;
9577
9626
  /** Epoch-ms of the last successful provider sync, if any. */
9578
9627
  lastSyncedAt;
9579
9628
  syncedAtByScript = /* @__PURE__ */ new Map();
9629
+ syncsInFlight = 0;
9630
+ /** The off-critical-path boot sequence, if one is running. @see runBootSequence */
9631
+ bootTask;
9632
+ /** A catch-up sync requested behind a stored read. @see requestCatchUpSync */
9633
+ catchUpSync;
9580
9634
  /** Last chain tip read, with the epoch-ms it was read at. @see currentChainTip */
9581
9635
  chainTipCache;
9582
9636
  /** In-flight chain tip read, so concurrent cache misses share one. */
@@ -9594,8 +9648,8 @@ var ContractManager = class _ContractManager {
9594
9648
  * `dispose()`, so it re-checks this at every await rather than run on a torn-down watcher. */
9595
9649
  disposed = false;
9596
9650
  constructor(config) {
9597
- chunk5XBH5SAL_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", config.vtxoSyncMaxAgeMs);
9598
- chunk5XBH5SAL_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", config.vtxoSyncOverlapMs);
9651
+ chunkKR6FLFIH_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", config.vtxoSyncMaxAgeMs);
9652
+ chunkKR6FLFIH_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", config.vtxoSyncOverlapMs);
9599
9653
  this.config = { ...config };
9600
9654
  this.watcher = new ContractWatcher({
9601
9655
  indexerProvider: config.indexerProvider,
@@ -9617,20 +9671,26 @@ var ContractManager = class _ContractManager {
9617
9671
  * {@link initialize}, {@link getContractsWithVtxos} and {@link createContract}.
9618
9672
  */
9619
9673
  getSyncState() {
9620
- return this.syncDegradedReason === void 0 ? { mode: "online", lastSyncedAt: this.lastSyncedAt } : {
9674
+ const syncing = this.syncsInFlight > 0;
9675
+ return this.syncDegradedReason === void 0 ? { mode: "online", syncing, lastSyncedAt: this.lastSyncedAt } : {
9621
9676
  mode: "degraded",
9677
+ syncing,
9622
9678
  reason: this.syncDegradedReason,
9623
9679
  lastSyncedAt: this.lastSyncedAt
9624
9680
  };
9625
9681
  }
9682
+ /** @inheritdoc */
9683
+ whenBooted() {
9684
+ return this.bootTask ?? Promise.resolve();
9685
+ }
9626
9686
  /** @see ContractManagerConfig.vtxoSyncMaxAgeMs — for factory-built managers. */
9627
9687
  setVtxoSyncMaxAge(maxAgeMs) {
9628
- chunk5XBH5SAL_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", maxAgeMs);
9688
+ chunkKR6FLFIH_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", maxAgeMs);
9629
9689
  this.config.vtxoSyncMaxAgeMs = maxAgeMs;
9630
9690
  }
9631
9691
  /** @see ContractManagerConfig.vtxoSyncOverlapMs — for factory-built managers. */
9632
9692
  setVtxoSyncOverlap(overlapMs) {
9633
- chunk5XBH5SAL_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", overlapMs);
9693
+ chunkKR6FLFIH_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", overlapMs);
9634
9694
  this.config.vtxoSyncOverlapMs = overlapMs;
9635
9695
  }
9636
9696
  markSyncOnline() {
@@ -9645,9 +9705,14 @@ var ContractManager = class _ContractManager {
9645
9705
  syncGapReason() {
9646
9706
  const annotations = this.annotationDegradedReason();
9647
9707
  const owedRefill = this.lookAheadRefillOwed ? "the look-ahead band is behind the allocation watermark, so a funded address inside it is not being watched yet" : void 0;
9648
- const reasons = [annotations, owedRefill].filter((r) => r !== void 0);
9708
+ const watcher = this.watcherStartFailure === void 0 ? void 0 : `the contract watcher failed to start, so incoming funds are not being observed \u2014 ${this.watcherStartFailure}`;
9709
+ const reasons = [annotations, owedRefill, watcher].filter(
9710
+ (r) => r !== void 0
9711
+ );
9649
9712
  return reasons.length === 0 ? void 0 : reasons.join("; ");
9650
9713
  }
9714
+ /** Why the lazy boot's watcher start failed; nothing retries it, so no sync may clear it. */
9715
+ watcherStartFailure;
9651
9716
  /** Contracts a sync could not annotate, as `script → reason`. */
9652
9717
  annotationFailures = /* @__PURE__ */ new Map();
9653
9718
  annotationDegradedReason() {
@@ -9673,7 +9738,7 @@ var ContractManager = class _ContractManager {
9673
9738
  this.markSyncOnline();
9674
9739
  return void 0;
9675
9740
  } catch (err) {
9676
- if (!chunk5XBH5SAL_cjs.isRetryableProviderError(err)) throw err;
9741
+ if (!chunkKR6FLFIH_cjs.isRetryableProviderError(err)) throw err;
9677
9742
  this.markSyncDegraded(err);
9678
9743
  return err;
9679
9744
  }
@@ -9692,20 +9757,74 @@ var ContractManager = class _ContractManager {
9692
9757
  for (const contract of contracts) {
9693
9758
  await this.watcher.addContract(contract);
9694
9759
  }
9695
- try {
9696
- await this.scheduleLookAheadDrain();
9697
- } catch (err) {
9698
- if (!chunk5XBH5SAL_cjs.isRetryableProviderError(err)) throw err;
9699
- this.lookAheadRefillOwed = true;
9700
- this.markSyncDegraded(err);
9760
+ if (!this.config.lazyInitialization) {
9761
+ try {
9762
+ await this.scheduleLookAheadDrain();
9763
+ } catch (err) {
9764
+ if (!chunkKR6FLFIH_cjs.isRetryableProviderError(err)) throw err;
9765
+ this.lookAheadRefillOwed = true;
9766
+ this.markSyncDegraded(err);
9767
+ }
9768
+ await this.trySync(() => this.reconcileWatched());
9769
+ this.initialized = true;
9770
+ this.stopWatcherFn = await this.watcher.startWatching(
9771
+ (event) => this.onWatcherEvent(event)
9772
+ );
9773
+ return;
9701
9774
  }
9702
- await this.trySync(() => this.reconcileWatched());
9703
9775
  this.initialized = true;
9704
- this.stopWatcherFn = await this.watcher.startWatching((event) => {
9705
- this.handleContractEvent(event).catch((error) => {
9706
- console.error("Error handling contract event:", error);
9707
- });
9776
+ const boot = this.runBootSequence();
9777
+ this.bootTask = boot;
9778
+ void boot.catch(() => {
9779
+ }).finally(() => {
9780
+ if (this.bootTask === boot) this.bootTask = void 0;
9781
+ });
9782
+ }
9783
+ async runBootSequence() {
9784
+ this.syncsInFlight++;
9785
+ this.watcherStartFailure = void 0;
9786
+ try {
9787
+ try {
9788
+ await this.scheduleLookAheadDrain();
9789
+ } catch (err) {
9790
+ this.lookAheadRefillOwed = true;
9791
+ this.reportBackgroundFailure("look-ahead drain", err);
9792
+ }
9793
+ try {
9794
+ await this.reconcileWatched();
9795
+ this.markSyncOnline();
9796
+ } catch (err) {
9797
+ this.reportBackgroundFailure("boot sync", err);
9798
+ }
9799
+ if (this.disposed) return;
9800
+ try {
9801
+ const stopWatching = await this.watcher.startWatching(
9802
+ (event) => this.onWatcherEvent(event)
9803
+ );
9804
+ if (this.disposed) stopWatching();
9805
+ else this.stopWatcherFn = stopWatching;
9806
+ } catch (err) {
9807
+ this.watcherStartFailure = err instanceof Error ? err.message : String(err);
9808
+ this.reportBackgroundFailure("watcher start", err);
9809
+ }
9810
+ } finally {
9811
+ this.syncsInFlight--;
9812
+ }
9813
+ }
9814
+ /** Tracked so {@link dispose} can wait for handlers still writing. */
9815
+ onWatcherEvent(event) {
9816
+ const handled = this.handleContractEvent(event).catch((error) => {
9817
+ console.error("Error handling contract event:", error);
9708
9818
  });
9819
+ this.inFlightEvents.add(handled);
9820
+ void handled.finally(() => this.inFlightEvents.delete(handled));
9821
+ }
9822
+ /** No throw: construction returned long ago, so the state is the channel. */
9823
+ reportBackgroundFailure(stage, err) {
9824
+ this.markSyncDegraded(err);
9825
+ if (!chunkKR6FLFIH_cjs.isRetryableProviderError(err)) {
9826
+ console.error(`[contracts] background ${stage} failed`, err);
9827
+ }
9709
9828
  }
9710
9829
  /**
9711
9830
  * Delta-sync the watched set (boot and reconnect), then reconcile the pending frontier, which
@@ -9805,7 +9924,7 @@ var ContractManager = class _ContractManager {
9805
9924
  const from = Math.max(0, watermark - lookAhead.size);
9806
9925
  const to = watermark + lookAhead.size;
9807
9926
  const deps = lookAhead.candidateDeps();
9808
- const handlers = chunkGVF4OCTL_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkGVF4OCTL_cjs.contractHandlers.get(t)).filter(hasCandidates);
9927
+ const handlers = chunkQLJXXVRO_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkQLJXXVRO_cjs.contractHandlers.get(t)).filter(hasCandidates);
9809
9928
  const band = /* @__PURE__ */ new Map();
9810
9929
  for (let index = from; index <= to; index++) {
9811
9930
  const descriptor = lookAhead.materialize(index);
@@ -9816,7 +9935,7 @@ var ContractManager = class _ContractManager {
9816
9935
  index,
9817
9936
  params: {
9818
9937
  ...candidate,
9819
- ...chunkGVF4OCTL_cjs.speculativeReceiveMetadata(descriptor)
9938
+ ...chunkQLJXXVRO_cjs.speculativeReceiveMetadata(descriptor)
9820
9939
  }
9821
9940
  });
9822
9941
  }
@@ -9875,7 +9994,7 @@ var ContractManager = class _ContractManager {
9875
9994
  });
9876
9995
  for (const entry of pending) entry.catchUpPending = false;
9877
9996
  } catch (err) {
9878
- if (!chunk5XBH5SAL_cjs.isRetryableProviderError(err)) throw err;
9997
+ if (!chunkKR6FLFIH_cjs.isRetryableProviderError(err)) throw err;
9879
9998
  this.markSyncDegraded(err);
9880
9999
  }
9881
10000
  }
@@ -9966,7 +10085,7 @@ var ContractManager = class _ContractManager {
9966
10085
  return result;
9967
10086
  }
9968
10087
  async upsertContractRow(params) {
9969
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(params.type);
10088
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(params.type);
9970
10089
  if (!handler) {
9971
10090
  throw new Error(`No handler registered for contract type '${params.type}'`);
9972
10091
  }
@@ -10034,7 +10153,7 @@ var ContractManager = class _ContractManager {
10034
10153
  `scanContracts: batchSize must be a positive integer (got ${String(opts.batchSize)})`
10035
10154
  );
10036
10155
  }
10037
- const registered = chunkGVF4OCTL_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkGVF4OCTL_cjs.contractHandlers.get(t)).filter(isDiscoverable);
10156
+ const registered = chunkQLJXXVRO_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkQLJXXVRO_cjs.contractHandlers.get(t)).filter(isDiscoverable);
10038
10157
  const discoverables = [
10039
10158
  ...registered.filter((h) => h.type === "boarding"),
10040
10159
  ...registered.filter((h) => h.type !== "boarding")
@@ -10160,7 +10279,7 @@ var ContractManager = class _ContractManager {
10160
10279
  return await collectContracts(this.config.contractRepository, dbFilter);
10161
10280
  }
10162
10281
  async getContractsWithVtxos(filter, pageSize, options) {
10163
- chunk5XBH5SAL_cjs.assertNonNegativeMs("maxSyncAgeMs", options?.maxSyncAgeMs);
10282
+ chunkKR6FLFIH_cjs.assertNonNegativeMs("maxSyncAgeMs", options?.maxSyncAgeMs);
10164
10283
  const contracts = await this.getContracts(filter);
10165
10284
  if (this.syncedWithin(
10166
10285
  contracts,
@@ -10187,6 +10306,32 @@ var ContractManager = class _ContractManager {
10187
10306
  vtxos: vtxosByScript.get(contract.script)?.slice() ?? []
10188
10307
  }));
10189
10308
  }
10309
+ async getStoredContractsWithVtxos(filter) {
10310
+ const contracts = await this.getContracts(filter);
10311
+ if (!this.syncedWithin(contracts, this.config.vtxoSyncMaxAgeMs ?? 0)) {
10312
+ this.requestCatchUpSync(contracts);
10313
+ }
10314
+ const vtxos = await this.getVtxosForContracts(contracts);
10315
+ return contracts.map((contract) => ({
10316
+ contract,
10317
+ vtxos: vtxos.filter((vtxo) => vtxo.contractScript === contract.script)
10318
+ }));
10319
+ }
10320
+ requestCatchUpSync(contracts) {
10321
+ if (this.disposed || this.bootTask || this.catchUpSync || contracts.length === 0) return;
10322
+ const run = (async () => {
10323
+ try {
10324
+ await this.syncContracts({ contracts });
10325
+ this.markSyncOnline();
10326
+ } catch (err) {
10327
+ this.reportBackgroundFailure("catch-up sync", err);
10328
+ }
10329
+ })();
10330
+ this.catchUpSync = run;
10331
+ void run.finally(() => {
10332
+ if (this.catchUpSync === run) this.catchUpSync = void 0;
10333
+ });
10334
+ }
10190
10335
  async annotateVtxos(vtxos, tapscripts) {
10191
10336
  if (vtxos.length === 0) return [];
10192
10337
  const scripts = Array.from(new Set(vtxos.map((v) => v.script)));
@@ -10199,7 +10344,7 @@ var ContractManager = class _ContractManager {
10199
10344
  }
10200
10345
  const tapscriptCache = tapscripts ?? /* @__PURE__ */ new Map();
10201
10346
  return vtxos.map(
10202
- (vtxo) => extendVirtualCoinForContract(chunk5XBH5SAL_cjs.normalizeVtxo(vtxo), byScript, tapscriptCache)
10347
+ (vtxo) => extendVirtualCoinForContract(chunkKR6FLFIH_cjs.normalizeVtxo(vtxo), byScript, tapscriptCache)
10203
10348
  );
10204
10349
  }
10205
10350
  /** @inheritdoc */
@@ -10244,14 +10389,14 @@ var ContractManager = class _ContractManager {
10244
10389
  const byScript = new Map(contracts.map((contract) => [contract.script, contract]));
10245
10390
  const asking = vtxos.filter((vtxo) => {
10246
10391
  const contract = byScript.get(vtxo.script);
10247
- return contract !== void 0 && chunkGVF4OCTL_cjs.contractHandlers.get(contract.type)?.assertSpendableNow !== void 0;
10392
+ return contract !== void 0 && chunkQLJXXVRO_cjs.contractHandlers.get(contract.type)?.assertSpendableNow !== void 0;
10248
10393
  });
10249
10394
  if (asking.length === 0) return refused;
10250
10395
  const tip = await this.currentChainTip();
10251
10396
  const walletDescriptorValue = await walletDescriptor?.();
10252
10397
  for (const vtxo of asking) {
10253
10398
  const contract = byScript.get(vtxo.script);
10254
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(contract.type);
10399
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(contract.type);
10255
10400
  if (!handler?.assertSpendableNow) continue;
10256
10401
  const context = {
10257
10402
  collaborative: true,
@@ -10261,7 +10406,7 @@ var ContractManager = class _ContractManager {
10261
10406
  walletDescriptor: walletDescriptorValue,
10262
10407
  // `isVirtualCoin` only checks `script`, which every input has; `isCsvSpendable`
10263
10408
  // reads `vtxo.status.block_time` unguarded, so require `status` too.
10264
- vtxo: chunk5XBH5SAL_cjs.isVirtualCoin(vtxo) && "status" in vtxo ? vtxo : void 0
10409
+ vtxo: chunkKR6FLFIH_cjs.isVirtualCoin(vtxo) && "status" in vtxo ? vtxo : void 0
10265
10410
  };
10266
10411
  try {
10267
10412
  await handler.assertSpendableNow(
@@ -10374,7 +10519,7 @@ var ContractManager = class _ContractManager {
10374
10519
  const { contractScript, collaborative = true, walletDescriptor, vtxo } = options;
10375
10520
  const [contract] = await this.getContracts({ script: contractScript });
10376
10521
  if (!contract) return [];
10377
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(contract.type);
10522
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(contract.type);
10378
10523
  if (!handler) return [];
10379
10524
  const script = handler.createScript(contract.params);
10380
10525
  const tip = await this.currentChainTip();
@@ -10396,7 +10541,7 @@ var ContractManager = class _ContractManager {
10396
10541
  const { contractScript, collaborative = true, walletDescriptor } = options;
10397
10542
  const [contract] = await this.getContracts({ script: contractScript });
10398
10543
  if (!contract) return [];
10399
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(contract.type);
10544
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(contract.type);
10400
10545
  if (!handler) return [];
10401
10546
  const script = handler.createScript(contract.params);
10402
10547
  const context = {
@@ -10442,7 +10587,7 @@ var ContractManager = class _ContractManager {
10442
10587
  }
10443
10588
  async refreshOutpoints(outpoints) {
10444
10589
  if (outpoints.length === 0) return;
10445
- const { vtxos } = await chunk5XBH5SAL_cjs.getNormalizedVtxos(this.config.indexerProvider, {
10590
+ const { vtxos } = await chunkKR6FLFIH_cjs.getNormalizedVtxos(this.config.indexerProvider, {
10446
10591
  outpoints
10447
10592
  });
10448
10593
  if (vtxos.length === 0) return;
@@ -10503,6 +10648,7 @@ var ContractManager = class _ContractManager {
10503
10648
  }
10504
10649
  }
10505
10650
  async handleContractEvent(event) {
10651
+ if (this.disposed) return;
10506
10652
  if (this.lookAheadRefillOwed) this.requestLookAheadDrain();
10507
10653
  try {
10508
10654
  switch (event.type) {
@@ -10534,7 +10680,7 @@ var ContractManager = class _ContractManager {
10534
10680
  break;
10535
10681
  }
10536
10682
  } catch (err) {
10537
- if (!chunk5XBH5SAL_cjs.isRetryableProviderError(err)) throw err;
10683
+ if (!chunkKR6FLFIH_cjs.isRetryableProviderError(err)) throw err;
10538
10684
  this.markSyncDegraded(err);
10539
10685
  }
10540
10686
  this.emitEvent(event);
@@ -10556,6 +10702,14 @@ var ContractManager = class _ContractManager {
10556
10702
  }
10557
10703
  /** Sync virtual outputs for the given contracts (default: the watched set). */
10558
10704
  async syncContracts(options) {
10705
+ this.syncsInFlight++;
10706
+ try {
10707
+ return await this.performContractSync(options);
10708
+ } finally {
10709
+ this.syncsInFlight--;
10710
+ }
10711
+ }
10712
+ async performContractSync(options) {
10559
10713
  const cursor = await getSyncCursor(this.config.walletRepository);
10560
10714
  const window2 = options.window ?? computeSyncWindow(cursor, this.config.vtxoSyncOverlapMs);
10561
10715
  const mustUpdateCursor = options.contracts === void 0 && options.window === void 0 && (window2.after ?? 0) <= cursor;
@@ -10609,7 +10763,7 @@ var ContractManager = class _ContractManager {
10609
10763
  */
10610
10764
  async reconcilePendingFrontier(contracts) {
10611
10765
  const scriptToContract = new Map(contracts.map((c) => [c.script, c]));
10612
- const vtxos = await chunk5XBH5SAL_cjs.getAllNormalizedVtxos(
10766
+ const vtxos = await chunkKR6FLFIH_cjs.getAllNormalizedVtxos(
10613
10767
  this.config.indexerProvider,
10614
10768
  contracts.map((c) => c.script),
10615
10769
  { pendingOnly: true }
@@ -10683,7 +10837,7 @@ var ContractManager = class _ContractManager {
10683
10837
  }
10684
10838
  return result;
10685
10839
  }
10686
- async fetchContractVtxosBulk(contracts, pageSize = chunk5XBH5SAL_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
10840
+ async fetchContractVtxosBulk(contracts, pageSize = chunkKR6FLFIH_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
10687
10841
  if (contracts.length === 0) {
10688
10842
  return { vtxosByScript: /* @__PURE__ */ new Map(), promoted: /* @__PURE__ */ new Map() };
10689
10843
  }
@@ -10699,7 +10853,7 @@ var ContractManager = class _ContractManager {
10699
10853
  before: syncWindow.before
10700
10854
  }
10701
10855
  } : {};
10702
- const vtxos = await chunk5XBH5SAL_cjs.getAllNormalizedVtxos(
10856
+ const vtxos = await chunkKR6FLFIH_cjs.getAllNormalizedVtxos(
10703
10857
  this.config.indexerProvider,
10704
10858
  contracts.map((c) => c.script),
10705
10859
  { ...windowOpts, pageSize }
@@ -10724,34 +10878,49 @@ var ContractManager = class _ContractManager {
10724
10878
  }
10725
10879
  return { vtxosByScript: result, promoted };
10726
10880
  }
10727
- /** Stop the watcher, clear callbacks, and mark the manager uninitialized. */
10881
+ /**
10882
+ * Stop the watcher, clear callbacks, and mark the manager uninitialized.
10883
+ *
10884
+ * Teardown is synchronous. The returned promise settles once watcher events already being
10885
+ * handled, any look-ahead drain, and any lazy boot sequence finish; after that nothing more is written to the
10886
+ * repositories.
10887
+ */
10728
10888
  dispose() {
10729
10889
  this.disposed = true;
10730
10890
  const pendingDrain = this.lookAheadDrain;
10891
+ const pendingBoot = this.bootTask;
10731
10892
  this.stopWatcherFn?.();
10732
10893
  this.stopWatcherFn = void 0;
10733
10894
  this.eventCallbacks.clear();
10734
10895
  this.lookAheadEntries.clear();
10735
- if (pendingDrain) {
10736
- void pendingDrain.catch(() => {
10737
- }).then(() => {
10738
- if (this.disposed) this.lookAheadEntries.clear();
10739
- });
10740
- }
10896
+ const drainUnwound = pendingDrain?.catch(() => {
10897
+ }).then(() => {
10898
+ if (this.disposed) this.lookAheadEntries.clear();
10899
+ });
10741
10900
  this.initialized = false;
10901
+ return Promise.all([...this.inFlightEvents, drainUnwound, pendingBoot]).then(
10902
+ () => void 0
10903
+ );
10742
10904
  }
10743
10905
  /**
10744
- * Symbol.dispose implementation for the `using` keyword.
10906
+ * Symbol.dispose implementation for the `using` keyword. Teardown is immediate, but it does
10907
+ * not wait for in-flight work; use `await using` for that.
10908
+ */
10909
+ [Symbol.dispose]() {
10910
+ void this.dispose();
10911
+ }
10912
+ /**
10913
+ * Symbol.asyncDispose implementation for the `await using` keyword; waits like {@link dispose}.
10745
10914
  * @example
10746
10915
  * ```typescript
10747
10916
  * {
10748
- * using manager = await wallet.getContractManager();
10917
+ * await using manager = await wallet.getContractManager();
10749
10918
  * // ... use manager
10750
- * } // automatically disposed
10919
+ * } // disposed, with in-flight events finished
10751
10920
  * ```
10752
10921
  */
10753
- [Symbol.dispose]() {
10754
- this.dispose();
10922
+ async [Symbol.asyncDispose]() {
10923
+ await this.dispose();
10755
10924
  }
10756
10925
  };
10757
10926
 
@@ -10786,7 +10955,7 @@ function parseLegacyExpiry(batchExpiry) {
10786
10955
  if (typeof batchExpiry !== "number" || !Number.isFinite(batchExpiry) || batchExpiry <= 0) {
10787
10956
  return {};
10788
10957
  }
10789
- if (batchExpiry >= chunk5XBH5SAL_cjs.EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(batchExpiry) };
10958
+ if (batchExpiry >= chunkKR6FLFIH_cjs.EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(batchExpiry) };
10790
10959
  return { expiresAtHeight: batchExpiry / 1e3 };
10791
10960
  }
10792
10961
  function legacyVtxoFacts(status) {
@@ -11024,7 +11193,7 @@ function backfillContractWatchState(store) {
11024
11193
  };
11025
11194
  readPage();
11026
11195
  }
11027
- var unspentFlag = (vtxo) => chunk5XBH5SAL_cjs.isVtxoSpent(vtxo) ? {} : { unspent: 1 };
11196
+ var unspentFlag = (vtxo) => chunkKR6FLFIH_cjs.isVtxoSpent(vtxo) ? {} : { unspent: 1 };
11028
11197
  function backfillVtxoIndexFields(transaction) {
11029
11198
  const store = transaction.objectStore(STORE_VTXOS);
11030
11199
  const pageSize = 1e3;
@@ -11055,7 +11224,7 @@ var DEFAULT_DB_NAME = "arkade-service-worker";
11055
11224
  var DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS = 1e4;
11056
11225
  function normalizeOptions2(pathOrOptions) {
11057
11226
  const o = typeof pathOrOptions === "string" ? { path: pathOrOptions } : pathOrOptions;
11058
- chunk5XBH5SAL_cjs.assertTimerMs("activationTimeoutMs", o.activationTimeoutMs);
11227
+ chunkKR6FLFIH_cjs.assertTimerMs("activationTimeoutMs", o.activationTimeoutMs);
11059
11228
  return {
11060
11229
  path: o.path,
11061
11230
  activationTimeoutMs: o.activationTimeoutMs ?? DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS
@@ -11274,7 +11443,7 @@ var deserializeTapLeaf = (t) => {
11274
11443
  const s = base.hex.decode(t.s);
11275
11444
  return [cb, s];
11276
11445
  };
11277
- var deserializeVtxo = (o) => chunk5XBH5SAL_cjs.normalizeVtxo({
11446
+ var deserializeVtxo = (o) => chunkKR6FLFIH_cjs.normalizeVtxo({
11278
11447
  ...o,
11279
11448
  createdAt: new Date(o.createdAt),
11280
11449
  tapTree: base.hex.decode(o.tapTree),
@@ -11698,7 +11867,7 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
11698
11867
  */
11699
11868
  materializeDescriptorAt(index) {
11700
11869
  const descriptor = this.identity.descriptor;
11701
- const network = chunkGVF4OCTL_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
11870
+ const network = chunkQLJXXVRO_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
11702
11871
  const expansion = descriptorsScure.expand({ descriptor, network, index });
11703
11872
  const keyInfo = expansion.expansionMap?.["@0"];
11704
11873
  if (!keyInfo?.keyExpression) {
@@ -11766,7 +11935,7 @@ function signingDescriptorIndex(descriptor) {
11766
11935
  }
11767
11936
  function newestWalletReceiveContract(contracts, serverPubKeyHex) {
11768
11937
  return contracts.filter(
11769
- (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkGVF4OCTL_cjs.WALLET_RECEIVE_SOURCE
11938
+ (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkQLJXXVRO_cjs.WALLET_RECEIVE_SOURCE
11770
11939
  ).sort((a, b) => {
11771
11940
  if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
11772
11941
  return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
@@ -11817,7 +11986,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
11817
11986
  const provider = await resolveDescriptorProvider(config, setup.walletRepository);
11818
11987
  if (!provider) return void 0;
11819
11988
  const allowSilentFallback = (config.walletMode ?? "auto") === "auto";
11820
- const expectedContractType = setup.offchainTapscript instanceof chunkGVF4OCTL_cjs.DelegateVtxo.Script ? "delegate" : "default";
11989
+ const expectedContractType = setup.offchainTapscript instanceof chunkQLJXXVRO_cjs.DelegateVtxo.Script ? "delegate" : "default";
11821
11990
  const factoryOpts = {
11822
11991
  walletRepository: setup.walletRepository,
11823
11992
  contractRepository: setup.contractRepository,
@@ -11974,7 +12143,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
11974
12143
  };
11975
12144
  function deriveLeafPubkey(descriptor) {
11976
12145
  try {
11977
- return chunkGVF4OCTL_cjs.deriveDescriptorLeafPubKey(descriptor);
12146
+ return chunkQLJXXVRO_cjs.deriveDescriptorLeafPubKey(descriptor);
11978
12147
  } catch (e) {
11979
12148
  throw new NonRangeableDescriptorError(
11980
12149
  "Cannot derive leaf pubkey: descriptor is not a materialized, parsable tr(...) shape.",
@@ -11986,7 +12155,7 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
11986
12155
  const pubKey = deriveLeafPubkey(descriptor);
11987
12156
  const tapscript = rebuildTapscript(current, pubKey);
11988
12157
  const serverPubKey = tapscript.options.serverPubKey;
11989
- const csvTimelock2 = chunk5XBH5SAL_cjs.timelockToSequence(tapscript.options.csvTimelock).toString();
12158
+ const csvTimelock2 = chunkKR6FLFIH_cjs.timelockToSequence(tapscript.options.csvTimelock).toString();
11990
12159
  const base$1 = {
11991
12160
  script: base.hex.encode(tapscript.pkScript),
11992
12161
  address: tapscript.address(hrp, serverPubKey).encode(),
@@ -11994,11 +12163,11 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
11994
12163
  // Read at sign time to route rotated-pubkey inputs through `signWithDescriptor`; without
11995
12164
  // it spends are rejected with `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
11996
12165
  metadata: {
11997
- ...tagSource && { source: chunkGVF4OCTL_cjs.WALLET_RECEIVE_SOURCE },
12166
+ ...tagSource && { source: chunkQLJXXVRO_cjs.WALLET_RECEIVE_SOURCE },
11998
12167
  signingDescriptor: descriptor
11999
12168
  }
12000
12169
  };
12001
- const params = tapscript instanceof chunkGVF4OCTL_cjs.DelegateVtxo.Script ? {
12170
+ const params = tapscript instanceof chunkQLJXXVRO_cjs.DelegateVtxo.Script ? {
12002
12171
  ...base$1,
12003
12172
  type: "delegate",
12004
12173
  params: {
@@ -12019,10 +12188,10 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
12019
12188
  return { tapscript, params };
12020
12189
  }
12021
12190
  function rebuildTapscript(current, pubKey) {
12022
- if (current instanceof chunkGVF4OCTL_cjs.DelegateVtxo.Script) {
12023
- return new chunkGVF4OCTL_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
12191
+ if (current instanceof chunkQLJXXVRO_cjs.DelegateVtxo.Script) {
12192
+ return new chunkQLJXXVRO_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
12024
12193
  }
12025
- return new chunkGVF4OCTL_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
12194
+ return new chunkQLJXXVRO_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
12026
12195
  }
12027
12196
  async function pickActiveReceive(contractRepository, serverPubKey, expectedType) {
12028
12197
  const candidates = await collectContracts(contractRepository, {
@@ -12080,7 +12249,7 @@ function computeOffchainBalance(vtxos, caps) {
12080
12249
  }
12081
12250
  };
12082
12251
  for (const vtxo of vtxos) {
12083
- if (chunk5XBH5SAL_cjs.isVtxoSpent(vtxo)) continue;
12252
+ if (chunkKR6FLFIH_cjs.isVtxoSpent(vtxo)) continue;
12084
12253
  addAssets(owned, vtxo);
12085
12254
  if (vtxo.isUnrolled) {
12086
12255
  unrolled += vtxo.value;
@@ -12090,11 +12259,11 @@ function computeOffchainBalance(vtxos, caps) {
12090
12259
  pendingRecovery += vtxo.value;
12091
12260
  continue;
12092
12261
  }
12093
- if (chunk5XBH5SAL_cjs.canRecoverOnchain(vtxo, now)) {
12262
+ if (chunkKR6FLFIH_cjs.canRecoverOnchain(vtxo, now)) {
12094
12263
  recoverable += vtxo.value;
12095
12264
  continue;
12096
12265
  }
12097
- if (!chunk5XBH5SAL_cjs.canSpendOffchain(vtxo, now)) continue;
12266
+ if (!chunkKR6FLFIH_cjs.canSpendOffchain(vtxo, now)) continue;
12098
12267
  if (vtxo.isPreconfirmed) {
12099
12268
  preconfirmed += vtxo.value;
12100
12269
  } else {
@@ -12305,7 +12474,7 @@ function intentProofJobs(coins) {
12305
12474
  if (coins.length === 0) return [];
12306
12475
  const coinJobs = coins.map((coin, i) => ({
12307
12476
  index: i + 1,
12308
- lookupScript: chunk5XBH5SAL_cjs.VtxoScript.decode(coin.tapTree).pkScript
12477
+ lookupScript: chunkKR6FLFIH_cjs.VtxoScript.decode(coin.tapTree).pkScript
12309
12478
  }));
12310
12479
  return [{ index: 0, lookupScript: coinJobs[0].lookupScript }, ...coinJobs];
12311
12480
  }
@@ -12331,7 +12500,7 @@ function dedupeTimelocks(timelocks) {
12331
12500
  const seen = /* @__PURE__ */ new Set();
12332
12501
  const deduped = [];
12333
12502
  for (const timelock of timelocks) {
12334
- const sequence = chunk5XBH5SAL_cjs.timelockToSequence(timelock).toString();
12503
+ const sequence = chunkKR6FLFIH_cjs.timelockToSequence(timelock).toString();
12335
12504
  if (seen.has(sequence)) continue;
12336
12505
  seen.add(sequence);
12337
12506
  deduped.push(timelock);
@@ -12347,7 +12516,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
12347
12516
  if (!newest?.params.pubKey) return baseline;
12348
12517
  try {
12349
12518
  const pubKey = base.hex.decode(newest.params.pubKey);
12350
- return new chunkGVF4OCTL_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
12519
+ return new chunkQLJXXVRO_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
12351
12520
  } catch (e) {
12352
12521
  console.warn("Skipping malformed boarding contract at boot", newest.script, e);
12353
12522
  return baseline;
@@ -12379,21 +12548,21 @@ function filterFlatVtxos(vtxos, filter, pendingSpendOutpoints) {
12379
12548
  if (vtxo.isUnrolled) {
12380
12549
  return !!f.withUnrolled;
12381
12550
  }
12382
- if (chunk5XBH5SAL_cjs.isVtxoSpent(vtxo)) {
12551
+ if (chunkKR6FLFIH_cjs.isVtxoSpent(vtxo)) {
12383
12552
  return false;
12384
12553
  }
12385
- if (!f.withRecoverable && chunk5XBH5SAL_cjs.canRecoverOnchain(vtxo, now)) {
12554
+ if (!f.withRecoverable && chunkKR6FLFIH_cjs.canRecoverOnchain(vtxo, now)) {
12386
12555
  return false;
12387
12556
  }
12388
12557
  return true;
12389
12558
  });
12390
12559
  }
12391
12560
  async function refreshSweptStateOfExpiredInputs(wallet, inputs) {
12392
- const candidates = inputs.filter(chunk5XBH5SAL_cjs.isVirtualCoin).map(chunk5XBH5SAL_cjs.normalizeVtxo).filter((v) => !v.isSwept);
12561
+ const candidates = inputs.filter(chunkKR6FLFIH_cjs.isVirtualCoin).map(chunkKR6FLFIH_cjs.normalizeVtxo).filter((v) => !v.isSwept);
12393
12562
  if (candidates.length === 0) return inputs;
12394
- const now = candidates.some((v) => v.expiresAtHeight !== void 0) ? await chunk5XBH5SAL_cjs.resolveTimeHeight(wallet.onchainProvider) : { timestamp: /* @__PURE__ */ new Date() };
12563
+ const now = candidates.some((v) => v.expiresAtHeight !== void 0) ? await chunkKR6FLFIH_cjs.resolveTimeHeight(wallet.onchainProvider) : { timestamp: /* @__PURE__ */ new Date() };
12395
12564
  const suspects = candidates.filter(
12396
- (v) => chunk5XBH5SAL_cjs.isPastExpiry(v, now) || v.expiresAtHeight !== void 0 && now.height === void 0
12565
+ (v) => chunkKR6FLFIH_cjs.isPastExpiry(v, now) || v.expiresAtHeight !== void 0 && now.height === void 0
12397
12566
  );
12398
12567
  if (suspects.length === 0) return inputs;
12399
12568
  let sweptNow;
@@ -12407,12 +12576,12 @@ async function refreshSweptStateOfExpiredInputs(wallet, inputs) {
12407
12576
  );
12408
12577
  } catch (e) {
12409
12578
  const message = "could not confirm the swept state of expired settlement inputs; retry the settlement";
12410
- throw chunk5XBH5SAL_cjs.isRetryableProviderError(e) ? new chunk5XBH5SAL_cjs.ProviderUnavailableError(message, { cause: e }) : new Error(message, { cause: e });
12579
+ throw chunkKR6FLFIH_cjs.isRetryableProviderError(e) ? new chunkKR6FLFIH_cjs.ProviderUnavailableError(message, { cause: e }) : new Error(message, { cause: e });
12411
12580
  }
12412
12581
  if (sweptNow.size === 0) return inputs;
12413
12582
  return inputs.map((input) => {
12414
- if (!chunk5XBH5SAL_cjs.isVirtualCoin(input) || !sweptNow.has(`${input.txid}:${input.vout}`)) return input;
12415
- return { ...chunk5XBH5SAL_cjs.normalizeVtxo(input), isSwept: true };
12583
+ if (!chunkKR6FLFIH_cjs.isVirtualCoin(input) || !sweptNow.has(`${input.txid}:${input.vout}`)) return input;
12584
+ return { ...chunkKR6FLFIH_cjs.normalizeVtxo(input), isSwept: true };
12416
12585
  });
12417
12586
  }
12418
12587
  var PENDING_RECOVERY_REASON = "is past its operator signer's rotation cutoff \u2014 the operator will not co-sign it until it recovers";
@@ -12495,6 +12664,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
12495
12664
  walletRepository;
12496
12665
  contractRepository;
12497
12666
  delegateProvider;
12667
+ lazyInitialization = false;
12668
+ boardingLoaded = false;
12498
12669
  _contractManager;
12499
12670
  _contractManagerInitializing;
12500
12671
  watcherConfig;
@@ -12557,9 +12728,11 @@ var ReadonlyWallet = class _ReadonlyWallet {
12557
12728
  * construct, so it is safe for readonly callers.
12558
12729
  */
12559
12730
  getProviderConnectionState() {
12731
+ const syncing = this._contractManager?.getSyncState().syncing ?? false;
12560
12732
  if (this._serverInfoSource === "cache") {
12561
12733
  return {
12562
12734
  mode: "degraded",
12735
+ syncing,
12563
12736
  source: "cache",
12564
12737
  provider: "arkade",
12565
12738
  reason: "constructed from cached server-info; operator was unreachable at boot",
@@ -12570,6 +12743,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12570
12743
  if (sync?.mode === "degraded") {
12571
12744
  return {
12572
12745
  mode: "degraded",
12746
+ syncing,
12573
12747
  source: "repository",
12574
12748
  provider: "indexer",
12575
12749
  reason: sync.reason,
@@ -12578,6 +12752,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12578
12752
  }
12579
12753
  return {
12580
12754
  mode: "online",
12755
+ syncing,
12581
12756
  source: "live",
12582
12757
  lastOnlineAt: sync?.lastSyncedAt ?? this._serverInfoLastOnlineAt ?? 0
12583
12758
  };
@@ -12679,7 +12854,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12679
12854
  async getArkadeReader() {
12680
12855
  const indexer = this.indexerProvider;
12681
12856
  return {
12682
- getVtxos: (opts) => chunk5XBH5SAL_cjs.getNormalizedVtxos(indexer, opts),
12857
+ getVtxos: (opts) => chunkKR6FLFIH_cjs.getNormalizedVtxos(indexer, opts),
12683
12858
  getVirtualTxs: (txids, opts) => indexer.getVirtualTxs(txids, opts)
12684
12859
  };
12685
12860
  }
@@ -12714,7 +12889,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12714
12889
  }
12715
12890
  /** Shared setup for ReadonlyWallet.create() and Wallet.create(). */
12716
12891
  static async setupWalletConfig(config, pubKey) {
12717
- const arkProvider = config.arkProvider || new chunk5XBH5SAL_cjs.RestArkProvider();
12892
+ const arkProvider = config.arkProvider || new chunkKR6FLFIH_cjs.RestArkProvider();
12718
12893
  let indexerProvider = config.indexerProvider;
12719
12894
  if (!indexerProvider) {
12720
12895
  const derived = extractArkProviderUrl(arkProvider);
@@ -12723,7 +12898,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12723
12898
  "indexerProvider is required when arkProvider is provided without a discoverable serverUrl"
12724
12899
  );
12725
12900
  }
12726
- indexerProvider = new chunkQ7PC3NHX_cjs.RestIndexerProvider(derived ?? chunk5XBH5SAL_cjs.DEFAULT_ARKADE_SERVER_URL);
12901
+ indexerProvider = new chunkYFHGGSII_cjs.RestIndexerProvider(derived ?? chunkKR6FLFIH_cjs.DEFAULT_ARKADE_SERVER_URL);
12727
12902
  }
12728
12903
  const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
12729
12904
  const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
@@ -12732,7 +12907,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12732
12907
  source: serverInfoSource,
12733
12908
  lastOnlineAt: serverInfoLastOnlineAt
12734
12909
  } = await resolveArkInfo(arkProvider, walletRepository);
12735
- const network = chunk5XBH5SAL_cjs.networkFromArkadeInfo(info);
12910
+ const network = chunkKR6FLFIH_cjs.networkFromArkadeInfo(info);
12736
12911
  if ("descriptor" in config.identity) {
12737
12912
  const descriptor = config.identity.descriptor;
12738
12913
  const identityIsMainnet = !descriptor.includes("tpub");
@@ -12768,18 +12943,18 @@ var ReadonlyWallet = class _ReadonlyWallet {
12768
12943
  }
12769
12944
  }
12770
12945
  const boardingTimelock = config.boardingTimelock ?? toTimelock(info.boardingExitDelay);
12771
- const serverPubKey = chunkGVF4OCTL_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
12772
- const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) => chunkGVF4OCTL_cjs.toXOnly(base.hex.decode(info2.pubkey), "delegate key")).catch(() => void 0) : void 0;
12946
+ const serverPubKey = chunkQLJXXVRO_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
12947
+ const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) => chunkQLJXXVRO_cjs.toXOnly(base.hex.decode(info2.pubkey), "delegate key")).catch(() => void 0) : void 0;
12773
12948
  const offchainOptions = {
12774
12949
  pubKey,
12775
12950
  serverPubKey,
12776
12951
  csvTimelock: exitTimelock
12777
12952
  };
12778
- const offchainTapscript = !delegatePubKey ? new chunkGVF4OCTL_cjs.DefaultVtxo.Script(offchainOptions) : new chunkGVF4OCTL_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
12779
- const boardingTapscript = chunkGVF4OCTL_cjs.BoardingContractHandler.createScript({
12953
+ const offchainTapscript = !delegatePubKey ? new chunkQLJXXVRO_cjs.DefaultVtxo.Script(offchainOptions) : new chunkQLJXXVRO_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
12954
+ const boardingTapscript = chunkQLJXXVRO_cjs.BoardingContractHandler.createScript({
12780
12955
  pubKey: base.hex.encode(pubKey),
12781
12956
  serverPubKey: base.hex.encode(serverPubKey),
12782
- csvTimelock: chunk5XBH5SAL_cjs.timelockToSequence(boardingTimelock).toString()
12957
+ csvTimelock: chunkKR6FLFIH_cjs.timelockToSequence(boardingTimelock).toString()
12783
12958
  });
12784
12959
  return {
12785
12960
  arkProvider,
@@ -12824,6 +12999,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12824
12999
  );
12825
13000
  wallet.vtxoSyncOverlapMs = config.vtxoSyncOverlapMs;
12826
13001
  wallet.intentRepository = config.storage?.intentRepository;
13002
+ wallet.lazyInitialization = config.lazyInitialization ?? false;
12827
13003
  wallet.virtualTxRepository = config.storage?.virtualTxRepository;
12828
13004
  wallet.exitDataCapture = config.storage?.exitDataCapture;
12829
13005
  wallet._serverInfoSource = setup.serverInfoSource;
@@ -12864,6 +13040,19 @@ var ReadonlyWallet = class _ReadonlyWallet {
12864
13040
  // The bucketer drops every spent coin and the gate reads contracts only.
12865
13041
  this.contractSnapshot(void 0, { unspentOnly: true })
12866
13042
  ]);
13043
+ return this.balanceFromSnapshot(boardingUtxos, snapshot);
13044
+ }
13045
+ /** Cached balance; inspect connection state and boarding.loaded before displaying zeros. */
13046
+ async getStoredBalance() {
13047
+ const [boardingUtxos, snapshot] = await Promise.all([
13048
+ this.getStoredBoardingUtxos(),
13049
+ this.contractSnapshotStored()
13050
+ ]);
13051
+ const balance = await this.balanceFromSnapshot(boardingUtxos, snapshot);
13052
+ balance.boarding.loaded = this.boardingLoaded;
13053
+ return balance;
13054
+ }
13055
+ async balanceFromSnapshot(boardingUtxos, snapshot) {
12867
13056
  const vtxos = filterSnapshotVtxos(
12868
13057
  snapshot,
12869
13058
  { withRecoverable: true, withUnrolled: true },
@@ -12890,6 +13079,14 @@ var ReadonlyWallet = class _ReadonlyWallet {
12890
13079
  this._pendingSpendOutpoints
12891
13080
  );
12892
13081
  }
13082
+ /** Cached VTXOs; may be empty before the first sync. Never use for coin selection. */
13083
+ async getStoredVtxos(filter) {
13084
+ return filterSnapshotVtxos(
13085
+ await this.contractSnapshotStored(),
13086
+ filter,
13087
+ this._pendingSpendOutpoints
13088
+ );
13089
+ }
12893
13090
  /** @inheritdoc */
12894
13091
  async getSpendableVtxos(filter) {
12895
13092
  const snapshot = await this.contractSnapshot(filter, {
@@ -12912,7 +13109,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12912
13109
  if (!filter?.withUnrolled) {
12913
13110
  logExcludedVtxos(
12914
13111
  "getSpendableVtxos",
12915
- snapshot.flatMap((contract) => contract.vtxos).filter((vtxo) => vtxo.isUnrolled && !chunk5XBH5SAL_cjs.isVtxoSpent(vtxo)),
13112
+ snapshot.flatMap((contract) => contract.vtxos).filter((vtxo) => vtxo.isUnrolled && !chunkKR6FLFIH_cjs.isVtxoSpent(vtxo)),
12916
13113
  [() => UNROLLED_REASON]
12917
13114
  );
12918
13115
  }
@@ -12994,6 +13191,10 @@ var ReadonlyWallet = class _ReadonlyWallet {
12994
13191
  requireSynced: filter?.requireSynced
12995
13192
  });
12996
13193
  }
13194
+ async contractSnapshotStored() {
13195
+ const contractManager = await this.getContractManager();
13196
+ return contractManager.getStoredContractsWithVtxos ? contractManager.getStoredContractsWithVtxos() : contractManager.getContractsWithVtxos();
13197
+ }
12997
13198
  /**
12998
13199
  * The two exclusion sets the gate is made of, derived from one snapshot so
12999
13200
  * {@link getSpendableVtxos} and the balance answer about the same instant.
@@ -13050,7 +13251,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13050
13251
  this.getBoardingTxs()
13051
13252
  ]);
13052
13253
  const allVtxos = snapshot.flatMap((_) => _.vtxos);
13053
- const resolveTxCreatedAt = (txids) => chunk5XBH5SAL_cjs.fetchVtxoCreatedAtByTxid(this.indexerProvider, txids);
13254
+ const resolveTxCreatedAt = (txids) => chunkKR6FLFIH_cjs.fetchVtxoCreatedAtByTxid(this.indexerProvider, txids);
13054
13255
  return buildTransactionHistory(
13055
13256
  allVtxos,
13056
13257
  boardingTxs,
@@ -13204,9 +13405,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
13204
13405
  async getBoardingTapscripts(allowedSigners) {
13205
13406
  const byScript = /* @__PURE__ */ new Map();
13206
13407
  const add = (s) => byScript.set(base.hex.encode(s.pkScript), s);
13207
- const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunkGVF4OCTL_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13408
+ const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunkQLJXXVRO_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13208
13409
  add(
13209
- new chunkGVF4OCTL_cjs.DefaultVtxo.Script({
13410
+ new chunkQLJXXVRO_cjs.DefaultVtxo.Script({
13210
13411
  pubKey: await this.identity.xOnlyPublicKey(),
13211
13412
  serverPubKey: this.boardingTapscript.options.serverPubKey,
13212
13413
  csvTimelock: boardingCsv
@@ -13221,7 +13422,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13221
13422
  for (const c of boardingContracts) {
13222
13423
  if (!allowed.has(toXOnlySignerHex(c.params.serverPubKey))) continue;
13223
13424
  try {
13224
- add(chunkGVF4OCTL_cjs.BoardingContractHandler.createScript(c.params));
13425
+ add(chunkQLJXXVRO_cjs.BoardingContractHandler.createScript(c.params));
13225
13426
  } catch (e) {
13226
13427
  console.warn("Skipping malformed boarding contract", c.script, e);
13227
13428
  }
@@ -13250,7 +13451,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13250
13451
  // Per-row CSV delay decoded from THIS tapscript's exit leaf —
13251
13452
  // not the wallet's current boarding timelock, which a signer
13252
13453
  // rotation may have changed.
13253
- csvTimelock: chunk5XBH5SAL_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
13454
+ csvTimelock: chunkKR6FLFIH_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
13254
13455
  coins: utxos
13255
13456
  };
13256
13457
  })
@@ -13258,6 +13459,14 @@ var ReadonlyWallet = class _ReadonlyWallet {
13258
13459
  await this.walletRepository.saveUtxos(
13259
13460
  new Map(groups.map((group, i) => [addresses[i], group.coins]))
13260
13461
  );
13462
+ for (const [i, group] of groups.entries()) {
13463
+ const fresh = new Set(group.coins.map((coin) => `${coin.txid}:${coin.vout}`));
13464
+ const cached = await collectUtxos(this.walletRepository, addresses[i]);
13465
+ const kept = cached.filter((coin) => fresh.has(`${coin.txid}:${coin.vout}`));
13466
+ if (kept.length === cached.length) continue;
13467
+ await this.walletRepository.deleteUtxos(addresses[i]);
13468
+ if (kept.length > 0) await this.walletRepository.saveUtxos(addresses[i], kept);
13469
+ }
13261
13470
  return groups;
13262
13471
  }
13263
13472
  /**
@@ -13271,8 +13480,21 @@ var ReadonlyWallet = class _ReadonlyWallet {
13271
13480
  toXOnlySignerHex(base.hex.encode(this.boardingTapscript.options.serverPubKey))
13272
13481
  ]);
13273
13482
  const groups = await this.getBoardingUtxosForSigners(currentOnly);
13483
+ this.boardingLoaded = true;
13274
13484
  return groups.flatMap((g) => g.coins);
13275
13485
  }
13486
+ async getStoredBoardingUtxos() {
13487
+ const currentOnly = /* @__PURE__ */ new Set([
13488
+ toXOnlySignerHex(base.hex.encode(this.boardingTapscript.options.serverPubKey))
13489
+ ]);
13490
+ const tapscripts = await this.getBoardingTapscripts(currentOnly);
13491
+ const perAddress = await Promise.all(
13492
+ tapscripts.map(
13493
+ (tapscript) => collectUtxos(this.walletRepository, tapscript.onchainAddress(this.network))
13494
+ )
13495
+ );
13496
+ return perAddress.flat();
13497
+ }
13276
13498
  /**
13277
13499
  * Subscribe to onchain and offchain notifications for newly received funds.
13278
13500
  *
@@ -13375,7 +13597,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13375
13597
  /** Fetch Arkade transaction ids that are still pending final settlement. */
13376
13598
  async fetchPendingTxs() {
13377
13599
  const scripts = await this.getWalletScripts();
13378
- const vtxos = await chunk5XBH5SAL_cjs.getAllNormalizedVtxos(this.indexerProvider, scripts);
13600
+ const vtxos = await chunkKR6FLFIH_cjs.getAllNormalizedVtxos(this.indexerProvider, scripts);
13379
13601
  return vtxos.filter(
13380
13602
  (vtxo) => (vtxo.isSpent || vtxo.isPreconfirmed && !vtxo.isSwept) && vtxo.arkTxId !== void 0
13381
13603
  ).map((_) => _.arkTxId);
@@ -13406,7 +13628,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13406
13628
  });
13407
13629
  for (const contract of contracts) {
13408
13630
  if (map.has(contract.script)) continue;
13409
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(contract.type);
13631
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(contract.type);
13410
13632
  if (handler) {
13411
13633
  const script = handler.createScript(contract.params);
13412
13634
  map.set(contract.script, script);
@@ -13499,6 +13721,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13499
13721
  onVtxosSpent = (vtxos) => pruneExitBranches(virtualTxRepository, vtxos);
13500
13722
  }
13501
13723
  const manager = await ContractManager.create({
13724
+ lazyInitialization: this.lazyInitialization,
13502
13725
  indexerProvider: this.indexerProvider,
13503
13726
  contractRepository: this.contractRepository,
13504
13727
  walletRepository: this.walletRepository,
@@ -13517,7 +13740,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13517
13740
  }
13518
13741
  });
13519
13742
  const baselinePubkey = await this.identity.xOnlyPublicKey();
13520
- const delegatePubKey = this.offchainTapscript instanceof chunkGVF4OCTL_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
13743
+ const delegatePubKey = this.offchainTapscript instanceof chunkQLJXXVRO_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
13521
13744
  const baselineSigners = [
13522
13745
  this.offchainTapscript.options.serverPubKey,
13523
13746
  ...[...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h))
@@ -13525,8 +13748,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
13525
13748
  const seenBaselineScripts = /* @__PURE__ */ new Set();
13526
13749
  for (const serverPubKey of baselineSigners) {
13527
13750
  for (const csvTimelock2 of this.walletContractTimelocks) {
13528
- const csvTimelockStr = chunk5XBH5SAL_cjs.timelockToSequence(csvTimelock2).toString();
13529
- const defaultScript = new chunkGVF4OCTL_cjs.DefaultVtxo.Script({
13751
+ const csvTimelockStr = chunkKR6FLFIH_cjs.timelockToSequence(csvTimelock2).toString();
13752
+ const defaultScript = new chunkQLJXXVRO_cjs.DefaultVtxo.Script({
13530
13753
  pubKey: baselinePubkey,
13531
13754
  serverPubKey,
13532
13755
  csvTimelock: csvTimelock2
@@ -13547,7 +13770,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13547
13770
  });
13548
13771
  }
13549
13772
  if (delegatePubKey) {
13550
- const delegateScript = new chunkGVF4OCTL_cjs.DelegateVtxo.Script({
13773
+ const delegateScript = new chunkQLJXXVRO_cjs.DelegateVtxo.Script({
13551
13774
  pubKey: baselinePubkey,
13552
13775
  serverPubKey,
13553
13776
  delegatePubKey,
@@ -13571,9 +13794,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
13571
13794
  }
13572
13795
  }
13573
13796
  }
13574
- const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunkGVF4OCTL_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13797
+ const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunkQLJXXVRO_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13575
13798
  for (const serverPubKey of baselineSigners) {
13576
- const baselineBoarding = new chunkGVF4OCTL_cjs.DefaultVtxo.Script({
13799
+ const baselineBoarding = new chunkQLJXXVRO_cjs.DefaultVtxo.Script({
13577
13800
  pubKey: baselinePubkey,
13578
13801
  serverPubKey,
13579
13802
  csvTimelock: boardingCsvTimelock
@@ -13586,7 +13809,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13586
13809
  params: {
13587
13810
  pubKey: base.hex.encode(baselineBoarding.options.pubKey),
13588
13811
  serverPubKey: base.hex.encode(serverPubKey),
13589
- csvTimelock: chunk5XBH5SAL_cjs.timelockToSequence(boardingCsvTimelock).toString()
13812
+ csvTimelock: chunkKR6FLFIH_cjs.timelockToSequence(boardingCsvTimelock).toString()
13590
13813
  },
13591
13814
  script: boardingScriptHex,
13592
13815
  address: baselineBoarding.address(this.network.hrp, serverPubKey).encode(),
@@ -13598,7 +13821,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13598
13821
  /** Dispose wallet-owned managers and release background resources. */
13599
13822
  async dispose() {
13600
13823
  const manager = this._contractManager ?? (this._contractManagerInitializing ? await this._contractManagerInitializing.catch(() => void 0) : void 0);
13601
- manager?.dispose();
13824
+ await manager?.dispose();
13602
13825
  this._contractManager = void 0;
13603
13826
  this._contractManagerInitializing = void 0;
13604
13827
  }
@@ -13773,7 +13996,7 @@ var Wallet2 = class extends ReadonlyWallet {
13773
13996
  serverPubKey: this.offchainTapscript.options.serverPubKey,
13774
13997
  deprecatedSignerPubKeys: [...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h)),
13775
13998
  csvTimelocks: this.walletContractTimelocks,
13776
- delegatePubKey: this.offchainTapscript instanceof chunkGVF4OCTL_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0
13999
+ delegatePubKey: this.offchainTapscript instanceof chunkQLJXXVRO_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0
13777
14000
  };
13778
14001
  }
13779
14002
  _signerRouter;
@@ -13933,7 +14156,7 @@ var Wallet2 = class extends ReadonlyWallet {
13933
14156
  const [row] = await manager.getContracts({ script: base.hex.encode(display.pkScript) });
13934
14157
  const persisted = row?.metadata?.signingDescriptor;
13935
14158
  if (typeof persisted === "string") return persisted;
13936
- return chunkGVF4OCTL_cjs.identityDescriptor(this.identity);
14159
+ return chunkQLJXXVRO_cjs.identityDescriptor(this.identity);
13937
14160
  }
13938
14161
  /**
13939
14162
  * Build, persist and shape one address of `type` owned by `descriptor`. The descriptor is the
@@ -13943,7 +14166,7 @@ var Wallet2 = class extends ReadonlyWallet {
13943
14166
  async mintAddress(manager, type, descriptor, tagSource, allocated) {
13944
14167
  if (type === "boarding") {
13945
14168
  const built2 = this.buildBoardingContract(
13946
- chunkGVF4OCTL_cjs.deriveDescriptorLeafPubKey(descriptor),
14169
+ chunkQLJXXVRO_cjs.deriveDescriptorLeafPubKey(descriptor),
13947
14170
  descriptor,
13948
14171
  tagSource
13949
14172
  );
@@ -13980,11 +14203,11 @@ var Wallet2 = class extends ReadonlyWallet {
13980
14203
  * (offchain analogue: {@link buildReceiveContract}).
13981
14204
  */
13982
14205
  buildBoardingContract(pubKey, descriptor, tagSource) {
13983
- const tapscript = new chunkGVF4OCTL_cjs.DefaultVtxo.Script({
14206
+ const tapscript = new chunkQLJXXVRO_cjs.DefaultVtxo.Script({
13984
14207
  ...this._boardingTapscript.options,
13985
14208
  pubKey
13986
14209
  });
13987
- const csvTimelock2 = tapscript.options.csvTimelock ?? chunkGVF4OCTL_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
14210
+ const csvTimelock2 = tapscript.options.csvTimelock ?? chunkQLJXXVRO_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13988
14211
  return {
13989
14212
  tapscript,
13990
14213
  params: {
@@ -13992,13 +14215,13 @@ var Wallet2 = class extends ReadonlyWallet {
13992
14215
  params: {
13993
14216
  pubKey: base.hex.encode(pubKey),
13994
14217
  serverPubKey: base.hex.encode(tapscript.options.serverPubKey),
13995
- csvTimelock: chunk5XBH5SAL_cjs.timelockToSequence(csvTimelock2).toString()
14218
+ csvTimelock: chunkKR6FLFIH_cjs.timelockToSequence(csvTimelock2).toString()
13996
14219
  },
13997
14220
  script: base.hex.encode(tapscript.pkScript),
13998
14221
  address: tapscript.address(this.network.hrp, this.arkServerPublicKey).encode(),
13999
14222
  state: "active",
14000
14223
  metadata: {
14001
- ...tagSource && { source: chunkGVF4OCTL_cjs.WALLET_RECEIVE_SOURCE },
14224
+ ...tagSource && { source: chunkQLJXXVRO_cjs.WALLET_RECEIVE_SOURCE },
14002
14225
  signingDescriptor: descriptor
14003
14226
  }
14004
14227
  }
@@ -14020,7 +14243,7 @@ var Wallet2 = class extends ReadonlyWallet {
14020
14243
  if (this._hdProvider) {
14021
14244
  return (await this.getContractManager()).getNextSigningDescriptor();
14022
14245
  }
14023
- return chunkGVF4OCTL_cjs.identityDescriptor(this.identity);
14246
+ return chunkQLJXXVRO_cjs.identityDescriptor(this.identity);
14024
14247
  }
14025
14248
  /**
14026
14249
  * @see HDAllocationCapable.advanceSigningDescriptorWatermark
@@ -14096,7 +14319,7 @@ var Wallet2 = class extends ReadonlyWallet {
14096
14319
  * the stable public API.
14097
14320
  */
14098
14321
  async rotateServerSigner(newServerPubKey, checkpointTapscript) {
14099
- const xonly = chunkGVF4OCTL_cjs.toXOnly(newServerPubKey, "ark signer key");
14322
+ const xonly = chunkQLJXXVRO_cjs.toXOnly(newServerPubKey, "ark signer key");
14100
14323
  const newServerUnrollScript = assertValidServerUnrollScript(
14101
14324
  checkpointTapscript,
14102
14325
  resolveCheckpointExitDelayPolicy(this.network, this.checkpointExitDelayPolicy)
@@ -14125,21 +14348,21 @@ var Wallet2 = class extends ReadonlyWallet {
14125
14348
  const [currentBoardingRow] = await manager.getContracts({
14126
14349
  script: currentBoardingScript
14127
14350
  });
14128
- const newOffchain = this.offchainTapscript instanceof chunkGVF4OCTL_cjs.DelegateVtxo.Script ? new chunkGVF4OCTL_cjs.DelegateVtxo.Script({
14351
+ const newOffchain = this.offchainTapscript instanceof chunkQLJXXVRO_cjs.DelegateVtxo.Script ? new chunkQLJXXVRO_cjs.DelegateVtxo.Script({
14129
14352
  ...this.offchainTapscript.options,
14130
14353
  serverPubKey: xonly
14131
- }) : new chunkGVF4OCTL_cjs.DefaultVtxo.Script({
14354
+ }) : new chunkQLJXXVRO_cjs.DefaultVtxo.Script({
14132
14355
  ...this.offchainTapscript.options,
14133
14356
  serverPubKey: xonly
14134
14357
  });
14135
- const newBoarding = new chunkGVF4OCTL_cjs.DefaultVtxo.Script({
14358
+ const newBoarding = new chunkQLJXXVRO_cjs.DefaultVtxo.Script({
14136
14359
  ...this._boardingTapscript.options,
14137
14360
  serverPubKey: xonly
14138
14361
  });
14139
- const offchainCsv = chunk5XBH5SAL_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
14362
+ const offchainCsv = chunkKR6FLFIH_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
14140
14363
  const newOffchainScript = base.hex.encode(newOffchain.pkScript);
14141
14364
  const newOffchainAddress = newOffchain.address(this.network.hrp, xonly).encode();
14142
- if (newOffchain instanceof chunkGVF4OCTL_cjs.DelegateVtxo.Script) {
14365
+ if (newOffchain instanceof chunkQLJXXVRO_cjs.DelegateVtxo.Script) {
14143
14366
  await manager.createContract({
14144
14367
  type: "delegate",
14145
14368
  params: {
@@ -14167,13 +14390,13 @@ var Wallet2 = class extends ReadonlyWallet {
14167
14390
  metadata: currentOffchainRow?.metadata
14168
14391
  });
14169
14392
  }
14170
- const boardingCsv = newBoarding.options.csvTimelock ?? chunkGVF4OCTL_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
14393
+ const boardingCsv = newBoarding.options.csvTimelock ?? chunkQLJXXVRO_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
14171
14394
  await manager.createContract({
14172
14395
  type: "boarding",
14173
14396
  params: {
14174
14397
  pubKey: base.hex.encode(newBoarding.options.pubKey),
14175
14398
  serverPubKey: base.hex.encode(xonly),
14176
- csvTimelock: chunk5XBH5SAL_cjs.timelockToSequence(boardingCsv).toString()
14399
+ csvTimelock: chunkKR6FLFIH_cjs.timelockToSequence(boardingCsv).toString()
14177
14400
  },
14178
14401
  script: base.hex.encode(newBoarding.pkScript),
14179
14402
  address: newBoarding.address(this.network.hrp, xonly).encode(),
@@ -14201,14 +14424,14 @@ var Wallet2 = class extends ReadonlyWallet {
14201
14424
  _restoreInFlight;
14202
14425
  _addPendingSpends(inputs) {
14203
14426
  for (const input of inputs) {
14204
- if (chunk5XBH5SAL_cjs.isVirtualCoin(input)) {
14427
+ if (chunkKR6FLFIH_cjs.isVirtualCoin(input)) {
14205
14428
  this._pendingSpendOutpoints.add(`${input.txid}:${input.vout}`);
14206
14429
  }
14207
14430
  }
14208
14431
  }
14209
14432
  _removePendingSpends(inputs) {
14210
14433
  for (const input of inputs) {
14211
- if (chunk5XBH5SAL_cjs.isVirtualCoin(input)) {
14434
+ if (chunkKR6FLFIH_cjs.isVirtualCoin(input)) {
14212
14435
  this._pendingSpendOutpoints.delete(`${input.txid}:${input.vout}`);
14213
14436
  }
14214
14437
  }
@@ -14259,13 +14482,13 @@ var Wallet2 = class extends ReadonlyWallet {
14259
14482
  const manager = await this.getContractManager();
14260
14483
  const provider = this._hdProvider;
14261
14484
  const hd = provider !== void 0;
14262
- const staticDescriptor = hd ? void 0 : await chunkGVF4OCTL_cjs.identityDescriptor(this.identity);
14485
+ const staticDescriptor = hd ? void 0 : await chunkQLJXXVRO_cjs.identityDescriptor(this.identity);
14263
14486
  const materialize = (index) => hd ? provider.materializeDescriptorAt(index) : staticDescriptor;
14264
- const delegatePubKey = this.offchainTapscript instanceof chunkGVF4OCTL_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
14487
+ const delegatePubKey = this.offchainTapscript instanceof chunkQLJXXVRO_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
14265
14488
  const arkInfo = await this.arkProvider.getInfo();
14266
- const currentSignerPubKey = chunkGVF4OCTL_cjs.toXOnly(base.hex.decode(arkInfo.signerPubkey), "ark signer key");
14489
+ const currentSignerPubKey = chunkQLJXXVRO_cjs.toXOnly(base.hex.decode(arkInfo.signerPubkey), "ark signer key");
14267
14490
  const deprecatedSignerPubKeys = arkInfo.deprecatedSigners.map(
14268
- (s) => chunkGVF4OCTL_cjs.toXOnly(base.hex.decode(s.pubkey), "deprecated signer key")
14491
+ (s) => chunkQLJXXVRO_cjs.toXOnly(base.hex.decode(s.pubkey), "deprecated signer key")
14269
14492
  );
14270
14493
  const deps = {
14271
14494
  indexerProvider: this.indexerProvider,
@@ -14277,7 +14500,7 @@ var Wallet2 = class extends ReadonlyWallet {
14277
14500
  deprecatedSignerPubKeys,
14278
14501
  csvTimelocks: this.walletContractTimelocks,
14279
14502
  // Boarding-exit CSV, distinct from the unilateral-exit matrix.
14280
- boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunkGVF4OCTL_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
14503
+ boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunkQLJXXVRO_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
14281
14504
  delegatePubKey
14282
14505
  };
14283
14506
  const result = await manager.scanContracts({
@@ -14387,7 +14610,7 @@ var Wallet2 = class extends ReadonlyWallet {
14387
14610
  throw new Error("Invalid configured public key");
14388
14611
  }
14389
14612
  const setup = await ReadonlyWallet.setupWalletConfig(config, pubkey);
14390
- const forfeitPubkey = chunkGVF4OCTL_cjs.toXOnly(base.hex.decode(setup.info.forfeitPubkey), "forfeit key");
14613
+ const forfeitPubkey = chunkQLJXXVRO_cjs.toXOnly(base.hex.decode(setup.info.forfeitPubkey), "forfeit key");
14391
14614
  const forfeitAddress = btcSigner.Address(setup.network).decode(setup.info.forfeitAddress);
14392
14615
  const forfeitOutputScript = btcSigner.OutScript.encode(forfeitAddress);
14393
14616
  const checkpointExitDelayOverrides = {
@@ -14441,6 +14664,7 @@ var Wallet2 = class extends ReadonlyWallet {
14441
14664
  },
14442
14665
  checkpointExitDelayOverrides
14443
14666
  );
14667
+ wallet.lazyInitialization = config.lazyInitialization ?? false;
14444
14668
  wallet._serverInfoSource = setup.serverInfoSource;
14445
14669
  if (setup.serverInfoSource === "live") {
14446
14670
  const now = Date.now();
@@ -14527,12 +14751,17 @@ var Wallet2 = class extends ReadonlyWallet {
14527
14751
  *
14528
14752
  * @param params - Optional settlement inputs and outputs. When omitted, the wallet settles all eligible funds.
14529
14753
  * @param eventCallback - Optional callback invoked for settlement stream events.
14754
+ * @param hooks - Optional phases for preparation and intent registration.
14530
14755
  * @returns The finalized Arkade transaction id
14531
14756
  */
14532
- async settle(params, eventCallback) {
14533
- return this._withTxLock(() => this._settleImpl(params, eventCallback));
14757
+ async settle(params, eventCallback, hooks) {
14758
+ return this._withTxLock(() => {
14759
+ hooks?.onPhase?.("preparing");
14760
+ const onRegistrationAttempt = hooks?.onPhase ? () => hooks.onPhase?.("registration_attempt") : void 0;
14761
+ return this._settleImpl(params, eventCallback, onRegistrationAttempt);
14762
+ });
14534
14763
  }
14535
- async _settleImpl(params, eventCallback) {
14764
+ async _settleImpl(params, eventCallback, onRegistrationAttempt) {
14536
14765
  if (params?.inputs) {
14537
14766
  for (const input of params.inputs) {
14538
14767
  if (typeof input === "string") {
@@ -14546,13 +14775,13 @@ var Wallet2 = class extends ReadonlyWallet {
14546
14775
  void this.logUngatedInputs("settle({ inputs })", params.inputs);
14547
14776
  }
14548
14777
  const offchainAddress = await this.getAddress();
14549
- const offchainPkScript = chunk5XBH5SAL_cjs.ArkAddress.decode(offchainAddress).pkScript;
14778
+ const offchainPkScript = chunkKR6FLFIH_cjs.ArkAddress.decode(offchainAddress).pkScript;
14550
14779
  const offchainOutputScript = base.hex.encode(offchainPkScript);
14551
14780
  if (!params) {
14552
14781
  const { fees, vtxoMaxAmount } = await this.arkProvider.getInfo();
14553
14782
  const estimator = new Estimator(fees.intentFee);
14554
14783
  let amount = 0;
14555
- const exitScript = chunk5XBH5SAL_cjs.CSVMultisigTapscript.decode(
14784
+ const exitScript = chunkKR6FLFIH_cjs.CSVMultisigTapscript.decode(
14556
14785
  base.hex.decode(this.boardingTapscript.exitScript)
14557
14786
  );
14558
14787
  const boardingTimelock = exitScript.params.timelock;
@@ -14584,7 +14813,7 @@ var Wallet2 = class extends ReadonlyWallet {
14584
14813
  if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
14585
14814
  break;
14586
14815
  }
14587
- const inputFee = estimator.evalOffchainInput(chunk5XBH5SAL_cjs.toOffchainInputFeeParams(vtxo));
14816
+ const inputFee = estimator.evalOffchainInput(chunkKR6FLFIH_cjs.toOffchainInputFeeParams(vtxo));
14588
14817
  if (inputFee.satoshis >= vtxo.value) {
14589
14818
  continue;
14590
14819
  }
@@ -14635,7 +14864,7 @@ var Wallet2 = class extends ReadonlyWallet {
14635
14864
  let script;
14636
14865
  let arkAddress;
14637
14866
  try {
14638
- arkAddress = chunk5XBH5SAL_cjs.ArkAddress.decode(output.address);
14867
+ arkAddress = chunkKR6FLFIH_cjs.ArkAddress.decode(output.address);
14639
14868
  } catch {
14640
14869
  arkAddress = void 0;
14641
14870
  }
@@ -14707,11 +14936,11 @@ var Wallet2 = class extends ReadonlyWallet {
14707
14936
  ]);
14708
14937
  let intentTxId;
14709
14938
  try {
14710
- intentTxId = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(intent.proof)).id;
14939
+ intentTxId = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(intent.proof)).id;
14711
14940
  } catch {
14712
14941
  intentTxId = params.inputs.map((i) => `${i.txid}:${i.vout}`).sort().join("|");
14713
14942
  }
14714
- const settleInputVtxos = params.inputs.filter(chunk5XBH5SAL_cjs.isVirtualCoin);
14943
+ const settleInputVtxos = params.inputs.filter(chunkKR6FLFIH_cjs.isVirtualCoin);
14715
14944
  const contractManager = await this.getContractManager();
14716
14945
  await contractManager.assertAnnotatable(settleInputVtxos);
14717
14946
  await contractManager.assertSpendableNow?.(
@@ -14747,6 +14976,7 @@ var Wallet2 = class extends ReadonlyWallet {
14747
14976
  }
14748
14977
  yield* stream;
14749
14978
  })();
14979
+ onRegistrationAttempt?.();
14750
14980
  const intentId = await this.safeRegisterIntent(intent, params.inputs);
14751
14981
  await this.persistIntentSnapshot(
14752
14982
  intentTxId,
@@ -14820,7 +15050,7 @@ var Wallet2 = class extends ReadonlyWallet {
14820
15050
  async maybeRotateBoardingAfterBoard(inputs) {
14821
15051
  if (!this._descriptorProvider) return;
14822
15052
  const consumedBoarding = inputs.some(
14823
- (input) => typeof input !== "string" && !chunk5XBH5SAL_cjs.isVirtualCoin(input)
15053
+ (input) => typeof input !== "string" && !chunkKR6FLFIH_cjs.isVirtualCoin(input)
14824
15054
  );
14825
15055
  if (!consumedBoarding) return;
14826
15056
  try {
@@ -14831,7 +15061,7 @@ var Wallet2 = class extends ReadonlyWallet {
14831
15061
  }
14832
15062
  async handleSettlementFinalizationEvent(event, inputs, forfeitOutputScript, expectedRecipients, connectorsGraph, validatedCommitmentTxid) {
14833
15063
  const signedForfeits = [];
14834
- let settlementPsbt = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
15064
+ let settlementPsbt = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
14835
15065
  assertFinalCommitmentMatchesValidated(
14836
15066
  settlementPsbt,
14837
15067
  validatedCommitmentTxid,
@@ -14844,7 +15074,7 @@ var Wallet2 = class extends ReadonlyWallet {
14844
15074
  let connectorIndex = 0;
14845
15075
  const connectorsLeaves = connectorsGraph?.leaves() || [];
14846
15076
  for (const input of inputs) {
14847
- if (!chunk5XBH5SAL_cjs.isVirtualCoin(input)) {
15077
+ if (!chunkKR6FLFIH_cjs.isVirtualCoin(input)) {
14848
15078
  let matched = false;
14849
15079
  for (let i = 0; i < settlementPsbt.inputsLength; i++) {
14850
15080
  const settlementInput = settlementPsbt.getInput(i);
@@ -14882,7 +15112,7 @@ var Wallet2 = class extends ReadonlyWallet {
14882
15112
  }
14883
15113
  continue;
14884
15114
  }
14885
- if (!chunk5XBH5SAL_cjs.requiresForfeit(input) || isSubdust({ value: input.value }, this.dustAmount)) {
15115
+ if (!chunkKR6FLFIH_cjs.requiresForfeit(input) || isSubdust({ value: input.value }, this.dustAmount)) {
14886
15116
  continue;
14887
15117
  }
14888
15118
  if (connectorsLeaves.length === 0) {
@@ -14910,7 +15140,7 @@ var Wallet2 = class extends ReadonlyWallet {
14910
15140
  index: input.vout,
14911
15141
  witnessUtxo: {
14912
15142
  amount: BigInt(input.value),
14913
- script: chunk5XBH5SAL_cjs.VtxoScript.decode(input.tapTree).pkScript
15143
+ script: chunkKR6FLFIH_cjs.VtxoScript.decode(input.tapTree).pkScript
14914
15144
  },
14915
15145
  sighashType: btcSigner.SigHash.DEFAULT,
14916
15146
  tapLeafScript: [input.forfeitTapLeafScript]
@@ -14929,7 +15159,7 @@ var Wallet2 = class extends ReadonlyWallet {
14929
15159
  forfeitTx = await this._signerRouter.sign(forfeitTx, [
14930
15160
  {
14931
15161
  index: 0,
14932
- lookupScript: chunk5XBH5SAL_cjs.VtxoScript.decode(input.tapTree).pkScript
15162
+ lookupScript: chunkKR6FLFIH_cjs.VtxoScript.decode(input.tapTree).pkScript
14933
15163
  }
14934
15164
  ]);
14935
15165
  signedForfeits.push(base.base64.encode(forfeitTx.toPSBT()));
@@ -14987,7 +15217,7 @@ var Wallet2 = class extends ReadonlyWallet {
14987
15217
  resolveBatchExpiryPolicy(this.network, this.batchExpiryPolicy)
14988
15218
  );
14989
15219
  await this.arkProvider.confirmRegistration(intentId);
14990
- const sweepTapscript = chunk5XBH5SAL_cjs.CSVMultisigTapscript.encode({
15220
+ const sweepTapscript = chunkKR6FLFIH_cjs.CSVMultisigTapscript.encode({
14991
15221
  timelock,
14992
15222
  pubkeys: [this.forfeitPubkey]
14993
15223
  }).script;
@@ -15002,14 +15232,14 @@ var Wallet2 = class extends ReadonlyWallet {
15002
15232
  throw new Error("Sweep tap tree root not set");
15003
15233
  }
15004
15234
  const xOnlyPublicKeys = event.cosignersPublicKeys.map(
15005
- (k) => base.hex.encode(chunkGVF4OCTL_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
15235
+ (k) => base.hex.encode(chunkQLJXXVRO_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
15006
15236
  );
15007
15237
  const signerPublicKey = await session.getPublicKey();
15008
- const xonlySignerPublicKey = chunkGVF4OCTL_cjs.toXOnly(signerPublicKey, "signer key");
15238
+ const xonlySignerPublicKey = chunkQLJXXVRO_cjs.toXOnly(signerPublicKey, "signer key");
15009
15239
  if (!xOnlyPublicKeys.includes(base.hex.encode(xonlySignerPublicKey))) {
15010
15240
  return { skip: true };
15011
15241
  }
15012
- const commitmentTx = chunk5XBH5SAL_cjs.Transaction.fromPSBT(
15242
+ const commitmentTx = chunkKR6FLFIH_cjs.Transaction.fromPSBT(
15013
15243
  base.base64.decode(event.unsignedCommitmentTx)
15014
15244
  );
15015
15245
  validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
@@ -15091,9 +15321,9 @@ var Wallet2 = class extends ReadonlyWallet {
15091
15321
  ...existing ?? {},
15092
15322
  intentTxId,
15093
15323
  registerProof: intent.proof,
15094
- registerProofMessage: chunk5XBH5SAL_cjs.Intent.encodeMessage(intent.message),
15324
+ registerProofMessage: chunkKR6FLFIH_cjs.Intent.encodeMessage(intent.message),
15095
15325
  deleteProof: deleteIntent.proof,
15096
- deleteProofMessage: chunk5XBH5SAL_cjs.Intent.encodeMessage(deleteIntent.message),
15326
+ deleteProofMessage: chunkKR6FLFIH_cjs.Intent.encodeMessage(deleteIntent.message),
15097
15327
  intentVtxos: inputs.map((i) => ({
15098
15328
  txid: i.txid,
15099
15329
  vout: i.vout
@@ -15126,7 +15356,7 @@ var Wallet2 = class extends ReadonlyWallet {
15126
15356
  try {
15127
15357
  return await this.arkProvider.registerIntent(intent);
15128
15358
  } catch (error) {
15129
- if (error instanceof chunk5XBH5SAL_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
15359
+ if (error instanceof chunkKR6FLFIH_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
15130
15360
  const deleteIntent = await this.makeDeleteIntentSignature(inputs);
15131
15361
  await this.arkProvider.deleteIntent(deleteIntent);
15132
15362
  return this.arkProvider.registerIntent(intent);
@@ -15142,7 +15372,7 @@ var Wallet2 = class extends ReadonlyWallet {
15142
15372
  expire_at: 0,
15143
15373
  cosigners_public_keys: cosignerPubKeys
15144
15374
  };
15145
- const proof = chunk5XBH5SAL_cjs.Intent.create(message, coins, outputs);
15375
+ const proof = chunkKR6FLFIH_cjs.Intent.create(message, coins, outputs);
15146
15376
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
15147
15377
  return {
15148
15378
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -15154,7 +15384,7 @@ var Wallet2 = class extends ReadonlyWallet {
15154
15384
  type: "delete",
15155
15385
  expire_at: 0
15156
15386
  };
15157
- const proof = chunk5XBH5SAL_cjs.Intent.create(message, coins, []);
15387
+ const proof = chunkKR6FLFIH_cjs.Intent.create(message, coins, []);
15158
15388
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
15159
15389
  return {
15160
15390
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -15166,7 +15396,7 @@ var Wallet2 = class extends ReadonlyWallet {
15166
15396
  type: "get-pending-tx",
15167
15397
  expire_at: 0
15168
15398
  };
15169
- const proof = chunk5XBH5SAL_cjs.Intent.create(message, coins, []);
15399
+ const proof = chunkKR6FLFIH_cjs.Intent.create(message, coins, []);
15170
15400
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
15171
15401
  return {
15172
15402
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -15187,7 +15417,7 @@ var Wallet2 = class extends ReadonlyWallet {
15187
15417
  if (!vtxos || vtxos.length === 0) {
15188
15418
  const scriptMap = await this.getScriptMap();
15189
15419
  const allExtended = [];
15190
- const fetchedVtxos = await chunk5XBH5SAL_cjs.getAllNormalizedVtxos(this.indexerProvider, [
15420
+ const fetchedVtxos = await chunkKR6FLFIH_cjs.getAllNormalizedVtxos(this.indexerProvider, [
15191
15421
  ...scriptMap.keys()
15192
15422
  ]);
15193
15423
  for (const vtxo of fetchedVtxos) {
@@ -15230,8 +15460,8 @@ var Wallet2 = class extends ReadonlyWallet {
15230
15460
  batchPending.push(pendingTx.arkTxid);
15231
15461
  try {
15232
15462
  const checkpointTxs = pendingTx.signedCheckpointTxs.map((c) => {
15233
- const tx = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(c));
15234
- chunk5XBH5SAL_cjs.assertAllowedSighashTypes(tx);
15463
+ const tx = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(c));
15464
+ chunkKR6FLFIH_cjs.assertAllowedSighashTypes(tx);
15235
15465
  return tx;
15236
15466
  });
15237
15467
  assertCheckpointsMatchInputs(
@@ -15300,11 +15530,11 @@ var Wallet2 = class extends ReadonlyWallet {
15300
15530
  * and one per deprecated signer — else a pre-rotation tx would stay pending forever.
15301
15531
  */
15302
15532
  checkpointUnrollCandidates(info) {
15303
- const current = chunk5XBH5SAL_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
15533
+ const current = chunkKR6FLFIH_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
15304
15534
  const candidates = [this._serverUnrollScript, current];
15305
15535
  for (const deprecated of signerSetFromInfo(info).deprecated.keys()) {
15306
15536
  candidates.push(
15307
- chunk5XBH5SAL_cjs.CSVMultisigTapscript.encode({
15537
+ chunkKR6FLFIH_cjs.CSVMultisigTapscript.encode({
15308
15538
  ...current.params,
15309
15539
  pubkeys: [base.hex.decode(deprecated)]
15310
15540
  })
@@ -15393,7 +15623,7 @@ var Wallet2 = class extends ReadonlyWallet {
15393
15623
  if (vtxos.length === 0) {
15394
15624
  throw new Error("No VTXOs found for this arkadeCash");
15395
15625
  }
15396
- const myPkScript = chunk5XBH5SAL_cjs.ArkAddress.decode(await this.getAddress()).pkScript;
15626
+ const myPkScript = chunkKR6FLFIH_cjs.ArkAddress.decode(await this.getAddress()).pkScript;
15397
15627
  let { spendable, recoverable, unclaimed } = this.classifyCashVtxos(vtxos);
15398
15628
  let swept = 0;
15399
15629
  const drainable = vtxos.filter(
@@ -15520,7 +15750,7 @@ var Wallet2 = class extends ReadonlyWallet {
15520
15750
  params: {
15521
15751
  pubKey: base.hex.encode(cash.publicKey),
15522
15752
  serverPubKey: base.hex.encode(cash.serverPubKey),
15523
- csvTimelock: chunk5XBH5SAL_cjs.timelockToSequence(cash.csvTimelock).toString()
15753
+ csvTimelock: chunkKR6FLFIH_cjs.timelockToSequence(cash.csvTimelock).toString()
15524
15754
  },
15525
15755
  script: base.hex.encode(cashScript.pkScript),
15526
15756
  address: cashAddress.encode(),
@@ -15601,7 +15831,7 @@ var Wallet2 = class extends ReadonlyWallet {
15601
15831
  const recoverable = [];
15602
15832
  const unclaimed = [];
15603
15833
  for (const vtxo of vtxos) {
15604
- if (chunk5XBH5SAL_cjs.isVtxoSpent(vtxo)) {
15834
+ if (chunkKR6FLFIH_cjs.isVtxoSpent(vtxo)) {
15605
15835
  unclaimed.push(cashReport(vtxo, "already-spent"));
15606
15836
  } else if (vtxo.isUnrolled) {
15607
15837
  unclaimed.push(cashReport(vtxo, "exited"));
@@ -15623,7 +15853,7 @@ var Wallet2 = class extends ReadonlyWallet {
15623
15853
  const all = [];
15624
15854
  const seen = /* @__PURE__ */ new Set();
15625
15855
  for (let pageIndex = 0; ; pageIndex++) {
15626
- const { vtxos, page } = await chunk5XBH5SAL_cjs.getNormalizedVtxos(this.indexerProvider, {
15856
+ const { vtxos, page } = await chunkKR6FLFIH_cjs.getNormalizedVtxos(this.indexerProvider, {
15627
15857
  scripts,
15628
15858
  pageIndex,
15629
15859
  pageSize
@@ -15661,7 +15891,7 @@ var Wallet2 = class extends ReadonlyWallet {
15661
15891
  for (let i = 0; i < inputs.length; i += MAX_INPUTS_PER_INTENT) {
15662
15892
  const batch = inputs.slice(i, i + MAX_INPUTS_PER_INTENT);
15663
15893
  const message = { type: "get-pending-tx", expire_at: 0 };
15664
- const proof = chunk5XBH5SAL_cjs.Intent.create(message, batch, []);
15894
+ const proof = chunkKR6FLFIH_cjs.Intent.create(message, batch, []);
15665
15895
  const signedProof = await identity.sign(
15666
15896
  proof,
15667
15897
  Array.from({ length: batch.length + 1 }, (_, j) => j)
@@ -15682,8 +15912,8 @@ var Wallet2 = class extends ReadonlyWallet {
15682
15912
  for (const pendingTx of pendingTxs) {
15683
15913
  try {
15684
15914
  const checkpointTxs = pendingTx.signedCheckpointTxs.map((checkpoint) => {
15685
- const tx = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(checkpoint));
15686
- chunk5XBH5SAL_cjs.assertAllowedSighashTypes(tx);
15915
+ const tx = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(checkpoint));
15916
+ chunkKR6FLFIH_cjs.assertAllowedSighashTypes(tx);
15687
15917
  return tx;
15688
15918
  });
15689
15919
  assertCheckpointsMatchInputs(
@@ -15723,7 +15953,7 @@ var Wallet2 = class extends ReadonlyWallet {
15723
15953
  }
15724
15954
  /** Sum the outputs of an ark tx PSBT that pay the given scriptPubKey. */
15725
15955
  arkTxAmountPaidTo(arkTxPsbt, pkScriptHex) {
15726
- const arkTx = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(arkTxPsbt));
15956
+ const arkTx = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(arkTxPsbt));
15727
15957
  let total = 0;
15728
15958
  for (let i = 0; i < arkTx.outputsLength; i++) {
15729
15959
  const output = arkTx.getOutput(i);
@@ -15758,13 +15988,13 @@ var Wallet2 = class extends ReadonlyWallet {
15758
15988
  */
15759
15989
  async send(...args) {
15760
15990
  const params = asSendParams(args);
15761
- return this._withTxLock(() => this._sendImpl(params));
15991
+ const validUntil = captureSendDeadline(params.validUntil);
15992
+ const inputExpiryFloor = captureInputExpiryFloor(params.inputExpiryFloor);
15993
+ assertSendDeadline(validUntil);
15994
+ return this._withTxLock(() => this._sendImpl(params, validUntil, inputExpiryFloor));
15762
15995
  }
15763
- async _sendImpl({
15764
- recipients: args,
15765
- selectedVtxos,
15766
- maxChangeFee
15767
- }) {
15996
+ async _sendImpl({ recipients: args, selectedVtxos, maxChangeFee }, validUntil, inputExpiryFloor) {
15997
+ assertSendDeadline(validUntil);
15768
15998
  if (args.length === 0) {
15769
15999
  throw new Error("At least one receiver is required");
15770
16000
  }
@@ -15775,6 +16005,10 @@ var Wallet2 = class extends ReadonlyWallet {
15775
16005
  throw new Error("send({ maxChangeFee }): expected a non-negative safe integer");
15776
16006
  }
15777
16007
  if (selectedVtxos) {
16008
+ if (inputExpiryFloor) selectedVtxos = selectedVtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo);
16009
+ if (inputExpiryFloor && selectedVtxos.some((coin) => !meetsInputExpiryFloor(coin, inputExpiryFloor))) {
16010
+ throw new Error("send({ selectedVtxos }): input expiry floor not met");
16011
+ }
15778
16012
  void this.logUngatedInputs("send({ selectedVtxos })", selectedVtxos);
15779
16013
  }
15780
16014
  const offchainTapscript = this.offchainTapscript;
@@ -15793,6 +16027,11 @@ var Wallet2 = class extends ReadonlyWallet {
15793
16027
  withRecoverable: false,
15794
16028
  genericallySpendableOnly: true
15795
16029
  });
16030
+ if (inputExpiryFloor) {
16031
+ virtualCoins = virtualCoins.filter(
16032
+ (coin) => meetsInputExpiryFloor(coin, inputExpiryFloor)
16033
+ );
16034
+ }
15796
16035
  }
15797
16036
  const assetChanges = /* @__PURE__ */ new Map();
15798
16037
  let selectedCoins = selectedVtxos ? [...selectedVtxos] : [];
@@ -15901,7 +16140,7 @@ var Wallet2 = class extends ReadonlyWallet {
15901
16140
  script: recipient.script,
15902
16141
  amount: BigInt(recipient.amount),
15903
16142
  // Already checked against the recipient address in `validateRecipients`.
15904
- ...recipient.tapTree ? { tapTree: chunk5XBH5SAL_cjs.toBIP371TapTree(recipient.tapTree) } : {}
16143
+ ...recipient.tapTree ? { tapTree: chunkKR6FLFIH_cjs.toBIP371TapTree(recipient.tapTree) } : {}
15905
16144
  }));
15906
16145
  const totalBtcOutput = outputs.reduce((sum, o) => sum + Number(o.amount), 0);
15907
16146
  let changeAmount = totalBtcSelected - totalBtcOutput;
@@ -16027,27 +16266,33 @@ var Wallet2 = class extends ReadonlyWallet {
16027
16266
  outputs.push(Extension.create(allExtPackets).txOut());
16028
16267
  }
16029
16268
  const sentAmount = recipients.reduce((sum, r) => sum + r.amount, 0);
16030
- return this._submitOffchainSpend(selectedCoins, outputs, {
16031
- sentAmount,
16032
- changeAmount: BigInt(changeAmount),
16033
- changeVout: changeReceiver ? changeIndex : 0,
16034
- offchainTapscript,
16035
- serverPubKey,
16036
- serverUnrollScript,
16037
- changeAssets: changeReceiver?.assets
16038
- });
16269
+ return this._submitOffchainSpend(
16270
+ selectedCoins,
16271
+ outputs,
16272
+ {
16273
+ sentAmount,
16274
+ changeAmount: BigInt(changeAmount),
16275
+ changeVout: changeReceiver ? changeIndex : 0,
16276
+ offchainTapscript,
16277
+ serverPubKey,
16278
+ serverUnrollScript,
16279
+ changeAssets: changeReceiver?.assets
16280
+ },
16281
+ { validUntil }
16282
+ );
16039
16283
  }
16040
16284
  /**
16041
16285
  * Shared submit/persist tail of `send` and {@link sendSelectedVtxosToSelf}; callers own coin
16042
16286
  * selection, outputs and the synchronous epoch snapshot.
16043
16287
  */
16044
- async _submitOffchainSpend(inputs, outputs, persist) {
16288
+ async _submitOffchainSpend(inputs, outputs, persist, options) {
16045
16289
  this._addPendingSpends(inputs);
16046
16290
  try {
16047
- const { arkTxid, signedCheckpointTxs } = await this.buildAndSubmitOffchainTx(
16291
+ const { arkTxid, signedCheckpointTxs } = await this._buildAndSubmitOffchainTx(
16048
16292
  inputs,
16049
16293
  outputs,
16050
- persist.serverUnrollScript
16294
+ persist.serverUnrollScript,
16295
+ options
16051
16296
  );
16052
16297
  await this.updateDbAfterOffchainTx(
16053
16298
  inputs,
@@ -16082,10 +16327,10 @@ var Wallet2 = class extends ReadonlyWallet {
16082
16327
  const serverPubKey = this.arkServerPublicKey;
16083
16328
  const serverUnrollScript = this.serverUnrollScript;
16084
16329
  const arkAddress = offchainTapscript.address(this.network.hrp, serverPubKey);
16085
- const normalizedInputs = inputs.map(chunk5XBH5SAL_cjs.normalizeVtxo);
16086
- const at = now ?? await chunk5XBH5SAL_cjs.resolveTimeHeight(this.onchainProvider);
16330
+ const normalizedInputs = inputs.map(chunkKR6FLFIH_cjs.normalizeVtxo);
16331
+ const at = now ?? await chunkKR6FLFIH_cjs.resolveTimeHeight(this.onchainProvider);
16087
16332
  for (const input of normalizedInputs) {
16088
- if (!chunk5XBH5SAL_cjs.canSpendOffchain(input, at)) {
16333
+ if (!chunkKR6FLFIH_cjs.canSpendOffchain(input, at)) {
16089
16334
  throw new Error(
16090
16335
  `sendSelectedVtxosToSelf: input ${input.txid}:${input.vout} is not cooperatively spendable`
16091
16336
  );
@@ -16140,7 +16385,16 @@ var Wallet2 = class extends ReadonlyWallet {
16140
16385
  *
16141
16386
  * @returns The Arkade transaction id and server-signed checkpoint PSBTs (for bookkeeping)
16142
16387
  */
16143
- async buildAndSubmitOffchainTx(inputs, outputs, serverUnrollScript = this.serverUnrollScript) {
16388
+ async buildAndSubmitOffchainTx(inputs, outputs, serverUnrollScript = this.serverUnrollScript, options) {
16389
+ const validUntil = captureSendDeadline(options?.validUntil);
16390
+ assertSendDeadline(validUntil);
16391
+ return this._withTxLock(
16392
+ () => this._buildAndSubmitOffchainTx(inputs, outputs, serverUnrollScript, { validUntil })
16393
+ );
16394
+ }
16395
+ async _buildAndSubmitOffchainTx(inputs, outputs, serverUnrollScript, options) {
16396
+ const validUntil = captureSendDeadline(options?.validUntil);
16397
+ assertSendDeadline(validUntil);
16144
16398
  void this.logUngatedInputs("buildAndSubmitOffchainTx", inputs);
16145
16399
  await (await this.getContractManager()).assertAnnotatable(inputs);
16146
16400
  const offchainTx = buildOffchainTx(
@@ -16155,7 +16409,7 @@ var Wallet2 = class extends ReadonlyWallet {
16155
16409
  );
16156
16410
  const arkTxJobs = inputs.map((input, index) => ({
16157
16411
  index,
16158
- lookupScript: chunk5XBH5SAL_cjs.VtxoScript.decode(input.tapTree).pkScript
16412
+ lookupScript: chunkKR6FLFIH_cjs.VtxoScript.decode(input.tapTree).pkScript
16159
16413
  }));
16160
16414
  const identity = this.identity;
16161
16415
  const signer = {
@@ -16198,7 +16452,25 @@ var Wallet2 = class extends ReadonlyWallet {
16198
16452
  {
16199
16453
  // Mark pending before submitting — if we crash between submit and
16200
16454
  // finalize, the next init recovers via finalizePendingTxs.
16201
- beforeSubmit: () => this.setPendingTxFlag(true),
16455
+ beforeSubmit: async () => {
16456
+ const ownsPendingFlag = validUntil !== void 0 && !await this.hasPendingTxFlag();
16457
+ await this.setPendingTxFlag(true);
16458
+ try {
16459
+ assertSendDeadline(validUntil);
16460
+ } catch (error) {
16461
+ if (ownsPendingFlag) {
16462
+ try {
16463
+ await this.setPendingTxFlag(false);
16464
+ } catch (clearError) {
16465
+ console.error(
16466
+ "Failed to clear pending tx flag after deadline expiry:",
16467
+ clearError
16468
+ );
16469
+ }
16470
+ }
16471
+ throw error;
16472
+ }
16473
+ },
16202
16474
  afterFinalize: async () => {
16203
16475
  try {
16204
16476
  await this.setPendingTxFlag(false);
@@ -16234,7 +16506,7 @@ var Wallet2 = class extends ReadonlyWallet {
16234
16506
  }
16235
16507
  const checkpointIdByOutpoint = /* @__PURE__ */ new Map();
16236
16508
  for (const encoded of signedCheckpointTxs) {
16237
- const checkpoint = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
16509
+ const checkpoint = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
16238
16510
  for (let i = 0; i < checkpoint.inputsLength; i++) {
16239
16511
  const input = checkpoint.getInput(i);
16240
16512
  if (!input.txid) continue;
@@ -16350,12 +16622,12 @@ var Wallet2 = class extends ReadonlyWallet {
16350
16622
  const spentVtxos = [];
16351
16623
  const inputArkTxIds = /* @__PURE__ */ new Set();
16352
16624
  const boardingRemovalsByAddress = /* @__PURE__ */ new Map();
16353
- const vtxoInputs = inputs.filter(chunk5XBH5SAL_cjs.isVirtualCoin);
16625
+ const vtxoInputs = inputs.filter(chunkKR6FLFIH_cjs.isVirtualCoin);
16354
16626
  const cm = await this.getContractManager();
16355
16627
  const annotatedVtxos = await cm.annotateVtxos(vtxoInputs);
16356
16628
  const annotatedByKey = new Map(annotatedVtxos.map((v) => [`${v.txid}:${v.vout}`, v]));
16357
16629
  for (const input of inputs) {
16358
- if (chunk5XBH5SAL_cjs.isVirtualCoin(input)) {
16630
+ if (chunkKR6FLFIH_cjs.isVirtualCoin(input)) {
16359
16631
  const outpoint = `${input.txid}:${input.vout}`;
16360
16632
  const vtxo = annotatedByKey.get(outpoint);
16361
16633
  if (!vtxo) {
@@ -16372,7 +16644,7 @@ var Wallet2 = class extends ReadonlyWallet {
16372
16644
  } else {
16373
16645
  let sourceAddress;
16374
16646
  try {
16375
- sourceAddress = chunk5XBH5SAL_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
16647
+ sourceAddress = chunkKR6FLFIH_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
16376
16648
  this.network
16377
16649
  );
16378
16650
  } catch {
@@ -16430,7 +16702,7 @@ var Wallet2 = class extends ReadonlyWallet {
16430
16702
  }
16431
16703
  };
16432
16704
  function selectVirtualCoins(coins, targetAmount) {
16433
- const sortedCoins = coins.map(chunk5XBH5SAL_cjs.normalizeVtxo).sort((a, b) => {
16705
+ const sortedCoins = coins.map(chunkKR6FLFIH_cjs.normalizeVtxo).sort((a, b) => {
16434
16706
  const expiryA = a.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
16435
16707
  const expiryB = b.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
16436
16708
  if (expiryA !== expiryB) {
@@ -16542,7 +16814,7 @@ function assertTimeoutMap(name, timeouts) {
16542
16814
  if (value === void 0) {
16543
16815
  throw new Error(`${name}.${key} must be a non-negative safe integer`);
16544
16816
  }
16545
- chunk5XBH5SAL_cjs.assertTimerMs(`${name}.${key}`, value);
16817
+ chunkKR6FLFIH_cjs.assertTimerMs(`${name}.${key}`, value);
16546
16818
  }
16547
16819
  }
16548
16820
  var MessageBus = class {
@@ -16558,8 +16830,8 @@ var MessageBus = class {
16558
16830
  }) {
16559
16831
  this.walletRepository = walletRepository;
16560
16832
  this.contractRepository = contractRepository;
16561
- chunk5XBH5SAL_cjs.assertTimerMs("tickIntervalMs", tickIntervalMs);
16562
- chunk5XBH5SAL_cjs.assertTimerMs("messageTimeoutMs", messageTimeoutMs);
16833
+ chunkKR6FLFIH_cjs.assertTimerMs("tickIntervalMs", tickIntervalMs);
16834
+ chunkKR6FLFIH_cjs.assertTimerMs("messageTimeoutMs", messageTimeoutMs);
16563
16835
  assertTimeoutMap("messageTimeoutOverrides", messageTimeoutOverrides);
16564
16836
  this.intentRepository = intentRepository;
16565
16837
  this.handlers = new Map(messageHandlers.map((u) => [u.messageTag, u]));
@@ -16813,14 +17085,14 @@ var MessageBus = class {
16813
17085
  this.initialized = true;
16814
17086
  }
16815
17087
  async buildServices(config) {
16816
- const arkProvider = new chunk5XBH5SAL_cjs.RestArkProvider(config.arkServer.url);
17088
+ const arkProvider = new chunkKR6FLFIH_cjs.RestArkProvider(config.arkServer.url);
16817
17089
  const storage = {
16818
17090
  walletRepository: this.walletRepository,
16819
17091
  contractRepository: this.contractRepository,
16820
17092
  ...this.intentRepository && { intentRepository: this.intentRepository }
16821
17093
  };
16822
17094
  const delegateProvider = config.delegateUrl ? new RestDelegateProvider(config.delegateUrl) : void 0;
16823
- const indexerProvider = new chunkQ7PC3NHX_cjs.RestIndexerProvider(config.arkServer.url);
17095
+ const indexerProvider = new chunkYFHGGSII_cjs.RestIndexerProvider(config.arkServer.url);
16824
17096
  const serialized = normalizeSerializedIdentity(config.wallet);
16825
17097
  if (isSigningSerialized(serialized)) {
16826
17098
  const identity2 = hydrateIdentity(serialized);
@@ -16833,6 +17105,7 @@ var MessageBus = class {
16833
17105
  delegateProvider,
16834
17106
  settlementConfig: config.settlementConfig,
16835
17107
  walletMode: config.walletMode,
17108
+ lazyInitialization: config.lazyInitialization,
16836
17109
  watcherConfig: config.watcherConfig,
16837
17110
  lookAheadWindow: config.lookAheadWindow,
16838
17111
  minBatchExpirySeconds: config.minBatchExpirySeconds,
@@ -16842,6 +17115,7 @@ var MessageBus = class {
16842
17115
  }
16843
17116
  const identity = hydrateIdentity(serialized);
16844
17117
  const readonlyWallet = await ReadonlyWallet.create({
17118
+ lazyInitialization: config.lazyInitialization,
16845
17119
  identity,
16846
17120
  arkProvider,
16847
17121
  arkServerPublicKey: config.arkServer.publicKey,
@@ -17158,7 +17432,7 @@ var offboardNetworkNames = [
17158
17432
  function offboardDestinationScript(destinationAddress) {
17159
17433
  for (const networkName of offboardNetworkNames) {
17160
17434
  try {
17161
- const network = chunk5XBH5SAL_cjs.networks[networkName];
17435
+ const network = chunkKR6FLFIH_cjs.networks[networkName];
17162
17436
  const addr = btcSigner.Address(network).decode(destinationAddress);
17163
17437
  return btcSigner.OutScript.encode(addr);
17164
17438
  } catch {
@@ -17194,7 +17468,7 @@ function filterOffboardInputs(vtxos, feeInfo, named) {
17194
17468
  const inputs = [];
17195
17469
  let subtotal = 0n;
17196
17470
  for (const vtxo of vtxos) {
17197
- const inputFee = estimator.evalOffchainInput(chunk5XBH5SAL_cjs.toOffchainInputFeeParams(vtxo));
17471
+ const inputFee = estimator.evalOffchainInput(chunkKR6FLFIH_cjs.toOffchainInputFeeParams(vtxo));
17198
17472
  if (inputFee.satoshis >= vtxo.value) {
17199
17473
  if (named) {
17200
17474
  throw new Error(
@@ -17291,7 +17565,7 @@ var Ramps = class {
17291
17565
  }
17292
17566
  amount = amount ?? totalAmount;
17293
17567
  const offchainAddress = await this.wallet.getAddress();
17294
- const offchainAddr = chunk5XBH5SAL_cjs.ArkAddress.decode(offchainAddress);
17568
+ const offchainAddr = chunkKR6FLFIH_cjs.ArkAddress.decode(offchainAddress);
17295
17569
  const offchainScript = base.hex.encode(offchainAddr.pkScript);
17296
17570
  const outputFee = estimator.evalOffchainOutput({
17297
17571
  amount,
@@ -17415,7 +17689,7 @@ var Ramps = class {
17415
17689
  async fundChange(left, estimator) {
17416
17690
  if (left <= 0n) return { change: 0n };
17417
17691
  const changeAddress = await this.wallet.getAddress();
17418
- const changeScript = base.hex.encode(chunk5XBH5SAL_cjs.ArkAddress.decode(changeAddress).pkScript);
17692
+ const changeScript = base.hex.encode(chunkKR6FLFIH_cjs.ArkAddress.decode(changeAddress).pkScript);
17419
17693
  const { change } = changeAfterOutputFee(
17420
17694
  left,
17421
17695
  (amount) => BigInt(estimator.evalOffchainOutput({ amount, script: changeScript }).satoshis)
@@ -17428,8 +17702,6 @@ var Ramps = class {
17428
17702
  return { change, changeAddress };
17429
17703
  }
17430
17704
  };
17431
-
17432
- // src/wallet/serviceWorker/wallet-message-handler.ts
17433
17705
  var WalletNotInitializedError = class extends Error {
17434
17706
  constructor() {
17435
17707
  super("Wallet handler not initialized");
@@ -17572,9 +17844,11 @@ var WalletMessageHandler = class {
17572
17844
  // `onWalletInitialized` re-subscribes incoming funds while
17573
17845
  // `ensureContractEventBroadcasting` deliberately keeps its subscription, so
17574
17846
  // a shared bump would leave the live contract-event emitter permanently
17575
- // stale, and folding requests in would truncate an in-flight settle.
17847
+ // stale, folding requests in would truncate an in-flight settle, and
17848
+ // sharing with boarding would kill every lazy refresh (see `boardingEpoch`).
17576
17849
  incomingFundsEpoch = 0;
17577
17850
  contractEventsEpoch = 0;
17851
+ boardingEpoch = 0;
17578
17852
  /** Per-request progress callbacks: ends with the handler, not with a re-init. */
17579
17853
  requestEpoch = 0;
17580
17854
  /**
@@ -17599,6 +17873,7 @@ var WalletMessageHandler = class {
17599
17873
  this.requestEpoch++;
17600
17874
  this.incomingFundsEpoch++;
17601
17875
  this.contractEventsEpoch++;
17876
+ this.boardingEpoch++;
17602
17877
  this.channel = void 0;
17603
17878
  this.onNextTick = [];
17604
17879
  if (this.incomingFundsSubscription) {
@@ -17640,6 +17915,8 @@ var WalletMessageHandler = class {
17640
17915
  return this.incomingFundsEpoch;
17641
17916
  case "contractEvents":
17642
17917
  return this.contractEventsEpoch;
17918
+ case "boarding":
17919
+ return this.boardingEpoch;
17643
17920
  case "request":
17644
17921
  return this.requestEpoch;
17645
17922
  default: {
@@ -17812,7 +18089,10 @@ var WalletMessageHandler = class {
17812
18089
  });
17813
18090
  }
17814
18091
  case "GET_BOARDING_UTXOS": {
17815
- const utxos = await this.getAllBoardingUtxos();
18092
+ if (!this.readonlyWallet) {
18093
+ throw new WalletNotInitializedError();
18094
+ }
18095
+ const utxos = await this.readonlyWallet.getBoardingUtxos();
17816
18096
  return this.tagged({
17817
18097
  id,
17818
18098
  type: "BOARDING_UTXOS",
@@ -18088,6 +18368,43 @@ var WalletMessageHandler = class {
18088
18368
  payload: { txid }
18089
18369
  });
18090
18370
  }
18371
+ case "SEND_WITH_DEADLINE":
18372
+ case "SEND_WITH_INPUT_EXPIRY_FLOOR": {
18373
+ const wallet = this.requireWallet();
18374
+ const {
18375
+ recipients,
18376
+ selectedVtxos,
18377
+ maxChangeFee,
18378
+ validUntil: wireDeadline
18379
+ } = message.payload;
18380
+ const inputExpiryFloor = message.type === "SEND_WITH_INPUT_EXPIRY_FLOOR" ? captureInputExpiryFloor(
18381
+ message.payload.inputExpiryFloor,
18382
+ true
18383
+ ) : void 0;
18384
+ const validUntil = captureSendDeadline(
18385
+ wireDeadline,
18386
+ message.type === "SEND_WITH_DEADLINE"
18387
+ );
18388
+ try {
18389
+ const txid = await wallet.send({
18390
+ recipients,
18391
+ ...selectedVtxos ? { selectedVtxos } : {},
18392
+ ...maxChangeFee !== void 0 ? { maxChangeFee } : {},
18393
+ validUntil,
18394
+ ...inputExpiryFloor ? { inputExpiryFloor } : {}
18395
+ });
18396
+ return this.tagged({ id, type: "SEND_SUCCESS", payload: { txid } });
18397
+ } catch (error) {
18398
+ if (validUntil === void 0 || !(error instanceof SendDeadlineExceededError))
18399
+ throw error;
18400
+ return this.tagged({
18401
+ id,
18402
+ type: "SEND_DEADLINE_EXCEEDED",
18403
+ error,
18404
+ payload: { validUntil }
18405
+ });
18406
+ }
18407
+ }
18091
18408
  case "GET_ASSET_DETAILS": {
18092
18409
  const { assetId } = message.payload;
18093
18410
  const assetDetails = await this.readonlyWallet.assetManager.getAssetDetails(assetId);
@@ -18283,9 +18600,16 @@ var WalletMessageHandler = class {
18283
18600
  // Wallet methods
18284
18601
  async handleInitWallet({ payload }) {
18285
18602
  const { arkServerUrl } = payload;
18286
- this.indexerProvider = new chunkQ7PC3NHX_cjs.RestIndexerProvider(arkServerUrl);
18603
+ this.lazyBoardingInit = payload.lazyBoarding ?? false;
18604
+ this.boardingEpoch++;
18605
+ this.boardingLoaded = false;
18606
+ this.indexerProvider = new chunkYFHGGSII_cjs.RestIndexerProvider(arkServerUrl);
18287
18607
  await this.onWalletInitialized();
18288
18608
  }
18609
+ /** @see RequestInitWallet.payload.lazyBoarding */
18610
+ lazyBoardingInit = false;
18611
+ /** Set once this session has actually fetched the boarding addresses. */
18612
+ boardingLoaded = false;
18289
18613
  /**
18290
18614
  * The worker's own balance. Same bucketing rules as `Wallet.getBalance` —
18291
18615
  * both call {@link computeOffchainBalance} — but deliberately a different
@@ -18296,7 +18620,7 @@ var WalletMessageHandler = class {
18296
18620
  */
18297
18621
  async handleGetBalance() {
18298
18622
  const [boardingUtxos, { snapshot, vtxos: allVtxos }] = await Promise.all([
18299
- this.getAllBoardingUtxos(),
18623
+ this.getBoardingUtxosForBalance(),
18300
18624
  // The bucketer drops every spent coin and the gate reads contracts only.
18301
18625
  this.repoSnapshot({ unspentOnly: true })
18302
18626
  ]);
@@ -18312,11 +18636,14 @@ var WalletMessageHandler = class {
18312
18636
  isUnlocked: (vtxo) => unlocked.has(`${vtxo.txid}:${vtxo.vout}`),
18313
18637
  dustCarrier: getDustAmount(this.readonlyWallet)
18314
18638
  });
18315
- return toWalletBalance(boardingUtxos, offchain);
18639
+ const balance = toWalletBalance(boardingUtxos, offchain);
18640
+ balance.boarding.loaded = this.boardingLoaded;
18641
+ return balance;
18316
18642
  }
18317
- async getAllBoardingUtxos() {
18643
+ async getBoardingUtxosForBalance() {
18318
18644
  if (!this.readonlyWallet) return [];
18319
- return this.readonlyWallet.getBoardingUtxos();
18645
+ if (!this.lazyBoardingInit) return this.readonlyWallet.getBoardingUtxos();
18646
+ return this.readonlyWallet.getStoredBoardingUtxos ? this.readonlyWallet.getStoredBoardingUtxos() : this.readonlyWallet.getBoardingUtxos();
18320
18647
  }
18321
18648
  async onWalletInitialized() {
18322
18649
  const wallet = this.readonlyWallet;
@@ -18326,7 +18653,7 @@ var WalletMessageHandler = class {
18326
18653
  const init = this.newGeneration("incomingFunds");
18327
18654
  await this.ensureContractEventBroadcasting();
18328
18655
  if (init.stale) return;
18329
- await this.refreshCachedData();
18656
+ await this.refreshCachedData({ lazyBoarding: this.lazyBoardingInit });
18330
18657
  if (init.stale) return;
18331
18658
  if (this.wallet) {
18332
18659
  try {
@@ -18424,27 +18751,75 @@ var WalletMessageHandler = class {
18424
18751
  }
18425
18752
  }
18426
18753
  /**
18427
- * Refresh virtual outputs, boarding inputs, and transaction history from cache.
18428
- * Shared by onWalletInitialized (full bootstrap) and reloadWallet
18429
- * (post-refresh), avoiding duplicate subscriptions and VtxoManager restarts.
18754
+ * Refresh boarding inputs and transaction history. The virtual outputs come
18755
+ * from the contract manager, which runs before this. Shared by
18756
+ * onWalletInitialized (full bootstrap) and reloadWallet (post-refresh),
18757
+ * avoiding duplicate subscriptions and VtxoManager restarts.
18758
+ *
18759
+ * Both legs reach the onchain provider, so `lazyBoarding` moves them both
18760
+ * off the caller's path. @see RequestInitWallet.payload.lazyBoarding
18430
18761
  */
18431
- async refreshCachedData() {
18762
+ async refreshCachedData(opts) {
18432
18763
  if (!this.readonlyWallet || !this.walletRepository) {
18433
18764
  return;
18434
18765
  }
18435
- const boardingAddresses = await this.readonlyWallet.getBoardingAddresses();
18436
- const fresh = await this.readonlyWallet.getBoardingUtxos();
18437
- const freshKeys = new Set(fresh.map((u) => `${u.txid}:${u.vout}`));
18438
- for (const addr of boardingAddresses) {
18439
- const cached = await collectUtxos(this.walletRepository, addr);
18440
- const kept = cached.filter((u) => freshKeys.has(`${u.txid}:${u.vout}`));
18441
- if (kept.length === cached.length) continue;
18442
- await this.walletRepository.deleteUtxos(addr);
18443
- if (kept.length > 0) await this.walletRepository.saveUtxos(addr, kept);
18766
+ if (opts?.lazyBoarding) {
18767
+ const emitter = this.newEmitter("boarding");
18768
+ void (async () => {
18769
+ await this.refreshBoardingCache(emitter);
18770
+ if (emitter.stale) return;
18771
+ this.boardingLoaded = true;
18772
+ const coins = await this.readonlyWallet?.getStoredBoardingUtxos?.() ?? [];
18773
+ emitter.emit(
18774
+ this.tagged({
18775
+ type: "UTXO_UPDATE",
18776
+ broadcast: true,
18777
+ payload: { coins }
18778
+ })
18779
+ );
18780
+ await this.refreshHistoryCache(emitter);
18781
+ })().catch((error) => {
18782
+ console.warn("[wallet] background refresh failed", error);
18783
+ });
18784
+ return;
18444
18785
  }
18445
- const address = await this.readonlyWallet.getAddress();
18786
+ await this.refreshBoardingCache();
18787
+ this.boardingLoaded = true;
18788
+ await this.refreshHistoryCache();
18789
+ }
18790
+ /** @param gen - set by a background caller; each write is skipped once it goes stale. */
18791
+ async refreshHistoryCache(gen) {
18792
+ const wallet = this.readonlyWallet;
18793
+ const repository = this.walletRepository;
18794
+ if (!wallet || !repository) return;
18795
+ const address = await wallet.getAddress();
18446
18796
  const txs = await this.buildTransactionHistoryFromCache();
18447
- if (txs) await this.walletRepository.saveTransactions(address, txs);
18797
+ if (txs && !gen?.stale) await repository.saveTransactions(address, txs);
18798
+ }
18799
+ /**
18800
+ * @param gen - set by a background caller; each write here is skipped once it goes stale.
18801
+ * The fetch saves the fetched rows itself, before control returns, so that one write is
18802
+ * outside this check.
18803
+ */
18804
+ async refreshBoardingCache(gen) {
18805
+ const wallet = this.readonlyWallet;
18806
+ const repository = this.walletRepository;
18807
+ if (!wallet || !repository) return;
18808
+ const currentSigner = toXOnlySignerHex(
18809
+ base.hex.encode(wallet.boardingTapscript.options.serverPubKey)
18810
+ );
18811
+ const groups = await wallet.getBoardingUtxosForSigners(/* @__PURE__ */ new Set([currentSigner]));
18812
+ for (const { tapscript, coins } of groups) {
18813
+ if (gen?.stale) return;
18814
+ const address = tapscript.onchainAddress(wallet.network);
18815
+ const freshKeys = new Set(coins.map((coin) => `${coin.txid}:${coin.vout}`));
18816
+ const cached = await collectUtxos(repository, address);
18817
+ const kept = cached.filter((coin) => freshKeys.has(`${coin.txid}:${coin.vout}`));
18818
+ if (kept.length === cached.length) continue;
18819
+ if (gen?.stale) return;
18820
+ await repository.deleteUtxos(address);
18821
+ if (kept.length > 0) await repository.saveUtxos(address, kept);
18822
+ }
18448
18823
  }
18449
18824
  /**
18450
18825
  * Force a full VTXO refresh from the indexer, then refresh cached data.
@@ -18538,6 +18913,8 @@ var WalletMessageHandler = class {
18538
18913
  this.requestEpoch++;
18539
18914
  this.incomingFundsEpoch++;
18540
18915
  this.contractEventsEpoch++;
18916
+ this.boardingEpoch++;
18917
+ this.boardingLoaded = false;
18541
18918
  this.onNextTick = [];
18542
18919
  if (this.incomingFundsSubscription) {
18543
18920
  this.incomingFundsSubscription();
@@ -18648,7 +19025,7 @@ var WalletMessageHandler = class {
18648
19025
  this.readonlyWallet.getBoardingTxs()
18649
19026
  ]);
18650
19027
  const indexerProvider = this.indexerProvider;
18651
- const resolveTxCreatedAt = indexerProvider ? (txids) => chunk5XBH5SAL_cjs.fetchVtxoCreatedAtByTxid(indexerProvider, txids) : void 0;
19028
+ const resolveTxCreatedAt = indexerProvider ? (txids) => chunkKR6FLFIH_cjs.fetchVtxoCreatedAtByTxid(indexerProvider, txids) : void 0;
18652
19029
  return buildTransactionHistory(
18653
19030
  vtxos,
18654
19031
  boardingTxs,
@@ -18717,7 +19094,7 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
18717
19094
  // budget so the worker's snapshot fallback stays reachable before this
18718
19095
  // page deadline fires — lowering it below the budget would time the page
18719
19096
  // out while the worker is still seconds from answering from cache.
18720
- GET_ARKADE_INFO: chunk5XBH5SAL_cjs.INFO_FETCH_TIMEOUT_MS + 8e3,
19097
+ GET_ARKADE_INFO: chunkKR6FLFIH_cjs.INFO_FETCH_TIMEOUT_MS + 8e3,
18721
19098
  INDEXER_GET_VTXOS: 2e4,
18722
19099
  INDEXER_GET_VIRTUAL_TXS: 2e4,
18723
19100
  GET_VTXOS: 2e4,
@@ -18741,6 +19118,8 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
18741
19118
  // are treated as long-running on both sides of the bus: the values below
18742
19119
  // are retained only for type completeness and are never enforced.
18743
19120
  SEND: 5e4,
19121
+ SEND_WITH_DEADLINE: 5e4,
19122
+ SEND_WITH_INPUT_EXPIRY_FLOOR: 5e4,
18744
19123
  SETTLE: 5e4,
18745
19124
  // Broadcast: the server round-trip a spend ends in, so it belongs
18746
19125
  // with the writes rather than the reads above.
@@ -18856,7 +19235,7 @@ var ServiceWorkerAssetManager = class extends ServiceWorkerReadonlyAssetManager
18856
19235
  }
18857
19236
  };
18858
19237
  var initializeMessageBus = (serviceWorker, config, timeoutMs = 2e3) => {
18859
- chunk5XBH5SAL_cjs.assertTimerMs("messageBusTimeoutMs", timeoutMs);
19238
+ chunkKR6FLFIH_cjs.assertTimerMs("messageBusTimeoutMs", timeoutMs);
18860
19239
  const initCmd = {
18861
19240
  tag: "INITIALIZE_MESSAGE_BUS",
18862
19241
  id: getRandomId(),
@@ -18938,13 +19317,15 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
18938
19317
  const serializedWallet = await serializeReadonlyIdentity(options.identity);
18939
19318
  return _ServiceWorkerReadonlyWallet.bootstrap(wallet, options, serializedWallet, {
18940
19319
  delegateUrl: options.delegateUrl,
19320
+ lazyInitialization: options.lazyInitialization,
18941
19321
  watcherConfig: options.watcherConfig
18942
19322
  });
18943
19323
  }
18944
19324
  /** Shared tail of both `create()` factories: boot the bus, INIT_WALLET, cache for reinit. */
18945
19325
  static async bootstrap(wallet, options, serializedWallet, busConfig) {
18946
- const arkServer = options.arkServer ?? { url: chunk5XBH5SAL_cjs.DEFAULT_ARKADE_SERVER_URL };
19326
+ const arkServer = options.arkServer ?? { url: chunkKR6FLFIH_cjs.DEFAULT_ARKADE_SERVER_URL };
18947
19327
  const initWalletPayload = {
19328
+ lazyBoarding: options.lazyBoarding,
18948
19329
  arkServerUrl: arkServer.url,
18949
19330
  arkServerPublicKey: arkServer.publicKey
18950
19331
  };
@@ -18952,7 +19333,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
18952
19333
  Object.entries(options.messageTimeouts ?? {}).filter(([, ms]) => ms !== void 0)
18953
19334
  );
18954
19335
  for (const [key, value] of Object.entries(overrides)) {
18955
- chunk5XBH5SAL_cjs.assertTimerMs(`messageTimeouts.${key}`, value);
19336
+ chunkKR6FLFIH_cjs.assertTimerMs(`messageTimeouts.${key}`, value);
18956
19337
  }
18957
19338
  const messageTimeouts = {
18958
19339
  ...DEFAULT_MESSAGE_TIMEOUTS,
@@ -19027,6 +19408,16 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19027
19408
  if (request.id !== response.id) {
19028
19409
  return;
19029
19410
  }
19411
+ if (response.type === "SEND_DEADLINE_EXCEEDED") {
19412
+ if (event.source !== this.serviceWorker || response.tag !== request.tag) return;
19413
+ cleanup();
19414
+ if ((request.type === "SEND_WITH_DEADLINE" || request.type === "SEND_WITH_INPUT_EXPIRY_FLOOR") && response.error instanceof Error && (response.broadcast === void 0 || response.broadcast === false) && Number.isSafeInteger(response.payload?.validUntil) && response.payload.validUntil > 0 && response.payload.validUntil === request.payload.validUntil) {
19415
+ reject(new SendDeadlineExceededError(request.payload.validUntil));
19416
+ } else {
19417
+ reject(new Error("Invalid timed-send refusal response"));
19418
+ }
19419
+ return;
19420
+ }
19030
19421
  cleanup();
19031
19422
  if (response.error) {
19032
19423
  reject(restoreErrorName(response));
@@ -19282,7 +19673,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19282
19673
  try {
19283
19674
  const response = await this.sendMessage(message);
19284
19675
  const { vtxos, page } = response.payload;
19285
- return { vtxos: vtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo), page: page && { ...page } };
19676
+ return { vtxos: vtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo), page: page && { ...page } };
19286
19677
  } catch (cause) {
19287
19678
  throw new Error(`Failed to get vtxos: ${cause}`, { cause });
19288
19679
  }
@@ -19386,7 +19777,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19386
19777
  };
19387
19778
  try {
19388
19779
  const response = await this.sendMessage(message);
19389
- return response.payload.vtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo);
19780
+ return response.payload.vtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo);
19390
19781
  } catch (error) {
19391
19782
  throw new Error(`Failed to get vtxos: ${error}`);
19392
19783
  }
@@ -19417,7 +19808,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19417
19808
  "Service worker does not support the requested contract scope or freshness check"
19418
19809
  );
19419
19810
  }
19420
- return payload.vtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo);
19811
+ return payload.vtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo);
19421
19812
  } catch (error) {
19422
19813
  throw new Error(`Failed to get spendable vtxos: ${error}`);
19423
19814
  }
@@ -19595,7 +19986,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19595
19986
  };
19596
19987
  try {
19597
19988
  const response = await sendContractMessage(message);
19598
- return response.payload.vtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo);
19989
+ return response.payload.vtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo);
19599
19990
  } catch (cause) {
19600
19991
  throw new Error(`Failed to annotate vtxos: ${cause}`, { cause });
19601
19992
  }
@@ -19769,8 +20160,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
19769
20160
  });
19770
20161
  }
19771
20162
  },
19772
- dispose() {
19773
- return;
20163
+ async dispose() {
19774
20164
  },
19775
20165
  [Symbol.dispose]() {
19776
20166
  return;
@@ -19830,6 +20220,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
19830
20220
  delegateUrl: options.delegateUrl,
19831
20221
  settlementConfig: options.settlementConfig,
19832
20222
  walletMode: options.walletMode,
20223
+ lazyInitialization: options.lazyInitialization,
19833
20224
  watcherConfig: options.watcherConfig,
19834
20225
  lookAheadWindow: options.lookAheadWindow,
19835
20226
  minBatchExpirySeconds: options.minBatchExpirySeconds,
@@ -20067,27 +20458,51 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
20067
20458
  }
20068
20459
  async send(...args) {
20069
20460
  const [first] = args;
20070
- const { recipients, selectedVtxos, maxChangeFee } = args.length === 1 && first && "recipients" in first ? first : {
20461
+ const {
20462
+ recipients,
20463
+ selectedVtxos,
20464
+ maxChangeFee,
20465
+ validUntil: wireDeadline,
20466
+ inputExpiryFloor: wireInputExpiryFloor
20467
+ } = args.length === 1 && first && "recipients" in first ? first : {
20071
20468
  recipients: args,
20072
20469
  selectedVtxos: void 0,
20073
- maxChangeFee: void 0
20470
+ maxChangeFee: void 0,
20471
+ validUntil: void 0,
20472
+ inputExpiryFloor: void 0
20074
20473
  };
20075
- const message = {
20474
+ const validUntil = captureSendDeadline(wireDeadline);
20475
+ const inputExpiryFloor = captureInputExpiryFloor(wireInputExpiryFloor);
20476
+ const options = {
20477
+ ...selectedVtxos ? { selectedVtxos } : {},
20478
+ ...maxChangeFee !== void 0 ? { maxChangeFee } : {}
20479
+ };
20480
+ const message = inputExpiryFloor !== void 0 ? {
20076
20481
  tag: this.messageTag,
20077
- type: "SEND",
20482
+ type: "SEND_WITH_INPUT_EXPIRY_FLOOR",
20078
20483
  id: getRandomId(),
20079
- // Omitted rather than sent as `undefined`, so an older worker sees
20080
- // exactly the payload it saw before.
20081
20484
  payload: {
20082
20485
  recipients,
20083
- ...selectedVtxos ? { selectedVtxos } : {},
20084
- ...maxChangeFee !== void 0 ? { maxChangeFee } : {}
20486
+ ...options,
20487
+ inputExpiryFloor,
20488
+ ...validUntil === void 0 ? {} : { validUntil }
20085
20489
  }
20490
+ } : validUntil === void 0 ? {
20491
+ tag: this.messageTag,
20492
+ type: "SEND",
20493
+ id: getRandomId(),
20494
+ payload: { recipients, ...options }
20495
+ } : {
20496
+ tag: this.messageTag,
20497
+ type: "SEND_WITH_DEADLINE",
20498
+ id: getRandomId(),
20499
+ payload: { recipients, ...options, validUntil }
20086
20500
  };
20087
20501
  try {
20088
20502
  const response = await this.sendMessage(message);
20089
20503
  return response.payload.txid;
20090
20504
  } catch (error) {
20505
+ if (error instanceof SendDeadlineExceededError) throw error;
20091
20506
  throw new Error(`Send failed: ${error}`);
20092
20507
  }
20093
20508
  }
@@ -20190,7 +20605,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
20190
20605
  };
20191
20606
  try {
20192
20607
  const response = await wallet.sendMessage(message);
20193
- return response.payload.vtxos.map(chunk5XBH5SAL_cjs.normalizeVtxo);
20608
+ return response.payload.vtxos.map(chunkKR6FLFIH_cjs.normalizeVtxo);
20194
20609
  } catch (e) {
20195
20610
  throw new Error(`Failed to get expiring vtxos: ${e}`);
20196
20611
  }
@@ -20307,12 +20722,12 @@ var OnchainWallet = class _OnchainWallet {
20307
20722
  * @returns Configured onchain wallet
20308
20723
  * @throws Error if the configured identity cannot produce a valid x-only public key
20309
20724
  */
20310
- static async create(identity, networkName = chunk5XBH5SAL_cjs.DEFAULT_NETWORK_NAME, provider) {
20725
+ static async create(identity, networkName = chunkKR6FLFIH_cjs.DEFAULT_NETWORK_NAME, provider) {
20311
20726
  const pubkey = await identity.xOnlyPublicKey();
20312
20727
  if (!pubkey) {
20313
20728
  throw new Error("Invalid configured public key");
20314
20729
  }
20315
- const network = chunk5XBH5SAL_cjs.getNetwork(networkName);
20730
+ const network = chunkKR6FLFIH_cjs.getNetwork(networkName);
20316
20731
  const onchainProvider = provider || new EsploraProvider(ESPLORA_URL[networkName]);
20317
20732
  const onchainP2TR = btcSigner.p2tr(pubkey, void 0, network);
20318
20733
  return new _OnchainWallet(identity, network, onchainP2TR, onchainProvider);
@@ -20412,7 +20827,7 @@ var OnchainWallet = class _OnchainWallet {
20412
20827
  feeRate,
20413
20828
  params.address
20414
20829
  );
20415
- let tx = new chunk5XBH5SAL_cjs.Transaction();
20830
+ let tx = new chunkKR6FLFIH_cjs.Transaction();
20416
20831
  for (const input of inputs) {
20417
20832
  tx.addInput({
20418
20833
  txid: input.txid,
@@ -20470,7 +20885,7 @@ var OnchainWallet = class _OnchainWallet {
20470
20885
  * @throws If the parent has no anchor, or funding cannot be selected/signed
20471
20886
  */
20472
20887
  async bumpAnchor(parentHex, feeRate) {
20473
- const parent = chunk5XBH5SAL_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
20888
+ const parent = chunkKR6FLFIH_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
20474
20889
  const coins = (await this.getCoins()).filter((c) => c.status.confirmed);
20475
20890
  const child = await this.buildBumpPackage(parent, feeRate, coins);
20476
20891
  return [parent.hex, child.hex];
@@ -21286,7 +21701,7 @@ var CachingArkProvider = class {
21286
21701
  constructor(inner, ttlMs = DEFAULT_TTL_MS) {
21287
21702
  this.inner = inner;
21288
21703
  this.ttlMs = ttlMs;
21289
- chunk5XBH5SAL_cjs.assertNonNegativeMs("ttlMs", ttlMs);
21704
+ chunkKR6FLFIH_cjs.assertNonNegativeMs("ttlMs", ttlMs);
21290
21705
  this.unsubscribe = inner.onServerInfoChanged?.((info) => {
21291
21706
  this.cached = info;
21292
21707
  this.expiresAt = Date.now() + this.ttlMs;
@@ -21378,7 +21793,7 @@ async function resolvePrevTxs(txids, source, onchain) {
21378
21793
  try {
21379
21794
  const { txs } = await source.getVirtualTxs(wanted);
21380
21795
  for (const psbt of txs) {
21381
- const tx = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(psbt));
21796
+ const tx = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(psbt));
21382
21797
  resolved.set(tx.id, tx.toBytes());
21383
21798
  }
21384
21799
  } catch (err) {
@@ -21411,7 +21826,7 @@ async function resolvePrevTxs(txids, source, onchain) {
21411
21826
  async function attachPrevArkTxs(tx, txids, source, onchain) {
21412
21827
  const pending = [];
21413
21828
  for (let i = 0; i < tx.inputsLength; i++) {
21414
- if (chunk5XBH5SAL_cjs.getArkPsbtFields(tx, i, chunk5XBH5SAL_cjs.PrevArkTxField).length === 0) pending.push(i);
21829
+ if (chunkKR6FLFIH_cjs.getArkPsbtFields(tx, i, chunkKR6FLFIH_cjs.PrevArkTxField).length === 0) pending.push(i);
21415
21830
  }
21416
21831
  if (pending.length === 0) return;
21417
21832
  const resolved = await resolvePrevTxs(
@@ -21420,13 +21835,13 @@ async function attachPrevArkTxs(tx, txids, source, onchain) {
21420
21835
  onchain
21421
21836
  );
21422
21837
  for (const i of pending) {
21423
- chunk5XBH5SAL_cjs.setArkPsbtField(tx, i, chunk5XBH5SAL_cjs.PrevArkTxField, resolved.get(txidAt(txids, i)));
21838
+ chunkKR6FLFIH_cjs.setArkPsbtField(tx, i, chunkKR6FLFIH_cjs.PrevArkTxField, resolved.get(txidAt(txids, i)));
21424
21839
  }
21425
21840
  }
21426
21841
  async function attachPrevoutTxs(tx, source) {
21427
21842
  const pending = [];
21428
21843
  for (let i = 0; i < tx.inputsLength; i++) {
21429
- if (chunk5XBH5SAL_cjs.getArkPsbtFields(tx, i, chunk5XBH5SAL_cjs.PrevoutTxField).length > 0) continue;
21844
+ if (chunkKR6FLFIH_cjs.getArkPsbtFields(tx, i, chunkKR6FLFIH_cjs.PrevoutTxField).length > 0) continue;
21430
21845
  const input = tx.getInput(i);
21431
21846
  if (!input?.txid) throw new PrevTxUnavailableError(`input ${i} has no outpoint`);
21432
21847
  pending.push({ index: i, txid: base.hex.encode(input.txid) });
@@ -21437,7 +21852,7 @@ async function attachPrevoutTxs(tx, source) {
21437
21852
  resolved.set(txid, await source.getRawTransaction(txid));
21438
21853
  }
21439
21854
  for (const { index, txid } of pending) {
21440
- chunk5XBH5SAL_cjs.setArkPsbtField(tx, index, chunk5XBH5SAL_cjs.PrevoutTxField, resolved.get(txid));
21855
+ chunkKR6FLFIH_cjs.setArkPsbtField(tx, index, chunkKR6FLFIH_cjs.PrevoutTxField, resolved.get(txid));
21441
21856
  }
21442
21857
  }
21443
21858
  async function withPrevTxs(coins, source, onchain) {
@@ -21463,7 +21878,7 @@ exports.BIP322 = void 0;
21463
21878
  async function sign2(message, identity, network) {
21464
21879
  const xOnlyPubKey = await identity.xOnlyPublicKey();
21465
21880
  const payment = btcSigner.p2tr(xOnlyPubKey, void 0, network);
21466
- const toSpend = chunk5XBH5SAL_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
21881
+ const toSpend = chunkKR6FLFIH_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
21467
21882
  const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
21468
21883
  const signed = await identity.sign(toSign, [0]);
21469
21884
  signed.finalizeIdx(0);
@@ -21521,7 +21936,7 @@ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
21521
21936
  if (sighashType !== btcSigner.SigHash.DEFAULT && sighashType !== btcSigner.SigHash.ALL) {
21522
21937
  return false;
21523
21938
  }
21524
- const toSpend = chunk5XBH5SAL_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
21939
+ const toSpend = chunkKR6FLFIH_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
21525
21940
  const toSign = craftBIP322ToSignP2TR(toSpend, pkScript);
21526
21941
  const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
21527
21942
  const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
@@ -21542,7 +21957,7 @@ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
21542
21957
  }
21543
21958
  const sighashType = sigWithHash[sigWithHash.length - 1];
21544
21959
  const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
21545
- const toSpend = chunk5XBH5SAL_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
21960
+ const toSpend = chunkKR6FLFIH_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
21546
21961
  const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
21547
21962
  const scriptCode = btcSigner.OutScript.encode({ type: "pkh", hash: addressHash });
21548
21963
  const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
@@ -21595,7 +22010,7 @@ function encodeCompactSize(n) {
21595
22010
  return buf;
21596
22011
  }
21597
22012
  function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
21598
- const tx = new chunk5XBH5SAL_cjs.Transaction({ version: 0 });
22013
+ const tx = new chunkKR6FLFIH_cjs.Transaction({ version: 0 });
21599
22014
  tx.addInput({
21600
22015
  txid: toSpend.id,
21601
22016
  index: 0,
@@ -21609,12 +22024,12 @@ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
21609
22024
  });
21610
22025
  tx.addOutput({
21611
22026
  amount: 0n,
21612
- script: chunk5XBH5SAL_cjs.OP_RETURN_EMPTY_PKSCRIPT
22027
+ script: chunkKR6FLFIH_cjs.OP_RETURN_EMPTY_PKSCRIPT
21613
22028
  });
21614
22029
  return tx;
21615
22030
  }
21616
22031
  function craftBIP322ToSignSimple(toSpend, pkScript) {
21617
- const tx = new chunk5XBH5SAL_cjs.Transaction({ version: 0 });
22032
+ const tx = new chunkKR6FLFIH_cjs.Transaction({ version: 0 });
21618
22033
  tx.addInput({
21619
22034
  txid: toSpend.id,
21620
22035
  index: 0,
@@ -21626,7 +22041,7 @@ function craftBIP322ToSignSimple(toSpend, pkScript) {
21626
22041
  });
21627
22042
  tx.addOutput({
21628
22043
  amount: 0n,
21629
- script: chunk5XBH5SAL_cjs.OP_RETURN_EMPTY_PKSCRIPT
22044
+ script: chunkKR6FLFIH_cjs.OP_RETURN_EMPTY_PKSCRIPT
21630
22045
  });
21631
22046
  return tx;
21632
22047
  }
@@ -21639,7 +22054,7 @@ var RestEmulatorProvider = class {
21639
22054
  serverUrl;
21640
22055
  async getInfo() {
21641
22056
  const url = `${this.serverUrl}/v1/info`;
21642
- const response = await chunk5XBH5SAL_cjs.baseFetch(url);
22057
+ const response = await chunkKR6FLFIH_cjs.baseFetch(url);
21643
22058
  if (!response.ok) {
21644
22059
  const errorText2 = await response.text();
21645
22060
  throw new Error(`Failed to get emulator info: ${errorText2}`);
@@ -21757,7 +22172,7 @@ var RestEmulatorProvider = class {
21757
22172
  }
21758
22173
  };
21759
22174
  function finalizeVirtualTx(type, psbtBase64) {
21760
- const tx = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
22175
+ const tx = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
21761
22176
  if (type === "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */) {
21762
22177
  const input = tx.getInput(0);
21763
22178
  if (!input) {
@@ -21784,14 +22199,14 @@ var ExitPathError = class extends Error {
21784
22199
  reason;
21785
22200
  };
21786
22201
  function delayWeight(sequence) {
21787
- const t = chunk5XBH5SAL_cjs.sequenceToTimelock(sequence);
22202
+ const t = chunkKR6FLFIH_cjs.sequenceToTimelock(sequence);
21788
22203
  return t.type === "blocks" ? Number(t.value) : Number(t.value) / 600;
21789
22204
  }
21790
22205
  async function resolveUnilateralPath(params) {
21791
22206
  const { vtxo, scriptHex, contractRepository } = params;
21792
22207
  const contract = contractRepository ? (await collectContracts(contractRepository, { script: scriptHex }))[0] : void 0;
21793
22208
  if (contract) {
21794
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(contract.type);
22209
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(contract.type);
21795
22210
  if (!handler) {
21796
22211
  throw new ExitPathError(
21797
22212
  "no-handler",
@@ -21813,12 +22228,12 @@ async function resolveUnilateralPath(params) {
21813
22228
  paths.sort((a, b) => delayWeight(a.sequence) - delayWeight(b.sequence));
21814
22229
  return { selection: paths[0], label: `${contract.type}:unilateral` };
21815
22230
  }
21816
- const decoded = chunk5XBH5SAL_cjs.VtxoScript.decode(vtxo.tapTree);
22231
+ const decoded = chunkKR6FLFIH_cjs.VtxoScript.decode(vtxo.tapTree);
21817
22232
  let best;
21818
22233
  for (const exit of decoded.exitPaths()) {
21819
22234
  const leaf = decoded.findLeaf(base.hex.encode(exit.script));
21820
22235
  if (!leaf) continue;
21821
- const sequence = chunk5XBH5SAL_cjs.timelockToSequence(exit.params.timelock);
22236
+ const sequence = chunkKR6FLFIH_cjs.timelockToSequence(exit.params.timelock);
21822
22237
  const weight = delayWeight(sequence);
21823
22238
  if (!best || weight < best.weight) {
21824
22239
  best = { selection: { leaf, sequence }, weight };
@@ -22025,7 +22440,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
22025
22440
  const txWeightEstimator = TxWeightEstimator.create();
22026
22441
  const walletDescriptor = base.hex.encode(await wallet.identity.xOnlyPublicKey());
22027
22442
  for (const vtxo of vtxos) {
22028
- if (!chunk5XBH5SAL_cjs.canSweepOnchain(vtxo)) {
22443
+ if (!chunkKR6FLFIH_cjs.canSweepOnchain(vtxo)) {
22029
22444
  throw new Error(
22030
22445
  `Vtxo ${vtxo.txid}:${vtxo.vout} cannot be swept onchain: it is not fully unrolled (use unroll first), or its exit output was already spent`
22031
22446
  );
@@ -22036,14 +22451,14 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
22036
22451
  }
22037
22452
  const resolved = await resolveUnilateralPath({
22038
22453
  vtxo,
22039
- scriptHex: base.hex.encode(chunk5XBH5SAL_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
22454
+ scriptHex: base.hex.encode(chunkKR6FLFIH_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
22040
22455
  contractRepository: wallet.contractRepository,
22041
22456
  walletDescriptor,
22042
22457
  currentTime: Date.now()
22043
22458
  });
22044
22459
  const spendingLeaf = resolved.selection.leaf;
22045
22460
  const sequence = resolved.selection.sequence;
22046
- const timelock = chunk5XBH5SAL_cjs.sequenceToTimelock(sequence);
22461
+ const timelock = chunkKR6FLFIH_cjs.sequenceToTimelock(sequence);
22047
22462
  const elapsed = timelock.type === "blocks" ? chainTip.height >= txStatus.blockHeight + Number(timelock.value) : chainTip.time >= txStatus.blockTime + Number(timelock.value);
22048
22463
  if (!elapsed) {
22049
22464
  throw new Error(`no available exit path found for vtxo ${vtxo.txid}:${vtxo.vout}`);
@@ -22056,7 +22471,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
22056
22471
  sequence,
22057
22472
  witnessUtxo: {
22058
22473
  amount: BigInt(vtxo.value),
22059
- script: chunk5XBH5SAL_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
22474
+ script: chunkKR6FLFIH_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
22060
22475
  },
22061
22476
  sighashType: btcSigner.SigHash.DEFAULT
22062
22477
  });
@@ -22066,7 +22481,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
22066
22481
  btcSigner.TaprootControlBlock.encode(spendingLeaf[0]).length
22067
22482
  );
22068
22483
  }
22069
- const tx = new chunk5XBH5SAL_cjs.Transaction({ version: 2 });
22484
+ const tx = new chunkKR6FLFIH_cjs.Transaction({ version: 2 });
22070
22485
  for (const input of inputs) {
22071
22486
  tx.addInput(input);
22072
22487
  }
@@ -22149,7 +22564,7 @@ async function buildSignedSweep(params) {
22149
22564
  `uneconomic vtxo ${vtxo.txid}:${vtxo.vout}: value ${vtxo.value} - fee ${fee} < dust`
22150
22565
  );
22151
22566
  }
22152
- const tx = new chunk5XBH5SAL_cjs.Transaction({ version: 2 });
22567
+ const tx = new chunkKR6FLFIH_cjs.Transaction({ version: 2 });
22153
22568
  tx.addInput({
22154
22569
  txid: vtxo.txid,
22155
22570
  index: vtxo.vout,
@@ -22174,7 +22589,7 @@ async function buildSignedSweep(params) {
22174
22589
  finalScriptWitness: [
22175
22590
  tapScriptSig[0][1],
22176
22591
  ...path.extraWitness,
22177
- chunk5XBH5SAL_cjs.scriptFromTapLeafScript(path.leaf),
22592
+ chunkKR6FLFIH_cjs.scriptFromTapLeafScript(path.leaf),
22178
22593
  btcSigner.TaprootControlBlock.encode(controlBlock)
22179
22594
  ]
22180
22595
  });
@@ -22204,7 +22619,7 @@ async function resolveFeeRate(opts) {
22204
22619
  }
22205
22620
  async function selectExitVtxos(opts) {
22206
22621
  if (!opts.vtxos) return opts.wallet.getVtxos();
22207
- const res = await chunk5XBH5SAL_cjs.getNormalizedVtxos(opts.wallet.indexerProvider, { outpoints: opts.vtxos });
22622
+ const res = await chunkKR6FLFIH_cjs.getNormalizedVtxos(opts.wallet.indexerProvider, { outpoints: opts.vtxos });
22208
22623
  const tapTrees = /* @__PURE__ */ new Map();
22209
22624
  const out = [];
22210
22625
  for (const vtxo of res.vtxos) {
@@ -22219,7 +22634,7 @@ async function selectExitVtxos(opts) {
22219
22634
  `no contract registered for vtxo script ${vtxo.script} \u2014 register the contract before exiting`
22220
22635
  );
22221
22636
  }
22222
- const handler = chunkGVF4OCTL_cjs.contractHandlers.get(contract.type);
22637
+ const handler = chunkQLJXXVRO_cjs.contractHandlers.get(contract.type);
22223
22638
  if (!handler) {
22224
22639
  throw new Error(`no contract handler registered for type '${contract.type}'`);
22225
22640
  }
@@ -22249,7 +22664,7 @@ async function computeExitLayout(opts, feeRate) {
22249
22664
  if (pendingNodes.length > 0) {
22250
22665
  const txs = await resolver.getVirtualTxs(pendingNodes.map((n) => n.txid));
22251
22666
  for (const psbt of txs) {
22252
- psbts.set(chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
22667
+ psbts.set(chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
22253
22668
  }
22254
22669
  }
22255
22670
  const childVsize = Number(
@@ -22277,7 +22692,7 @@ async function computeExitLayout(opts, feeRate) {
22277
22692
  try {
22278
22693
  const resolved = await resolveUnilateralPath({
22279
22694
  vtxo,
22280
- scriptHex: base.hex.encode(chunk5XBH5SAL_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
22695
+ scriptHex: base.hex.encode(chunkKR6FLFIH_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
22281
22696
  contractRepository: wallet.contractRepository,
22282
22697
  walletDescriptor,
22283
22698
  currentTime: Date.now()
@@ -22296,7 +22711,7 @@ async function computeExitLayout(opts, feeRate) {
22296
22711
  });
22297
22712
  continue;
22298
22713
  }
22299
- const t = chunk5XBH5SAL_cjs.sequenceToTimelock(resolved.selection.sequence);
22714
+ const t = chunkKR6FLFIH_cjs.sequenceToTimelock(resolved.selection.sequence);
22300
22715
  const delay = { type: t.type, value: Number(t.value) };
22301
22716
  infos.push({ outpoint, value: vtxo.value, sweepFee, path: resolved.label, delay });
22302
22717
  sweeps.push({ vtxo, resolved, sweepFee, delay });
@@ -22403,7 +22818,7 @@ var Executor = class {
22403
22818
  constructor(pkg, provider, opts) {
22404
22819
  this.pkg = pkg;
22405
22820
  this.provider = provider;
22406
- chunk5XBH5SAL_cjs.assertTimerMs("pollIntervalMs", opts?.pollIntervalMs);
22821
+ chunkKR6FLFIH_cjs.assertTimerMs("pollIntervalMs", opts?.pollIntervalMs);
22407
22822
  this.pollIntervalMs = opts?.pollIntervalMs ?? 5e3;
22408
22823
  this.feeWallet = opts?.feeWallet;
22409
22824
  this.signal = opts?.signal;
@@ -22698,7 +23113,7 @@ async function prepare(opts) {
22698
23113
  txid: sweep.vtxo.txid,
22699
23114
  vout: sweep.vtxo.vout,
22700
23115
  value: sweep.vtxo.value,
22701
- pkScript: chunk5XBH5SAL_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
23116
+ pkScript: chunkKR6FLFIH_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
22702
23117
  },
22703
23118
  path: sweep.resolved.selection,
22704
23119
  outputAddress: opts.sweepAddress,
@@ -22787,7 +23202,7 @@ async function prepare(opts) {
22787
23202
  if (newFee <= splitterFee) break;
22788
23203
  splitterFee = newFee;
22789
23204
  }
22790
- const splitter = new chunk5XBH5SAL_cjs.Transaction({ version: 2 });
23205
+ const splitter = new chunkKR6FLFIH_cjs.Transaction({ version: 2 });
22791
23206
  for (const coin of selected.inputs) {
22792
23207
  splitter.addInput({
22793
23208
  txid: coin.txid,
@@ -22926,44 +23341,44 @@ var UnilateralExit = {
22926
23341
 
22927
23342
  // src/arkade/index.ts
22928
23343
  var arkade_exports = {};
22929
- chunk5XBH5SAL_cjs.__export(arkade_exports, {
22930
- ARKADE_OP: () => chunkGVF4OCTL_cjs.ARKADE_OP,
22931
- ARKADE_OPCODES: () => chunkGVF4OCTL_cjs.ARKADE_OPCODES,
22932
- ARKADE_OPCODE_NAMES: () => chunkGVF4OCTL_cjs.ARKADE_OPCODE_NAMES,
22933
- ARKADE_OPCODE_VALUES: () => chunkGVF4OCTL_cjs.ARKADE_OPCODE_VALUES,
22934
- ARKADE_OPS: () => chunkGVF4OCTL_cjs.ARKADE_OPS,
23344
+ chunkKR6FLFIH_cjs.__export(arkade_exports, {
23345
+ ARKADE_OP: () => chunkQLJXXVRO_cjs.ARKADE_OP,
23346
+ ARKADE_OPCODES: () => chunkQLJXXVRO_cjs.ARKADE_OPCODES,
23347
+ ARKADE_OPCODE_NAMES: () => chunkQLJXXVRO_cjs.ARKADE_OPCODE_NAMES,
23348
+ ARKADE_OPCODE_VALUES: () => chunkQLJXXVRO_cjs.ARKADE_OPCODE_VALUES,
23349
+ ARKADE_OPS: () => chunkQLJXXVRO_cjs.ARKADE_OPS,
22935
23350
  Arkade: () => Arkade,
22936
23351
  ArkadeContract: () => ArkadeContract,
22937
- ArkadeProgramScript: () => chunkGVF4OCTL_cjs.ArkadeProgramScript,
22938
- ArkadeScript: () => chunkGVF4OCTL_cjs.ArkadeScript,
23352
+ ArkadeProgramScript: () => chunkQLJXXVRO_cjs.ArkadeProgramScript,
23353
+ ArkadeScript: () => chunkQLJXXVRO_cjs.ArkadeScript,
22939
23354
  ArkadeTransactionBuilder: () => ArkadeTransactionBuilder,
22940
- BigNum: () => chunkGVF4OCTL_cjs.bignum_exports,
23355
+ BigNum: () => chunkQLJXXVRO_cjs.bignum_exports,
22941
23356
  OP: () => btcSigner.OP,
22942
- OPCODE_NAMES: () => chunkGVF4OCTL_cjs.OPCODE_NAMES,
22943
- OPCODE_VALUES: () => chunkGVF4OCTL_cjs.OPCODE_VALUES,
22944
- SUPPORTED_PROGRAM_VERSION: () => chunkGVF4OCTL_cjs.SUPPORTED_PROGRAM_VERSION,
23357
+ OPCODE_NAMES: () => chunkQLJXXVRO_cjs.OPCODE_NAMES,
23358
+ OPCODE_VALUES: () => chunkQLJXXVRO_cjs.OPCODE_VALUES,
23359
+ SUPPORTED_PROGRAM_VERSION: () => chunkQLJXXVRO_cjs.SUPPORTED_PROGRAM_VERSION,
22945
23360
  Script: () => btcSigner.Script,
22946
- arkadeScriptHash: () => chunkGVF4OCTL_cjs.arkadeScriptHash,
22947
- arkadeWitnessHash: () => chunkGVF4OCTL_cjs.arkadeWitnessHash,
22948
- asmToBytes: () => chunkGVF4OCTL_cjs.asmToBytes,
22949
- bytesToASM: () => chunkGVF4OCTL_cjs.bytesToASM,
22950
- computeArkadeScriptPublicKey: () => chunkGVF4OCTL_cjs.computeArkadeScriptPublicKey,
23361
+ arkadeScriptHash: () => chunkQLJXXVRO_cjs.arkadeScriptHash,
23362
+ arkadeWitnessHash: () => chunkQLJXXVRO_cjs.arkadeWitnessHash,
23363
+ asmToBytes: () => chunkQLJXXVRO_cjs.asmToBytes,
23364
+ bytesToASM: () => chunkQLJXXVRO_cjs.bytesToASM,
23365
+ computeArkadeScriptPublicKey: () => chunkQLJXXVRO_cjs.computeArkadeScriptPublicKey,
22951
23366
  createArkadeBatchHandler: () => createArkadeBatchHandler,
22952
- deserializeArkadeContractParams: () => chunkGVF4OCTL_cjs.deserializeArkadeContractParams,
22953
- fromASM: () => chunkGVF4OCTL_cjs.fromASM,
22954
- getOpcodeName: () => chunkGVF4OCTL_cjs.getOpcodeName,
22955
- getOpcodeValue: () => chunkGVF4OCTL_cjs.getOpcodeValue,
23367
+ deserializeArkadeContractParams: () => chunkQLJXXVRO_cjs.deserializeArkadeContractParams,
23368
+ fromASM: () => chunkQLJXXVRO_cjs.fromASM,
23369
+ getOpcodeName: () => chunkQLJXXVRO_cjs.getOpcodeName,
23370
+ getOpcodeValue: () => chunkQLJXXVRO_cjs.getOpcodeValue,
22956
23371
  isContractArtifact: () => isContractArtifact,
22957
- parseArtifact: () => chunkGVF4OCTL_cjs.parseArtifact,
23372
+ parseArtifact: () => chunkQLJXXVRO_cjs.parseArtifact,
22958
23373
  programFromArtifact: () => programFromArtifact,
22959
- resolveAsm: () => chunkGVF4OCTL_cjs.resolveAsm,
22960
- serializeArkadeContractParams: () => chunkGVF4OCTL_cjs.serializeArkadeContractParams,
22961
- stringifyArtifact: () => chunkGVF4OCTL_cjs.stringifyArtifact,
22962
- toASM: () => chunkGVF4OCTL_cjs.toASM,
22963
- validateProgram: () => chunkGVF4OCTL_cjs.validateProgram,
22964
- witnessRefToBytes: () => chunkGVF4OCTL_cjs.witnessRefToBytes
23374
+ resolveAsm: () => chunkQLJXXVRO_cjs.resolveAsm,
23375
+ serializeArkadeContractParams: () => chunkQLJXXVRO_cjs.serializeArkadeContractParams,
23376
+ stringifyArtifact: () => chunkQLJXXVRO_cjs.stringifyArtifact,
23377
+ toASM: () => chunkQLJXXVRO_cjs.toASM,
23378
+ validateProgram: () => chunkQLJXXVRO_cjs.validateProgram,
23379
+ witnessRefToBytes: () => chunkQLJXXVRO_cjs.witnessRefToBytes
22965
23380
  });
22966
- var isVtxoCoin = (input) => chunk5XBH5SAL_cjs.isVirtualCoin(input);
23381
+ var isVtxoCoin = (input) => chunkKR6FLFIH_cjs.isVirtualCoin(input);
22967
23382
  function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message, session, arkProvider, emulator, network, recipients, batchExpiryPolicy) {
22968
23383
  let batchId;
22969
23384
  let sweepTapTreeRoot;
@@ -22984,23 +23399,23 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
22984
23399
  );
22985
23400
  await arkProvider.confirmRegistration(intentId);
22986
23401
  batchId = event.id;
22987
- const sweepTapscript = chunk5XBH5SAL_cjs.CSVMultisigTapscript.encode({
23402
+ const sweepTapscript = chunkKR6FLFIH_cjs.CSVMultisigTapscript.encode({
22988
23403
  timelock,
22989
- pubkeys: [chunkGVF4OCTL_cjs.toXOnly(base.hex.decode(info.forfeitPubkey), "forfeit key")]
23404
+ pubkeys: [chunkQLJXXVRO_cjs.toXOnly(base.hex.decode(info.forfeitPubkey), "forfeit key")]
22990
23405
  }).script;
22991
23406
  sweepTapTreeRoot = payment_js.tapLeafHash(sweepTapscript);
22992
23407
  return { skip: false };
22993
23408
  },
22994
23409
  onTreeSigningStarted: async (event, vtxoTree) => {
22995
23410
  const signerPubKey = await session.getPublicKey();
22996
- const xonlySignerPubKey = chunkGVF4OCTL_cjs.toXOnly(signerPubKey, "signer key");
23411
+ const xonlySignerPubKey = chunkQLJXXVRO_cjs.toXOnly(signerPubKey, "signer key");
22997
23412
  const xOnlyPubkeys = event.cosignersPublicKeys.map(
22998
- (k) => base.hex.encode(chunkGVF4OCTL_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
23413
+ (k) => base.hex.encode(chunkQLJXXVRO_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
22999
23414
  );
23000
23415
  if (!xOnlyPubkeys.includes(base.hex.encode(xonlySignerPubKey))) {
23001
23416
  return { skip: true };
23002
23417
  }
23003
- const commitmentTx = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(event.unsignedCommitmentTx));
23418
+ const commitmentTx = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(event.unsignedCommitmentTx));
23004
23419
  validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
23005
23420
  if (recipients && recipients.length > 0) {
23006
23421
  validateBatchRecipients(commitmentTx, vtxoTree.leaves(), recipients, network);
@@ -23038,7 +23453,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
23038
23453
  if (connectorTree) {
23039
23454
  validateConnectorsTxGraph(event.commitmentTx, connectorTree);
23040
23455
  }
23041
- let commitmentPsbt = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
23456
+ let commitmentPsbt = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
23042
23457
  assertFinalCommitmentMatchesValidated(
23043
23458
  commitmentPsbt,
23044
23459
  validatedCommitmentTxid,
@@ -23080,7 +23495,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
23080
23495
  boardingIndices.push(boardingIdx);
23081
23496
  continue;
23082
23497
  }
23083
- if (!chunk5XBH5SAL_cjs.requiresForfeit(input) || isSubdust(input, info.dust)) {
23498
+ if (!chunkKR6FLFIH_cjs.requiresForfeit(input) || isSubdust(input, info.dust)) {
23084
23499
  continue;
23085
23500
  }
23086
23501
  if (connectorIndex >= connectorLeaves.length) {
@@ -23101,7 +23516,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
23101
23516
  index: input.vout,
23102
23517
  witnessUtxo: {
23103
23518
  amount: BigInt(input.value),
23104
- script: chunk5XBH5SAL_cjs.VtxoScript.decode(input.tapTree).pkScript
23519
+ script: chunkKR6FLFIH_cjs.VtxoScript.decode(input.tapTree).pkScript
23105
23520
  },
23106
23521
  sighashType: btcSigner.SigHash.DEFAULT,
23107
23522
  tapLeafScript: [input.forfeitTapLeafScript]
@@ -23246,7 +23661,7 @@ function flatten(param, structs, stack = []) {
23246
23661
  function opcodeToken(token) {
23247
23662
  const base = token.slice(3);
23248
23663
  const name = base === "0" || /^([1-9]|1[0-6])$/.test(base) ? token : base;
23249
- if (!Object.hasOwn(chunkGVF4OCTL_cjs.ARKADE_OPS, name)) {
23664
+ if (!Object.hasOwn(chunkQLJXXVRO_cjs.ARKADE_OPS, name)) {
23250
23665
  fail(`opcode '${token}' is not in this SDK's table`);
23251
23666
  }
23252
23667
  return name;
@@ -23293,7 +23708,7 @@ function providedWitness(witness) {
23293
23708
  }
23294
23709
  function csvTimelock(leafName, operand) {
23295
23710
  if (typeof operand === "string") return { type: "sequence", value: operand };
23296
- const timelock = chunk5XBH5SAL_cjs.sequenceToCanonicalTimelock(operand);
23711
+ const timelock = chunkKR6FLFIH_cjs.sequenceToCanonicalTimelock(operand);
23297
23712
  if (!timelock) {
23298
23713
  fail(`leaf '${leafName}': CSV literal ${operand} is not a canonical BIP68 sequence`);
23299
23714
  }
@@ -23412,7 +23827,7 @@ function programFromArtifact(artifact) {
23412
23827
  const paramNames = /* @__PURE__ */ new Set();
23413
23828
  for (const param of params) claim(paramNames, param.name, "program parameter");
23414
23829
  return {
23415
- version: chunkGVF4OCTL_cjs.SUPPORTED_PROGRAM_VERSION,
23830
+ version: chunkQLJXXVRO_cjs.SUPPORTED_PROGRAM_VERSION,
23416
23831
  name: artifact.contractName,
23417
23832
  params,
23418
23833
  functions
@@ -23453,16 +23868,16 @@ var Arkade = class _Arkade {
23453
23868
  /** Connect and resolve the server key, checkpoint closure and (if present) the co-signer key. */
23454
23869
  static async connect(opts) {
23455
23870
  const info = await opts.arkade.getInfo();
23456
- const serverKey = chunkGVF4OCTL_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
23457
- const checkpoint = chunk5XBH5SAL_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
23458
- const network = opts.network ?? (Object.hasOwn(chunk5XBH5SAL_cjs.networks, info.network) ? chunk5XBH5SAL_cjs.getNetwork(info.network) : chunk5XBH5SAL_cjs.DEFAULT_NETWORK);
23871
+ const serverKey = chunkQLJXXVRO_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
23872
+ const checkpoint = chunkKR6FLFIH_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
23873
+ const network = opts.network ?? (Object.hasOwn(chunkKR6FLFIH_cjs.networks, info.network) ? chunkKR6FLFIH_cjs.getNetwork(info.network) : chunkKR6FLFIH_cjs.DEFAULT_NETWORK);
23459
23874
  let emulatorKey;
23460
23875
  if (opts.emulator) {
23461
- emulatorKey = base.hex.decode(chunk5XBH5SAL_cjs.resolveEmulatorPubkey(network, opts.emulatorPubkey));
23876
+ emulatorKey = base.hex.decode(chunkKR6FLFIH_cjs.resolveEmulatorPubkey(network, opts.emulatorPubkey));
23462
23877
  }
23463
23878
  let userKey;
23464
23879
  if (opts.identity) {
23465
- userKey = chunkGVF4OCTL_cjs.toXOnly(await opts.identity.xOnlyPublicKey(), "identity key");
23880
+ userKey = chunkQLJXXVRO_cjs.toXOnly(await opts.identity.xOnlyPublicKey(), "identity key");
23466
23881
  }
23467
23882
  return new _Arkade({
23468
23883
  arkProvider: opts.arkade,
@@ -23485,7 +23900,7 @@ var Arkade = class _Arkade {
23485
23900
  * explicit args win.
23486
23901
  */
23487
23902
  contract(program, args = {}) {
23488
- const declared = (program.params ?? []).map(chunkGVF4OCTL_cjs.inputName);
23903
+ const declared = (program.params ?? []).map(chunkQLJXXVRO_cjs.inputName);
23489
23904
  if (declared.includes("server") && args.server === void 0) {
23490
23905
  args = { ...args, server: this.serverKey };
23491
23906
  }
@@ -23505,7 +23920,7 @@ var ArkadeContract = class _ArkadeContract {
23505
23920
  userKey: client.userKey,
23506
23921
  emulatorKey: client.emulatorKey
23507
23922
  };
23508
- this.vtxoScript = new chunkGVF4OCTL_cjs.ArkadeProgramScript(program, args, this.keys);
23923
+ this.vtxoScript = new chunkQLJXXVRO_cjs.ArkadeProgramScript(program, args, this.keys);
23509
23924
  this.tapTree = this.vtxoScript.encode();
23510
23925
  this.compiled = this.vtxoScript.compiled;
23511
23926
  }
@@ -23530,7 +23945,7 @@ var ArkadeContract = class _ArkadeContract {
23530
23945
  `ArkadeContract.fromContract: expected contract type 'arkade', got '${contract.type}'`
23531
23946
  );
23532
23947
  }
23533
- const typed = chunkGVF4OCTL_cjs.deserializeArkadeContractParams(contract.params);
23948
+ const typed = chunkQLJXXVRO_cjs.deserializeArkadeContractParams(contract.params);
23534
23949
  return new _ArkadeContract(client, typed.program, typed.args, {
23535
23950
  serverKey: typed.serverKey,
23536
23951
  userKey: typed.userKey,
@@ -23566,7 +23981,7 @@ var ArkadeContract = class _ArkadeContract {
23566
23981
  toContractParams() {
23567
23982
  return {
23568
23983
  type: "arkade",
23569
- params: chunkGVF4OCTL_cjs.serializeArkadeContractParams({
23984
+ params: chunkQLJXXVRO_cjs.serializeArkadeContractParams({
23570
23985
  program: this.program,
23571
23986
  args: this.args,
23572
23987
  serverKey: this.keys.serverKey,
@@ -23606,17 +24021,17 @@ var ArkadeContract = class _ArkadeContract {
23606
24021
  const [registered] = await manager.getContracts({ script: scriptHex });
23607
24022
  if (registered) {
23608
24023
  const [withVtxos] = await manager.getContractsWithVtxos({ script: scriptHex });
23609
- return (withVtxos?.vtxos ?? []).filter((v) => !chunk5XBH5SAL_cjs.isVtxoSpent(v) && !v.isUnrolled);
24024
+ return (withVtxos?.vtxos ?? []).filter((v) => !chunkKR6FLFIH_cjs.isVtxoSpent(v) && !v.isUnrolled);
23610
24025
  }
23611
24026
  }
23612
24027
  if (!this.client.indexer) {
23613
24028
  throw new Error("ArkadeContract.getUtxos: an indexer is required");
23614
24029
  }
23615
- const { vtxos } = await chunk5XBH5SAL_cjs.getNormalizedVtxos(this.client.indexer, {
24030
+ const { vtxos } = await chunkKR6FLFIH_cjs.getNormalizedVtxos(this.client.indexer, {
23616
24031
  scripts: [scriptHex],
23617
24032
  spendableOnly: true
23618
24033
  });
23619
- return vtxos.filter((v) => !chunk5XBH5SAL_cjs.isVtxoSpent(v) && !v.isUnrolled);
24034
+ return vtxos.filter((v) => !chunkKR6FLFIH_cjs.isVtxoSpent(v) && !v.isUnrolled);
23620
24035
  }
23621
24036
  /** Total spendable balance (requires an indexer). */
23622
24037
  async getBalance() {
@@ -23637,6 +24052,7 @@ var ArkadeTransactionBuilder = class {
23637
24052
  outputs = [];
23638
24053
  fundingCoins = [];
23639
24054
  assetSpecs = [];
24055
+ extraPackets = [];
23640
24056
  coin;
23641
24057
  changeScript;
23642
24058
  from(coin) {
@@ -23656,6 +24072,11 @@ var ArkadeTransactionBuilder = class {
23656
24072
  this.assetSpecs.push(spec);
23657
24073
  return this;
23658
24074
  }
24075
+ /** Add an extension packet; reusing the asset or emulator packet's type fails at build. */
24076
+ withPacket(packet) {
24077
+ this.extraPackets.push(packet);
24078
+ return this;
24079
+ }
23659
24080
  /** Destination for any surplus (inputs − outputs). Required when the spend is not exact. */
23660
24081
  change(script) {
23661
24082
  this.changeScript = script;
@@ -23714,7 +24135,7 @@ var ArkadeTransactionBuilder = class {
23714
24135
  this.contract.client.checkpoint
23715
24136
  );
23716
24137
  if (coin.sourceTx) {
23717
- chunk5XBH5SAL_cjs.setArkPsbtField(arkTx, 0, chunk5XBH5SAL_cjs.PrevArkTxField, coin.sourceTx);
24138
+ chunkKR6FLFIH_cjs.setArkPsbtField(arkTx, 0, chunkKR6FLFIH_cjs.PrevArkTxField, coin.sourceTx);
23718
24139
  }
23719
24140
  if (this.fn.arkadeScript) {
23720
24141
  const indexer = this.contract.client.indexer;
@@ -23731,8 +24152,8 @@ var ArkadeTransactionBuilder = class {
23731
24152
  }
23732
24153
  const condition = (def.tapscript.witness ?? []).map((w) => this.witnessBytes(w));
23733
24154
  if (condition.length > 0) {
23734
- chunk5XBH5SAL_cjs.setArkPsbtField(arkTx, 0, chunk5XBH5SAL_cjs.ConditionWitness, condition);
23735
- chunk5XBH5SAL_cjs.setArkPsbtField(checkpoints[0], 0, chunk5XBH5SAL_cjs.ConditionWitness, condition);
24155
+ chunkKR6FLFIH_cjs.setArkPsbtField(arkTx, 0, chunkKR6FLFIH_cjs.ConditionWitness, condition);
24156
+ chunkKR6FLFIH_cjs.setArkPsbtField(checkpoints[0], 0, chunkKR6FLFIH_cjs.ConditionWitness, condition);
23736
24157
  }
23737
24158
  const packets = [];
23738
24159
  if (this.assetSpecs.length > 0) {
@@ -23747,6 +24168,7 @@ var ArkadeTransactionBuilder = class {
23747
24168
  ])
23748
24169
  );
23749
24170
  }
24171
+ packets.push(...this.extraPackets);
23750
24172
  if (packets.length > 0) {
23751
24173
  attachExtension(arkTx, packets);
23752
24174
  }
@@ -23771,7 +24193,7 @@ var ArkadeTransactionBuilder = class {
23771
24193
  base.base64.encode(signedArk2.toPSBT()),
23772
24194
  signedCps.map((c) => base.base64.encode(c.toPSBT()))
23773
24195
  );
23774
- const txid = chunk5XBH5SAL_cjs.Transaction.fromPSBT(base.base64.decode(res2.signedArkTx)).id;
24196
+ const txid = chunkKR6FLFIH_cjs.Transaction.fromPSBT(base.base64.decode(res2.signedArkTx)).id;
23775
24197
  return {
23776
24198
  txid,
23777
24199
  signedArkTx: res2.signedArkTx,
@@ -23836,23 +24258,23 @@ var ArkadeTransactionBuilder = class {
23836
24258
  }
23837
24259
  buildAssetPacket() {
23838
24260
  const groups = this.assetSpecs.map((s) => {
23839
- const id = typeof s.assetId === "string" ? chunkQ7PC3NHX_cjs.AssetId.fromString(s.assetId) : chunkQ7PC3NHX_cjs.AssetId.fromBytes(s.assetId);
23840
- return chunkQ7PC3NHX_cjs.AssetGroup.create(
24261
+ const id = typeof s.assetId === "string" ? chunkYFHGGSII_cjs.AssetId.fromString(s.assetId) : chunkYFHGGSII_cjs.AssetId.fromBytes(s.assetId);
24262
+ return chunkYFHGGSII_cjs.AssetGroup.create(
23841
24263
  id,
23842
24264
  null,
23843
- s.inputs.map((i) => chunkQ7PC3NHX_cjs.AssetInput.create(i.vin, i.amount)),
23844
- s.outputs.map((o) => chunkQ7PC3NHX_cjs.AssetOutput.create(o.vout, o.amount)),
23845
- (s.metadata ?? []).map((m) => chunkQ7PC3NHX_cjs.Metadata.create(m.key, m.value))
24265
+ s.inputs.map((i) => chunkYFHGGSII_cjs.AssetInput.create(i.vin, i.amount)),
24266
+ s.outputs.map((o) => chunkYFHGGSII_cjs.AssetOutput.create(o.vout, o.amount)),
24267
+ (s.metadata ?? []).map((m) => chunkYFHGGSII_cjs.Metadata.create(m.key, m.value))
23846
24268
  );
23847
24269
  });
23848
- return chunkQ7PC3NHX_cjs.Packet.create(groups);
24270
+ return chunkYFHGGSII_cjs.Packet.create(groups);
23849
24271
  }
23850
24272
  witnessBytes(ref) {
23851
- return chunkGVF4OCTL_cjs.witnessRefToBytes(ref, this.args, this.contract.args);
24273
+ return chunkQLJXXVRO_cjs.witnessRefToBytes(ref, this.args, this.contract.args);
23852
24274
  }
23853
24275
  };
23854
24276
  function bindInputs(fn, callArgs) {
23855
- const names = (fn.def.inputs ?? []).map(chunkGVF4OCTL_cjs.inputName);
24277
+ const names = (fn.def.inputs ?? []).map(chunkQLJXXVRO_cjs.inputName);
23856
24278
  if (callArgs.length !== names.length) {
23857
24279
  throw new Error(`${fn.name}: expected ${names.length} argument(s), got ${callArgs.length}`);
23858
24280
  }
@@ -24266,17 +24688,17 @@ var walletFeeSource = (wallet) => async () => (await wallet.arkProvider.getInfo(
24266
24688
  function offchainInputFees(vtxos, fees) {
24267
24689
  const estimator = new Estimator(fees?.intentFee ?? {});
24268
24690
  return vtxos.reduce(
24269
- (total, vtxo) => total + estimator.evalOffchainInput(chunk5XBH5SAL_cjs.toOffchainInputFeeParams(vtxo)).satoshis,
24691
+ (total, vtxo) => total + estimator.evalOffchainInput(chunkKR6FLFIH_cjs.toOffchainInputFeeParams(vtxo)).satoshis,
24270
24692
  0
24271
24693
  );
24272
24694
  }
24273
24695
  async function changeOutputFee(wallet, inputs, needed, fees) {
24274
24696
  const estimator = new Estimator(fees?.intentFee ?? {});
24275
24697
  const net = inputs.reduce(
24276
- (total, vtxo) => total + BigInt(vtxo.value) - BigInt(estimator.evalOffchainInput(chunk5XBH5SAL_cjs.toOffchainInputFeeParams(vtxo)).satoshis),
24698
+ (total, vtxo) => total + BigInt(vtxo.value) - BigInt(estimator.evalOffchainInput(chunkKR6FLFIH_cjs.toOffchainInputFeeParams(vtxo)).satoshis),
24277
24699
  0n
24278
24700
  );
24279
- const script = base.hex.encode(chunk5XBH5SAL_cjs.ArkAddress.decode(await wallet.getAddress()).pkScript);
24701
+ const script = base.hex.encode(chunkKR6FLFIH_cjs.ArkAddress.decode(await wallet.getAddress()).pkScript);
24280
24702
  return changeAfterOutputFee(
24281
24703
  net - needed,
24282
24704
  (amount) => BigInt(estimator.evalOffchainOutput({ amount, script }).satoshis)
@@ -24418,6 +24840,7 @@ exports.RestDelegateProvider = RestDelegateProvider;
24418
24840
  exports.RestEmulatorProvider = RestEmulatorProvider;
24419
24841
  exports.SIGNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS = SIGNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS;
24420
24842
  exports.SeedIdentity = SeedIdentity;
24843
+ exports.SendDeadlineExceededError = SendDeadlineExceededError;
24421
24844
  exports.ServiceWorkerReadonlyWallet = ServiceWorkerReadonlyWallet;
24422
24845
  exports.ServiceWorkerTimeoutError = ServiceWorkerTimeoutError;
24423
24846
  exports.ServiceWorkerWallet = ServiceWorkerWallet;
@@ -24448,6 +24871,7 @@ exports.assertNoAssets = assertNoAssets;
24448
24871
  exports.assertNoSelection = assertNoSelection;
24449
24872
  exports.assertPageRequest = assertPageRequest;
24450
24873
  exports.assertRecipientArkadeAddress = assertRecipientArkadeAddress;
24874
+ exports.assertSendDeadline = assertSendDeadline;
24451
24875
  exports.assertSendableAmount = assertSendableAmount;
24452
24876
  exports.assertSubmittedArkTxid = assertSubmittedArkTxid;
24453
24877
  exports.assertValidBatchExpiry = assertValidBatchExpiry;
@@ -24463,6 +24887,7 @@ exports.buildForfeitTx = buildForfeitTx;
24463
24887
  exports.buildOffchainTx = buildOffchainTx;
24464
24888
  exports.buildPreimageMessage = buildPreimageMessage;
24465
24889
  exports.buildSaltedPreimageMessage = buildSaltedPreimageMessage;
24890
+ exports.captureSendDeadline = captureSendDeadline;
24466
24891
  exports.checkSaveVtxosForScript = checkSaveVtxosForScript;
24467
24892
  exports.claimWithPreimageIdentity = claimWithPreimageIdentity;
24468
24893
  exports.classifyAgainstSignerSet = classifyAgainstSignerSet;
@@ -24578,5 +25003,5 @@ exports.waitForIncomingFunds = waitForIncomingFunds;
24578
25003
  exports.walletFeeSource = walletFeeSource;
24579
25004
  exports.warnAndFilterVtxosForScript = warnAndFilterVtxosForScript;
24580
25005
  exports.withPrevTxs = withPrevTxs;
24581
- //# sourceMappingURL=chunk-R5OFJ23O.cjs.map
24582
- //# sourceMappingURL=chunk-R5OFJ23O.cjs.map
25006
+ //# sourceMappingURL=chunk-H7W2KLN2.cjs.map
25007
+ //# sourceMappingURL=chunk-H7W2KLN2.cjs.map