@arkade-os/sdk 0.4.65 → 0.4.67

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 (82) hide show
  1. package/README.md +66 -15
  2. package/dist/adapters/expo.cjs +5 -5
  3. package/dist/adapters/expo.d.cts +3 -6
  4. package/dist/adapters/expo.d.ts +3 -6
  5. package/dist/adapters/expo.js +3 -3
  6. package/dist/adapters/indexedDB.cjs +5 -5
  7. package/dist/adapters/indexedDB.js +4 -4
  8. package/dist/{asyncStorageTaskQueue-Chwe60Ce.d.cts → asyncStorageTaskQueue-LTpeXYaD.d.cts} +2 -2
  9. package/dist/{asyncStorageTaskQueue-Dq_UcvDx.d.ts → asyncStorageTaskQueue-Za-e_zMk.d.ts} +2 -2
  10. package/dist/{chunk-G552MISJ.cjs → chunk-2JV4VQ7C.cjs} +56 -28
  11. package/dist/chunk-2JV4VQ7C.cjs.map +1 -0
  12. package/dist/{chunk-TFSVXMTM.js → chunk-3WIWNE4P.js} +56 -29
  13. package/dist/chunk-3WIWNE4P.js.map +1 -0
  14. package/dist/{chunk-XMOIRDLF.js → chunk-6TAQF6EV.js} +118 -16
  15. package/dist/chunk-6TAQF6EV.js.map +1 -0
  16. package/dist/{chunk-5YTSQSLE.js → chunk-AEWJU6NZ.js} +1033 -193
  17. package/dist/chunk-AEWJU6NZ.js.map +1 -0
  18. package/dist/{chunk-XN55B6EP.cjs → chunk-CO3KKSWM.cjs} +46 -19
  19. package/dist/chunk-CO3KKSWM.cjs.map +1 -0
  20. package/dist/{chunk-RESN6QHP.js → chunk-EALWOVHK.js} +4 -4
  21. package/dist/{chunk-RESN6QHP.js.map → chunk-EALWOVHK.js.map} +1 -1
  22. package/dist/{chunk-GFZNEMGL.cjs → chunk-MJUTO3PY.cjs} +1425 -574
  23. package/dist/chunk-MJUTO3PY.cjs.map +1 -0
  24. package/dist/{chunk-TYTPVPKD.js → chunk-MZFUZUTQ.js} +4 -4
  25. package/dist/{chunk-TYTPVPKD.js.map → chunk-MZFUZUTQ.js.map} +1 -1
  26. package/dist/{chunk-BABJ77NG.cjs → chunk-OIZ2V2VD.cjs} +163 -60
  27. package/dist/chunk-OIZ2V2VD.cjs.map +1 -0
  28. package/dist/{chunk-SJQM5AVB.cjs → chunk-R2YAMONM.cjs} +17 -17
  29. package/dist/{chunk-SJQM5AVB.cjs.map → chunk-R2YAMONM.cjs.map} +1 -1
  30. package/dist/{chunk-3G5V564P.js → chunk-X3VEMUVV.js} +32 -6
  31. package/dist/chunk-X3VEMUVV.js.map +1 -0
  32. package/dist/{chunk-7X744EFF.cjs → chunk-YDRZDZPP.cjs} +10 -10
  33. package/dist/{chunk-7X744EFF.cjs.map → chunk-YDRZDZPP.cjs.map} +1 -1
  34. package/dist/contracts/handlers/index.cjs +9 -9
  35. package/dist/contracts/handlers/index.d.cts +3 -3
  36. package/dist/contracts/handlers/index.d.ts +3 -3
  37. package/dist/contracts/handlers/index.js +2 -2
  38. package/dist/{delegate-BBQW61ym.d.cts → delegate-Bz2e2zXY.d.cts} +1 -1
  39. package/dist/{delegate-Dv_9OVHv.d.ts → delegate-cdmzb2f9.d.ts} +1 -1
  40. package/dist/{wallet-DJUnN939.d.ts → hdWalletCapable-BSjuUYOO.d.cts} +319 -128
  41. package/dist/{wallet-C2NvHjWB.d.cts → hdWalletCapable-Hi12xjCJ.d.ts} +319 -128
  42. package/dist/{index-fDDiA1-L.d.ts → index-BiACuWaf.d.ts} +109 -13
  43. package/dist/{index-BtTtQFUX.d.cts → index-D2GjZxBr.d.cts} +109 -13
  44. package/dist/{index-CFOMyVMt.d.cts → index-DU5o_hz7.d.cts} +275 -51
  45. package/dist/{index-CFOMyVMt.d.ts → index-DU5o_hz7.d.ts} +275 -51
  46. package/dist/index.cjs +328 -276
  47. package/dist/index.d.cts +312 -41
  48. package/dist/index.d.ts +312 -41
  49. package/dist/index.js +4 -4
  50. package/dist/repositories/realm/index.cjs +19 -19
  51. package/dist/repositories/realm/index.d.cts +2 -2
  52. package/dist/repositories/realm/index.d.ts +2 -2
  53. package/dist/repositories/realm/index.js +5 -5
  54. package/dist/repositories/sqlite/index.cjs +18 -18
  55. package/dist/repositories/sqlite/index.d.cts +2 -2
  56. package/dist/repositories/sqlite/index.d.ts +2 -2
  57. package/dist/repositories/sqlite/index.js +5 -5
  58. package/dist/{taskRunner-CIKOS2OO.d.cts → taskRunner-BZJMLQ6g.d.cts} +2 -2
  59. package/dist/{taskRunner-BDzWbpct.d.ts → taskRunner-DATaRQus.d.ts} +2 -2
  60. package/dist/wallet/expo/background.cjs +14 -14
  61. package/dist/wallet/expo/background.d.cts +3 -3
  62. package/dist/wallet/expo/background.d.ts +3 -3
  63. package/dist/wallet/expo/background.js +6 -6
  64. package/dist/wallet/expo/index.cjs +18 -14
  65. package/dist/wallet/expo/index.cjs.map +1 -1
  66. package/dist/wallet/expo/index.d.cts +7 -5
  67. package/dist/wallet/expo/index.d.ts +7 -5
  68. package/dist/wallet/expo/index.js +10 -6
  69. package/dist/wallet/expo/index.js.map +1 -1
  70. package/dist/worker/expo/index.cjs +9 -9
  71. package/dist/worker/expo/index.d.cts +4 -4
  72. package/dist/worker/expo/index.d.ts +4 -4
  73. package/dist/worker/expo/index.js +5 -5
  74. package/package.json +3 -3
  75. package/dist/chunk-3G5V564P.js.map +0 -1
  76. package/dist/chunk-5YTSQSLE.js.map +0 -1
  77. package/dist/chunk-BABJ77NG.cjs.map +0 -1
  78. package/dist/chunk-G552MISJ.cjs.map +0 -1
  79. package/dist/chunk-GFZNEMGL.cjs.map +0 -1
  80. package/dist/chunk-TFSVXMTM.js.map +0 -1
  81. package/dist/chunk-XMOIRDLF.js.map +0 -1
  82. package/dist/chunk-XN55B6EP.cjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkXN55B6EP_cjs = require('./chunk-XN55B6EP.cjs');
4
- var chunkBABJ77NG_cjs = require('./chunk-BABJ77NG.cjs');
5
- var chunkG552MISJ_cjs = require('./chunk-G552MISJ.cjs');
3
+ var chunkCO3KKSWM_cjs = require('./chunk-CO3KKSWM.cjs');
4
+ var chunkOIZ2V2VD_cjs = require('./chunk-OIZ2V2VD.cjs');
5
+ var chunk2JV4VQ7C_cjs = require('./chunk-2JV4VQ7C.cjs');
6
6
  var chunk5BLDMQED_cjs = require('./chunk-5BLDMQED.cjs');
7
7
  var utils_js = require('@scure/btc-signer/utils.js');
8
8
  var btcSigner = require('@scure/btc-signer');
@@ -188,7 +188,7 @@ var TreeSignerSession = class _TreeSignerSession {
188
188
  noncesByPubkey.set(base.hex.encode(myPublicKey.subarray(1)), myNonce);
189
189
  const tx = this.graph.find(txid);
190
190
  if (!tx) throw new Error(`missing tx for txid ${txid}`);
191
- const cosigners = chunkG552MISJ_cjs.getArkPsbtFields(tx.root, 0, chunkG552MISJ_cjs.CosignerPublicKey).map(
191
+ const cosigners = chunk2JV4VQ7C_cjs.getArkPsbtFields(tx.root, 0, chunk2JV4VQ7C_cjs.CosignerPublicKey).map(
192
192
  (c) => base.hex.encode(c.key.subarray(1))
193
193
  // xonly pubkey
194
194
  );
@@ -240,7 +240,7 @@ var TreeSignerSession = class _TreeSignerSession {
240
240
  if (!aggNonce) throw new Error("missing aggregate nonce");
241
241
  const prevoutAmounts = [];
242
242
  const prevoutScripts = [];
243
- const cosigners = chunkG552MISJ_cjs.getArkPsbtFields(g.root, 0, chunkG552MISJ_cjs.CosignerPublicKey).map((c) => c.key);
243
+ const cosigners = chunk2JV4VQ7C_cjs.getArkPsbtFields(g.root, 0, chunk2JV4VQ7C_cjs.CosignerPublicKey).map((c) => c.key);
244
244
  const { finalKey } = aggregateKeys(cosigners, true, {
245
245
  taprootTweak: this.scriptRoot
246
246
  });
@@ -431,7 +431,7 @@ var SeedIdentity = class _SeedIdentity {
431
431
  let network;
432
432
  if ("descriptor" in opts && typeof opts.descriptor === "string") {
433
433
  descriptor = opts.descriptor;
434
- network = chunkBABJ77NG_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
434
+ network = chunkOIZ2V2VD_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
435
435
  } else {
436
436
  network = opts.isMainnet ?? true ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
437
437
  descriptor = descriptorsScure.scriptExpressions.trBIP32({
@@ -529,7 +529,7 @@ var SeedIdentity = class _SeedIdentity {
529
529
  * `StaticDescriptorProvider` for legacy single-key wallets.
530
530
  */
531
531
  isOurs(descriptor) {
532
- return chunkBABJ77NG_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
532
+ return chunkOIZ2V2VD_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
533
533
  }
534
534
  /**
535
535
  * Signs each request with the key derived from its descriptor.
@@ -578,7 +578,7 @@ var SeedIdentity = class _SeedIdentity {
578
578
  }
579
579
  // ── internal helpers ─────────────────────────────────────────────
580
580
  derivePrivateKeyForDescriptor(descriptor) {
581
- const network = chunkBABJ77NG_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
581
+ const network = chunkOIZ2V2VD_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
582
582
  const expansion = descriptorsScure.expand({ descriptor, network });
583
583
  if (expansion.isRanged) {
584
584
  throw new Error(
@@ -664,7 +664,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
664
664
  */
665
665
  descriptor;
666
666
  constructor(descriptor) {
667
- const network = chunkBABJ77NG_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
667
+ const network = chunkOIZ2V2VD_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
668
668
  let expansion;
669
669
  try {
670
670
  expansion = descriptorsScure.expand({ descriptor, network, index: 0 });
@@ -714,7 +714,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
714
714
  * `StaticDescriptorProvider` for legacy single-key wallets.
715
715
  */
716
716
  isOurs(descriptor) {
717
- return chunkBABJ77NG_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
717
+ return chunkOIZ2V2VD_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
718
718
  }
719
719
  };
720
720
  function serializeSeedOwnedSigningIdentity(identity) {
@@ -876,10 +876,10 @@ var DescriptorIdentity = class {
876
876
  this.base = base;
877
877
  }
878
878
  async xOnlyPublicKey() {
879
- return chunkBABJ77NG_cjs.deriveDescriptorLeafPubKey(this.descriptor);
879
+ return chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(this.descriptor);
880
880
  }
881
881
  async compressedPublicKey() {
882
- return chunkBABJ77NG_cjs.deriveDescriptorLeafCompressedPubKey(this.descriptor);
882
+ return chunkOIZ2V2VD_cjs.deriveDescriptorLeafCompressedPubKey(this.descriptor);
883
883
  }
884
884
  async sign(tx, inputIndexes) {
885
885
  const [signed] = await this.signer.signWithDescriptor([
@@ -939,14 +939,20 @@ var ForeignDescriptorError = class extends Error {
939
939
  descriptor;
940
940
  name = "ForeignDescriptorError";
941
941
  };
942
+ var WalletCannotAllocateAddressError = class extends Error {
943
+ name = "WalletCannotAllocateAddressError";
944
+ constructor(reason, options) {
945
+ super(`cannot allocate a fresh address: ${reason}`, options);
946
+ }
947
+ };
942
948
  async function resolveDescriptorSigner(descriptor, identity, provider) {
943
949
  const owner = provider?.isOurs(descriptor) ? provider : isHDCapableIdentity(identity) && identity.isOurs(descriptor) ? identity : void 0;
944
- if (owner && chunkBABJ77NG_cjs.parseHDDescriptor(descriptor)) {
950
+ if (owner && chunkOIZ2V2VD_cjs.parseHDDescriptor(descriptor)) {
945
951
  return new DescriptorIdentity({ descriptor, signer: owner, base: identity });
946
952
  }
947
953
  let key;
948
954
  try {
949
- key = chunkBABJ77NG_cjs.deriveDescriptorLeafPubKey(descriptor);
955
+ key = chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(descriptor);
950
956
  } catch {
951
957
  throw new ForeignDescriptorError(descriptor);
952
958
  }
@@ -963,6 +969,10 @@ function isHDAllocationCapable(value) {
963
969
  const v = value;
964
970
  return typeof v.getNextSigningDescriptor === "function" && typeof v.advanceSigningDescriptorWatermark === "function";
965
971
  }
972
+ function isAddressAllocationCapable(value) {
973
+ if (typeof value !== "object" || value === null) return false;
974
+ return typeof value.getNewAddresses === "function";
975
+ }
966
976
 
967
977
  // ../../node_modules/@noble/hashes/utils.js
968
978
  function isBytes(a) {
@@ -1317,22 +1327,33 @@ function buildSaltedPreimageMessage(xonly, salt) {
1317
1327
  }
1318
1328
  var PREIMAGE_INDEX = 0;
1319
1329
  function isPerArtifactDescriptor(descriptor) {
1320
- return chunkBABJ77NG_cjs.parseHDDescriptor(descriptor) !== null;
1330
+ return chunkOIZ2V2VD_cjs.parseHDDescriptor(descriptor) !== null;
1321
1331
  }
1322
1332
  async function provisionDescriptor(wallet) {
1323
1333
  const allocated = isHDAllocationCapable(wallet) ? await wallet.getNextSigningDescriptor() : void 0;
1324
- return allocated ?? await chunkBABJ77NG_cjs.identityDescriptor(wallet.identity);
1334
+ return allocated ?? await chunkOIZ2V2VD_cjs.identityDescriptor(wallet.identity);
1325
1335
  }
1326
1336
  async function provisionRefundKey(wallet) {
1327
- const descriptor = await provisionDescriptor(wallet);
1337
+ const descriptor = await chunkOIZ2V2VD_cjs.identityDescriptor(wallet.identity);
1328
1338
  const signer = await contractSigner(wallet, descriptor);
1329
- return { descriptor, pubkey: await signer.xOnlyPublicKey() };
1339
+ const pubkey = await signer.xOnlyPublicKey();
1340
+ const identityPubkey = await wallet.identity.xOnlyPublicKey();
1341
+ if (!utils_js.equalBytes(pubkey, identityPubkey)) {
1342
+ throw new Error(
1343
+ "provisionRefundKey: descriptor pubkey does not match wallet identity \u2014 the refund key and the refund address would be on different keys"
1344
+ );
1345
+ }
1346
+ const address = await wallet.getAddress();
1347
+ const { pkScript } = chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
1348
+ return { descriptor, pubkey, pkScript, address };
1330
1349
  }
1331
1350
  async function provisionClaimSecret(wallet, opts = {}) {
1332
1351
  if (opts.preimage && opts.preimage.length !== 32) {
1333
1352
  throw new Error(`preimage must be 32 bytes, got ${opts.preimage.length}`);
1334
1353
  }
1335
- const { descriptor, pubkey } = await provisionRefundKey(wallet);
1354
+ const descriptor = await provisionDescriptor(wallet);
1355
+ const signer = await contractSigner(wallet, descriptor);
1356
+ const pubkey = await signer.xOnlyPublicKey();
1336
1357
  const claim = async () => {
1337
1358
  if (opts.preimage) return { preimage: opts.preimage, mustPersistPreimage: true };
1338
1359
  if (isPerArtifactDescriptor(descriptor)) {
@@ -1369,7 +1390,7 @@ async function contractSigner(wallet, descriptor) {
1369
1390
  const signer = isHDWalletCapable(wallet) ? await wallet.signerForDescriptor(descriptor) : wallet.identity;
1370
1391
  let expected;
1371
1392
  try {
1372
- expected = chunkBABJ77NG_cjs.deriveDescriptorLeafPubKey(descriptor);
1393
+ expected = chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(descriptor);
1373
1394
  } catch (cause) {
1374
1395
  throw new ForeignDescriptorError(descriptor, { cause });
1375
1396
  }
@@ -1588,14 +1609,14 @@ var RestDelegateProvider = class {
1588
1609
  */
1589
1610
  async delegate(intent, forfeitTxs, options) {
1590
1611
  const url = `${this.url}/v1/delegate`;
1591
- const response = await chunkG552MISJ_cjs.baseFetch(url, {
1612
+ const response = await chunk2JV4VQ7C_cjs.baseFetch(url, {
1592
1613
  method: "POST",
1593
1614
  headers: {
1594
1615
  "Content-Type": "application/json"
1595
1616
  },
1596
1617
  body: JSON.stringify({
1597
1618
  intent: {
1598
- message: chunkG552MISJ_cjs.Intent.encodeMessage(intent.message),
1619
+ message: chunk2JV4VQ7C_cjs.Intent.encodeMessage(intent.message),
1599
1620
  proof: intent.proof
1600
1621
  },
1601
1622
  forfeit_txs: forfeitTxs,
@@ -1615,7 +1636,7 @@ var RestDelegateProvider = class {
1615
1636
  */
1616
1637
  async getDelegateInfo() {
1617
1638
  const url = `${this.url}/v1/delegator/info`;
1618
- const response = await chunkG552MISJ_cjs.rateGate.runHttp(url, () => chunkG552MISJ_cjs.baseFetch(url));
1639
+ const response = await chunk2JV4VQ7C_cjs.rateGate.runHttp(url, () => chunk2JV4VQ7C_cjs.baseFetch(url));
1619
1640
  if (!response.ok) {
1620
1641
  const errorText2 = await response.text();
1621
1642
  throw new Error(`Failed to get delegate info: ${errorText2}`);
@@ -1632,8 +1653,6 @@ var RestDelegatorProvider = RestDelegateProvider;
1632
1653
  function isDelegateInfo(data) {
1633
1654
  return !!data && typeof data === "object" && "pubkey" in data && "fee" in data && typeof data.pubkey === "string" && typeof data.fee === "string" && data.pubkey !== "" && data.fee !== "" && (typeof data.delegateAddress === "string" && data.delegateAddress !== "" || typeof data.delegatorAddress === "string" && data.delegatorAddress !== "");
1634
1655
  }
1635
-
1636
- // src/providers/onchain.ts
1637
1656
  var ESPLORA_URL = {
1638
1657
  bitcoin: "https://mempool.arkade.sh/api",
1639
1658
  testnet: "https://mempool.space/testnet/api",
@@ -1642,7 +1661,7 @@ var ESPLORA_URL = {
1642
1661
  regtest: "http://localhost:3000/api"
1643
1662
  };
1644
1663
  var EsploraProvider = class {
1645
- constructor(baseUrl = ESPLORA_URL[chunkG552MISJ_cjs.DEFAULT_NETWORK_NAME], opts) {
1664
+ constructor(baseUrl = ESPLORA_URL[chunk2JV4VQ7C_cjs.DEFAULT_NETWORK_NAME], opts) {
1646
1665
  this.baseUrl = baseUrl;
1647
1666
  this.pollingInterval = opts?.pollingInterval ?? 15e3;
1648
1667
  this.forcePolling = opts?.forcePolling ?? false;
@@ -1651,14 +1670,14 @@ var EsploraProvider = class {
1651
1670
  pollingInterval;
1652
1671
  forcePolling;
1653
1672
  async getCoins(address) {
1654
- const response = await chunkG552MISJ_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
1673
+ const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
1655
1674
  if (!response.ok) {
1656
1675
  throw new Error(`Failed to fetch UTXOs: ${response.statusText}`);
1657
1676
  }
1658
1677
  return response.json();
1659
1678
  }
1660
1679
  async getFeeRate() {
1661
- const response = await chunkG552MISJ_cjs.baseFetch(`${this.baseUrl}/fee-estimates`);
1680
+ const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/fee-estimates`);
1662
1681
  if (response.status === 404) {
1663
1682
  return void 0;
1664
1683
  }
@@ -1679,7 +1698,7 @@ var EsploraProvider = class {
1679
1698
  }
1680
1699
  }
1681
1700
  async getTxOutspends(txid) {
1682
- const response = await chunkG552MISJ_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
1701
+ const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
1683
1702
  if (!response.ok) {
1684
1703
  const error = await response.text();
1685
1704
  throw new Error(`Failed to get transaction outspends: ${error}`);
@@ -1687,15 +1706,23 @@ var EsploraProvider = class {
1687
1706
  return response.json();
1688
1707
  }
1689
1708
  async getTransactions(address) {
1690
- const response = await chunkG552MISJ_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
1709
+ const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
1691
1710
  if (!response.ok) {
1692
1711
  const error = await response.text();
1693
1712
  throw new Error(`Failed to get transactions: ${error}`);
1694
1713
  }
1695
1714
  return response.json();
1696
1715
  }
1716
+ async getRawTransaction(txid) {
1717
+ const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/hex`);
1718
+ if (!response.ok) {
1719
+ const error = await response.text();
1720
+ throw new Error(`Failed to get raw transaction ${txid}: ${error}`);
1721
+ }
1722
+ return base.hex.decode((await response.text()).trim());
1723
+ }
1697
1724
  async getTxStatus(txid) {
1698
- const txresponse = await chunkG552MISJ_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
1725
+ const txresponse = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
1699
1726
  if (!txresponse.ok) {
1700
1727
  throw new Error(txresponse.statusText);
1701
1728
  }
@@ -1703,7 +1730,7 @@ var EsploraProvider = class {
1703
1730
  if (!tx.status.confirmed) {
1704
1731
  return { confirmed: false };
1705
1732
  }
1706
- const response = await chunkG552MISJ_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
1733
+ const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
1707
1734
  if (!response.ok) {
1708
1735
  throw new Error(`Failed to get transaction status: ${response.statusText}`);
1709
1736
  }
@@ -1787,7 +1814,7 @@ var EsploraProvider = class {
1787
1814
  return stopFunc;
1788
1815
  }
1789
1816
  async getChainTip() {
1790
- const tipBlocks = await chunkG552MISJ_cjs.baseFetch(`${this.baseUrl}/blocks`);
1817
+ const tipBlocks = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/blocks`);
1791
1818
  if (!tipBlocks.ok) {
1792
1819
  throw new Error(`Failed to get chain tip: ${tipBlocks.statusText}`);
1793
1820
  }
@@ -1806,7 +1833,7 @@ var EsploraProvider = class {
1806
1833
  };
1807
1834
  }
1808
1835
  async broadcastPackage(parent, child) {
1809
- const response = await chunkG552MISJ_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
1836
+ const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
1810
1837
  method: "POST",
1811
1838
  headers: {
1812
1839
  "Content-Type": "application/json"
@@ -1817,10 +1844,12 @@ var EsploraProvider = class {
1817
1844
  const error = await response.text();
1818
1845
  throw new Error(`Failed to broadcast package: ${error}`);
1819
1846
  }
1820
- return response.json();
1847
+ const result = await response.json();
1848
+ assertPackageAccepted(result);
1849
+ return result;
1821
1850
  }
1822
1851
  async broadcastTx(tx) {
1823
- const response = await chunkG552MISJ_cjs.baseFetch(`${this.baseUrl}/tx`, {
1852
+ const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx`, {
1824
1853
  method: "POST",
1825
1854
  headers: {
1826
1855
  "Content-Type": "text/plain"
@@ -1834,6 +1863,24 @@ var EsploraProvider = class {
1834
1863
  return response.text();
1835
1864
  }
1836
1865
  };
1866
+ function assertPackageAccepted(result) {
1867
+ if (!result || typeof result !== "object") return;
1868
+ const r = result;
1869
+ const msg = typeof r.package_msg === "string" ? r.package_msg : void 0;
1870
+ if (msg === void 0 || msg === "success") return;
1871
+ const reasons = [];
1872
+ const results = r["tx-results"];
1873
+ if (results && typeof results === "object") {
1874
+ for (const entry of Object.values(results)) {
1875
+ if (!entry || typeof entry !== "object" || entry.error === void 0) continue;
1876
+ const txid = typeof entry.txid === "string" ? entry.txid : "unknown tx";
1877
+ reasons.push(`${txid}: ${String(entry.error)}`);
1878
+ }
1879
+ }
1880
+ throw new Error(
1881
+ reasons.length > 0 ? `Package rejected (${msg}) \u2014 ${reasons.join("; ")}` : `Package rejected (${msg})`
1882
+ );
1883
+ }
1837
1884
  function isValidBlocksTip(tip) {
1838
1885
  return Array.isArray(tip) && tip.every((t) => {
1839
1886
  return t && typeof t === "object" && typeof t.id === "string" && t.id.length > 0 && typeof t.height === "number" && t.height >= 0 && typeof t.mediantime === "number" && t.mediantime > 0;
@@ -1982,7 +2029,7 @@ function findP2AOutput(tx) {
1982
2029
  var CHILD_DUST_AMOUNT = 546;
1983
2030
  function buildAnchorChild(params) {
1984
2031
  const { parent, feeRate, fundingCoins, changeAddress, tapInternalKey, network } = params;
1985
- const child = new chunkG552MISJ_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
2032
+ const child = new chunk2JV4VQ7C_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
1986
2033
  child.addInput(findP2AOutput(parent));
1987
2034
  const estimator = TxWeightEstimator.create().addP2AInput();
1988
2035
  for (const _ of fundingCoins) {
@@ -2030,7 +2077,7 @@ function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
2030
2077
  );
2031
2078
  }
2032
2079
  function buildForfeitTxWithOutput(inputs, output, txLocktime) {
2033
- const tx = new chunkG552MISJ_cjs.Transaction({
2080
+ const tx = new chunk2JV4VQ7C_cjs.Transaction({
2034
2081
  version: 3,
2035
2082
  lockTime: txLocktime
2036
2083
  });
@@ -2106,7 +2153,7 @@ function validateVtxoTxGraph(graph, roundTransaction, sweepTapTreeRoot) {
2106
2153
  if (previousScriptKey.length !== 32) {
2107
2154
  throw new Error(`parent output ${childIndex} has invalid script`);
2108
2155
  }
2109
- const cosigners = chunkG552MISJ_cjs.getArkPsbtFields(child.root, 0, chunkG552MISJ_cjs.CosignerPublicKey);
2156
+ const cosigners = chunk2JV4VQ7C_cjs.getArkPsbtFields(child.root, 0, chunk2JV4VQ7C_cjs.CosignerPublicKey);
2110
2157
  if (cosigners.length === 0) {
2111
2158
  throw ErrMissingCosignersPublicKeys;
2112
2159
  }
@@ -2164,7 +2211,7 @@ var EmulatorPacket = class _EmulatorPacket {
2164
2211
  return new _EmulatorPacket(entries);
2165
2212
  }
2166
2213
  static fromBytes(data) {
2167
- const reader = new chunkXN55B6EP_cjs.BufferReader(data);
2214
+ const reader = new chunkCO3KKSWM_cjs.BufferReader(data);
2168
2215
  const entryCount = reader.readCompactSize();
2169
2216
  const entries = [];
2170
2217
  for (let i = 0; i < entryCount; i++) {
@@ -2182,7 +2229,7 @@ var EmulatorPacket = class _EmulatorPacket {
2182
2229
  return _EmulatorPacket.PACKET_TYPE;
2183
2230
  }
2184
2231
  serialize() {
2185
- const writer = new chunkXN55B6EP_cjs.BufferWriter();
2232
+ const writer = new chunkCO3KKSWM_cjs.BufferWriter();
2186
2233
  writer.writeCompactSize(this.entries.length);
2187
2234
  for (const entry of this.entries) {
2188
2235
  writer.writeUint16LE(entry.vin);
@@ -2269,7 +2316,7 @@ var Extension = class _Extension {
2269
2316
  `expected magic prefix ${base.hex.encode(ARKADE_MAGIC)}, got ${base.hex.encode(payload.slice(0, Math.min(payload.length, ARKADE_MAGIC.length)))}`
2270
2317
  );
2271
2318
  }
2272
- const reader = new chunkXN55B6EP_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
2319
+ const reader = new chunkCO3KKSWM_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
2273
2320
  const packets = [];
2274
2321
  while (reader.remaining() > 0) {
2275
2322
  const packetType = reader.readByte();
@@ -2343,7 +2390,7 @@ var Extension = class _Extension {
2343
2390
  */
2344
2391
  getAssetPacket() {
2345
2392
  for (const p of this.packets) {
2346
- if (p instanceof chunkXN55B6EP_cjs.Packet) {
2393
+ if (p instanceof chunkCO3KKSWM_cjs.Packet) {
2347
2394
  return p;
2348
2395
  }
2349
2396
  }
@@ -2381,8 +2428,8 @@ var Extension = class _Extension {
2381
2428
  };
2382
2429
  function parsePacket(packetType, data) {
2383
2430
  switch (packetType) {
2384
- case chunkXN55B6EP_cjs.Packet.PACKET_TYPE:
2385
- return chunkXN55B6EP_cjs.Packet.fromBytes(data);
2431
+ case chunkCO3KKSWM_cjs.Packet.PACKET_TYPE:
2432
+ return chunkCO3KKSWM_cjs.Packet.fromBytes(data);
2386
2433
  case EmulatorPacket.PACKET_TYPE:
2387
2434
  return EmulatorPacket.fromBytes(data);
2388
2435
  default:
@@ -2429,16 +2476,16 @@ function buildOpReturnScript(data) {
2429
2476
  }
2430
2477
  return script;
2431
2478
  }
2432
- var ErrOffchainOutputNotFound = (address) => new chunkG552MISJ_cjs.ServerResponseMismatchError(`offchain send output not found: ${address}`);
2433
- var ErrInvalidAssetOutputAmount = (got, want, assetId) => new chunkG552MISJ_cjs.ServerResponseMismatchError(
2479
+ var ErrOffchainOutputNotFound = (address) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(`offchain send output not found: ${address}`);
2480
+ var ErrInvalidAssetOutputAmount = (got, want, assetId) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2434
2481
  `invalid asset output amount for ${assetId}: got ${got}, want ${want}`
2435
2482
  );
2436
- var ErrAssetGroupNotFound = (assetId) => new chunkG552MISJ_cjs.ServerResponseMismatchError(`asset group not found in batch leaf: ${assetId}`);
2437
- var ErrAssetOutputNotFound = (assetId, outputIndex) => new chunkG552MISJ_cjs.ServerResponseMismatchError(
2483
+ var ErrAssetGroupNotFound = (assetId) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(`asset group not found in batch leaf: ${assetId}`);
2484
+ var ErrAssetOutputNotFound = (assetId, outputIndex) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2438
2485
  `asset output not found in asset group ${assetId} at index ${outputIndex}`
2439
2486
  );
2440
- var ErrOnchainOutputNotFound = (address) => new chunkG552MISJ_cjs.ServerResponseMismatchError(`onchain output not found: ${address}`);
2441
- var ErrUnvalidatedOffchainOutput = (address) => new chunkG552MISJ_cjs.ServerResponseMismatchError(
2487
+ var ErrOnchainOutputNotFound = (address) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(`onchain output not found: ${address}`);
2488
+ var ErrUnvalidatedOffchainOutput = (address) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2442
2489
  `offchain output ${address} cannot be validated: virtual output tree signing did not run`
2443
2490
  );
2444
2491
  var ErrInvalidOnchainOutputAmount = (address) => new Error(`invalid onchain output amount: ${address}`);
@@ -2447,7 +2494,7 @@ var ErrInvalidOffchainOutputAmount = (address) => new Error(`invalid offchain ou
2447
2494
  function assertFinalCommitmentMatchesValidated(finalCommitmentTx, validatedCommitmentTxid, context) {
2448
2495
  if (!validatedCommitmentTxid) return;
2449
2496
  if (finalCommitmentTx.id === validatedCommitmentTxid) return;
2450
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
2497
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2451
2498
  `${context}: finalization commitment tx ${finalCommitmentTx.id} differs from the validated commitment tx ${validatedCommitmentTxid}`
2452
2499
  );
2453
2500
  }
@@ -2457,7 +2504,7 @@ function validateBatchRecipients(commitmentTx, vtxoTreeLeaves, recipients, netwo
2457
2504
  for (const recipient of recipients) {
2458
2505
  let arkAddress;
2459
2506
  try {
2460
- arkAddress = chunkG552MISJ_cjs.ArkAddress.decode(recipient.address);
2507
+ arkAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(recipient.address);
2461
2508
  } catch {
2462
2509
  validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
2463
2510
  continue;
@@ -2469,7 +2516,7 @@ function validateBatchRecipientsWithoutTree(commitmentTx, recipients, network) {
2469
2516
  const usedOnchainOutputs = /* @__PURE__ */ new Set();
2470
2517
  for (const recipient of recipients) {
2471
2518
  try {
2472
- chunkG552MISJ_cjs.ArkAddress.decode(recipient.address);
2519
+ chunk2JV4VQ7C_cjs.ArkAddress.decode(recipient.address);
2473
2520
  } catch {
2474
2521
  validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
2475
2522
  continue;
@@ -2702,7 +2749,7 @@ function assetMintResolver() {
2702
2749
  if (!tx.assets?.length || !tx.key.arkTxid) return void 0;
2703
2750
  const minted = tx.assets.filter((a) => {
2704
2751
  try {
2705
- return base.hex.encode(chunkXN55B6EP_cjs.AssetId.fromString(a.assetId).txid) === tx.key.arkTxid;
2752
+ return base.hex.encode(chunkCO3KKSWM_cjs.AssetId.fromString(a.assetId).txid) === tx.key.arkTxid;
2706
2753
  } catch {
2707
2754
  return false;
2708
2755
  }
@@ -2745,7 +2792,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
2745
2792
  const existing = inputsByAssetId.get(asset.assetId);
2746
2793
  inputsByAssetId.set(asset.assetId, [
2747
2794
  ...existing ?? [],
2748
- chunkXN55B6EP_cjs.AssetInput.create(inputIndex, asset.amount)
2795
+ chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount)
2749
2796
  ]);
2750
2797
  }
2751
2798
  }
@@ -2757,7 +2804,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
2757
2804
  const existing = outputsByAssetId.get(asset.assetId);
2758
2805
  outputsByAssetId.set(asset.assetId, [
2759
2806
  ...existing ?? [],
2760
- chunkXN55B6EP_cjs.AssetOutput.create(outputIndex, asset.amount)
2807
+ chunkCO3KKSWM_cjs.AssetOutput.create(outputIndex, asset.amount)
2761
2808
  ]);
2762
2809
  }
2763
2810
  }
@@ -2768,7 +2815,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
2768
2815
  const existing = outputsByAssetId.get(asset.assetId);
2769
2816
  outputsByAssetId.set(asset.assetId, [
2770
2817
  ...existing ?? [],
2771
- chunkXN55B6EP_cjs.AssetOutput.create(outputIndex, asset.amount)
2818
+ chunkCO3KKSWM_cjs.AssetOutput.create(outputIndex, asset.amount)
2772
2819
  ]);
2773
2820
  }
2774
2821
  }
@@ -2777,11 +2824,11 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
2777
2824
  for (const assetIdStr of allAssetIds) {
2778
2825
  const inputs = inputsByAssetId.get(assetIdStr);
2779
2826
  const outputs = outputsByAssetId.get(assetIdStr);
2780
- const assetId = chunkXN55B6EP_cjs.AssetId.fromString(assetIdStr);
2781
- const group = chunkXN55B6EP_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
2827
+ const assetId = chunkCO3KKSWM_cjs.AssetId.fromString(assetIdStr);
2828
+ const group = chunkCO3KKSWM_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
2782
2829
  groups.push(group);
2783
2830
  }
2784
- return chunkXN55B6EP_cjs.Packet.create(groups);
2831
+ return chunkCO3KKSWM_cjs.Packet.create(groups);
2785
2832
  }
2786
2833
  function selectCoinsWithAsset(coins, assetId, requiredAmount) {
2787
2834
  const coinsWithAsset = coins.filter((coin) => coin.assets?.some((a) => a.assetId === assetId));
@@ -2818,8 +2865,7 @@ function selectedCoinsToAssetInputs(selectedCoins) {
2818
2865
  }
2819
2866
  function toXOnlySignerHex(pubkeyHex) {
2820
2867
  const bytes = base.hex.decode(pubkeyHex);
2821
- if (bytes.length === 33) return base.hex.encode(bytes.slice(1));
2822
- if (bytes.length === 32) return base.hex.encode(bytes);
2868
+ if (bytes.length === 32 || bytes.length === 33) return base.hex.encode(chunkOIZ2V2VD_cjs.toXOnly(bytes, "signer key"));
2823
2869
  throw new Error(`invalid signer pubkey length: expected 32 or 33 bytes, got ${bytes.length}`);
2824
2870
  }
2825
2871
  function signerSetFromInfo(info) {
@@ -2866,13 +2912,13 @@ var toTimelock = (value) => ({
2866
2912
  var toSeconds = (t) => t.type === "seconds" ? t.value : t.value * NOMINAL_BLOCK_SECONDS;
2867
2913
  function assertTimelockInPolicy(timelock, policy, label, overrideOption) {
2868
2914
  if (policy.requireSeconds && timelock.type === "blocks") {
2869
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
2915
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2870
2916
  `${label} rejected: block-typed timelocks are not accepted (got ${timelock.value})`
2871
2917
  );
2872
2918
  }
2873
2919
  const seconds = toSeconds(timelock);
2874
2920
  if (seconds < policy.minSeconds) {
2875
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
2921
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2876
2922
  `${label} rejected: ${timelock.value} ${timelock.type} is below the ${policy.minSeconds}s floor; pass ${overrideOption}: ${seconds}n to Wallet.create to lower it`
2877
2923
  );
2878
2924
  }
@@ -2893,7 +2939,7 @@ function resolveBatchExpiryPolicy(network, overrides) {
2893
2939
  }
2894
2940
  function assertValidBatchExpiry(batchExpiry, policy) {
2895
2941
  if (policy.advertisedVtxoTreeExpiry !== void 0 && batchExpiry !== policy.advertisedVtxoTreeExpiry) {
2896
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
2942
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2897
2943
  `batch expiry rejected: ${batchExpiry} does not match the advertised vtxoTreeExpiry ${policy.advertisedVtxoTreeExpiry}`
2898
2944
  );
2899
2945
  }
@@ -2923,21 +2969,21 @@ function resolveCheckpointExitDelayPolicy(network, overrides) {
2923
2969
  function assertValidServerUnrollScript(checkpointTapscript, policy) {
2924
2970
  let script;
2925
2971
  try {
2926
- script = chunkG552MISJ_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
2972
+ script = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
2927
2973
  } catch (e) {
2928
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
2974
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2929
2975
  `checkpoint exit delay rejected: invalid checkpointTapscript from server (${e instanceof Error ? e.message : String(e)})`
2930
2976
  );
2931
2977
  }
2932
2978
  if (policy.advertisedForfeitPubkey !== void 0) {
2933
2979
  const { pubkeys } = script.params;
2934
2980
  if (pubkeys.length !== 1) {
2935
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
2981
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2936
2982
  `checkpoint exit delay rejected: checkpointTapscript must commit to exactly one pubkey, got ${pubkeys.length} [${pubkeys.map(base.hex.encode).join(", ")}]`
2937
2983
  );
2938
2984
  }
2939
2985
  if (!utils_js.equalBytes(pubkeys[0], policy.advertisedForfeitPubkey)) {
2940
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
2986
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
2941
2987
  `checkpoint exit delay rejected: checkpointTapscript pubkey ${base.hex.encode(pubkeys[0])} does not match the advertised forfeitPubkey ${base.hex.encode(policy.advertisedForfeitPubkey)}`
2942
2988
  );
2943
2989
  }
@@ -2981,8 +3027,8 @@ function buildOffchainTx(inputs, outputs, serverUnrollScript) {
2981
3027
  function buildVirtualTx(inputs, outputs) {
2982
3028
  let lockTime = 0n;
2983
3029
  for (const input of inputs) {
2984
- const tapscript = chunkG552MISJ_cjs.decodeTapscript(chunkG552MISJ_cjs.scriptFromTapLeafScript(input.tapLeafScript));
2985
- if (chunkG552MISJ_cjs.CLTVMultisigTapscript.is(tapscript)) {
3030
+ const tapscript = chunk2JV4VQ7C_cjs.decodeTapscript(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(input.tapLeafScript));
3031
+ if (chunk2JV4VQ7C_cjs.CLTVMultisigTapscript.is(tapscript)) {
2986
3032
  if (lockTime !== 0n) {
2987
3033
  if (isSeconds(lockTime) !== isSeconds(tapscript.params.absoluteTimelock)) {
2988
3034
  throw new Error("cannot mix seconds and blocks locktime");
@@ -2993,7 +3039,7 @@ function buildVirtualTx(inputs, outputs) {
2993
3039
  }
2994
3040
  }
2995
3041
  }
2996
- const tx = new chunkG552MISJ_cjs.Transaction({
3042
+ const tx = new chunk2JV4VQ7C_cjs.Transaction({
2997
3043
  version: 3,
2998
3044
  lockTime: Number(lockTime)
2999
3045
  });
@@ -3003,12 +3049,12 @@ function buildVirtualTx(inputs, outputs) {
3003
3049
  index: input.vout,
3004
3050
  sequence: lockTime ? btcSigner.DEFAULT_SEQUENCE - 1 : void 0,
3005
3051
  witnessUtxo: {
3006
- script: chunkG552MISJ_cjs.VtxoScript.decode(input.tapTree).pkScript,
3052
+ script: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript,
3007
3053
  amount: BigInt(input.value)
3008
3054
  },
3009
3055
  tapLeafScript: [input.tapLeafScript]
3010
3056
  });
3011
- chunkG552MISJ_cjs.setArkPsbtField(tx, i, chunkG552MISJ_cjs.VtxoTaprootTree, input.tapTree);
3057
+ chunk2JV4VQ7C_cjs.setArkPsbtField(tx, i, chunk2JV4VQ7C_cjs.VtxoTaprootTree, input.tapTree);
3012
3058
  }
3013
3059
  for (const output of outputs) {
3014
3060
  tx.addOutput(output);
@@ -3017,8 +3063,8 @@ function buildVirtualTx(inputs, outputs) {
3017
3063
  return tx;
3018
3064
  }
3019
3065
  function buildCheckpointTx(vtxo, serverUnrollScript) {
3020
- const collaborativeClosure = chunkG552MISJ_cjs.decodeTapscript(chunkG552MISJ_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
3021
- const checkpointVtxoScript = new chunkG552MISJ_cjs.VtxoScript([
3066
+ const collaborativeClosure = chunk2JV4VQ7C_cjs.decodeTapscript(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
3067
+ const checkpointVtxoScript = new chunk2JV4VQ7C_cjs.VtxoScript([
3022
3068
  serverUnrollScript.script,
3023
3069
  collaborativeClosure.script
3024
3070
  ]);
@@ -3171,7 +3217,7 @@ function combineTapscriptSigs(signedTx, originalTx) {
3171
3217
  }
3172
3218
  function isValidArkAddress(address) {
3173
3219
  try {
3174
- chunkG552MISJ_cjs.ArkAddress.decode(address);
3220
+ chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
3175
3221
  return true;
3176
3222
  } catch (e) {
3177
3223
  return false;
@@ -3179,16 +3225,16 @@ function isValidArkAddress(address) {
3179
3225
  }
3180
3226
  function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, context) {
3181
3227
  if (serverCheckpointTxs.length !== expectedCheckpoints.length) {
3182
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3228
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3183
3229
  `${context} returned ${serverCheckpointTxs.length} checkpoints, expected ${expectedCheckpoints.length}`
3184
3230
  );
3185
3231
  }
3186
3232
  const byTxid = new Map(expectedCheckpoints.map((c) => [c.id, c]));
3187
3233
  return serverCheckpointTxs.map((encoded, index) => {
3188
- const server = chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
3234
+ const server = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
3189
3235
  const local = byTxid.get(server.id);
3190
3236
  if (!local) {
3191
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3237
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3192
3238
  `${context} checkpoint ${index} txid ${server.id} does not match any submitted checkpoint`
3193
3239
  );
3194
3240
  }
@@ -3198,14 +3244,14 @@ function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, contex
3198
3244
  }
3199
3245
  function assertSubmittedArkTxid(response, signedArkTx, context) {
3200
3246
  if (response.arkTxid !== signedArkTx.id) {
3201
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3247
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3202
3248
  `${context} returned ark txid ${response.arkTxid}, expected ${signedArkTx.id}`
3203
3249
  );
3204
3250
  }
3205
3251
  if (response.finalArkTx === void 0) return;
3206
- const finalTxid = chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx)).id;
3252
+ const finalTxid = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx)).id;
3207
3253
  if (finalTxid !== signedArkTx.id) {
3208
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3254
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3209
3255
  `${context} returned final ark tx ${finalTxid}, expected ${signedArkTx.id}`
3210
3256
  );
3211
3257
  }
@@ -3224,10 +3270,10 @@ function assertServerSignedLeaf(serverTx, localTx, inputIndex, serverPubkeyHex,
3224
3270
  [serverPubkeyHex],
3225
3271
  void 0,
3226
3272
  void 0,
3227
- payment_js.tapLeafHash(chunkG552MISJ_cjs.scriptFromTapLeafScript(leaf))
3273
+ payment_js.tapLeafHash(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(leaf))
3228
3274
  );
3229
3275
  } catch (error) {
3230
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3276
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3231
3277
  `${context}: input ${inputIndex} is not signed by the server on the leaf being spent (${error instanceof Error ? error.message : String(error)})`
3232
3278
  );
3233
3279
  }
@@ -3236,20 +3282,20 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
3236
3282
  const byOutpoint = new Map(inputs.map((input) => [`${input.txid}:${input.vout}`, input]));
3237
3283
  for (const [index, checkpoint] of checkpoints.entries()) {
3238
3284
  if (checkpoint.inputsLength !== 1) {
3239
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3285
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3240
3286
  `${context}: checkpoint ${index} spends ${checkpoint.inputsLength} inputs, expected 1`
3241
3287
  );
3242
3288
  }
3243
3289
  const spent = checkpoint.getInput(0);
3244
3290
  if (!spent.txid || spent.index === void 0) {
3245
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3291
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3246
3292
  `${context}: checkpoint ${index} has no input outpoint`
3247
3293
  );
3248
3294
  }
3249
3295
  const outpoint = `${base.hex.encode(spent.txid)}:${spent.index}`;
3250
3296
  const input = byOutpoint.get(outpoint);
3251
3297
  if (!input) {
3252
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3298
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3253
3299
  `${context}: checkpoint ${index} spends ${outpoint}, which is not one of the requested virtual outputs`
3254
3300
  );
3255
3301
  }
@@ -3257,7 +3303,7 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
3257
3303
  (unroll) => buildCheckpointTx(input, unroll).tx.id === checkpoint.id
3258
3304
  );
3259
3305
  if (!rebuilt) {
3260
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3306
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3261
3307
  `${context}: checkpoint ${index} txid ${checkpoint.id} differs from the checkpoint built locally for ${outpoint}`
3262
3308
  );
3263
3309
  }
@@ -3284,14 +3330,12 @@ async function submitOffchainTx(provider, offchainTx, signer, hooks, options) {
3284
3330
  const verify = options?.verifyServerSignatures;
3285
3331
  if (verify) {
3286
3332
  if (response.finalArkTx === void 0) {
3287
- throw new chunkG552MISJ_cjs.ServerResponseMismatchError(
3333
+ throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
3288
3334
  "submitTx: server returned no final ark tx to verify its signatures against"
3289
3335
  );
3290
3336
  }
3291
- const finalArkTx = chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx));
3292
- const serverPubkeyHex = base.hex.encode(
3293
- verify.serverPubkey.length === 33 ? verify.serverPubkey.subarray(1) : verify.serverPubkey
3294
- );
3337
+ const finalArkTx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx));
3338
+ const serverPubkeyHex = base.hex.encode(chunkOIZ2V2VD_cjs.toXOnly(verify.serverPubkey, "server key"));
3295
3339
  for (let i = 0; i < offchainTx.arkTx.inputsLength; i++) {
3296
3340
  assertServerSignedLeaf(
3297
3341
  finalArkTx,
@@ -3347,12 +3391,12 @@ function claimWithPreimageIdentity(identity, preimage) {
3347
3391
  return {
3348
3392
  ...identity,
3349
3393
  sign: async (tx, inputIndexes) => {
3350
- const signed = chunkG552MISJ_cjs.Transaction.fromPSBT(
3394
+ const signed = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(
3351
3395
  (await identity.sign(tx.clone(), inputIndexes)).toPSBT()
3352
3396
  );
3353
3397
  const indexes = inputIndexes ?? Array.from({ length: signed.inputsLength }, (_, i) => i);
3354
3398
  for (const index of indexes) {
3355
- chunkG552MISJ_cjs.setArkPsbtField(signed, index, chunkG552MISJ_cjs.ConditionWitness, [preimage]);
3399
+ chunk2JV4VQ7C_cjs.setArkPsbtField(signed, index, chunk2JV4VQ7C_cjs.ConditionWitness, [preimage]);
3356
3400
  }
3357
3401
  return signed;
3358
3402
  }
@@ -3544,7 +3588,7 @@ function extendCoinWithTapscript(boardingTapscript, utxo) {
3544
3588
  };
3545
3589
  }
3546
3590
  function deriveContractTapscripts(contract) {
3547
- const handler = chunkBABJ77NG_cjs.contractHandlers.get(contract.type);
3591
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
3548
3592
  if (!handler) {
3549
3593
  throw new Error(`No handler for contract type '${contract.type}'`);
3550
3594
  }
@@ -3615,7 +3659,7 @@ function getRandomId() {
3615
3659
  }
3616
3660
  function isValidArkAddress2(address) {
3617
3661
  try {
3618
- chunkG552MISJ_cjs.ArkAddress.decode(address);
3662
+ chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
3619
3663
  return true;
3620
3664
  } catch (e) {
3621
3665
  return false;
@@ -3643,7 +3687,7 @@ function assertRecipientArkAddress(encoded, address, context) {
3643
3687
  function assertTapTreeDerivesAddress(encoded, tapTree, address) {
3644
3688
  let derived;
3645
3689
  try {
3646
- derived = chunkG552MISJ_cjs.VtxoScript.decode(tapTree).pkScript;
3690
+ derived = chunk2JV4VQ7C_cjs.VtxoScript.decode(tapTree).pkScript;
3647
3691
  } catch (e) {
3648
3692
  throw new Error(
3649
3693
  `Invalid tapTree for ${encoded}: ${e instanceof Error ? e.message : String(e)}`
@@ -3660,7 +3704,7 @@ function validateRecipients(recipients, dustAmount, context) {
3660
3704
  for (const recipient of recipients) {
3661
3705
  let address;
3662
3706
  try {
3663
- address = chunkG552MISJ_cjs.ArkAddress.decode(recipient.address);
3707
+ address = chunk2JV4VQ7C_cjs.ArkAddress.decode(recipient.address);
3664
3708
  } catch (e) {
3665
3709
  throw new Error(`Invalid Arkade address: ${recipient.address}`);
3666
3710
  }
@@ -3685,7 +3729,7 @@ function validateRecipients(recipients, dustAmount, context) {
3685
3729
 
3686
3730
  // src/contracts/spendability.ts
3687
3731
  function isContractGenericallySpendable(contract) {
3688
- return chunkBABJ77NG_cjs.contractHandlers.get(contract.type)?.isGenericallySpendable?.(contract) === true;
3732
+ return chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type)?.isGenericallySpendable?.(contract) === true;
3689
3733
  }
3690
3734
  function gatedContracts(contracts) {
3691
3735
  const gated = /* @__PURE__ */ new Map();
@@ -3698,7 +3742,7 @@ function gateExclusion(gated) {
3698
3742
  return (vtxo) => {
3699
3743
  const type = vtxo.script === void 0 ? void 0 : gated.get(vtxo.script);
3700
3744
  if (type === void 0) return void 0;
3701
- if (!chunkBABJ77NG_cjs.contractHandlers.has(type)) {
3745
+ if (!chunkOIZ2V2VD_cjs.contractHandlers.has(type)) {
3702
3746
  return `at ${vtxo.script} (contract type '${type}') has no handler registered in this build`;
3703
3747
  }
3704
3748
  return `at ${vtxo.script} (contract type '${type}') is not generically spendable`;
@@ -3734,7 +3778,9 @@ function selectPendingRecoveryOutpoints(contractsWithVtxos, signerSet, nowSecond
3734
3778
  continue;
3735
3779
  }
3736
3780
  for (const v of vtxos) {
3737
- if (!chunkG552MISJ_cjs.hasTerminalSpend(v) && !v.isSwept) out.add(`${v.txid}:${v.vout}`);
3781
+ if (!chunk2JV4VQ7C_cjs.hasTerminalSpend(v) && !v.isSwept && !v.isUnrolled) {
3782
+ out.add(`${v.txid}:${v.vout}`);
3783
+ }
3738
3784
  }
3739
3785
  }
3740
3786
  return out;
@@ -3767,10 +3813,10 @@ function byValueDescending(vtxos) {
3767
3813
  return [...vtxos].sort((a, b) => b.value - a.value);
3768
3814
  }
3769
3815
  async function fetchTimeHeight(wallet) {
3770
- return chunkG552MISJ_cjs.resolveTimeHeight(wallet.onchainProvider);
3816
+ return chunk2JV4VQ7C_cjs.resolveTimeHeight(wallet.onchainProvider);
3771
3817
  }
3772
3818
  function canMigrateBySend(vtxo, now) {
3773
- if (!chunkG552MISJ_cjs.canSpendOffchain(vtxo, now)) return false;
3819
+ if (!chunk2JV4VQ7C_cjs.canSpendOffchain(vtxo, now)) return false;
3774
3820
  return vtxo.expiresAt !== void 0 || vtxo.expiresAtHeight !== void 0;
3775
3821
  }
3776
3822
  function byExpiryAscending(vtxos, now) {
@@ -3778,7 +3824,7 @@ function byExpiryAscending(vtxos, now) {
3778
3824
  if (vtxo.isSwept) return -Infinity;
3779
3825
  if (vtxo.expiresAt !== void 0) return vtxo.expiresAt.getTime();
3780
3826
  if (vtxo.expiresAtHeight !== void 0) {
3781
- return chunkG552MISJ_cjs.isPastExpiry(vtxo, now) ? -Infinity : Infinity;
3827
+ return chunk2JV4VQ7C_cjs.isPastExpiry(vtxo, now) ? -Infinity : Infinity;
3782
3828
  }
3783
3829
  return Infinity;
3784
3830
  };
@@ -3805,7 +3851,7 @@ function priceSettlementInputs(vtxos, estimator) {
3805
3851
  const payable = [];
3806
3852
  const net = /* @__PURE__ */ new Map();
3807
3853
  for (const vtxo of vtxos) {
3808
- const inputFee = estimator.evalOffchainInput(chunkG552MISJ_cjs.toOffchainInputFeeParams(vtxo));
3854
+ const inputFee = estimator.evalOffchainInput(chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(vtxo));
3809
3855
  if (inputFee.satoshis >= vtxo.value) {
3810
3856
  continue;
3811
3857
  }
@@ -3831,7 +3877,7 @@ function deductOffchainOutputFee(subtotal, estimator, arkAddress) {
3831
3877
  }
3832
3878
  const outputFee = estimator.evalOffchainOutput({
3833
3879
  amount: subtotal,
3834
- script: base.hex.encode(chunkG552MISJ_cjs.ArkAddress.decode(arkAddress).pkScript)
3880
+ script: base.hex.encode(chunk2JV4VQ7C_cjs.ArkAddress.decode(arkAddress).pkScript)
3835
3881
  });
3836
3882
  return subtotal - BigInt(outputFee.satoshis);
3837
3883
  }
@@ -3849,10 +3895,10 @@ var DEFAULT_SETTLEMENT_CONFIG = {
3849
3895
  };
3850
3896
  function getRecoverableVtxos(vtxos, dustAmount, now) {
3851
3897
  return vtxos.filter((vtxo) => {
3852
- if (chunkG552MISJ_cjs.canRecoverOnchain(vtxo, now)) {
3898
+ if (chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now)) {
3853
3899
  return true;
3854
3900
  }
3855
- if (chunkG552MISJ_cjs.canSpendOffchain(vtxo, now) && vtxo.isPreconfirmed && isSubdust(vtxo, dustAmount)) {
3901
+ if (chunk2JV4VQ7C_cjs.canSpendOffchain(vtxo, now) && vtxo.isPreconfirmed && isSubdust(vtxo, dustAmount)) {
3856
3902
  return true;
3857
3903
  }
3858
3904
  return false;
@@ -3883,7 +3929,7 @@ function getRecoverableWithSubdust(vtxos, dustAmount, now) {
3883
3929
  }
3884
3930
  function isVtxoExpiringSoon(vtxo, thresholdMs) {
3885
3931
  const realThresholdMs = thresholdMs <= 100 ? DEFAULT_THRESHOLD_MS : thresholdMs;
3886
- const expiresAt = chunkG552MISJ_cjs.normalizeVtxo(vtxo).expiresAt;
3932
+ const expiresAt = chunk2JV4VQ7C_cjs.normalizeVtxo(vtxo).expiresAt;
3887
3933
  if (expiresAt === void 0) return false;
3888
3934
  const now = Date.now();
3889
3935
  const batchExpiry = expiresAt.getTime();
@@ -3892,7 +3938,7 @@ function isVtxoExpiringSoon(vtxo, thresholdMs) {
3892
3938
  }
3893
3939
  function getExpiringAndRecoverableVtxos(vtxos, thresholdMs, dustAmount, now) {
3894
3940
  return vtxos.filter(
3895
- (vtxo) => isVtxoExpiringSoon(vtxo, thresholdMs) || chunkG552MISJ_cjs.canRecoverOnchain(vtxo, now) || isSubdust(vtxo, dustAmount)
3941
+ (vtxo) => isVtxoExpiringSoon(vtxo, thresholdMs) || chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now) || isSubdust(vtxo, dustAmount)
3896
3942
  );
3897
3943
  }
3898
3944
  function isMigrationCapable(wallet) {
@@ -4491,11 +4537,11 @@ var VtxoManager = class _VtxoManager {
4491
4537
  `Sweep not economical: output ${outputAmount} sats after ${fee} sats fee is below dust (${dustAmount} sats)`
4492
4538
  );
4493
4539
  }
4494
- const tx = new chunkG552MISJ_cjs.Transaction();
4540
+ const tx = new chunk2JV4VQ7C_cjs.Transaction();
4495
4541
  for (const utxo of expiredUtxos) {
4496
- const utxoScript = chunkG552MISJ_cjs.VtxoScript.decode(utxo.tapTree);
4542
+ const utxoScript = chunk2JV4VQ7C_cjs.VtxoScript.decode(utxo.tapTree);
4497
4543
  const utxoExitLeaf = utxoScript.leaves.find(
4498
- (leaf) => chunkG552MISJ_cjs.CSVMultisigTapscript.isScriptValid(chunkG552MISJ_cjs.scriptFromTapLeafScript(leaf)) === true
4544
+ (leaf) => chunk2JV4VQ7C_cjs.CSVMultisigTapscript.isScriptValid(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(leaf)) === true
4499
4545
  );
4500
4546
  if (!utxoExitLeaf) {
4501
4547
  throw new Error(
@@ -4510,7 +4556,7 @@ var VtxoManager = class _VtxoManager {
4510
4556
  amount: BigInt(utxo.value)
4511
4557
  },
4512
4558
  tapLeafScript: [utxoExitLeaf],
4513
- sequence: chunkG552MISJ_cjs.getSequence(utxoExitLeaf)
4559
+ sequence: chunk2JV4VQ7C_cjs.getSequence(utxoExitLeaf)
4514
4560
  });
4515
4561
  }
4516
4562
  tx.addOutputAddress(boardingAddress, outputAmount, this.getNetwork());
@@ -4543,6 +4589,7 @@ var VtxoManager = class _VtxoManager {
4543
4589
  async getDeprecatedSignerStatus() {
4544
4590
  const wallet = this.requireMigrationCapableWallet();
4545
4591
  const info = await wallet.arkProvider.getInfo();
4592
+ await wallet.settleServerInfoChanges?.();
4546
4593
  const { reports: vtxoReports } = await this.classifyDeprecatedSignerContracts(info);
4547
4594
  const { reports: boardingReports } = await this.classifyDeprecatedSignerBoarding(info);
4548
4595
  return mergeSignerReports(vtxoReports, boardingReports);
@@ -4556,26 +4603,33 @@ var VtxoManager = class _VtxoManager {
4556
4603
  */
4557
4604
  async migrateCore(options) {
4558
4605
  const wallet = this.requireMigrationCapableWallet();
4606
+ const signerBeforeRefresh = base.hex.encode(wallet.arkServerPublicKey);
4559
4607
  const info = await wallet.arkProvider.getInfo();
4608
+ await wallet.settleServerInfoChanges?.();
4609
+ const rotatedOnRefresh = signerBeforeRefresh !== base.hex.encode(wallet.arkServerPublicKey);
4560
4610
  wallet.refreshDeprecatedSigners(info);
4561
4611
  const signerSet = signerSetFromInfo(info);
4562
4612
  const nowSeconds = Math.floor(Date.now() / 1e3);
4563
4613
  const walletSignerHex = base.hex.encode(wallet.arkServerPublicKey);
4564
4614
  const walletClass = classifyAgainstSignerSet(walletSignerHex, signerSet, nowSeconds);
4565
4615
  if (signerSet.deprecated.size === 0 && walletClass.status === "CURRENT") {
4566
- return { rotated: false, expired: [], signers: [] };
4616
+ return { rotated: rotatedOnRefresh, expired: [], signers: [] };
4567
4617
  }
4568
4618
  if (walletClass.status === "UNKNOWN_SIGNER") {
4569
4619
  const { reports: vtxoReports2 } = await this.classifyDeprecatedSignerContracts(info);
4570
4620
  const { reports: boardingReports2 } = await this.classifyDeprecatedSignerBoarding(info);
4571
4621
  return {
4572
- rotated: false,
4622
+ // Normally false here — a drained rotation targets the active
4623
+ // signer, which classifies CURRENT, not UNKNOWN. It is true only
4624
+ // when a second rotation landed inside the drain, leaving us on a
4625
+ // signer newer than `info`: still a rotation this pass applied.
4626
+ rotated: rotatedOnRefresh,
4573
4627
  expired: [],
4574
4628
  signers: mergeSignerReports(vtxoReports2, boardingReports2),
4575
4629
  skipped: "unknown-wallet-signer"
4576
4630
  };
4577
4631
  }
4578
- const rotated = await this.ensureReceiveOnActiveSigner(info);
4632
+ const rotated = await this.ensureReceiveOnActiveSigner(info) || rotatedOnRefresh;
4579
4633
  const {
4580
4634
  reports: vtxoReports,
4581
4635
  migratable: vtxoMigratable,
@@ -4744,8 +4798,9 @@ var VtxoManager = class _VtxoManager {
4744
4798
  if (!serverPubKey) continue;
4745
4799
  const cls = classifyAgainstSignerSet(serverPubKey, signerSet, nowSeconds);
4746
4800
  if (cls.status === "CURRENT") continue;
4747
- const recoverable = vtxos.filter((v) => v.isSwept && !chunkG552MISJ_cjs.hasTerminalSpend(v));
4748
- const spendable = vtxos.filter((v) => !chunkG552MISJ_cjs.hasTerminalSpend(v) && !v.isSwept);
4801
+ const live = vtxos.filter((v) => !v.isUnrolled);
4802
+ const recoverable = live.filter((v) => v.isSwept && !chunk2JV4VQ7C_cjs.hasTerminalSpend(v));
4803
+ const spendable = live.filter((v) => !chunk2JV4VQ7C_cjs.hasTerminalSpend(v) && !v.isSwept);
4749
4804
  const value = spendable.reduce((sum, v) => sum + v.value, 0);
4750
4805
  let recoverableCount = 0;
4751
4806
  let recoverableValue = 0;
@@ -4758,7 +4813,7 @@ var VtxoManager = class _VtxoManager {
4758
4813
  awaitingSweepCount = spendable.length;
4759
4814
  awaitingSweepValue = value;
4760
4815
  for (const v of spendable) {
4761
- const exp = chunkG552MISJ_cjs.toBatchExpiry(v);
4816
+ const exp = chunk2JV4VQ7C_cjs.toBatchExpiry(v);
4762
4817
  if (exp !== void 0 && (nextSweepEta === void 0 || exp < nextSweepEta)) {
4763
4818
  nextSweepEta = exp;
4764
4819
  }
@@ -5019,7 +5074,7 @@ var VtxoManager = class _VtxoManager {
5019
5074
  /** Decodes the boarding tapscript exit path to extract the CSV timelock. */
5020
5075
  getBoardingTimelock() {
5021
5076
  const wallet = this.getSweepWallet();
5022
- const exitScript = chunkG552MISJ_cjs.CSVMultisigTapscript.decode(
5077
+ const exitScript = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(
5023
5078
  base.hex.decode(wallet.boardingTapscript.exitScript)
5024
5079
  );
5025
5080
  return exitScript.params.timelock;
@@ -5150,8 +5205,8 @@ var VtxoManager = class _VtxoManager {
5150
5205
  * or doesn't carry the metadata.
5151
5206
  */
5152
5207
  extractSpentOutpoint(error) {
5153
- const ark = chunkG552MISJ_cjs.maybeArkError(error);
5154
- if (!chunkG552MISJ_cjs.isArkError(ark, chunkG552MISJ_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
5208
+ const ark = chunk2JV4VQ7C_cjs.maybeArkError(error);
5209
+ if (!chunk2JV4VQ7C_cjs.isArkError(ark, chunk2JV4VQ7C_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
5155
5210
  const raw = ark.metadata?.vtxo_outpoint;
5156
5211
  if (typeof raw !== "string") return void 0;
5157
5212
  const [txid, voutStr] = raw.split(":");
@@ -5341,7 +5396,7 @@ var VtxoManager = class _VtxoManager {
5341
5396
  if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
5342
5397
  break;
5343
5398
  }
5344
- const inputFee = estimator.evalOffchainInput(chunkG552MISJ_cjs.toOffchainInputFeeParams(v));
5399
+ const inputFee = estimator.evalOffchainInput(chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(v));
5345
5400
  if (inputFee.satoshis >= v.value) {
5346
5401
  continue;
5347
5402
  }
@@ -5361,7 +5416,7 @@ var VtxoManager = class _VtxoManager {
5361
5416
  const arkAddress = await this.wallet.getAddress();
5362
5417
  const outputFee = estimator.evalOffchainOutput({
5363
5418
  amount: totalAmount,
5364
- script: base.hex.encode(chunkG552MISJ_cjs.ArkAddress.decode(arkAddress).pkScript)
5419
+ script: base.hex.encode(chunk2JV4VQ7C_cjs.ArkAddress.decode(arkAddress).pkScript)
5365
5420
  });
5366
5421
  totalAmount -= BigInt(outputFee.satoshis);
5367
5422
  if (totalAmount < dustAmount) return;
@@ -5441,7 +5496,7 @@ var ArkNote = class _ArkNote {
5441
5496
  this.value = value;
5442
5497
  this.HRP = HRP;
5443
5498
  const preimageHash = utils_js.sha256(this.preimage);
5444
- this.vtxoScript = new chunkG552MISJ_cjs.VtxoScript([noteTapscript(preimageHash)]);
5499
+ this.vtxoScript = new chunk2JV4VQ7C_cjs.VtxoScript([noteTapscript(preimageHash)]);
5445
5500
  const leaf = this.vtxoScript.leaves[0];
5446
5501
  this.txid = base.hex.encode(new Uint8Array(preimageHash).reverse());
5447
5502
  this.tapTree = this.vtxoScript.encode();
@@ -5608,7 +5663,7 @@ var ArkadeCash = class _ArkadeCash {
5608
5663
  const privateKey = data.slice(1, 33);
5609
5664
  const serverPubKey = data.slice(33, 65);
5610
5665
  const sequence = new DataView(data.buffer, data.byteOffset + 65, 4).getUint32(0, false);
5611
- const csvTimelock = chunkG552MISJ_cjs.sequenceToTimelock(sequence);
5666
+ const csvTimelock = chunk2JV4VQ7C_cjs.sequenceToTimelock(sequence);
5612
5667
  return new _ArkadeCash(privateKey, serverPubKey, csvTimelock, decoded.prefix);
5613
5668
  }
5614
5669
  toString() {
@@ -5616,7 +5671,7 @@ var ArkadeCash = class _ArkadeCash {
5616
5671
  data[0] = _ArkadeCash.Version;
5617
5672
  data.set(this._privateKey, 1);
5618
5673
  data.set(this._serverPubKey, 33);
5619
- const sequence = chunkG552MISJ_cjs.timelockToSequence(this.csvTimelock);
5674
+ const sequence = chunk2JV4VQ7C_cjs.timelockToSequence(this.csvTimelock);
5620
5675
  new DataView(data.buffer, data.byteOffset + 65, 4).setUint32(0, sequence, false);
5621
5676
  const words = base.bech32m.toWords(data);
5622
5677
  return base.bech32m.encode(this.hrp, words, 1023);
@@ -5625,7 +5680,7 @@ var ArkadeCash = class _ArkadeCash {
5625
5680
  return SingleKey.fromPrivateKey(this._privateKey);
5626
5681
  }
5627
5682
  get vtxoScript() {
5628
- return new chunkBABJ77NG_cjs.DefaultVtxo.Script({
5683
+ return new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
5629
5684
  pubKey: this._publicKey,
5630
5685
  serverPubKey: this._serverPubKey,
5631
5686
  csvTimelock: this.csvTimelock
@@ -5886,7 +5941,7 @@ async function captureExitBranch(params) {
5886
5941
  const nonCommitment = ordered.filter((c) => chainTxTypeToChainedExit(c.type) !== 1 /* Commitment */).map((c) => c.txid);
5887
5942
  if (nonCommitment.length > 0) {
5888
5943
  for (const psbt of await resolver.getVirtualTxs(nonCommitment)) {
5889
- psbtByTxid.set(chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
5944
+ psbtByTxid.set(chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
5890
5945
  }
5891
5946
  }
5892
5947
  }
@@ -5929,10 +5984,10 @@ var IndexerExitDataSource = class {
5929
5984
  while (hasMore) {
5930
5985
  const { chain: page, page: meta } = await this.indexer.getVtxoChain(
5931
5986
  { txid: vtxo.txid, vout: vtxo.vout },
5932
- { pageIndex, pageSize: chunkG552MISJ_cjs.DEFAULT_PAGE_SIZE }
5987
+ { pageIndex, pageSize: chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE }
5933
5988
  );
5934
5989
  chain.push(...page);
5935
- hasMore = meta ? page.length === chunkG552MISJ_cjs.DEFAULT_PAGE_SIZE : false;
5990
+ hasMore = meta ? page.length === chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE : false;
5936
5991
  pageIndex++;
5937
5992
  }
5938
5993
  return chain;
@@ -5944,12 +5999,12 @@ var IndexerExitDataSource = class {
5944
5999
  while (hasMore) {
5945
6000
  const { txs, page } = await this.indexer.getVirtualTxs(txids, {
5946
6001
  pageIndex,
5947
- pageSize: chunkG552MISJ_cjs.DEFAULT_PAGE_SIZE
6002
+ pageSize: chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE
5948
6003
  });
5949
6004
  for (const psbt of txs) {
5950
- out.set(chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
6005
+ out.set(chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
5951
6006
  }
5952
- hasMore = page ? txs.length === chunkG552MISJ_cjs.DEFAULT_PAGE_SIZE : false;
6007
+ hasMore = page ? txs.length === chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE : false;
5953
6008
  pageIndex++;
5954
6009
  }
5955
6010
  return out;
@@ -5970,7 +6025,7 @@ function chainedTxTypeToChainTxType(t) {
5970
6025
  }
5971
6026
  }
5972
6027
  function psbtInputTxids(psbtBase64) {
5973
- const tx = chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
6028
+ const tx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
5974
6029
  const ids = [];
5975
6030
  for (let i = 0; i < tx.inputsLength; i++) {
5976
6031
  const txid = tx.getInput(i).txid;
@@ -6151,6 +6206,8 @@ function serializeArkInfoSnapshot(info, savedAt) {
6151
6206
  unilateralExitDelay: info.unilateralExitDelay.toString(),
6152
6207
  boardingExitDelay: info.boardingExitDelay.toString(),
6153
6208
  vtxoTreeExpiry: info.vtxoTreeExpiry?.toString(),
6209
+ maxTxWeight: info.maxTxWeight?.toString(),
6210
+ maxOpReturnOutputs: info.maxOpReturnOutputs?.toString(),
6154
6211
  sessionDuration: info.sessionDuration.toString(),
6155
6212
  dust: info.dust.toString(),
6156
6213
  fees: info.fees,
@@ -6201,6 +6258,8 @@ function hydrateArkInfo(snapshot) {
6201
6258
  signerPubkey: a.signerPubkey,
6202
6259
  unilateralExitDelay: BigInt(a.unilateralExitDelay),
6203
6260
  vtxoTreeExpiry: a.vtxoTreeExpiry !== void 0 ? BigInt(a.vtxoTreeExpiry) : void 0,
6261
+ maxTxWeight: a.maxTxWeight !== void 0 ? BigInt(a.maxTxWeight) : void 0,
6262
+ maxOpReturnOutputs: a.maxOpReturnOutputs !== void 0 ? BigInt(a.maxOpReturnOutputs) : void 0,
6204
6263
  utxoMaxAmount: BigInt(a.utxoMaxAmount),
6205
6264
  utxoMinAmount: BigInt(a.utxoMinAmount),
6206
6265
  version: a.version,
@@ -6273,8 +6332,10 @@ function parseStoredArkInfoSnapshot(raw) {
6273
6332
  ]) {
6274
6333
  assertDecimalString(a[field], `arkInfo.${field}`);
6275
6334
  }
6276
- if (a.vtxoTreeExpiry !== void 0) {
6277
- assertDecimalString(a.vtxoTreeExpiry, "arkInfo.vtxoTreeExpiry");
6335
+ for (const field of ["vtxoTreeExpiry", "maxTxWeight", "maxOpReturnOutputs"]) {
6336
+ if (a[field] !== void 0) {
6337
+ assertDecimalString(a[field], `arkInfo.${field}`);
6338
+ }
6278
6339
  }
6279
6340
  assertFeeInfo(a.fees, "arkInfo.fees");
6280
6341
  if (!Array.isArray(a.deprecatedSigners)) {
@@ -6323,10 +6384,10 @@ async function resolveArkInfo(arkProvider, walletRepository) {
6323
6384
  try {
6324
6385
  info = await arkProvider.getInfo();
6325
6386
  } catch (err) {
6326
- if (!chunkG552MISJ_cjs.isRetryableProviderError(err)) throw err;
6387
+ if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
6327
6388
  const snapshot = await loadArkInfoSnapshot(walletRepository);
6328
6389
  if (!snapshot) {
6329
- throw new chunkG552MISJ_cjs.ProviderUnavailableError(
6390
+ throw new chunk2JV4VQ7C_cjs.ProviderUnavailableError(
6330
6391
  "Arkade server info is unavailable and no cached snapshot exists",
6331
6392
  { cause: err }
6332
6393
  );
@@ -6709,7 +6770,7 @@ function collectArkTxidsNeedingCreatedAt(vtxos) {
6709
6770
  return [...txids];
6710
6771
  }
6711
6772
  async function buildTransactionHistory(vtxos, allBoardingTxs, commitmentsToIgnore, resolveTxCreatedAt) {
6712
- const fromOldestVtxo = vtxos.map(chunkG552MISJ_cjs.normalizeVtxo).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
6773
+ const fromOldestVtxo = vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
6713
6774
  const txidsNeedingCreatedAt = resolveTxCreatedAt ? collectArkTxidsNeedingCreatedAt(fromOldestVtxo) : [];
6714
6775
  const resolvedCreatedAt = resolveTxCreatedAt && txidsNeedingCreatedAt.length > 0 ? await resolveTxCreatedAt(txidsNeedingCreatedAt) : /* @__PURE__ */ new Map();
6715
6776
  const unmatchedSettledBoardingTxs = allBoardingTxs.filter(isSettledBoardingReceive).sort((a, b) => a.createdAt - b.createdAt);
@@ -6873,7 +6934,7 @@ var AssetManager = class extends ReadonlyAssetManager {
6873
6934
  const virtualCoins = await this.wallet.getSpendableVtxos({
6874
6935
  withRecoverable: false
6875
6936
  });
6876
- const controlAssetRef = params.controlAssetId ? chunkXN55B6EP_cjs.AssetRef.fromId(chunkXN55B6EP_cjs.AssetId.fromString(params.controlAssetId)) : null;
6937
+ const controlAssetRef = params.controlAssetId ? chunkCO3KKSWM_cjs.AssetRef.fromId(chunkCO3KKSWM_cjs.AssetId.fromString(params.controlAssetId)) : null;
6877
6938
  const coinSelection = selectVirtualCoins(virtualCoins, Number(this.wallet.dustAmount));
6878
6939
  let totalBtcSelected = 0n;
6879
6940
  const assetChanges = /* @__PURE__ */ new Map();
@@ -6886,8 +6947,8 @@ var AssetManager = class extends ReadonlyAssetManager {
6886
6947
  }
6887
6948
  }
6888
6949
  const groups = [];
6889
- const issuedAssetOutput = chunkXN55B6EP_cjs.AssetOutput.create(0, params.amount);
6890
- const issuedAssetGroup = chunkXN55B6EP_cjs.AssetGroup.create(
6950
+ const issuedAssetOutput = chunkCO3KKSWM_cjs.AssetOutput.create(0, params.amount);
6951
+ const issuedAssetGroup = chunkCO3KKSWM_cjs.AssetGroup.create(
6891
6952
  null,
6892
6953
  controlAssetRef,
6893
6954
  [],
@@ -6902,28 +6963,28 @@ var AssetManager = class extends ReadonlyAssetManager {
6902
6963
  for (const [inputIndex, assets] of assetInputs) {
6903
6964
  for (const asset of assets) {
6904
6965
  if (asset.assetId !== assetId) continue;
6905
- changeInputs.push(chunkXN55B6EP_cjs.AssetInput.create(inputIndex, asset.amount));
6966
+ changeInputs.push(chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount));
6906
6967
  }
6907
6968
  }
6908
6969
  groups.push(
6909
- chunkXN55B6EP_cjs.AssetGroup.create(
6910
- chunkXN55B6EP_cjs.AssetId.fromString(assetId),
6970
+ chunkCO3KKSWM_cjs.AssetGroup.create(
6971
+ chunkCO3KKSWM_cjs.AssetId.fromString(assetId),
6911
6972
  null,
6912
6973
  changeInputs,
6913
- [chunkXN55B6EP_cjs.AssetOutput.create(0, amount)],
6974
+ [chunkCO3KKSWM_cjs.AssetOutput.create(0, amount)],
6914
6975
  []
6915
6976
  )
6916
6977
  );
6917
6978
  }
6918
6979
  }
6919
6980
  const address = await this.wallet.getAddress();
6920
- const outputAddress = chunkG552MISJ_cjs.ArkAddress.decode(address);
6981
+ const outputAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
6921
6982
  const outputs = [
6922
6983
  {
6923
6984
  script: outputAddress.pkScript,
6924
6985
  amount: BigInt(totalBtcSelected)
6925
6986
  },
6926
- Extension.create([chunkXN55B6EP_cjs.Packet.create(groups)]).txOut()
6987
+ Extension.create([chunkCO3KKSWM_cjs.Packet.create(groups)]).txOut()
6927
6988
  ];
6928
6989
  const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(
6929
6990
  coinSelection.inputs,
@@ -6931,7 +6992,7 @@ var AssetManager = class extends ReadonlyAssetManager {
6931
6992
  );
6932
6993
  return {
6933
6994
  arkTxId: arkTxid,
6934
- assetId: chunkXN55B6EP_cjs.AssetId.create(arkTxid, 0).toString()
6995
+ assetId: chunkCO3KKSWM_cjs.AssetId.create(arkTxid, 0).toString()
6935
6996
  };
6936
6997
  }
6937
6998
  /**
@@ -7003,16 +7064,16 @@ var AssetManager = class extends ReadonlyAssetManager {
7003
7064
  for (const [inputIndex, assets] of assetInputs) {
7004
7065
  for (const asset of assets) {
7005
7066
  if (asset.assetId !== params.assetId) continue;
7006
- reissueInputs.push(chunkXN55B6EP_cjs.AssetInput.create(inputIndex, asset.amount));
7067
+ reissueInputs.push(chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount));
7007
7068
  }
7008
7069
  }
7009
7070
  const totalAssetAmount = assetToReissueAmount + params.amount;
7010
- const reissueAssetIdObj = chunkXN55B6EP_cjs.AssetId.fromString(params.assetId);
7011
- const reissueAssetGroup = chunkXN55B6EP_cjs.AssetGroup.create(
7071
+ const reissueAssetIdObj = chunkCO3KKSWM_cjs.AssetId.fromString(params.assetId);
7072
+ const reissueAssetGroup = chunkCO3KKSWM_cjs.AssetGroup.create(
7012
7073
  reissueAssetIdObj,
7013
7074
  null,
7014
7075
  reissueInputs,
7015
- [chunkXN55B6EP_cjs.AssetOutput.create(0, totalAssetAmount)],
7076
+ [chunkCO3KKSWM_cjs.AssetOutput.create(0, totalAssetAmount)],
7016
7077
  []
7017
7078
  );
7018
7079
  const groups = [reissueAssetGroup];
@@ -7021,27 +7082,27 @@ var AssetManager = class extends ReadonlyAssetManager {
7021
7082
  for (const [inputIndex, assets] of assetInputs) {
7022
7083
  for (const asset of assets) {
7023
7084
  if (asset.assetId !== assetId) continue;
7024
- changeInputs.push(chunkXN55B6EP_cjs.AssetInput.create(inputIndex, asset.amount));
7085
+ changeInputs.push(chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount));
7025
7086
  }
7026
7087
  }
7027
7088
  groups.push(
7028
- chunkXN55B6EP_cjs.AssetGroup.create(
7029
- chunkXN55B6EP_cjs.AssetId.fromString(assetId),
7089
+ chunkCO3KKSWM_cjs.AssetGroup.create(
7090
+ chunkCO3KKSWM_cjs.AssetId.fromString(assetId),
7030
7091
  null,
7031
7092
  changeInputs,
7032
- [chunkXN55B6EP_cjs.AssetOutput.create(0, amount)],
7093
+ [chunkCO3KKSWM_cjs.AssetOutput.create(0, amount)],
7033
7094
  []
7034
7095
  )
7035
7096
  );
7036
7097
  }
7037
7098
  const address = await this.wallet.getAddress();
7038
- const outputAddress = chunkG552MISJ_cjs.ArkAddress.decode(address);
7099
+ const outputAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
7039
7100
  const outputs = [
7040
7101
  {
7041
7102
  script: outputAddress.pkScript,
7042
7103
  amount: BigInt(totalBtcSelected)
7043
7104
  },
7044
- Extension.create([chunkXN55B6EP_cjs.Packet.create(groups)]).txOut()
7105
+ Extension.create([chunkCO3KKSWM_cjs.Packet.create(groups)]).txOut()
7045
7106
  ];
7046
7107
  const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
7047
7108
  return arkTxid;
@@ -7108,27 +7169,27 @@ var AssetManager = class extends ReadonlyAssetManager {
7108
7169
  for (const [inputIndex, assets] of assetInputs) {
7109
7170
  for (const asset of assets) {
7110
7171
  if (asset.assetId !== assetId) continue;
7111
- changeInputs.push(chunkXN55B6EP_cjs.AssetInput.create(inputIndex, asset.amount));
7172
+ changeInputs.push(chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount));
7112
7173
  }
7113
7174
  }
7114
7175
  groups.push(
7115
- chunkXN55B6EP_cjs.AssetGroup.create(
7116
- chunkXN55B6EP_cjs.AssetId.fromString(assetId),
7176
+ chunkCO3KKSWM_cjs.AssetGroup.create(
7177
+ chunkCO3KKSWM_cjs.AssetId.fromString(assetId),
7117
7178
  null,
7118
7179
  changeInputs,
7119
- amount > 0n ? [chunkXN55B6EP_cjs.AssetOutput.create(0, amount)] : [],
7180
+ amount > 0n ? [chunkCO3KKSWM_cjs.AssetOutput.create(0, amount)] : [],
7120
7181
  []
7121
7182
  )
7122
7183
  );
7123
7184
  }
7124
7185
  const address = await this.wallet.getAddress();
7125
- const outputAddress = chunkG552MISJ_cjs.ArkAddress.decode(address);
7186
+ const outputAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
7126
7187
  const outputs = [
7127
7188
  {
7128
7189
  script: outputAddress.pkScript,
7129
7190
  amount: BigInt(totalBtcSelected)
7130
7191
  },
7131
- Extension.create([chunkXN55B6EP_cjs.Packet.create(groups)]).txOut()
7192
+ Extension.create([chunkCO3KKSWM_cjs.Packet.create(groups)]).txOut()
7132
7193
  ];
7133
7194
  const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
7134
7195
  return arkTxid;
@@ -7153,7 +7214,7 @@ function castMetadata(metadata) {
7153
7214
  } else {
7154
7215
  throw new Error("Invalid metadata value type");
7155
7216
  }
7156
- md.push(chunkXN55B6EP_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
7217
+ md.push(chunkCO3KKSWM_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
7157
7218
  }
7158
7219
  return md;
7159
7220
  }
@@ -7174,10 +7235,10 @@ var DelegateManagerImpl = class {
7174
7235
  if (vtxos.length === 0) {
7175
7236
  return { delegated: [], failed: [] };
7176
7237
  }
7177
- const destinationScript = chunkG552MISJ_cjs.ArkAddress.decode(destination).pkScript;
7238
+ const destinationScript = chunk2JV4VQ7C_cjs.ArkAddress.decode(destination).pkScript;
7178
7239
  const arkInfo = await this.arkInfoProvider.getInfo();
7179
7240
  const delegateInfo = await this.delegateProvider.getDelegateInfo();
7180
- const eligible = vtxos.map(chunkG552MISJ_cjs.normalizeVtxo).filter(
7241
+ const eligible = vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo).filter(
7181
7242
  (v) => isAnnotated(v) && findDelegateTapLeaf(v, delegateInfo.pubkey) !== void 0
7182
7243
  );
7183
7244
  if (eligible.length === 0) {
@@ -7206,11 +7267,11 @@ var DelegateManagerImpl = class {
7206
7267
  const groupByExpiry = /* @__PURE__ */ new Map();
7207
7268
  let recoverableVtxos = [];
7208
7269
  for (const vtxo of eligible) {
7209
- if (chunkG552MISJ_cjs.canRecoverOnchain(vtxo, now)) {
7270
+ if (chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now)) {
7210
7271
  recoverableVtxos.push(vtxo);
7211
7272
  continue;
7212
7273
  }
7213
- const expiry = chunkG552MISJ_cjs.toBatchExpiry(vtxo);
7274
+ const expiry = chunk2JV4VQ7C_cjs.toBatchExpiry(vtxo);
7214
7275
  if (!expiry) continue;
7215
7276
  const dayKey = getDayTimestamp(expiry);
7216
7277
  groupByExpiry.set(dayKey, [...groupByExpiry.get(dayKey) ?? [], vtxo]);
@@ -7275,7 +7336,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7275
7336
  }
7276
7337
  if (!delegateAt) {
7277
7338
  const now = { timestamp: /* @__PURE__ */ new Date() };
7278
- const expiryTimestamp = vtxos.filter((coin) => !chunkG552MISJ_cjs.canRecoverOnchain(coin, now) && chunkG552MISJ_cjs.toBatchExpiry(coin)).reduce((min, coin) => Math.min(min, chunkG552MISJ_cjs.toBatchExpiry(coin)), Number.MAX_SAFE_INTEGER);
7339
+ const expiryTimestamp = vtxos.filter((coin) => !chunk2JV4VQ7C_cjs.canRecoverOnchain(coin, now) && chunk2JV4VQ7C_cjs.toBatchExpiry(coin)).reduce((min, coin) => Math.min(min, chunk2JV4VQ7C_cjs.toBatchExpiry(coin)), Number.MAX_SAFE_INTEGER);
7279
7340
  if (!expiryTimestamp || expiryTimestamp === Number.MAX_SAFE_INTEGER) {
7280
7341
  delegateAt = new Date(Date.now() + 1 * 60 * 1e3);
7281
7342
  } else {
@@ -7304,7 +7365,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7304
7365
  let amount = 0n;
7305
7366
  for (const coin of vtxos) {
7306
7367
  const inputFee = estimator.evalOffchainInput({
7307
- ...chunkG552MISJ_cjs.toOffchainInputFeeParams(coin),
7368
+ ...chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(coin),
7308
7369
  type: "vtxo"
7309
7370
  });
7310
7371
  if (inputFee.value >= coin.value) {
@@ -7318,7 +7379,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7318
7379
  const delegateFee = BigInt(Number(fee));
7319
7380
  if (delegateFee > 0n) {
7320
7381
  outputs.push({
7321
- script: chunkG552MISJ_cjs.ArkAddress.decode(delegateAddress).pkScript,
7382
+ script: chunk2JV4VQ7C_cjs.ArkAddress.decode(delegateAddress).pkScript,
7322
7383
  amount: delegateFee
7323
7384
  });
7324
7385
  }
@@ -7351,10 +7412,10 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
7351
7412
  destinationScript
7352
7413
  );
7353
7414
  const forfeitOutputScript = btcSigner.OutScript.encode(
7354
- btcSigner.Address(chunkG552MISJ_cjs.getNetwork(network)).decode(forfeitAddress)
7415
+ btcSigner.Address(chunk2JV4VQ7C_cjs.getNetwork(network)).decode(forfeitAddress)
7355
7416
  );
7356
7417
  const forfeits = await Promise.all(
7357
- vtxos.filter((v) => !chunkG552MISJ_cjs.canRecoverOnchain(v, { timestamp: /* @__PURE__ */ new Date() })).map(async (coin) => {
7418
+ vtxos.filter((v) => !chunk2JV4VQ7C_cjs.canRecoverOnchain(v, { timestamp: /* @__PURE__ */ new Date() })).map(async (coin) => {
7358
7419
  const forfeit = await makeDelegateForfeitTx(
7359
7420
  coin,
7360
7421
  dust,
@@ -7379,7 +7440,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
7379
7440
  index: input.vout,
7380
7441
  witnessUtxo: {
7381
7442
  amount: BigInt(input.value),
7382
- script: chunkG552MISJ_cjs.VtxoScript.decode(input.tapTree).pkScript
7443
+ script: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
7383
7444
  },
7384
7445
  sighashType: btcSigner.SigHash.ALL_ANYONECANPAY,
7385
7446
  tapLeafScript: [delegateTapLeaf]
@@ -7437,7 +7498,7 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
7437
7498
  expire_at: 0,
7438
7499
  cosigners_public_keys: cosignerPubKeys
7439
7500
  };
7440
- const proof = chunkG552MISJ_cjs.Intent.create(message, coins, outputs);
7501
+ const proof = chunk2JV4VQ7C_cjs.Intent.create(message, coins, outputs);
7441
7502
  const signedProof = await identity.sign(proof);
7442
7503
  return {
7443
7504
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -7455,10 +7516,10 @@ function getDayTimestamp(timestamp) {
7455
7516
  function findDelegateTapLeaf(vtxo, delegatePubkey) {
7456
7517
  if (!vtxo.tapTree) return void 0;
7457
7518
  const pk = delegatePubkey.length === 66 ? delegatePubkey.slice(2) : delegatePubkey;
7458
- const vtxoScript = chunkG552MISJ_cjs.VtxoScript.decode(vtxo.tapTree);
7519
+ const vtxoScript = chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree);
7459
7520
  return vtxoScript.leaves.find((tapLeaf) => {
7460
- const arkTapscript = chunkG552MISJ_cjs.decodeTapscript(chunkG552MISJ_cjs.scriptFromTapLeafScript(tapLeaf));
7461
- if (!chunkG552MISJ_cjs.MultisigTapscript.is(arkTapscript)) return false;
7521
+ const arkTapscript = chunk2JV4VQ7C_cjs.decodeTapscript(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(tapLeaf));
7522
+ if (!chunk2JV4VQ7C_cjs.MultisigTapscript.is(arkTapscript)) return false;
7462
7523
  return arkTapscript.params.pubkeys.map(base.hex.encode).includes(pk);
7463
7524
  });
7464
7525
  }
@@ -7739,7 +7800,7 @@ function createManagedConnection(dbName, version, initDatabase2) {
7739
7800
  };
7740
7801
  }
7741
7802
  function scriptFromArkAddress(address) {
7742
- return base.hex.encode(chunkG552MISJ_cjs.ArkAddress.decode(address).pkScript);
7803
+ return base.hex.encode(chunk2JV4VQ7C_cjs.ArkAddress.decode(address).pkScript);
7743
7804
  }
7744
7805
 
7745
7806
  // src/repositories/indexedDB/schema.ts
@@ -8234,7 +8295,7 @@ function validateVtxosForScript(vtxos, script, context) {
8234
8295
  }
8235
8296
  async function getVtxosForContract(repo, contract) {
8236
8297
  const vtxos = repo.getVtxosForScript ? await repo.getVtxosForScript(contract.script) : filterVtxosForScript(await repo.getVtxos(contract.address), contract.script);
8237
- return vtxos.map(chunkG552MISJ_cjs.normalizeVtxo);
8298
+ return vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
8238
8299
  }
8239
8300
  async function saveVtxosForContract(repo, contract, vtxos) {
8240
8301
  if (repo.saveVtxosForScript) {
@@ -8376,7 +8437,7 @@ function decodeArkContract(encoded) {
8376
8437
  }
8377
8438
  function contractFromArkContract(encoded, options = {}) {
8378
8439
  const parsed = decodeArkContract(encoded);
8379
- const handler = chunkBABJ77NG_cjs.contractHandlers.get(parsed.type);
8440
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(parsed.type);
8380
8441
  if (!handler) {
8381
8442
  throw new Error(`No handler registered for contract type '${parsed.type}'`);
8382
8443
  }
@@ -8390,9 +8451,9 @@ function contractFromArkContract(encoded, options = {}) {
8390
8451
  metadata: options.metadata
8391
8452
  };
8392
8453
  }
8393
- function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunkG552MISJ_cjs.DEFAULT_NETWORK.hrp, options = {}) {
8454
+ function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunk2JV4VQ7C_cjs.DEFAULT_NETWORK.hrp, options = {}) {
8394
8455
  const parsed = decodeArkContract(encoded);
8395
- const handler = chunkBABJ77NG_cjs.contractHandlers.getOrThrow(parsed.type);
8456
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.getOrThrow(parsed.type);
8396
8457
  const params = parsed.data;
8397
8458
  const vtxoScript = handler.createScript(params);
8398
8459
  return {
@@ -8646,9 +8707,9 @@ var ContractWatcher = class {
8646
8707
  this.connectionState = "connected";
8647
8708
  this.reconnectAttempts = 0;
8648
8709
  this.listenLoop().catch((e) => {
8649
- if (chunkG552MISJ_cjs.isEventSourceError(e)) {
8710
+ if (chunk2JV4VQ7C_cjs.isEventSourceError(e)) {
8650
8711
  console.debug("ContractWatcher subscription disconnected; reconnecting");
8651
- } else if (!chunkG552MISJ_cjs.isEventSourceUnavailableError(e)) {
8712
+ } else if (!chunk2JV4VQ7C_cjs.isEventSourceUnavailableError(e)) {
8652
8713
  console.error(e);
8653
8714
  }
8654
8715
  this.connectionState = "disconnected";
@@ -8660,7 +8721,7 @@ var ContractWatcher = class {
8660
8721
  this.scheduleReconnect();
8661
8722
  });
8662
8723
  } catch (error) {
8663
- if (!chunkG552MISJ_cjs.isEventSourceUnavailableError(error)) {
8724
+ if (!chunk2JV4VQ7C_cjs.isEventSourceUnavailableError(error)) {
8664
8725
  console.error("ContractWatcher connection failed:", error);
8665
8726
  }
8666
8727
  this.connectionState = "disconnected";
@@ -8686,7 +8747,7 @@ var ContractWatcher = class {
8686
8747
  * slower; what it loses is push latency.
8687
8748
  */
8688
8749
  reportEventSourceUnavailable(error) {
8689
- if (!chunkG552MISJ_cjs.isEventSourceUnavailableError(error)) return false;
8750
+ if (!chunk2JV4VQ7C_cjs.isEventSourceUnavailableError(error)) return false;
8690
8751
  if (!this.eventSourceReported) {
8691
8752
  this.eventSourceReported = true;
8692
8753
  console.warn(
@@ -8902,14 +8963,14 @@ var ContractWatcher = class {
8902
8963
  const timestamp = Date.now();
8903
8964
  if (update.newVtxos?.length) {
8904
8965
  this.processSubscriptionVtxos(
8905
- update.newVtxos.map(chunkG552MISJ_cjs.normalizeVtxo),
8966
+ update.newVtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo),
8906
8967
  "vtxo_received",
8907
8968
  timestamp
8908
8969
  );
8909
8970
  }
8910
8971
  if (update.spentVtxos?.length) {
8911
8972
  this.processSubscriptionVtxos(
8912
- update.spentVtxos.map(chunkG552MISJ_cjs.normalizeVtxo),
8973
+ update.spentVtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo),
8913
8974
  "vtxo_spent",
8914
8975
  timestamp
8915
8976
  );
@@ -9004,7 +9065,7 @@ var NON_TERMINAL_INTENT_STATES = ALL_INTENT_STATES.filter(
9004
9065
  (s) => !isTerminalIntentState(s)
9005
9066
  );
9006
9067
  function isConsumed(vtxo) {
9007
- return vtxo !== void 0 && (vtxo.isSpent === true || vtxo.settledBy !== void 0);
9068
+ return vtxo !== void 0 && chunk2JV4VQ7C_cjs.hasTerminalSpend(vtxo);
9008
9069
  }
9009
9070
  async function classifyIntent(intent, vtxosByOutpoint, now) {
9010
9071
  if (isTerminalIntentState(intent.state)) return void 0;
@@ -9014,6 +9075,11 @@ async function classifyIntent(intent, vtxosByOutpoint, now) {
9014
9075
  const commitmentTransactionId = intent.commitmentTransactionId ?? consumed.map((v) => v?.settledBy).find((s) => !!s);
9015
9076
  return terminal(intent, "batch_succeeded", now, { commitmentTransactionId });
9016
9077
  }
9078
+ if (consumed.some((vtxo) => vtxo?.isUnrolled)) {
9079
+ return terminal(intent, "cancelled", now, {
9080
+ cancellationReason: "reconciliation: an input was unilaterally exited"
9081
+ });
9082
+ }
9017
9083
  if (intent.state === "waiting_to_submit") {
9018
9084
  return terminal(intent, "cancelled", now, {
9019
9085
  cancellationReason: "reconciliation: intent was never submitted before restart"
@@ -9042,7 +9108,7 @@ async function reconcileIntents(deps) {
9042
9108
  let vtxosByOutpoint = /* @__PURE__ */ new Map();
9043
9109
  if (outpoints.length > 0) {
9044
9110
  try {
9045
- const { vtxos } = await chunkG552MISJ_cjs.getNormalizedVtxos(deps.indexerProvider, { outpoints });
9111
+ const { vtxos } = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(deps.indexerProvider, { outpoints });
9046
9112
  vtxosByOutpoint = new Map(vtxos.map((v) => [outpointKey(v), v]));
9047
9113
  } catch (e) {
9048
9114
  console.error("reconcileIntents: failed to fetch input VTXO state", e);
@@ -9216,7 +9282,7 @@ var ContractManager = class _ContractManager {
9216
9282
  await this.reconcileWatched();
9217
9283
  this.markSyncOnline();
9218
9284
  } catch (err) {
9219
- if (!chunkG552MISJ_cjs.isRetryableProviderError(err)) throw err;
9285
+ if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
9220
9286
  this.markSyncDegraded(err);
9221
9287
  }
9222
9288
  this.initialized = true;
@@ -9348,7 +9414,7 @@ var ContractManager = class _ContractManager {
9348
9414
  const from = Math.max(0, watermark - lookAhead.size);
9349
9415
  const to = watermark + lookAhead.size;
9350
9416
  const deps = lookAhead.candidateDeps();
9351
- const handlers = chunkBABJ77NG_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkBABJ77NG_cjs.contractHandlers.get(t)).filter(hasCandidates);
9417
+ const handlers = chunkOIZ2V2VD_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkOIZ2V2VD_cjs.contractHandlers.get(t)).filter(hasCandidates);
9352
9418
  const band = /* @__PURE__ */ new Map();
9353
9419
  for (let index = from; index <= to; index++) {
9354
9420
  const descriptor = lookAhead.materialize(index);
@@ -9359,7 +9425,7 @@ var ContractManager = class _ContractManager {
9359
9425
  index,
9360
9426
  params: {
9361
9427
  ...candidate,
9362
- ...chunkBABJ77NG_cjs.speculativeReceiveMetadata(descriptor)
9428
+ ...chunkOIZ2V2VD_cjs.speculativeReceiveMetadata(descriptor)
9363
9429
  }
9364
9430
  });
9365
9431
  }
@@ -9421,7 +9487,7 @@ var ContractManager = class _ContractManager {
9421
9487
  });
9422
9488
  for (const entry of pending) entry.catchUpPending = false;
9423
9489
  } catch (err) {
9424
- if (!chunkG552MISJ_cjs.isRetryableProviderError(err)) throw err;
9490
+ if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
9425
9491
  this.markSyncDegraded(err);
9426
9492
  }
9427
9493
  }
@@ -9471,7 +9537,7 @@ var ContractManager = class _ContractManager {
9471
9537
  await this.fetchContractVxosFromIndexer([contract]);
9472
9538
  this.markSyncOnline();
9473
9539
  } catch (err) {
9474
- if (!chunkG552MISJ_cjs.isRetryableProviderError(err)) throw err;
9540
+ if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
9475
9541
  this.markSyncDegraded(err);
9476
9542
  }
9477
9543
  await this.watcher.addContract(contract);
@@ -9508,7 +9574,7 @@ var ContractManager = class _ContractManager {
9508
9574
  return result;
9509
9575
  }
9510
9576
  async upsertContractRow(params) {
9511
- const handler = chunkBABJ77NG_cjs.contractHandlers.get(params.type);
9577
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(params.type);
9512
9578
  if (!handler) {
9513
9579
  throw new Error(`No handler registered for contract type '${params.type}'`);
9514
9580
  }
@@ -9608,7 +9674,7 @@ var ContractManager = class _ContractManager {
9608
9674
  `scanContracts: batchSize must be a positive integer (got ${String(opts.batchSize)})`
9609
9675
  );
9610
9676
  }
9611
- const registered = chunkBABJ77NG_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkBABJ77NG_cjs.contractHandlers.get(t)).filter(isDiscoverable);
9677
+ const registered = chunkOIZ2V2VD_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkOIZ2V2VD_cjs.contractHandlers.get(t)).filter(isDiscoverable);
9612
9678
  const discoverables = [
9613
9679
  ...registered.filter((h) => h.type === "boarding"),
9614
9680
  ...registered.filter((h) => h.type !== "boarding")
@@ -9743,7 +9809,7 @@ var ContractManager = class _ContractManager {
9743
9809
  await this.syncContracts({ contracts, pageSize });
9744
9810
  this.markSyncOnline();
9745
9811
  } catch (err) {
9746
- if (!chunkG552MISJ_cjs.isRetryableProviderError(err)) throw err;
9812
+ if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
9747
9813
  this.markSyncDegraded(err);
9748
9814
  }
9749
9815
  const vtxos = await this.getVtxosForContracts(contracts);
@@ -9764,7 +9830,7 @@ var ContractManager = class _ContractManager {
9764
9830
  }
9765
9831
  const tapscriptCache = tapscripts ?? /* @__PURE__ */ new Map();
9766
9832
  return vtxos.map(
9767
- (vtxo) => extendVirtualCoinForContract(chunkG552MISJ_cjs.normalizeVtxo(vtxo), byScript, tapscriptCache)
9833
+ (vtxo) => extendVirtualCoinForContract(chunk2JV4VQ7C_cjs.normalizeVtxo(vtxo), byScript, tapscriptCache)
9768
9834
  );
9769
9835
  }
9770
9836
  /** @inheritdoc */
@@ -9808,14 +9874,14 @@ var ContractManager = class _ContractManager {
9808
9874
  const byScript = new Map(contracts.map((contract) => [contract.script, contract]));
9809
9875
  const asking = vtxos.filter((vtxo) => {
9810
9876
  const contract = byScript.get(vtxo.script);
9811
- return contract !== void 0 && chunkBABJ77NG_cjs.contractHandlers.get(contract.type)?.assertSpendableNow !== void 0;
9877
+ return contract !== void 0 && chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type)?.assertSpendableNow !== void 0;
9812
9878
  });
9813
9879
  if (asking.length === 0) return refused;
9814
9880
  const tip = await this.currentChainTip();
9815
9881
  const walletKey = await walletPubKey?.();
9816
9882
  for (const vtxo of asking) {
9817
9883
  const contract = byScript.get(vtxo.script);
9818
- const handler = chunkBABJ77NG_cjs.contractHandlers.get(contract.type);
9884
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
9819
9885
  if (!handler?.assertSpendableNow) continue;
9820
9886
  const context = {
9821
9887
  collaborative: true,
@@ -9830,7 +9896,7 @@ var ContractManager = class _ContractManager {
9830
9896
  // the next handler to answer a CSV question would meet a
9831
9897
  // TypeError instead of a `false`. Carry the coin only when it
9832
9898
  // really is one.
9833
- vtxo: chunkG552MISJ_cjs.isVirtualCoin(vtxo) && "status" in vtxo ? vtxo : void 0
9899
+ vtxo: chunk2JV4VQ7C_cjs.isVirtualCoin(vtxo) && "status" in vtxo ? vtxo : void 0
9834
9900
  };
9835
9901
  try {
9836
9902
  await handler.assertSpendableNow(
@@ -9986,7 +10052,7 @@ var ContractManager = class _ContractManager {
9986
10052
  const { contractScript, collaborative = true, walletPubKey, vtxo } = options;
9987
10053
  const [contract] = await this.getContracts({ script: contractScript });
9988
10054
  if (!contract) return [];
9989
- const handler = chunkBABJ77NG_cjs.contractHandlers.get(contract.type);
10055
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
9990
10056
  if (!handler) return [];
9991
10057
  const script = handler.createScript(contract.params);
9992
10058
  const tip = await this.currentChainTip();
@@ -10014,7 +10080,7 @@ var ContractManager = class _ContractManager {
10014
10080
  const { contractScript, collaborative = true, walletPubKey } = options;
10015
10081
  const [contract] = await this.getContracts({ script: contractScript });
10016
10082
  if (!contract) return [];
10017
- const handler = chunkBABJ77NG_cjs.contractHandlers.get(contract.type);
10083
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
10018
10084
  if (!handler) return [];
10019
10085
  const script = handler.createScript(contract.params);
10020
10086
  const context = {
@@ -10070,7 +10136,7 @@ var ContractManager = class _ContractManager {
10070
10136
  }
10071
10137
  async refreshOutpoints(outpoints) {
10072
10138
  if (outpoints.length === 0) return;
10073
- const { vtxos } = await chunkG552MISJ_cjs.getNormalizedVtxos(this.config.indexerProvider, {
10139
+ const { vtxos } = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(this.config.indexerProvider, {
10074
10140
  outpoints
10075
10141
  });
10076
10142
  if (vtxos.length === 0) return;
@@ -10149,7 +10215,7 @@ var ContractManager = class _ContractManager {
10149
10215
  break;
10150
10216
  }
10151
10217
  } catch (err) {
10152
- if (!chunkG552MISJ_cjs.isRetryableProviderError(err)) throw err;
10218
+ if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
10153
10219
  this.markSyncDegraded(err);
10154
10220
  }
10155
10221
  this.emitEvent(event);
@@ -10228,7 +10294,7 @@ var ContractManager = class _ContractManager {
10228
10294
  */
10229
10295
  async reconcilePendingFrontier(contracts) {
10230
10296
  const scriptToContract = new Map(contracts.map((c) => [c.script, c]));
10231
- const vtxos = await chunkG552MISJ_cjs.getAllNormalizedVtxos(
10297
+ const vtxos = await chunk2JV4VQ7C_cjs.getAllNormalizedVtxos(
10232
10298
  this.config.indexerProvider,
10233
10299
  contracts.map((c) => c.script),
10234
10300
  { pendingOnly: true }
@@ -10311,7 +10377,7 @@ var ContractManager = class _ContractManager {
10311
10377
  }
10312
10378
  return result;
10313
10379
  }
10314
- async fetchContractVtxosBulk(contracts, pageSize = chunkG552MISJ_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
10380
+ async fetchContractVtxosBulk(contracts, pageSize = chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
10315
10381
  if (contracts.length === 0) {
10316
10382
  return { vtxosByScript: /* @__PURE__ */ new Map(), promoted: /* @__PURE__ */ new Map() };
10317
10383
  }
@@ -10327,7 +10393,7 @@ var ContractManager = class _ContractManager {
10327
10393
  before: syncWindow.before
10328
10394
  }
10329
10395
  } : {};
10330
- const vtxos = await chunkG552MISJ_cjs.getAllNormalizedVtxos(
10396
+ const vtxos = await chunk2JV4VQ7C_cjs.getAllNormalizedVtxos(
10331
10397
  this.config.indexerProvider,
10332
10398
  contracts.map((c) => c.script),
10333
10399
  { ...windowOpts, pageSize }
@@ -10472,7 +10538,7 @@ var deserializeTapLeaf = (t) => {
10472
10538
  const s = base.hex.decode(t.s);
10473
10539
  return [cb, s];
10474
10540
  };
10475
- var deserializeVtxo = (o) => chunkG552MISJ_cjs.normalizeVtxo({
10541
+ var deserializeVtxo = (o) => chunk2JV4VQ7C_cjs.normalizeVtxo({
10476
10542
  ...o,
10477
10543
  createdAt: new Date(o.createdAt),
10478
10544
  tapTree: base.hex.decode(o.tapTree),
@@ -11295,7 +11361,7 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
11295
11361
  */
11296
11362
  materializeDescriptorAt(index) {
11297
11363
  const descriptor = this.identity.descriptor;
11298
- const network = chunkBABJ77NG_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
11364
+ const network = chunkOIZ2V2VD_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
11299
11365
  const expansion = descriptorsScure.expand({ descriptor, network, index });
11300
11366
  const keyInfo = expansion.expansionMap?.["@0"];
11301
11367
  if (!keyInfo?.keyExpression) {
@@ -11443,7 +11509,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
11443
11509
  const provider = await resolveDescriptorProvider(config, setup.walletRepository);
11444
11510
  if (!provider) return void 0;
11445
11511
  const allowSilentFallback = (config.walletMode ?? "auto") === "auto";
11446
- const expectedContractType = setup.offchainTapscript instanceof chunkBABJ77NG_cjs.DelegateVtxo.Script ? "delegate" : "default";
11512
+ const expectedContractType = setup.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? "delegate" : "default";
11447
11513
  const factoryOpts = {
11448
11514
  walletRepository: setup.walletRepository,
11449
11515
  contractRepository: setup.contractRepository,
@@ -11623,7 +11689,9 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
11623
11689
  const { tapscript: newTapscript, params } = buildReceiveContract(
11624
11690
  wallet.offchainTapscript,
11625
11691
  descriptor,
11626
- wallet.network.hrp);
11692
+ wallet.network.hrp,
11693
+ true
11694
+ );
11627
11695
  const newScript = params.script;
11628
11696
  const manager = await wallet.getContractManager();
11629
11697
  await manager.createContract(params);
@@ -11642,7 +11710,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
11642
11710
  };
11643
11711
  function deriveLeafPubkey(descriptor) {
11644
11712
  try {
11645
- return chunkBABJ77NG_cjs.deriveDescriptorLeafPubKey(descriptor);
11713
+ return chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(descriptor);
11646
11714
  } catch (e) {
11647
11715
  throw new NonRangeableDescriptorError(
11648
11716
  "Cannot derive leaf pubkey: descriptor is not a materialized, parsable tr(...) shape.",
@@ -11654,7 +11722,7 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
11654
11722
  const pubKey = deriveLeafPubkey(descriptor);
11655
11723
  const tapscript = rebuildTapscript(current, pubKey);
11656
11724
  const serverPubKey = tapscript.options.serverPubKey;
11657
- const csvTimelock = chunkG552MISJ_cjs.timelockToSequence(tapscript.options.csvTimelock).toString();
11725
+ const csvTimelock = chunk2JV4VQ7C_cjs.timelockToSequence(tapscript.options.csvTimelock).toString();
11658
11726
  const base$1 = {
11659
11727
  script: base.hex.encode(tapscript.pkScript),
11660
11728
  address: tapscript.address(hrp, serverPubKey).encode(),
@@ -11665,11 +11733,11 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
11665
11733
  // index-0 key. Without it, spends produce unsigned PSBTs that the
11666
11734
  // server rejects with `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
11667
11735
  metadata: {
11668
- ...{ source: chunkBABJ77NG_cjs.WALLET_RECEIVE_SOURCE },
11736
+ ...tagSource && { source: chunkOIZ2V2VD_cjs.WALLET_RECEIVE_SOURCE },
11669
11737
  signingDescriptor: descriptor
11670
11738
  }
11671
11739
  };
11672
- const params = tapscript instanceof chunkBABJ77NG_cjs.DelegateVtxo.Script ? {
11740
+ const params = tapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? {
11673
11741
  ...base$1,
11674
11742
  type: "delegate",
11675
11743
  params: {
@@ -11690,10 +11758,10 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
11690
11758
  return { tapscript, params };
11691
11759
  }
11692
11760
  function rebuildTapscript(current, pubKey) {
11693
- if (current instanceof chunkBABJ77NG_cjs.DelegateVtxo.Script) {
11694
- return new chunkBABJ77NG_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
11761
+ if (current instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script) {
11762
+ return new chunkOIZ2V2VD_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
11695
11763
  }
11696
- return new chunkBABJ77NG_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
11764
+ return new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
11697
11765
  }
11698
11766
  async function pickActiveReceive(contractRepository, serverPubKey, expectedType) {
11699
11767
  const candidates = await contractRepository.getContracts({
@@ -11702,7 +11770,7 @@ async function pickActiveReceive(contractRepository, serverPubKey, expectedType)
11702
11770
  });
11703
11771
  const serverPubKeyHex = base.hex.encode(serverPubKey);
11704
11772
  const matching = candidates.filter(
11705
- (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkBABJ77NG_cjs.WALLET_RECEIVE_SOURCE
11773
+ (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkOIZ2V2VD_cjs.WALLET_RECEIVE_SOURCE
11706
11774
  ).sort((a, b) => {
11707
11775
  if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
11708
11776
  return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
@@ -11749,6 +11817,7 @@ function computeOffchainBalance(vtxos, caps) {
11749
11817
  let intentLocked = 0;
11750
11818
  let recoverable = 0;
11751
11819
  let pendingRecovery = 0;
11820
+ let unrolled = 0;
11752
11821
  const owned = /* @__PURE__ */ new Map();
11753
11822
  const spendable = /* @__PURE__ */ new Map();
11754
11823
  const addAssets = (into, vtxo) => {
@@ -11757,17 +11826,21 @@ function computeOffchainBalance(vtxos, caps) {
11757
11826
  }
11758
11827
  };
11759
11828
  for (const vtxo of vtxos) {
11760
- if (chunkG552MISJ_cjs.hasTerminalSpend(vtxo)) continue;
11829
+ if (chunk2JV4VQ7C_cjs.hasTerminalSpend(vtxo)) continue;
11761
11830
  addAssets(owned, vtxo);
11831
+ if (vtxo.isUnrolled) {
11832
+ unrolled += vtxo.value;
11833
+ continue;
11834
+ }
11762
11835
  if (isPendingRecovery(vtxo)) {
11763
11836
  pendingRecovery += vtxo.value;
11764
11837
  continue;
11765
11838
  }
11766
- if (chunkG552MISJ_cjs.canRecoverOnchain(vtxo, now)) {
11839
+ if (chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now)) {
11767
11840
  recoverable += vtxo.value;
11768
11841
  continue;
11769
11842
  }
11770
- if (!chunkG552MISJ_cjs.canSpendOffchain(vtxo, now)) continue;
11843
+ if (!chunk2JV4VQ7C_cjs.canSpendOffchain(vtxo, now)) continue;
11771
11844
  if (vtxo.isPreconfirmed) {
11772
11845
  preconfirmed += vtxo.value;
11773
11846
  } else {
@@ -11791,7 +11864,8 @@ function computeOffchainBalance(vtxos, caps) {
11791
11864
  intentLocked,
11792
11865
  recoverable,
11793
11866
  pendingRecovery,
11794
- total: settled + preconfirmed + recoverable + pendingRecovery,
11867
+ unrolled,
11868
+ total: settled + preconfirmed + recoverable + pendingRecovery + unrolled,
11795
11869
  assets: toAssets(owned),
11796
11870
  availableAssets: toAssets(spendable)
11797
11871
  };
@@ -11936,12 +12010,12 @@ var InputSignerRouter = class {
11936
12010
  };
11937
12011
 
11938
12012
  // src/wallet/wallet.ts
11939
- var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl || chunkG552MISJ_cjs.DEFAULT_ARKADE_SERVER_URL;
12013
+ var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl || chunk2JV4VQ7C_cjs.DEFAULT_ARKADE_SERVER_URL;
11940
12014
  function intentProofJobs(coins) {
11941
12015
  if (coins.length === 0) return [];
11942
12016
  const coinJobs = coins.map((coin, i) => ({
11943
12017
  index: i + 1,
11944
- lookupScript: chunkG552MISJ_cjs.VtxoScript.decode(coin.tapTree).pkScript
12018
+ lookupScript: chunk2JV4VQ7C_cjs.VtxoScript.decode(coin.tapTree).pkScript
11945
12019
  }));
11946
12020
  return [{ index: 0, lookupScript: coinJobs[0].lookupScript }, ...coinJobs];
11947
12021
  }
@@ -11963,11 +12037,6 @@ function extractArkProviderUrl(provider) {
11963
12037
  var DEFAULT_LOOK_AHEAD_WINDOW = 20;
11964
12038
  var MAX_USED_SIGNING_DESCRIPTORS_LOOK_AHEAD = 1e3;
11965
12039
  var MAINNET_UNILATERAL_EXIT_DELAY = 605184n;
11966
- function toXOnlyPubKey(pubkey) {
11967
- if (pubkey.length === 33) return pubkey.slice(1);
11968
- if (pubkey.length === 32) return pubkey;
11969
- throw new Error(`invalid signer pubkey length: expected 32 or 33, got ${pubkey.length}`);
11970
- }
11971
12040
  function delayToTimelock(delay) {
11972
12041
  return {
11973
12042
  value: delay,
@@ -11978,7 +12047,7 @@ function dedupeTimelocks(timelocks) {
11978
12047
  const seen = /* @__PURE__ */ new Set();
11979
12048
  const deduped = [];
11980
12049
  for (const timelock of timelocks) {
11981
- const sequence = chunkG552MISJ_cjs.timelockToSequence(timelock).toString();
12050
+ const sequence = chunk2JV4VQ7C_cjs.timelockToSequence(timelock).toString();
11982
12051
  if (seen.has(sequence)) continue;
11983
12052
  seen.add(sequence);
11984
12053
  deduped.push(timelock);
@@ -11995,7 +12064,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
11995
12064
  state: "active"
11996
12065
  });
11997
12066
  const newest = candidates.filter(
11998
- (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkBABJ77NG_cjs.WALLET_RECEIVE_SOURCE
12067
+ (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkOIZ2V2VD_cjs.WALLET_RECEIVE_SOURCE
11999
12068
  ).sort((a, b) => {
12000
12069
  if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
12001
12070
  return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
@@ -12003,7 +12072,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
12003
12072
  if (!newest?.params.pubKey) return baseline;
12004
12073
  try {
12005
12074
  const pubKey = base.hex.decode(newest.params.pubKey);
12006
- return new chunkBABJ77NG_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
12075
+ return new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
12007
12076
  } catch (e) {
12008
12077
  console.warn("Skipping malformed boarding contract at boot", newest.script, e);
12009
12078
  return baseline;
@@ -12019,13 +12088,16 @@ function filterSnapshotVtxos(snapshot, filter, pendingSpendOutpoints) {
12019
12088
  if (pendingSpendOutpoints.has(`${vtxo.txid}:${vtxo.vout}`)) {
12020
12089
  return false;
12021
12090
  }
12022
- if (!chunkG552MISJ_cjs.hasTerminalSpend(vtxo)) {
12023
- if (!f.withRecoverable && chunkG552MISJ_cjs.canRecoverOnchain(vtxo, now)) {
12024
- return false;
12025
- }
12026
- return true;
12091
+ if (vtxo.isUnrolled) {
12092
+ return !!f.withUnrolled;
12093
+ }
12094
+ if (chunk2JV4VQ7C_cjs.hasTerminalSpend(vtxo)) {
12095
+ return false;
12096
+ }
12097
+ if (!f.withRecoverable && chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now)) {
12098
+ return false;
12027
12099
  }
12028
- return !!(f.withUnrolled && vtxo.isUnrolled);
12100
+ return true;
12029
12101
  });
12030
12102
  }
12031
12103
  var PENDING_RECOVERY_REASON = "is past its operator signer's rotation cutoff \u2014 the operator will not co-sign it until it recovers";
@@ -12361,7 +12433,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12361
12433
  */
12362
12434
  static async setupWalletConfig(config, pubKey) {
12363
12435
  const arkadeServerUrl = getArkadeServerUrl(config);
12364
- const arkProvider = config.arkProvider || new chunkG552MISJ_cjs.RestArkProvider(arkadeServerUrl);
12436
+ const arkProvider = config.arkProvider || new chunk2JV4VQ7C_cjs.RestArkProvider(arkadeServerUrl);
12365
12437
  let indexerProvider = config.indexerProvider;
12366
12438
  if (!indexerProvider) {
12367
12439
  let indexerUrl = config.indexerUrl;
@@ -12378,7 +12450,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12378
12450
  indexerUrl = arkadeServerUrl;
12379
12451
  }
12380
12452
  }
12381
- indexerProvider = new chunkXN55B6EP_cjs.RestIndexerProvider(indexerUrl);
12453
+ indexerProvider = new chunkCO3KKSWM_cjs.RestIndexerProvider(indexerUrl);
12382
12454
  }
12383
12455
  const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
12384
12456
  const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
@@ -12387,7 +12459,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12387
12459
  source: serverInfoSource,
12388
12460
  lastOnlineAt: serverInfoLastOnlineAt
12389
12461
  } = await resolveArkInfo(arkProvider, walletRepository);
12390
- const network = chunkG552MISJ_cjs.getNetwork(info.network);
12462
+ const network = chunk2JV4VQ7C_cjs.getNetwork(info.network);
12391
12463
  if ("descriptor" in config.identity) {
12392
12464
  const descriptor = config.identity.descriptor;
12393
12465
  const identityIsMainnet = !descriptor.includes("tpub");
@@ -12427,18 +12499,18 @@ var ReadonlyWallet = class _ReadonlyWallet {
12427
12499
  value: info.boardingExitDelay,
12428
12500
  type: info.boardingExitDelay < 512n ? "blocks" : "seconds"
12429
12501
  };
12430
- const serverPubKey = base.hex.decode(info.signerPubkey).slice(1);
12431
- const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) => base.hex.decode(info2.pubkey).slice(1)).catch(() => void 0) : config.delegatorProvider ? await config.delegatorProvider.getDelegateInfo().then((info2) => base.hex.decode(info2.pubkey).slice(1)).catch(() => void 0) : void 0;
12502
+ const serverPubKey = chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
12503
+ const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) => chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info2.pubkey), "delegate key")).catch(() => void 0) : config.delegatorProvider ? await config.delegatorProvider.getDelegateInfo().then((info2) => chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info2.pubkey), "delegate key")).catch(() => void 0) : void 0;
12432
12504
  const offchainOptions = {
12433
12505
  pubKey,
12434
12506
  serverPubKey,
12435
12507
  csvTimelock: exitTimelock
12436
12508
  };
12437
- const offchainTapscript = !delegatePubKey ? new chunkBABJ77NG_cjs.DefaultVtxo.Script(offchainOptions) : new chunkBABJ77NG_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
12438
- const boardingTapscript = chunkBABJ77NG_cjs.BoardingContractHandler.createScript({
12509
+ const offchainTapscript = !delegatePubKey ? new chunkOIZ2V2VD_cjs.DefaultVtxo.Script(offchainOptions) : new chunkOIZ2V2VD_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
12510
+ const boardingTapscript = chunkOIZ2V2VD_cjs.BoardingContractHandler.createScript({
12439
12511
  pubKey: base.hex.encode(pubKey),
12440
12512
  serverPubKey: base.hex.encode(serverPubKey),
12441
- csvTimelock: chunkG552MISJ_cjs.timelockToSequence(boardingTimelock).toString()
12513
+ csvTimelock: chunk2JV4VQ7C_cjs.timelockToSequence(boardingTimelock).toString()
12442
12514
  });
12443
12515
  return {
12444
12516
  arkProvider,
@@ -12528,7 +12600,11 @@ var ReadonlyWallet = class _ReadonlyWallet {
12528
12600
  this.getBoardingUtxos(),
12529
12601
  this.contractSnapshot()
12530
12602
  ]);
12531
- const vtxos = filterSnapshotVtxos(snapshot, void 0, this._pendingSpendOutpoints);
12603
+ const vtxos = filterSnapshotVtxos(
12604
+ snapshot,
12605
+ { withRecoverable: true, withUnrolled: true },
12606
+ this._pendingSpendOutpoints
12607
+ );
12532
12608
  let confirmed = 0;
12533
12609
  let unconfirmed = 0;
12534
12610
  for (const utxo of boardingUtxos) {
@@ -12556,6 +12632,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12556
12632
  intentLocked: offchain.intentLocked,
12557
12633
  recoverable: offchain.recoverable,
12558
12634
  pendingRecovery: offchain.pendingRecovery,
12635
+ unrolled: offchain.unrolled,
12559
12636
  total: totalBoarding + offchain.total,
12560
12637
  assets: offchain.assets,
12561
12638
  availableAssets: offchain.availableAssets
@@ -12735,7 +12812,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12735
12812
  const response = await contractManager.getContractsWithVtxos();
12736
12813
  const allVtxos = response.flatMap((_) => _.vtxos);
12737
12814
  const { boardingTxs, commitmentsToIgnore } = await this.getBoardingTxs();
12738
- const resolveTxCreatedAt = (txids) => chunkG552MISJ_cjs.fetchVtxoCreatedAtByTxid(this.indexerProvider, txids);
12815
+ const resolveTxCreatedAt = (txids) => chunk2JV4VQ7C_cjs.fetchVtxoCreatedAtByTxid(this.indexerProvider, txids);
12739
12816
  return buildTransactionHistory(
12740
12817
  allVtxos,
12741
12818
  boardingTxs,
@@ -12829,7 +12906,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12829
12906
  },
12830
12907
  isUnrolled: true,
12831
12908
  ...boardingFacts,
12832
- virtualStatus: chunkG552MISJ_cjs.toVirtualStatus(boardingFacts),
12909
+ virtualStatus: chunk2JV4VQ7C_cjs.toVirtualStatus(boardingFacts),
12833
12910
  spentBy: "",
12834
12911
  createdAt: tx.status.confirmed ? new Date(tx.status.block_time * 1e3) : /* @__PURE__ */ new Date(0),
12835
12912
  script: scriptHex
@@ -12885,9 +12962,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
12885
12962
  async getBoardingTapscripts(allowedSigners) {
12886
12963
  const byScript = /* @__PURE__ */ new Map();
12887
12964
  const add = (s) => byScript.set(base.hex.encode(s.pkScript), s);
12888
- const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunkBABJ77NG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
12965
+ const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
12889
12966
  add(
12890
- new chunkBABJ77NG_cjs.DefaultVtxo.Script({
12967
+ new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
12891
12968
  pubKey: await this.identity.xOnlyPublicKey(),
12892
12969
  serverPubKey: this.boardingTapscript.options.serverPubKey,
12893
12970
  csvTimelock: boardingCsv
@@ -12902,7 +12979,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12902
12979
  for (const c of boardingContracts) {
12903
12980
  if (!allowed.has(toXOnlySignerHex(c.params.serverPubKey))) continue;
12904
12981
  try {
12905
- add(chunkBABJ77NG_cjs.BoardingContractHandler.createScript(c.params));
12982
+ add(chunkOIZ2V2VD_cjs.BoardingContractHandler.createScript(c.params));
12906
12983
  } catch (e) {
12907
12984
  console.warn("Skipping malformed boarding contract", c.script, e);
12908
12985
  }
@@ -12940,7 +13017,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
12940
13017
  // Per-row CSV delay decoded from THIS tapscript's exit leaf —
12941
13018
  // not the wallet's current boarding timelock, which a signer
12942
13019
  // rotation may have changed.
12943
- csvTimelock: chunkG552MISJ_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
13020
+ csvTimelock: chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
12944
13021
  coins: utxos
12945
13022
  });
12946
13023
  }
@@ -13073,7 +13150,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13073
13150
  /** Fetch Arkade transaction ids that are still pending final settlement. */
13074
13151
  async fetchPendingTxs() {
13075
13152
  const scripts = await this.getWalletScripts();
13076
- const vtxos = await chunkG552MISJ_cjs.getAllNormalizedVtxos(this.indexerProvider, scripts);
13153
+ const vtxos = await chunk2JV4VQ7C_cjs.getAllNormalizedVtxos(this.indexerProvider, scripts);
13077
13154
  return vtxos.filter(
13078
13155
  (vtxo) => (vtxo.isSpent || vtxo.isPreconfirmed && !vtxo.isSwept) && vtxo.arkTxId !== void 0
13079
13156
  ).map((_) => _.arkTxId);
@@ -13104,7 +13181,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13104
13181
  });
13105
13182
  for (const contract of contracts) {
13106
13183
  if (map.has(contract.script)) continue;
13107
- const handler = chunkBABJ77NG_cjs.contractHandlers.get(contract.type);
13184
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
13108
13185
  if (handler) {
13109
13186
  const script = handler.createScript(contract.params);
13110
13187
  map.set(contract.script, script);
@@ -13216,7 +13293,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13216
13293
  }
13217
13294
  });
13218
13295
  const baselinePubkey = await this.identity.xOnlyPublicKey();
13219
- const delegatePubKey = this.offchainTapscript instanceof chunkBABJ77NG_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
13296
+ const delegatePubKey = this.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
13220
13297
  const baselineSigners = [
13221
13298
  this.offchainTapscript.options.serverPubKey,
13222
13299
  ...[...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h))
@@ -13224,8 +13301,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
13224
13301
  const seenBaselineScripts = /* @__PURE__ */ new Set();
13225
13302
  for (const serverPubKey of baselineSigners) {
13226
13303
  for (const csvTimelock of this.walletContractTimelocks) {
13227
- const csvTimelockStr = chunkG552MISJ_cjs.timelockToSequence(csvTimelock).toString();
13228
- const defaultScript = new chunkBABJ77NG_cjs.DefaultVtxo.Script({
13304
+ const csvTimelockStr = chunk2JV4VQ7C_cjs.timelockToSequence(csvTimelock).toString();
13305
+ const defaultScript = new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
13229
13306
  pubKey: baselinePubkey,
13230
13307
  serverPubKey,
13231
13308
  csvTimelock
@@ -13246,7 +13323,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13246
13323
  });
13247
13324
  }
13248
13325
  if (delegatePubKey) {
13249
- const delegateScript = new chunkBABJ77NG_cjs.DelegateVtxo.Script({
13326
+ const delegateScript = new chunkOIZ2V2VD_cjs.DelegateVtxo.Script({
13250
13327
  pubKey: baselinePubkey,
13251
13328
  serverPubKey,
13252
13329
  delegatePubKey,
@@ -13270,9 +13347,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
13270
13347
  }
13271
13348
  }
13272
13349
  }
13273
- const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunkBABJ77NG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13350
+ const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13274
13351
  for (const serverPubKey of baselineSigners) {
13275
- const baselineBoarding = new chunkBABJ77NG_cjs.DefaultVtxo.Script({
13352
+ const baselineBoarding = new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
13276
13353
  pubKey: baselinePubkey,
13277
13354
  serverPubKey,
13278
13355
  csvTimelock: boardingCsvTimelock
@@ -13285,7 +13362,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
13285
13362
  params: {
13286
13363
  pubKey: base.hex.encode(baselineBoarding.options.pubKey),
13287
13364
  serverPubKey: base.hex.encode(serverPubKey),
13288
- csvTimelock: chunkG552MISJ_cjs.timelockToSequence(boardingCsvTimelock).toString()
13365
+ csvTimelock: chunk2JV4VQ7C_cjs.timelockToSequence(boardingCsvTimelock).toString()
13289
13366
  },
13290
13367
  script: boardingScriptHex,
13291
13368
  address: baselineBoarding.address(this.network.hrp, serverPubKey).encode(),
@@ -13415,6 +13492,27 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13415
13492
  console.warn("server-signer rotation on info change failed", e);
13416
13493
  }
13417
13494
  }
13495
+ /**
13496
+ * Await an `onServerInfoChanged` handler still applying a rotation.
13497
+ *
13498
+ * The provider emits synchronously but {@link handleServerInfoChanged} runs
13499
+ * off the emit, so between the two a caller can observe a half-applied
13500
+ * rotation: {@link rotateServerSigner} persists the active signer's contract
13501
+ * rows *before* committing the tapscripts, so `arkServerPublicKey` still
13502
+ * reads the old key while the new key's rows are already in the repository.
13503
+ * A path that refreshes server info and then reads signer-derived state must
13504
+ * drain the chain first, or it both reads that torn state and races the
13505
+ * handler for the rotation itself.
13506
+ *
13507
+ * Resolves once the chain is idle; a handler that threw already logged, and
13508
+ * its rejection is swallowed here.
13509
+ *
13510
+ * @internal Invoked by {@link dispose} and the {@link VtxoManager} migration
13511
+ * pass; not part of the stable public API.
13512
+ */
13513
+ async settleServerInfoChanges() {
13514
+ await this._serverInfoInFlight?.catch(() => void 0);
13515
+ }
13418
13516
  _receiveRotatorInstalled = false;
13419
13517
  /**
13420
13518
  * Descriptor-aware signer used by {@link _signerRouter} to sign
@@ -13464,7 +13562,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13464
13562
  serverPubKey: this.offchainTapscript.options.serverPubKey,
13465
13563
  deprecatedSignerPubKeys: [...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h)),
13466
13564
  csvTimelocks: this.walletContractTimelocks,
13467
- delegatePubKey: this.offchainTapscript instanceof chunkBABJ77NG_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0
13565
+ delegatePubKey: this.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0
13468
13566
  };
13469
13567
  }
13470
13568
  _signerRouter;
@@ -13549,43 +13647,250 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13549
13647
  * provider and keeps a single index-0 boarding address for its lifetime,
13550
13648
  * so this returns the existing {@link getBoardingAddress} unchanged
13551
13649
  * (no rotation, no index burned).
13650
+ *
13651
+ * **Behaviour change.** A wallet configured with a custom
13652
+ * {@link DescriptorProvider} (`walletMode: <provider>`) now rotates here.
13653
+ * It previously did not: allocation went through the contract manager,
13654
+ * which only wires an `allocate` hook for {@link HDDescriptorProvider}, so
13655
+ * such a wallet read as "declined to allocate" and silently kept its
13656
+ * index-0 boarding address forever. Those wallets now burn an index per
13657
+ * call — including via {@link maybeRotateBoardingAfterBoard}, which fires
13658
+ * on every settle that consumes a boarding UTXO. Funds at retired
13659
+ * addresses stay reachable: each rotation persists its `boarding` contract
13660
+ * before swapping, and {@link getBoardingUtxos} fans out over the full
13661
+ * historical set.
13662
+ *
13663
+ * @deprecated Use {@link getNewAddresses} — it mints any combination of
13664
+ * address types at one shared index, and reports the contract row behind
13665
+ * each. Note the difference in display behaviour: this method *swaps* the
13666
+ * advertised boarding address, where `getNewAddresses` mints side
13667
+ * addresses and leaves {@link getBoardingAddress} alone. To keep this
13668
+ * method's behaviour, keep calling this method.
13552
13669
  */
13553
13670
  async getNewBoardingAddress() {
13554
- const provider = this._descriptorProvider;
13555
- if (!provider) {
13556
- return this.getBoardingAddress();
13671
+ const [minted] = await this.allocateAddresses(["boarding"], false, true);
13672
+ if (!minted?.allocated) return this.getBoardingAddress();
13673
+ if (minted.type === "boarding") this.setBoardingTapscriptForRotation(minted.tapscript);
13674
+ return minted.address;
13675
+ }
13676
+ /**
13677
+ * Allocate a *fresh* address of each requested type, all derived from one
13678
+ * newly allocated HD index.
13679
+ *
13680
+ * This is the explicit allocator the receive path otherwise lacks:
13681
+ * {@link getAddress} and {@link getBoardingAddress} are stable reads of the
13682
+ * wallet's display addresses, and the display receive address only advances
13683
+ * when a payment arrives ({@link WalletReceiveRotator} rotates on
13684
+ * `vtxo_received`). Issuing a second address before the first is paid — one
13685
+ * invoice for Alice, another for Bob — has to go through here.
13686
+ *
13687
+ * Each call:
13688
+ *
13689
+ * - allocates **one** index from the shared HD stream, however many types
13690
+ * were asked for, so a `default` + `boarding` pair are siblings rather
13691
+ * than two burnt indices;
13692
+ * - builds each requested script at that index, preserving every other
13693
+ * option of the wallet's current script for that flavour (including a
13694
+ * delegate wallet's `delegate` shape);
13695
+ * - persists each as an `active` contract carrying its `signingDescriptor`,
13696
+ * so the ContractWatcher monitors it, the balance counts it, and
13697
+ * {@link signerForDescriptor} can recover the key;
13698
+ * - slides the look-ahead band, since the watermark moved past indices an
13699
+ * external issuer may still be handing out.
13700
+ *
13701
+ * The minted rows are deliberately left **untagged**: the boot lookups
13702
+ * adopt the newest {@link WALLET_RECEIVE_SOURCE}-tagged row as the display
13703
+ * address, and a side address issued to one counterparty must not become
13704
+ * the address the wallet advertises to everyone else. {@link getAddress}
13705
+ * and {@link getBoardingAddress} are unchanged by this call.
13706
+ *
13707
+ * A wallet with no HD stream (`walletMode: 'static'` / `'auto'`) has one
13708
+ * address per flavour for its lifetime. Without `forceNew` it returns those
13709
+ * — the real persisted rows, no index burned; with `forceNew` it throws
13710
+ * {@link WalletCannotAllocateAddressError} rather than hand back an address
13711
+ * that is not in fact fresh.
13712
+ *
13713
+ * @example
13714
+ * ```typescript
13715
+ * const [invoice] = await wallet.getNewAddresses({ forceNew: true });
13716
+ * // hand `invoice.address` to Alice, keep the descriptor with the invoice
13717
+ * const signer = await wallet.signerForDescriptor(invoice.signingDescriptor);
13718
+ * ```
13719
+ */
13720
+ async getNewAddresses(opts) {
13721
+ const minted = await this.allocateAddresses(
13722
+ opts?.types ?? ["default"],
13723
+ opts?.forceNew ?? false,
13724
+ false
13725
+ );
13726
+ return minted.map(({ address, signingDescriptor, contract }) => ({
13727
+ address,
13728
+ signingDescriptor,
13729
+ contract
13730
+ }));
13731
+ }
13732
+ /**
13733
+ * Shared allocation core behind {@link getNewAddresses} and the deprecated
13734
+ * {@link getNewBoardingAddress}, so the two cannot drift on what an
13735
+ * allocation costs or what gets persisted.
13736
+ *
13737
+ * @param tagSource - Tag the persisted rows {@link WALLET_RECEIVE_SOURCE},
13738
+ * making the next boot adopt them as the display address. Only the
13739
+ * deprecated boarding allocator passes `true`; `getNewAddresses` mints side
13740
+ * addresses and must not hijack what the wallet advertises.
13741
+ */
13742
+ async allocateAddresses(types, forceNew, tagSource) {
13743
+ if (types.length === 0) {
13744
+ throw new Error("getNewAddresses: `types` must name at least one address type");
13557
13745
  }
13558
13746
  const manager = await this.getContractManager();
13559
- const descriptor = await manager.getNextSigningDescriptor();
13560
- if (!descriptor) return this.getBoardingAddress();
13561
- const pubKey = chunkBABJ77NG_cjs.deriveDescriptorLeafPubKey(descriptor);
13562
- const newBoarding = new chunkBABJ77NG_cjs.DefaultVtxo.Script({
13747
+ const provider = this._descriptorProvider;
13748
+ const descriptor = !provider ? void 0 : provider instanceof HDDescriptorProvider ? await manager.getNextSigningDescriptor() : await provider.getNextSigningDescriptor();
13749
+ if (!descriptor) {
13750
+ if (forceNew) {
13751
+ throw new WalletCannotAllocateAddressError(
13752
+ provider ? "the descriptor provider declined to allocate an index" : "this wallet has no HD stream (walletMode 'static' / 'auto')"
13753
+ );
13754
+ }
13755
+ return this.currentAddresses(manager, types);
13756
+ }
13757
+ const allocated = [];
13758
+ try {
13759
+ for (const type of types) {
13760
+ allocated.push(await this.mintAddress(manager, type, descriptor, tagSource, true));
13761
+ }
13762
+ } finally {
13763
+ try {
13764
+ await manager.refillLookAhead();
13765
+ } catch (e) {
13766
+ console.warn("look-ahead refill after address allocation failed", e);
13767
+ }
13768
+ }
13769
+ return allocated;
13770
+ }
13771
+ /**
13772
+ * The wallet's existing display addresses, as persisted contract rows —
13773
+ * the honest answer for a wallet with no index to burn.
13774
+ *
13775
+ * Each type is minted from the descriptor that already owns its display
13776
+ * script ({@link displayDescriptor}), not from the identity key, so the
13777
+ * returned `signingDescriptor` is the one that signs for the returned
13778
+ * `address` even on a wallet that has rotated.
13779
+ */
13780
+ async currentAddresses(manager, types) {
13781
+ const out = [];
13782
+ for (const type of types) {
13783
+ const descriptor = await this.displayDescriptor(manager, type);
13784
+ out.push(await this.mintAddress(manager, type, descriptor, false, false));
13785
+ }
13786
+ return out;
13787
+ }
13788
+ /**
13789
+ * The descriptor that owns the wallet's current display script for `type`,
13790
+ * read off the row the wallet persisted when it adopted that script.
13791
+ *
13792
+ * Deriving it from the identity instead is only correct for a wallet that
13793
+ * never rotates. On one that has — an HD wallet whose provider later
13794
+ * declines to allocate — the display script belongs to an HD child, and
13795
+ * pairing its address with the identity descriptor hands the caller a
13796
+ * {@link NewAddress} whose `signingDescriptor` resolves, via
13797
+ * {@link signerForDescriptor}, to a signer holding the wrong key.
13798
+ *
13799
+ * Falls back to the identity's pathless `tr(pubkey)` when no row carries a
13800
+ * descriptor: the static / `auto` case, where the identity key genuinely
13801
+ * owns the display script and this is what `getNextSigningDescriptor`
13802
+ * answers too. (The index-0 baselines registered at construction carry no
13803
+ * `signingDescriptor` metadata, so those wallets take this path.)
13804
+ */
13805
+ async displayDescriptor(manager, type) {
13806
+ const display = type === "boarding" ? this._boardingTapscript : this.offchainTapscript;
13807
+ const [row] = await manager.getContracts({ script: base.hex.encode(display.pkScript) });
13808
+ const persisted = row?.metadata?.signingDescriptor;
13809
+ if (typeof persisted === "string") return persisted;
13810
+ return chunkOIZ2V2VD_cjs.identityDescriptor(this.identity);
13811
+ }
13812
+ /**
13813
+ * Build, persist and shape one address of `type` owned by `descriptor` —
13814
+ * the single build-and-register path behind both {@link allocateAddresses}
13815
+ * and {@link currentAddresses}, so a freshly allocated address and a
13816
+ * re-registered display address cannot disagree on what gets written.
13817
+ *
13818
+ * The descriptor is the sole source of the script's owner key in both
13819
+ * branches. Deriving one flavour from the descriptor and the other from a
13820
+ * tapscript field is what lets `address` and `signingDescriptor` drift
13821
+ * apart.
13822
+ */
13823
+ async mintAddress(manager, type, descriptor, tagSource, allocated) {
13824
+ if (type === "boarding") {
13825
+ const built2 = this.buildBoardingContract(
13826
+ chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(descriptor),
13827
+ descriptor,
13828
+ tagSource
13829
+ );
13830
+ const contract2 = await manager.createContract(built2.params);
13831
+ return {
13832
+ type,
13833
+ // `built.tapscript` is a `DefaultVtxo.Script` here without a
13834
+ // cast — the branch, not a widened local, does the narrowing.
13835
+ tapscript: built2.tapscript,
13836
+ // A boarding row persists the *ark* encoding of its script, so
13837
+ // `contract.address` is unusable for an onchain sender: the
13838
+ // onchain form has to be re-derived.
13839
+ address: built2.tapscript.onchainAddress(this.network),
13840
+ signingDescriptor: descriptor,
13841
+ contract: contract2,
13842
+ allocated
13843
+ };
13844
+ }
13845
+ const built = buildReceiveContract(
13846
+ this.offchainTapscript,
13847
+ descriptor,
13848
+ this.network.hrp,
13849
+ tagSource
13850
+ );
13851
+ const contract = await manager.createContract(built.params);
13852
+ return {
13853
+ type,
13854
+ tapscript: built.tapscript,
13855
+ // Offchain rows already store the address they advertise, and
13856
+ // reading it back keeps a coalesced row (`createContract` is
13857
+ // first-wins on script) honest about what was actually persisted.
13858
+ address: contract.address,
13859
+ signingDescriptor: descriptor,
13860
+ contract,
13861
+ allocated
13862
+ };
13863
+ }
13864
+ /**
13865
+ * Build the boarding contract owned by `pubKey`, keeping every other option
13866
+ * of the wallet's current boarding tapscript (notably the boarding-exit
13867
+ * CSV, which is index-independent). The offchain analogue lives in
13868
+ * {@link buildReceiveContract}.
13869
+ */
13870
+ buildBoardingContract(pubKey, descriptor, tagSource) {
13871
+ const tapscript = new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
13563
13872
  ...this._boardingTapscript.options,
13564
13873
  pubKey
13565
13874
  });
13566
- const csvTimelock = newBoarding.options.csvTimelock ?? chunkBABJ77NG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13567
- await manager.createContract({
13568
- type: "boarding",
13875
+ const csvTimelock = tapscript.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13876
+ return {
13877
+ tapscript,
13569
13878
  params: {
13570
- pubKey: base.hex.encode(pubKey),
13571
- serverPubKey: base.hex.encode(newBoarding.options.serverPubKey),
13572
- csvTimelock: chunkG552MISJ_cjs.timelockToSequence(csvTimelock).toString()
13573
- },
13574
- script: base.hex.encode(newBoarding.pkScript),
13575
- address: newBoarding.address(this.network.hrp, this.arkServerPublicKey).encode(),
13576
- state: "active",
13577
- metadata: {
13578
- source: chunkBABJ77NG_cjs.WALLET_RECEIVE_SOURCE,
13579
- signingDescriptor: descriptor
13879
+ type: "boarding",
13880
+ params: {
13881
+ pubKey: base.hex.encode(pubKey),
13882
+ serverPubKey: base.hex.encode(tapscript.options.serverPubKey),
13883
+ csvTimelock: chunk2JV4VQ7C_cjs.timelockToSequence(csvTimelock).toString()
13884
+ },
13885
+ script: base.hex.encode(tapscript.pkScript),
13886
+ address: tapscript.address(this.network.hrp, this.arkServerPublicKey).encode(),
13887
+ state: "active",
13888
+ metadata: {
13889
+ ...tagSource && { source: chunkOIZ2V2VD_cjs.WALLET_RECEIVE_SOURCE },
13890
+ signingDescriptor: descriptor
13891
+ }
13580
13892
  }
13581
- });
13582
- this.setBoardingTapscriptForRotation(newBoarding);
13583
- try {
13584
- await manager.refillLookAhead();
13585
- } catch (e) {
13586
- console.warn("look-ahead refill after boarding allocation failed", e);
13587
- }
13588
- return newBoarding.onchainAddress(this.network);
13893
+ };
13589
13894
  }
13590
13895
  /**
13591
13896
  * @see HDWalletCapable.getCurrentSigningDescriptor
@@ -13610,7 +13915,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13610
13915
  if (this._descriptorProvider instanceof HDDescriptorProvider) {
13611
13916
  return (await this.getContractManager()).getNextSigningDescriptor();
13612
13917
  }
13613
- return chunkBABJ77NG_cjs.identityDescriptor(this.identity);
13918
+ return chunkOIZ2V2VD_cjs.identityDescriptor(this.identity);
13614
13919
  }
13615
13920
  /**
13616
13921
  * @see HDAllocationCapable.advanceSigningDescriptorWatermark
@@ -13706,7 +14011,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13706
14011
  * the stable public API.
13707
14012
  */
13708
14013
  async rotateServerSigner(newServerPubKey, checkpointTapscript) {
13709
- const xonly = toXOnlyPubKey(newServerPubKey);
14014
+ const xonly = chunkOIZ2V2VD_cjs.toXOnly(newServerPubKey, "ark signer key");
13710
14015
  const newServerUnrollScript = assertValidServerUnrollScript(
13711
14016
  checkpointTapscript,
13712
14017
  resolveCheckpointExitDelayPolicy(this.network, this.checkpointExitDelayPolicy)
@@ -13735,21 +14040,21 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13735
14040
  const [currentBoardingRow] = await manager.getContracts({
13736
14041
  script: currentBoardingScript
13737
14042
  });
13738
- const newOffchain = this.offchainTapscript instanceof chunkBABJ77NG_cjs.DelegateVtxo.Script ? new chunkBABJ77NG_cjs.DelegateVtxo.Script({
14043
+ const newOffchain = this.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? new chunkOIZ2V2VD_cjs.DelegateVtxo.Script({
13739
14044
  ...this.offchainTapscript.options,
13740
14045
  serverPubKey: xonly
13741
- }) : new chunkBABJ77NG_cjs.DefaultVtxo.Script({
14046
+ }) : new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
13742
14047
  ...this.offchainTapscript.options,
13743
14048
  serverPubKey: xonly
13744
14049
  });
13745
- const newBoarding = new chunkBABJ77NG_cjs.DefaultVtxo.Script({
14050
+ const newBoarding = new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
13746
14051
  ...this._boardingTapscript.options,
13747
14052
  serverPubKey: xonly
13748
14053
  });
13749
- const offchainCsv = chunkG552MISJ_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
14054
+ const offchainCsv = chunk2JV4VQ7C_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
13750
14055
  const newOffchainScript = base.hex.encode(newOffchain.pkScript);
13751
14056
  const newOffchainAddress = newOffchain.address(this.network.hrp, xonly).encode();
13752
- if (newOffchain instanceof chunkBABJ77NG_cjs.DelegateVtxo.Script) {
14057
+ if (newOffchain instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script) {
13753
14058
  await manager.createContract({
13754
14059
  type: "delegate",
13755
14060
  params: {
@@ -13777,13 +14082,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13777
14082
  metadata: currentOffchainRow?.metadata
13778
14083
  });
13779
14084
  }
13780
- const boardingCsv = newBoarding.options.csvTimelock ?? chunkBABJ77NG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
14085
+ const boardingCsv = newBoarding.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
13781
14086
  await manager.createContract({
13782
14087
  type: "boarding",
13783
14088
  params: {
13784
14089
  pubKey: base.hex.encode(newBoarding.options.pubKey),
13785
14090
  serverPubKey: base.hex.encode(xonly),
13786
- csvTimelock: chunkG552MISJ_cjs.timelockToSequence(boardingCsv).toString()
14091
+ csvTimelock: chunk2JV4VQ7C_cjs.timelockToSequence(boardingCsv).toString()
13787
14092
  },
13788
14093
  script: base.hex.encode(newBoarding.pkScript),
13789
14094
  address: newBoarding.address(this.network.hrp, xonly).encode(),
@@ -13816,14 +14121,14 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13816
14121
  _restoreInFlight;
13817
14122
  _addPendingSpends(inputs) {
13818
14123
  for (const input of inputs) {
13819
- if (chunkG552MISJ_cjs.isVirtualCoin(input)) {
14124
+ if (chunk2JV4VQ7C_cjs.isVirtualCoin(input)) {
13820
14125
  this._pendingSpendOutpoints.add(`${input.txid}:${input.vout}`);
13821
14126
  }
13822
14127
  }
13823
14128
  }
13824
14129
  _removePendingSpends(inputs) {
13825
14130
  for (const input of inputs) {
13826
- if (chunkG552MISJ_cjs.isVirtualCoin(input)) {
14131
+ if (chunk2JV4VQ7C_cjs.isVirtualCoin(input)) {
13827
14132
  this._pendingSpendOutpoints.delete(`${input.txid}:${input.vout}`);
13828
14133
  }
13829
14134
  }
@@ -13881,13 +14186,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13881
14186
  const manager = await this.getContractManager();
13882
14187
  const provider = this._descriptorProvider;
13883
14188
  const hd = provider instanceof HDDescriptorProvider;
13884
- const staticDescriptor = hd ? void 0 : await chunkBABJ77NG_cjs.identityDescriptor(this.identity);
14189
+ const staticDescriptor = hd ? void 0 : await chunkOIZ2V2VD_cjs.identityDescriptor(this.identity);
13885
14190
  const materialize = (index) => hd ? provider.materializeDescriptorAt(index) : staticDescriptor;
13886
- const delegatePubKey = this.offchainTapscript instanceof chunkBABJ77NG_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
14191
+ const delegatePubKey = this.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
13887
14192
  const arkInfo = await this.arkProvider.getInfo();
13888
- const currentSignerPubKey = toXOnlyPubKey(base.hex.decode(arkInfo.signerPubkey));
14193
+ const currentSignerPubKey = chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(arkInfo.signerPubkey), "ark signer key");
13889
14194
  const deprecatedSignerPubKeys = arkInfo.deprecatedSigners.map(
13890
- (s) => toXOnlyPubKey(base.hex.decode(s.pubkey))
14195
+ (s) => chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(s.pubkey), "deprecated signer key")
13891
14196
  );
13892
14197
  const deps = {
13893
14198
  indexerProvider: this.indexerProvider,
@@ -13902,7 +14207,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13902
14207
  csvTimelocks: this.walletContractTimelocks,
13903
14208
  // Boarding-exit CSV so the boarding handler can build its
13904
14209
  // candidate script (distinct from the unilateral-exit matrix).
13905
- boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunkBABJ77NG_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
14210
+ boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
13906
14211
  delegatePubKey
13907
14212
  };
13908
14213
  const result = await manager.scanContracts({
@@ -13970,7 +14275,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
13970
14275
  await this._restoreInFlight?.catch(() => void 0);
13971
14276
  this._serverInfoUnsub?.();
13972
14277
  this._serverInfoUnsub = void 0;
13973
- await this._serverInfoInFlight?.catch(() => void 0);
14278
+ await this.settleServerInfoChanges();
13974
14279
  let rotatorError;
13975
14280
  try {
13976
14281
  await this._receiveRotator?.dispose();
@@ -14016,7 +14321,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14016
14321
  throw new Error("Invalid configured public key");
14017
14322
  }
14018
14323
  const setup = await ReadonlyWallet.setupWalletConfig(config, pubkey);
14019
- const forfeitPubkey = base.hex.decode(setup.info.forfeitPubkey).slice(1);
14324
+ const forfeitPubkey = chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(setup.info.forfeitPubkey), "forfeit key");
14020
14325
  const forfeitAddress = btcSigner.Address(setup.network).decode(setup.info.forfeitAddress);
14021
14326
  const forfeitOutputScript = btcSigner.OutScript.encode(forfeitAddress);
14022
14327
  const checkpointExitDelayOverrides = {
@@ -14165,7 +14470,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14165
14470
  inputs: params.selectedVtxos,
14166
14471
  changeAmount: BigInt(changeAmount)
14167
14472
  };
14168
- const outputAddress = chunkG552MISJ_cjs.ArkAddress.decode(params.address);
14473
+ const outputAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(params.address);
14169
14474
  assertRecipientArkAddress(
14170
14475
  params.address,
14171
14476
  outputAddress,
@@ -14231,13 +14536,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14231
14536
  void this.logUngatedInputs("settle({ inputs })", params.inputs);
14232
14537
  }
14233
14538
  const offchainAddress = await this.getAddress();
14234
- const offchainPkScript = chunkG552MISJ_cjs.ArkAddress.decode(offchainAddress).pkScript;
14539
+ const offchainPkScript = chunk2JV4VQ7C_cjs.ArkAddress.decode(offchainAddress).pkScript;
14235
14540
  const offchainOutputScript = base.hex.encode(offchainPkScript);
14236
14541
  if (!params) {
14237
14542
  const { fees, vtxoMaxAmount } = await this.arkProvider.getInfo();
14238
14543
  const estimator = new Estimator(fees.intentFee);
14239
14544
  let amount = 0;
14240
- const exitScript = chunkG552MISJ_cjs.CSVMultisigTapscript.decode(
14545
+ const exitScript = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(
14241
14546
  base.hex.decode(this.boardingTapscript.exitScript)
14242
14547
  );
14243
14548
  const boardingTimelock = exitScript.params.timelock;
@@ -14266,7 +14571,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14266
14571
  if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
14267
14572
  break;
14268
14573
  }
14269
- const inputFee = estimator.evalOffchainInput(chunkG552MISJ_cjs.toOffchainInputFeeParams(vtxo));
14574
+ const inputFee = estimator.evalOffchainInput(chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(vtxo));
14270
14575
  if (inputFee.satoshis >= vtxo.value) {
14271
14576
  continue;
14272
14577
  }
@@ -14313,7 +14618,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14313
14618
  let script;
14314
14619
  let arkAddress;
14315
14620
  try {
14316
- arkAddress = chunkG552MISJ_cjs.ArkAddress.decode(output.address);
14621
+ arkAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(output.address);
14317
14622
  } catch {
14318
14623
  arkAddress = void 0;
14319
14624
  }
@@ -14403,7 +14708,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14403
14708
  const abortController = new AbortController();
14404
14709
  let stream;
14405
14710
  let committedTxid;
14406
- const settleInputVtxos = params.inputs.filter(chunkG552MISJ_cjs.isVirtualCoin);
14711
+ const settleInputVtxos = params.inputs.filter(chunk2JV4VQ7C_cjs.isVirtualCoin);
14407
14712
  const contractManager = await this.getContractManager();
14408
14713
  await contractManager.assertAnnotatable(settleInputVtxos);
14409
14714
  await contractManager.assertSpendableNow?.(
@@ -14502,7 +14807,10 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14502
14807
  * `typeof` guard skips the arknote strings settle also accepts.
14503
14808
  *
14504
14809
  * No-ops for static / `auto` wallets (no descriptor provider — boarding
14505
- * stays on its fixed index-0 address). Best-effort and non-fatal: the
14810
+ * stays on its fixed index-0 address). Wallets on a custom
14811
+ * {@link DescriptorProvider} DO rotate here now, where they previously
14812
+ * no-opped — see the behaviour-change note on {@link
14813
+ * getNewBoardingAddress}. Best-effort and non-fatal: the
14506
14814
  * settle has already committed and its txid must be returned, so a
14507
14815
  * rotation failure is logged and swallowed rather than thrown. Funds at
14508
14816
  * the retired boarding address remain discoverable — the old `boarding`
@@ -14512,7 +14820,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14512
14820
  async maybeRotateBoardingAfterBoard(inputs) {
14513
14821
  if (!this._descriptorProvider) return;
14514
14822
  const consumedBoarding = inputs.some(
14515
- (input) => typeof input !== "string" && !chunkG552MISJ_cjs.isVirtualCoin(input)
14823
+ (input) => typeof input !== "string" && !chunk2JV4VQ7C_cjs.isVirtualCoin(input)
14516
14824
  );
14517
14825
  if (!consumedBoarding) return;
14518
14826
  try {
@@ -14536,7 +14844,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14536
14844
  let connectorIndex = 0;
14537
14845
  const connectorsLeaves = connectorsGraph?.leaves() || [];
14538
14846
  for (const input of inputs) {
14539
- if (!chunkG552MISJ_cjs.isVirtualCoin(input)) {
14847
+ if (!chunk2JV4VQ7C_cjs.isVirtualCoin(input)) {
14540
14848
  for (let i = 0; i < settlementPsbt.inputsLength; i++) {
14541
14849
  const settlementInput = settlementPsbt.getInput(i);
14542
14850
  if (!settlementInput.txid || settlementInput.index === void 0) {
@@ -14567,7 +14875,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14567
14875
  }
14568
14876
  continue;
14569
14877
  }
14570
- if (chunkG552MISJ_cjs.canRecoverOnchain(input, { timestamp: /* @__PURE__ */ new Date() }) || isSubdust({ value: input.value }, this.dustAmount)) {
14878
+ if (chunk2JV4VQ7C_cjs.canRecoverOnchain(input, { timestamp: /* @__PURE__ */ new Date() }) || isSubdust({ value: input.value }, this.dustAmount)) {
14571
14879
  continue;
14572
14880
  }
14573
14881
  if (connectorsLeaves.length === 0) {
@@ -14595,7 +14903,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14595
14903
  index: input.vout,
14596
14904
  witnessUtxo: {
14597
14905
  amount: BigInt(input.value),
14598
- script: chunkG552MISJ_cjs.VtxoScript.decode(input.tapTree).pkScript
14906
+ script: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
14599
14907
  },
14600
14908
  sighashType: btcSigner.SigHash.DEFAULT,
14601
14909
  tapLeafScript: [input.forfeitTapLeafScript]
@@ -14614,7 +14922,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14614
14922
  forfeitTx = await this._signerRouter.sign(forfeitTx, [
14615
14923
  {
14616
14924
  index: 0,
14617
- lookupScript: chunkG552MISJ_cjs.VtxoScript.decode(input.tapTree).pkScript
14925
+ lookupScript: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
14618
14926
  }
14619
14927
  ]);
14620
14928
  signedForfeits.push(base.base64.encode(forfeitTx.toPSBT()));
@@ -14672,7 +14980,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14672
14980
  resolveBatchExpiryPolicy(this.network, this.batchExpiryPolicy)
14673
14981
  );
14674
14982
  await this.arkProvider.confirmRegistration(intentId);
14675
- const sweepTapscript = chunkG552MISJ_cjs.CSVMultisigTapscript.encode({
14983
+ const sweepTapscript = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.encode({
14676
14984
  timelock,
14677
14985
  pubkeys: [this.forfeitPubkey]
14678
14986
  }).script;
@@ -14686,9 +14994,11 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14686
14994
  if (!sweepTapTreeRoot) {
14687
14995
  throw new Error("Sweep tap tree root not set");
14688
14996
  }
14689
- const xOnlyPublicKeys = event.cosignersPublicKeys.map((k) => k.slice(2));
14997
+ const xOnlyPublicKeys = event.cosignersPublicKeys.map(
14998
+ (k) => base.hex.encode(chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
14999
+ );
14690
15000
  const signerPublicKey = await session.getPublicKey();
14691
- const xonlySignerPublicKey = signerPublicKey.subarray(1);
15001
+ const xonlySignerPublicKey = chunkOIZ2V2VD_cjs.toXOnly(signerPublicKey, "signer key");
14692
15002
  if (!xOnlyPublicKeys.includes(base.hex.encode(xonlySignerPublicKey))) {
14693
15003
  return { skip: true };
14694
15004
  }
@@ -14778,9 +15088,9 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14778
15088
  ...existing ?? {},
14779
15089
  intentTxId,
14780
15090
  registerProof: intent.proof,
14781
- registerProofMessage: chunkG552MISJ_cjs.Intent.encodeMessage(intent.message),
15091
+ registerProofMessage: chunk2JV4VQ7C_cjs.Intent.encodeMessage(intent.message),
14782
15092
  deleteProof: deleteIntent.proof,
14783
- deleteProofMessage: chunkG552MISJ_cjs.Intent.encodeMessage(deleteIntent.message),
15093
+ deleteProofMessage: chunk2JV4VQ7C_cjs.Intent.encodeMessage(deleteIntent.message),
14784
15094
  intentVtxos: inputs.map((i) => ({
14785
15095
  txid: i.txid,
14786
15096
  vout: i.vout
@@ -14812,7 +15122,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14812
15122
  try {
14813
15123
  return await this.arkProvider.registerIntent(intent);
14814
15124
  } catch (error) {
14815
- if (error instanceof chunkG552MISJ_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
15125
+ if (error instanceof chunk2JV4VQ7C_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
14816
15126
  const deleteIntent = await this.makeDeleteIntentSignature(inputs);
14817
15127
  await this.arkProvider.deleteIntent(deleteIntent);
14818
15128
  return this.arkProvider.registerIntent(intent);
@@ -14828,7 +15138,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14828
15138
  expire_at: 0,
14829
15139
  cosigners_public_keys: cosignerPubKeys
14830
15140
  };
14831
- const proof = chunkG552MISJ_cjs.Intent.create(message, coins, outputs);
15141
+ const proof = chunk2JV4VQ7C_cjs.Intent.create(message, coins, outputs);
14832
15142
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
14833
15143
  return {
14834
15144
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -14840,7 +15150,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14840
15150
  type: "delete",
14841
15151
  expire_at: 0
14842
15152
  };
14843
- const proof = chunkG552MISJ_cjs.Intent.create(message, coins, []);
15153
+ const proof = chunk2JV4VQ7C_cjs.Intent.create(message, coins, []);
14844
15154
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
14845
15155
  return {
14846
15156
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -14852,7 +15162,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14852
15162
  type: "get-pending-tx",
14853
15163
  expire_at: 0
14854
15164
  };
14855
- const proof = chunkG552MISJ_cjs.Intent.create(message, coins, []);
15165
+ const proof = chunk2JV4VQ7C_cjs.Intent.create(message, coins, []);
14856
15166
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
14857
15167
  return {
14858
15168
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -14873,7 +15183,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14873
15183
  if (!vtxos || vtxos.length === 0) {
14874
15184
  const scriptMap = await this.getScriptMap();
14875
15185
  const allExtended = [];
14876
- const fetchedVtxos = await chunkG552MISJ_cjs.getAllNormalizedVtxos(this.indexerProvider, [
15186
+ const fetchedVtxos = await chunk2JV4VQ7C_cjs.getAllNormalizedVtxos(this.indexerProvider, [
14877
15187
  ...scriptMap.keys()
14878
15188
  ]);
14879
15189
  for (const vtxo of fetchedVtxos) {
@@ -14987,11 +15297,11 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
14987
15297
  * against the current key alone would leave it pending forever.
14988
15298
  */
14989
15299
  checkpointUnrollCandidates(info) {
14990
- const current = chunkG552MISJ_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
15300
+ const current = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
14991
15301
  const candidates = [this._serverUnrollScript, current];
14992
15302
  for (const deprecated of signerSetFromInfo(info).deprecated.keys()) {
14993
15303
  candidates.push(
14994
- chunkG552MISJ_cjs.CSVMultisigTapscript.encode({
15304
+ chunk2JV4VQ7C_cjs.CSVMultisigTapscript.encode({
14995
15305
  ...current.params,
14996
15306
  pubkeys: [base.hex.decode(deprecated)]
14997
15307
  })
@@ -15082,7 +15392,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15082
15392
  if (vtxos.length === 0) {
15083
15393
  throw new Error("No VTXOs found for this arkadeCash");
15084
15394
  }
15085
- const myPkScript = chunkG552MISJ_cjs.ArkAddress.decode(await this.getAddress()).pkScript;
15395
+ const myPkScript = chunk2JV4VQ7C_cjs.ArkAddress.decode(await this.getAddress()).pkScript;
15086
15396
  let { spendable, unclaimed } = this.classifyCashVtxos(vtxos);
15087
15397
  let swept = 0;
15088
15398
  const drainable = vtxos.filter((vtxo) => !isSubdust(vtxo, this.dustAmount));
@@ -15156,8 +15466,10 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15156
15466
  const spendable = [];
15157
15467
  const unclaimed = [];
15158
15468
  for (const vtxo of vtxos) {
15159
- if (chunkG552MISJ_cjs.hasTerminalSpend(vtxo)) {
15469
+ if (chunk2JV4VQ7C_cjs.hasTerminalSpend(vtxo)) {
15160
15470
  unclaimed.push(cashReport(vtxo, "already-spent"));
15471
+ } else if (vtxo.isUnrolled) {
15472
+ unclaimed.push(cashReport(vtxo, "exited"));
15161
15473
  } else if (isSubdust(vtxo, this.dustAmount)) {
15162
15474
  unclaimed.push(cashReport(vtxo, "subdust"));
15163
15475
  } else if (vtxo.isSwept) {
@@ -15176,7 +15488,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15176
15488
  const all = [];
15177
15489
  const seen = /* @__PURE__ */ new Set();
15178
15490
  for (let pageIndex = 0; ; pageIndex++) {
15179
- const { vtxos, page } = await chunkG552MISJ_cjs.getNormalizedVtxos(this.indexerProvider, {
15491
+ const { vtxos, page } = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(this.indexerProvider, {
15180
15492
  scripts,
15181
15493
  pageIndex,
15182
15494
  pageSize
@@ -15223,7 +15535,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15223
15535
  for (let i = 0; i < inputs.length; i += MAX_INPUTS_PER_INTENT) {
15224
15536
  const batch = inputs.slice(i, i + MAX_INPUTS_PER_INTENT);
15225
15537
  const message = { type: "get-pending-tx", expire_at: 0 };
15226
- const proof = chunkG552MISJ_cjs.Intent.create(message, batch, []);
15538
+ const proof = chunk2JV4VQ7C_cjs.Intent.create(message, batch, []);
15227
15539
  const signedProof = await identity.sign(
15228
15540
  proof,
15229
15541
  Array.from({ length: batch.length + 1 }, (_, j) => j)
@@ -15442,7 +15754,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15442
15754
  script: recipient.script,
15443
15755
  amount: BigInt(recipient.amount),
15444
15756
  // Already checked against the recipient address in `validateRecipients`.
15445
- ...recipient.tapTree ? { tapTree: chunkG552MISJ_cjs.TapTreeCoder.decode(recipient.tapTree) } : {}
15757
+ ...recipient.tapTree ? { tapTree: chunk2JV4VQ7C_cjs.TapTreeCoder.decode(recipient.tapTree) } : {}
15446
15758
  }));
15447
15759
  const totalBtcOutput = outputs.reduce((sum, o) => sum + Number(o.amount), 0);
15448
15760
  let changeAmount = totalBtcSelected - totalBtcOutput;
@@ -15586,10 +15898,10 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15586
15898
  const serverPubKey = this.arkServerPublicKey;
15587
15899
  const serverUnrollScript = this.serverUnrollScript;
15588
15900
  const arkAddress = offchainTapscript.address(this.network.hrp, serverPubKey);
15589
- const normalizedInputs = inputs.map(chunkG552MISJ_cjs.normalizeVtxo);
15590
- const at = now ?? await chunkG552MISJ_cjs.resolveTimeHeight(this.onchainProvider);
15901
+ const normalizedInputs = inputs.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
15902
+ const at = now ?? await chunk2JV4VQ7C_cjs.resolveTimeHeight(this.onchainProvider);
15591
15903
  for (const input of normalizedInputs) {
15592
- if (!chunkG552MISJ_cjs.canSpendOffchain(input, at)) {
15904
+ if (!chunk2JV4VQ7C_cjs.canSpendOffchain(input, at)) {
15593
15905
  throw new Error(
15594
15906
  `sendSelectedVtxosToSelf: input ${input.txid}:${input.vout} is not cooperatively spendable`
15595
15907
  );
@@ -15659,7 +15971,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15659
15971
  );
15660
15972
  const arkTxJobs = inputs.map((input, index) => ({
15661
15973
  index,
15662
- lookupScript: chunkG552MISJ_cjs.VtxoScript.decode(input.tapTree).pkScript
15974
+ lookupScript: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
15663
15975
  }));
15664
15976
  const identity = this.identity;
15665
15977
  const signer = {
@@ -15745,14 +16057,14 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15745
16057
  const spentBy = checkpointIdByOutpoint.get(`${vtxo.txid}:${vtxo.vout}`);
15746
16058
  spentVtxos.push({
15747
16059
  ...spentFacts,
15748
- virtualStatus: chunkG552MISJ_cjs.toVirtualStatus(spentFacts),
16060
+ virtualStatus: chunk2JV4VQ7C_cjs.toVirtualStatus(spentFacts),
15749
16061
  ...spentBy ? { spentBy } : {},
15750
16062
  arkTxId: arkTxid
15751
16063
  });
15752
16064
  for (const id of vtxo.commitmentTxIds) {
15753
16065
  commitmentTxIds.add(id);
15754
16066
  }
15755
- const vtxoExpiry = chunkG552MISJ_cjs.toBatchExpiry(vtxo);
16067
+ const vtxoExpiry = chunk2JV4VQ7C_cjs.toBatchExpiry(vtxo);
15756
16068
  if (vtxoExpiry) {
15757
16069
  batchExpiry = Math.min(batchExpiry, vtxoExpiry);
15758
16070
  }
@@ -15765,7 +16077,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15765
16077
  isSwept: false,
15766
16078
  isPreconfirmed: true,
15767
16079
  commitmentTxIds: Array.from(commitmentTxIds),
15768
- ...chunkG552MISJ_cjs.parseLegacyExpiry(batchExpiry)
16080
+ ...chunk2JV4VQ7C_cjs.parseLegacyExpiry(batchExpiry)
15769
16081
  };
15770
16082
  changeVtxo = {
15771
16083
  txid: arkTxid,
@@ -15777,7 +16089,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15777
16089
  tapTree: offchainTapscript.encode(),
15778
16090
  value: Number(changeAmount),
15779
16091
  ...changeFacts,
15780
- virtualStatus: chunkG552MISJ_cjs.toVirtualStatus(changeFacts),
16092
+ virtualStatus: chunk2JV4VQ7C_cjs.toVirtualStatus(changeFacts),
15781
16093
  spentBy: "",
15782
16094
  status: {
15783
16095
  confirmed: false
@@ -15846,12 +16158,12 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15846
16158
  const spentVtxos = [];
15847
16159
  const inputArkTxIds = /* @__PURE__ */ new Set();
15848
16160
  const boardingRemovalsByAddress = /* @__PURE__ */ new Map();
15849
- const vtxoInputs = inputs.filter(chunkG552MISJ_cjs.isVirtualCoin);
16161
+ const vtxoInputs = inputs.filter(chunk2JV4VQ7C_cjs.isVirtualCoin);
15850
16162
  const cm = await this.getContractManager();
15851
16163
  const annotatedVtxos = await cm.annotateVtxos(vtxoInputs);
15852
16164
  const annotatedByKey = new Map(annotatedVtxos.map((v) => [`${v.txid}:${v.vout}`, v]));
15853
16165
  for (const input of inputs) {
15854
- if (chunkG552MISJ_cjs.isVirtualCoin(input)) {
16166
+ if (chunk2JV4VQ7C_cjs.isVirtualCoin(input)) {
15855
16167
  const outpoint = `${input.txid}:${input.vout}`;
15856
16168
  const vtxo = annotatedByKey.get(outpoint);
15857
16169
  if (!vtxo) {
@@ -15863,13 +16175,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15863
16175
  const settledFacts = { ...vtxo, isSpent: true };
15864
16176
  spentVtxos.push({
15865
16177
  ...settledFacts,
15866
- virtualStatus: chunkG552MISJ_cjs.toVirtualStatus(settledFacts),
16178
+ virtualStatus: chunk2JV4VQ7C_cjs.toVirtualStatus(settledFacts),
15867
16179
  settledBy: commitmentTxid
15868
16180
  });
15869
16181
  } else {
15870
16182
  let sourceAddress;
15871
16183
  try {
15872
- sourceAddress = chunkG552MISJ_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
16184
+ sourceAddress = chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
15873
16185
  this.network
15874
16186
  );
15875
16187
  } catch {
@@ -15927,9 +16239,9 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
15927
16239
  }
15928
16240
  };
15929
16241
  function selectVirtualCoins(coins, targetAmount) {
15930
- const sortedCoins = coins.map(chunkG552MISJ_cjs.normalizeVtxo).sort((a, b) => {
15931
- const expiryA = chunkG552MISJ_cjs.toBatchExpiry(a) || Number.MAX_SAFE_INTEGER;
15932
- const expiryB = chunkG552MISJ_cjs.toBatchExpiry(b) || Number.MAX_SAFE_INTEGER;
16242
+ const sortedCoins = coins.map(chunk2JV4VQ7C_cjs.normalizeVtxo).sort((a, b) => {
16243
+ const expiryA = chunk2JV4VQ7C_cjs.toBatchExpiry(a) || Number.MAX_SAFE_INTEGER;
16244
+ const expiryB = chunk2JV4VQ7C_cjs.toBatchExpiry(b) || Number.MAX_SAFE_INTEGER;
15933
16245
  if (expiryA !== expiryB) {
15934
16246
  return expiryA - expiryB;
15935
16247
  }
@@ -16048,6 +16360,11 @@ var MessageBus = class {
16048
16360
  buildServicesFn;
16049
16361
  boundOnMessage = this.onMessage.bind(this);
16050
16362
  intentRepository;
16363
+ /** Pending broadcasts, drained FIFO by a single {@link drain} loop. */
16364
+ broadcastQueue = [];
16365
+ draining = false;
16366
+ /** Bumped wherever the generation owning the queued broadcasts ends. */
16367
+ broadcastEpoch = 0;
16051
16368
  /** Start the message bus and attach service-worker event listeners. */
16052
16369
  async start() {
16053
16370
  if (this.running) return;
@@ -16070,6 +16387,7 @@ var MessageBus = class {
16070
16387
  this.running = false;
16071
16388
  this.tickInProgress = false;
16072
16389
  this.initialized = false;
16390
+ this.invalidateBroadcasts();
16073
16391
  if (this.tickTimeout !== null) {
16074
16392
  self.clearTimeout(this.tickTimeout);
16075
16393
  this.tickTimeout = null;
@@ -16082,6 +16400,78 @@ var MessageBus = class {
16082
16400
  self.removeEventListener("message", this.boundOnMessage);
16083
16401
  await Promise.all(Array.from(this.handlers.values()).map((updater) => updater.stop()));
16084
16402
  }
16403
+ /** Invalidate every broadcast belonging to the outgoing generation. */
16404
+ invalidateBroadcasts() {
16405
+ this.broadcastEpoch++;
16406
+ this.broadcastQueue.length = 0;
16407
+ }
16408
+ broadcastToClients(responses) {
16409
+ this.broadcastQueue.push(...responses);
16410
+ void this.drain();
16411
+ }
16412
+ /**
16413
+ * Single fan-out loop, so pushes and tick responses keep one FIFO order.
16414
+ * A helper posting per response would race: `clients.matchAll()` gives no
16415
+ * cross-call resolution order, and it would de-batch `runTick`.
16416
+ */
16417
+ async drain() {
16418
+ if (this.draining) return;
16419
+ this.draining = true;
16420
+ try {
16421
+ while (this.broadcastQueue.length) {
16422
+ const epoch = this.broadcastEpoch;
16423
+ const batch = this.broadcastQueue.splice(0);
16424
+ if (!this.running) {
16425
+ this.logDroppedBroadcasts(batch, "bus stopped");
16426
+ return;
16427
+ }
16428
+ let clients;
16429
+ try {
16430
+ clients = await self.clients.matchAll({
16431
+ includeUncontrolled: true,
16432
+ type: "window"
16433
+ });
16434
+ } catch (err) {
16435
+ this.logDroppedBroadcasts(batch, "clients.matchAll failed", err);
16436
+ continue;
16437
+ }
16438
+ if (!this.running) {
16439
+ this.logDroppedBroadcasts(batch, "bus stopped during matchAll");
16440
+ return;
16441
+ }
16442
+ if (this.broadcastEpoch !== epoch) {
16443
+ this.logDroppedBroadcasts(batch, "re-init landed during matchAll");
16444
+ continue;
16445
+ }
16446
+ for (const message of batch) {
16447
+ for (const client of clients) {
16448
+ try {
16449
+ client.postMessage(message);
16450
+ } catch (err) {
16451
+ if (this.debug)
16452
+ console.warn(`[${message.tag}] broadcast to client failed`, err);
16453
+ }
16454
+ }
16455
+ }
16456
+ }
16457
+ } catch {
16458
+ } finally {
16459
+ this.draining = false;
16460
+ if (this.running && this.broadcastQueue.length) void this.drain();
16461
+ }
16462
+ }
16463
+ /**
16464
+ * A dropped batch has no periodic recovery to fall back on now that events
16465
+ * no longer ride the tick, so name the loss under {@link Options.debug}.
16466
+ */
16467
+ logDroppedBroadcasts(batch, reason, ...error) {
16468
+ if (!this.debug) return;
16469
+ console.warn(
16470
+ `dropping ${batch.length} broadcast(s): ${reason}`,
16471
+ batch.map((response) => response.tag),
16472
+ ...error
16473
+ );
16474
+ }
16085
16475
  scheduleNextTick() {
16086
16476
  if (!this.running) return;
16087
16477
  if (this.tickTimeout !== null) return;
@@ -16110,16 +16500,7 @@ var MessageBus = class {
16110
16500
  if (this.debug)
16111
16501
  console.log(`[${updater.messageTag}] outgoing tick response:`, response);
16112
16502
  if (response && response.length > 0) {
16113
- self.clients.matchAll({
16114
- includeUncontrolled: true,
16115
- type: "window"
16116
- }).then((clients) => {
16117
- for (const message of response) {
16118
- clients.forEach((client) => {
16119
- client.postMessage(message);
16120
- });
16121
- }
16122
- });
16503
+ this.broadcastToClients(response);
16123
16504
  }
16124
16505
  } catch (err) {
16125
16506
  if (this.debug) console.error(`[${updater.messageTag}] tick failed`, err);
@@ -16158,6 +16539,14 @@ var MessageBus = class {
16158
16539
  self.clearTimeout(this.tickTimeout);
16159
16540
  this.tickTimeout = null;
16160
16541
  }
16542
+ this.invalidateBroadcasts();
16543
+ const epoch = this.broadcastEpoch;
16544
+ const channel = {
16545
+ broadcast: (response) => {
16546
+ if (epoch !== this.broadcastEpoch) return;
16547
+ this.broadcastToClients([response]);
16548
+ }
16549
+ };
16161
16550
  if (this.initialized) {
16162
16551
  this.initialized = false;
16163
16552
  await Promise.all(
@@ -16174,9 +16563,7 @@ var MessageBus = class {
16174
16563
  try {
16175
16564
  for (const updater of this.handlers.values()) {
16176
16565
  if (this.debug) console.log(`Starting updater: ${updater.messageTag}`);
16177
- await updater.start(services, {
16178
- walletRepository: this.walletRepository
16179
- });
16566
+ await updater.start(services, { walletRepository: this.walletRepository }, channel);
16180
16567
  started.push(updater);
16181
16568
  }
16182
16569
  } catch (err) {
@@ -16189,7 +16576,7 @@ var MessageBus = class {
16189
16576
  this.initialized = true;
16190
16577
  }
16191
16578
  async buildServices(config) {
16192
- const arkProvider = new chunkG552MISJ_cjs.RestArkProvider(config.arkServer.url);
16579
+ const arkProvider = new chunk2JV4VQ7C_cjs.RestArkProvider(config.arkServer.url);
16193
16580
  const storage = {
16194
16581
  walletRepository: this.walletRepository,
16195
16582
  contractRepository: this.contractRepository,
@@ -16531,7 +16918,7 @@ var offboardNetworkNames = [
16531
16918
  function offboardDestinationScript(destinationAddress) {
16532
16919
  for (const networkName of offboardNetworkNames) {
16533
16920
  try {
16534
- const network = chunkG552MISJ_cjs.networks[networkName];
16921
+ const network = chunk2JV4VQ7C_cjs.networks[networkName];
16535
16922
  const addr = btcSigner.Address(network).decode(destinationAddress);
16536
16923
  return btcSigner.OutScript.encode(addr);
16537
16924
  } catch {
@@ -16595,7 +16982,7 @@ var Ramps = class {
16595
16982
  }
16596
16983
  amount = amount ?? totalAmount;
16597
16984
  const offchainAddress = await this.wallet.getAddress();
16598
- const offchainAddr = chunkG552MISJ_cjs.ArkAddress.decode(offchainAddress);
16985
+ const offchainAddr = chunk2JV4VQ7C_cjs.ArkAddress.decode(offchainAddress);
16599
16986
  const offchainScript = base.hex.encode(offchainAddr.pkScript);
16600
16987
  const outputFee = estimator.evalOffchainOutput({
16601
16988
  amount,
@@ -16655,7 +17042,7 @@ var Ramps = class {
16655
17042
  const filteredVtxos = [];
16656
17043
  let totalAmount = 0n;
16657
17044
  for (const vtxo of vtxos) {
16658
- const inputFee = estimator.evalOffchainInput(chunkG552MISJ_cjs.toOffchainInputFeeParams(vtxo));
17045
+ const inputFee = estimator.evalOffchainInput(chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(vtxo));
16659
17046
  if (inputFee.satoshis >= vtxo.value) {
16660
17047
  continue;
16661
17048
  }
@@ -16846,6 +17233,17 @@ var WalletMessageHandler = class {
16846
17233
  incomingFundsSubscription;
16847
17234
  contractEventsSubscription;
16848
17235
  onNextTick = [];
17236
+ channel;
17237
+ // One counter per subscription field, bumped exactly where that field is
17238
+ // dropped — never where a neighbour's is. They cannot be merged:
17239
+ // `onWalletInitialized` re-subscribes incoming funds while
17240
+ // `ensureContractEventBroadcasting` deliberately keeps its subscription, so
17241
+ // a shared bump would leave the live contract-event emitter permanently
17242
+ // stale, and folding requests in would truncate an in-flight settle.
17243
+ incomingFundsEpoch = 0;
17244
+ contractEventsEpoch = 0;
17245
+ /** Per-request progress callbacks: ends with the handler, not with a re-init. */
17246
+ requestEpoch = 0;
16849
17247
  /**
16850
17248
  * Instantiate a new WalletUpdater.
16851
17249
  * Can override the default `messageTag` allowing more than one updater to run in parallel.
@@ -16856,13 +17254,20 @@ var WalletMessageHandler = class {
16856
17254
  }
16857
17255
  // lifecycle methods
16858
17256
  async start(...params) {
16859
- const [services, repositories] = params;
17257
+ const [services, repositories, channel] = params;
16860
17258
  this.readonlyWallet = services.readonlyWallet;
16861
17259
  this.wallet = services.wallet;
16862
17260
  this.arkProvider = services.arkProvider;
16863
17261
  this.walletRepository = repositories.walletRepository;
17262
+ this.channel = channel;
17263
+ this.onNextTick = [];
16864
17264
  }
16865
17265
  async stop() {
17266
+ this.requestEpoch++;
17267
+ this.incomingFundsEpoch++;
17268
+ this.contractEventsEpoch++;
17269
+ this.channel = void 0;
17270
+ this.onNextTick = [];
16866
17271
  if (this.incomingFundsSubscription) {
16867
17272
  this.incomingFundsSubscription();
16868
17273
  this.incomingFundsSubscription = void 0;
@@ -16885,8 +17290,8 @@ var WalletMessageHandler = class {
16885
17290
  this.indexerProvider = void 0;
16886
17291
  }
16887
17292
  async tick(_now) {
16888
- const results = await Promise.allSettled(this.onNextTick.map((fn) => fn()));
16889
- this.onNextTick = [];
17293
+ const pending = this.onNextTick.splice(0);
17294
+ const results = await Promise.allSettled(pending.map((fn) => fn()));
16890
17295
  return results.map((result) => {
16891
17296
  if (result.status === "fulfilled") {
16892
17297
  return result.value;
@@ -16896,8 +17301,46 @@ var WalletMessageHandler = class {
16896
17301
  }
16897
17302
  }).filter((response) => response !== null);
16898
17303
  }
16899
- scheduleForNextTick(callback) {
16900
- this.onNextTick.push(callback);
17304
+ epochOf(scope) {
17305
+ switch (scope) {
17306
+ case "incomingFunds":
17307
+ return this.incomingFundsEpoch;
17308
+ case "contractEvents":
17309
+ return this.contractEventsEpoch;
17310
+ case "request":
17311
+ return this.requestEpoch;
17312
+ default: {
17313
+ const _exhaustive = scope;
17314
+ throw new Error(`Unknown scope: ${_exhaustive}`);
17315
+ }
17316
+ }
17317
+ }
17318
+ newGeneration(scope) {
17319
+ const born = this.epochOf(scope);
17320
+ const stale = () => born !== this.epochOf(scope);
17321
+ return {
17322
+ get stale() {
17323
+ return stale();
17324
+ }
17325
+ };
17326
+ }
17327
+ /**
17328
+ * A handle rather than a `broadcast(response, epoch)` call, because it can
17329
+ * only be written where the closure it guards is created — an epoch passed
17330
+ * at the call site reads identically whether it guards anything or not.
17331
+ */
17332
+ newEmitter(scope) {
17333
+ const gen = this.newGeneration(scope);
17334
+ return {
17335
+ get stale() {
17336
+ return gen.stale;
17337
+ },
17338
+ emit: (response) => {
17339
+ if (!response || gen.stale) return;
17340
+ if (this.channel) return this.channel.broadcast(response);
17341
+ this.onNextTick.push(() => response);
17342
+ }
17343
+ };
16901
17344
  }
16902
17345
  requireWallet() {
16903
17346
  if (!this.wallet) {
@@ -16926,6 +17369,7 @@ var WalletMessageHandler = class {
16926
17369
  }
16927
17370
  async handleMessage(message) {
16928
17371
  const id = message.id;
17372
+ const emitter = this.newEmitter("request");
16929
17373
  if (message.type === "INIT_WALLET") {
16930
17374
  await this.handleInitWallet(message);
16931
17375
  return this.tagged({
@@ -17194,6 +17638,18 @@ var WalletMessageHandler = class {
17194
17638
  payload: { descriptor }
17195
17639
  });
17196
17640
  }
17641
+ case "GET_NEW_ADDRESSES": {
17642
+ const wallet = this.wallet;
17643
+ if (!wallet) throw new WalletNotInitializedError();
17644
+ const addresses = await wallet.getNewAddresses(
17645
+ message.payload
17646
+ );
17647
+ return this.tagged({
17648
+ id,
17649
+ type: "NEW_ADDRESSES",
17650
+ payload: { addresses }
17651
+ });
17652
+ }
17197
17653
  case "GET_USED_SIGNING_DESCRIPTORS": {
17198
17654
  const wallet = this.wallet;
17199
17655
  const descriptors = isHDWalletCapable(wallet) ? await wallet.getUsedSigningDescriptors(
@@ -17284,8 +17740,8 @@ var WalletMessageHandler = class {
17284
17740
  const wallet = this.requireWallet();
17285
17741
  const vtxoManager = await wallet.getVtxoManager();
17286
17742
  const txid = await vtxoManager.recoverVtxos((e) => {
17287
- this.scheduleForNextTick(
17288
- () => this.tagged({
17743
+ emitter.emit(
17744
+ this.tagged({
17289
17745
  id,
17290
17746
  type: "RECOVER_VTXOS_EVENT",
17291
17747
  payload: e
@@ -17329,8 +17785,8 @@ var WalletMessageHandler = class {
17329
17785
  const wallet = this.requireWallet();
17330
17786
  const vtxoManager = await wallet.getVtxoManager();
17331
17787
  const txid = await vtxoManager.renewVtxos((e) => {
17332
- this.scheduleForNextTick(
17333
- () => this.tagged({
17788
+ emitter.emit(
17789
+ this.tagged({
17334
17790
  id,
17335
17791
  type: "RENEW_VTXOS_EVENT",
17336
17792
  payload: e
@@ -17368,8 +17824,8 @@ var WalletMessageHandler = class {
17368
17824
  const vtxoManager = await wallet.getVtxoManager();
17369
17825
  const report = await vtxoManager.migrateDeprecatedSignerVtxos({
17370
17826
  eventCallback: (e) => {
17371
- this.scheduleForNextTick(
17372
- () => this.tagged({
17827
+ emitter.emit(
17828
+ this.tagged({
17373
17829
  id,
17374
17830
  type: "MIGRATE_DEPRECATED_SIGNER_VTXOS_EVENT",
17375
17831
  payload: e
@@ -17422,7 +17878,7 @@ var WalletMessageHandler = class {
17422
17878
  // Wallet methods
17423
17879
  async handleInitWallet({ payload }) {
17424
17880
  const { arkServerUrl } = payload;
17425
- this.indexerProvider = new chunkXN55B6EP_cjs.RestIndexerProvider(arkServerUrl);
17881
+ this.indexerProvider = new chunkCO3KKSWM_cjs.RestIndexerProvider(arkServerUrl);
17426
17882
  await this.onWalletInitialized();
17427
17883
  }
17428
17884
  /**
@@ -17472,6 +17928,7 @@ var WalletMessageHandler = class {
17472
17928
  intentLocked: offchain.intentLocked,
17473
17929
  recoverable: offchain.recoverable,
17474
17930
  pendingRecovery: offchain.pendingRecovery,
17931
+ unrolled: offchain.unrolled,
17475
17932
  total: totalBoarding + offchain.total,
17476
17933
  assets: offchain.assets,
17477
17934
  availableAssets: offchain.availableAssets
@@ -17482,11 +17939,15 @@ var WalletMessageHandler = class {
17482
17939
  return this.readonlyWallet.getBoardingUtxos();
17483
17940
  }
17484
17941
  async onWalletInitialized() {
17485
- if (!this.readonlyWallet || !this.arkProvider || !this.indexerProvider || !this.walletRepository) {
17942
+ const wallet = this.readonlyWallet;
17943
+ if (!wallet || !this.arkProvider || !this.indexerProvider || !this.walletRepository) {
17486
17944
  return;
17487
17945
  }
17946
+ const init = this.newGeneration("incomingFunds");
17488
17947
  await this.ensureContractEventBroadcasting();
17948
+ if (init.stale) return;
17489
17949
  await this.refreshCachedData();
17950
+ if (init.stale) return;
17490
17951
  if (this.wallet) {
17491
17952
  try {
17492
17953
  const vtxos = await this.getVtxosFromRepo();
@@ -17499,72 +17960,81 @@ var WalletMessageHandler = class {
17499
17960
  } catch (error) {
17500
17961
  console.error("Error recovering pending transactions:", error);
17501
17962
  }
17963
+ if (init.stale) return;
17502
17964
  }
17503
17965
  if (this.incomingFundsSubscription) this.incomingFundsSubscription();
17504
- const address = await this.readonlyWallet.getAddress();
17505
- this.incomingFundsSubscription = await this.readonlyWallet.notifyIncomingFunds(
17506
- async (funds) => {
17507
- if (funds.type === "vtxo") {
17508
- const { newVtxos, spentVtxos } = funds;
17509
- if (newVtxos.length + spentVtxos.length === 0) return;
17510
- const byScript = /* @__PURE__ */ new Map();
17511
- for (const v of [...newVtxos, ...spentVtxos]) {
17512
- if (!v.script) {
17513
- console.warn(
17514
- `WalletMessageHandler.notifyIncomingFunds: dropping VTXO without script ${v.txid}:${v.vout}`
17515
- );
17516
- continue;
17517
- }
17518
- const arr = byScript.get(v.script) ?? [];
17519
- arr.push(v);
17520
- byScript.set(v.script, arr);
17521
- }
17522
- let walletScript;
17523
- try {
17524
- walletScript = scriptFromArkAddress(address);
17525
- } catch {
17526
- walletScript = void 0;
17527
- }
17528
- const cm = await this.readonlyWallet.getContractManager();
17529
- const contracts = await cm.getContracts();
17530
- const addrByScript = new Map(contracts.map((c) => [c.script, c.address]));
17531
- for (const [script, vtxos] of byScript) {
17532
- const filtered = warnAndFilterVtxosForScript(
17533
- vtxos,
17534
- script,
17535
- "WalletMessageHandler.notifyIncomingFunds"
17966
+ this.incomingFundsSubscription = void 0;
17967
+ this.incomingFundsEpoch++;
17968
+ const emitter = this.newEmitter("incomingFunds");
17969
+ const address = await wallet.getAddress();
17970
+ const unsubscribe = await wallet.notifyIncomingFunds(async (funds) => {
17971
+ if (emitter.stale) return;
17972
+ if (funds.type === "vtxo") {
17973
+ const { newVtxos, spentVtxos } = funds;
17974
+ if (newVtxos.length + spentVtxos.length === 0) return;
17975
+ const byScript = /* @__PURE__ */ new Map();
17976
+ for (const v of [...newVtxos, ...spentVtxos]) {
17977
+ if (!v.script) {
17978
+ console.warn(
17979
+ `WalletMessageHandler.notifyIncomingFunds: dropping VTXO without script ${v.txid}:${v.vout}`
17536
17980
  );
17537
- if (filtered.length === 0) continue;
17538
- const targetAddress = script === walletScript ? address : addrByScript.get(script);
17539
- if (!targetAddress) continue;
17540
- if (this.walletRepository) {
17541
- await saveVtxosForContract(
17542
- this.walletRepository,
17543
- { script, address: targetAddress },
17544
- filtered
17545
- );
17546
- }
17981
+ continue;
17547
17982
  }
17548
- this.scheduleForNextTick(
17549
- () => this.tagged({
17550
- type: "VTXO_UPDATE",
17551
- broadcast: true,
17552
- payload: { newVtxos, spentVtxos }
17553
- })
17554
- );
17983
+ const arr = byScript.get(v.script) ?? [];
17984
+ arr.push(v);
17985
+ byScript.set(v.script, arr);
17555
17986
  }
17556
- if (funds.type === "utxo") {
17557
- const utxos = await this.readonlyWallet.getBoardingUtxos();
17558
- this.scheduleForNextTick(
17559
- () => this.tagged({
17560
- type: "UTXO_UPDATE",
17561
- broadcast: true,
17562
- payload: { coins: utxos }
17563
- })
17987
+ let walletScript;
17988
+ try {
17989
+ walletScript = scriptFromArkAddress(address);
17990
+ } catch {
17991
+ walletScript = void 0;
17992
+ }
17993
+ const cm = await wallet.getContractManager();
17994
+ if (emitter.stale) return;
17995
+ const contracts = await cm.getContracts();
17996
+ if (emitter.stale) return;
17997
+ const addrByScript = new Map(contracts.map((c) => [c.script, c.address]));
17998
+ for (const [script, vtxos] of byScript) {
17999
+ const filtered = warnAndFilterVtxosForScript(
18000
+ vtxos,
18001
+ script,
18002
+ "WalletMessageHandler.notifyIncomingFunds"
17564
18003
  );
18004
+ if (filtered.length === 0) continue;
18005
+ const targetAddress = script === walletScript ? address : addrByScript.get(script);
18006
+ if (!targetAddress) continue;
18007
+ if (this.walletRepository) {
18008
+ if (emitter.stale) return;
18009
+ await saveVtxosForContract(
18010
+ this.walletRepository,
18011
+ { script, address: targetAddress },
18012
+ filtered
18013
+ );
18014
+ }
17565
18015
  }
18016
+ emitter.emit(
18017
+ this.tagged({
18018
+ type: "VTXO_UPDATE",
18019
+ broadcast: true,
18020
+ payload: { newVtxos, spentVtxos }
18021
+ })
18022
+ );
17566
18023
  }
17567
- );
18024
+ if (funds.type === "utxo") {
18025
+ if (emitter.stale) return;
18026
+ const utxos = await wallet.getBoardingUtxos();
18027
+ emitter.emit(
18028
+ this.tagged({
18029
+ type: "UTXO_UPDATE",
18030
+ broadcast: true,
18031
+ payload: { coins: utxos }
18032
+ })
18033
+ );
18034
+ }
18035
+ });
18036
+ if (emitter.stale) return unsubscribe();
18037
+ this.incomingFundsSubscription = unsubscribe;
17568
18038
  if (this.wallet) {
17569
18039
  try {
17570
18040
  await this.wallet.getVtxoManager();
@@ -17609,10 +18079,11 @@ var WalletMessageHandler = class {
17609
18079
  await this.refreshCachedData();
17610
18080
  }
17611
18081
  async handleSettle(message) {
18082
+ const emitter = this.newEmitter("request");
17612
18083
  const wallet = this.requireWallet();
17613
18084
  const txid = await wallet.settle(message.payload.params, (e) => {
17614
- this.scheduleForNextTick(
17615
- () => this.tagged({
18085
+ emitter.emit(
18086
+ this.tagged({
17616
18087
  id: message.id,
17617
18088
  type: "SETTLE_EVENT",
17618
18089
  payload: e
@@ -17689,30 +18160,39 @@ var WalletMessageHandler = class {
17689
18160
  throw new WalletNotInitializedError();
17690
18161
  }
17691
18162
  const allVtxos = await this.getVtxosFromRepo();
17692
- const vtxos = allVtxos.filter((v) => !chunkG552MISJ_cjs.hasTerminalSpend(v));
17693
18163
  const dustAmount = this.readonlyWallet.dustAmount;
18164
+ const withUnrolled = message.payload.filter?.withUnrolled ?? false;
17694
18165
  const includeRecoverable = message.payload.filter?.withRecoverable ?? false;
17695
- const filteredVtxos = includeRecoverable ? vtxos : vtxos.filter((v) => {
18166
+ return allVtxos.filter((v) => {
18167
+ if (v.isUnrolled) {
18168
+ return withUnrolled;
18169
+ }
18170
+ if (chunk2JV4VQ7C_cjs.hasTerminalSpend(v)) {
18171
+ return false;
18172
+ }
18173
+ if (includeRecoverable) {
18174
+ return true;
18175
+ }
17696
18176
  if (dustAmount != null && isSubdust(v, dustAmount)) {
17697
18177
  return false;
17698
18178
  }
17699
- if (chunkG552MISJ_cjs.isRecoverable(v)) {
18179
+ if (chunk2JV4VQ7C_cjs.isRecoverable(v)) {
17700
18180
  return false;
17701
18181
  }
17702
- if (chunkG552MISJ_cjs.isExpired(v)) {
18182
+ if (chunk2JV4VQ7C_cjs.isExpired(v)) {
17703
18183
  return false;
17704
18184
  }
17705
18185
  return true;
17706
18186
  });
17707
- if (!message.payload.filter?.withUnrolled) {
17708
- return filteredVtxos;
17709
- }
17710
- return filteredVtxos.concat(allVtxos.filter((v) => chunkG552MISJ_cjs.hasTerminalSpend(v) && v.isUnrolled));
17711
18187
  }
17712
18188
  /** Tear down handler subscriptions, then delegate the full wipe to the wallet. */
17713
18189
  async clear() {
17714
18190
  const wallet = this.wallet ?? this.readonlyWallet;
17715
18191
  if (!wallet) return;
18192
+ this.requestEpoch++;
18193
+ this.incomingFundsEpoch++;
18194
+ this.contractEventsEpoch++;
18195
+ this.onNextTick = [];
17716
18196
  if (this.incomingFundsSubscription) {
17717
18197
  this.incomingFundsSubscription();
17718
18198
  this.incomingFundsSubscription = void 0;
@@ -17797,17 +18277,21 @@ var WalletMessageHandler = class {
17797
18277
  if (!this.readonlyWallet) return null;
17798
18278
  const { boardingTxs, commitmentsToIgnore } = await this.readonlyWallet.getBoardingTxs();
17799
18279
  const indexerProvider = this.indexerProvider;
17800
- const resolveTxCreatedAt = indexerProvider ? (txids) => chunkG552MISJ_cjs.fetchVtxoCreatedAtByTxid(indexerProvider, txids) : void 0;
18280
+ const resolveTxCreatedAt = indexerProvider ? (txids) => chunk2JV4VQ7C_cjs.fetchVtxoCreatedAtByTxid(indexerProvider, txids) : void 0;
17801
18281
  return buildTransactionHistory(vtxos, boardingTxs, commitmentsToIgnore, resolveTxCreatedAt);
17802
18282
  }
17803
18283
  async ensureContractEventBroadcasting() {
17804
- if (!this.readonlyWallet) return;
18284
+ const wallet = this.readonlyWallet;
18285
+ if (!wallet) return;
17805
18286
  if (this.contractEventsSubscription) return;
18287
+ const gen = this.newGeneration("contractEvents");
17806
18288
  try {
17807
- const manager = await this.readonlyWallet.getContractManager();
18289
+ const manager = await wallet.getContractManager();
18290
+ if (gen.stale || this.contractEventsSubscription) return;
18291
+ const emitter = this.newEmitter("contractEvents");
17808
18292
  this.contractEventsSubscription = manager.onContractEvent((event) => {
17809
- this.scheduleForNextTick(
17810
- () => this.tagged({
18293
+ emitter.emit(
18294
+ this.tagged({
17811
18295
  type: "CONTRACT_EVENT",
17812
18296
  broadcast: true,
17813
18297
  payload: { event }
@@ -17838,6 +18322,9 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
17838
18322
  // Allocation is a local repository write plus a fire-and-forget band
17839
18323
  // slide — no indexer round trip on the request path.
17840
18324
  GET_NEXT_SIGNING_DESCRIPTOR: 1e4,
18325
+ // Same shape as the bare allocation above, plus one contract write per
18326
+ // requested type — still local, still no indexer round trip.
18327
+ GET_NEW_ADDRESSES: 1e4,
17841
18328
  GET_USED_SIGNING_DESCRIPTORS: 2e4,
17842
18329
  ADVANCE_SIGNING_DESCRIPTOR_WATERMARK: 1e4,
17843
18330
  // Medium reads — may involve indexer queries
@@ -18486,7 +18973,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
18486
18973
  };
18487
18974
  try {
18488
18975
  const response = await this.sendMessage(message);
18489
- return response.payload.vtxos.map(chunkG552MISJ_cjs.normalizeVtxo);
18976
+ return response.payload.vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
18490
18977
  } catch (error) {
18491
18978
  throw new Error(`Failed to get vtxos: ${error}`);
18492
18979
  }
@@ -18511,7 +18998,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
18511
18998
  };
18512
18999
  try {
18513
19000
  const response = await this.sendMessage(message);
18514
- return response.payload.vtxos.map(chunkG552MISJ_cjs.normalizeVtxo);
19001
+ return response.payload.vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
18515
19002
  } catch (error) {
18516
19003
  throw new Error(`Failed to get spendable vtxos: ${error}`);
18517
19004
  }
@@ -18642,7 +19129,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
18642
19129
  };
18643
19130
  try {
18644
19131
  const response = await sendContractMessage(message);
18645
- return response.payload.vtxos.map(chunkG552MISJ_cjs.normalizeVtxo);
19132
+ return response.payload.vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
18646
19133
  } catch (e) {
18647
19134
  throw new Error("Failed to annotate vtxos");
18648
19135
  }
@@ -18983,6 +19470,35 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
18983
19470
  throw new Error(`Failed to allocate next signing descriptor: ${error}`);
18984
19471
  }
18985
19472
  }
19473
+ /**
19474
+ * @see Wallet.getNewAddresses
19475
+ *
19476
+ * Proxied as a single request rather than rebuilt page-side out of
19477
+ * {@link getNextSigningDescriptor}: the worker owns the HD watermark *and*
19478
+ * the contract repository, so splitting the operation would let a page burn
19479
+ * an index and then fail to register the script, leaving an address nothing
19480
+ * watches.
19481
+ *
19482
+ * Note the error shape — `WalletCannotAllocateAddressError` is thrown
19483
+ * worker-side and cannot cross the message boundary as a class, so a
19484
+ * `forceNew` refusal surfaces here as a plain `Error` carrying its message
19485
+ * (and the worker-side error as `cause`). Callers that must branch on the
19486
+ * refusal match the message rather than `instanceof`.
19487
+ */
19488
+ async getNewAddresses(opts) {
19489
+ const message = {
19490
+ id: getRandomId(),
19491
+ tag: this.messageTag,
19492
+ type: "GET_NEW_ADDRESSES",
19493
+ ...opts ? { payload: opts } : {}
19494
+ };
19495
+ try {
19496
+ const response = await this.sendMessage(message);
19497
+ return response.payload.addresses;
19498
+ } catch (error) {
19499
+ throw new Error(`Failed to allocate new addresses: ${error}`, { cause: error });
19500
+ }
19501
+ }
18986
19502
  /** @see HDWalletCapable.getUsedSigningDescriptors */
18987
19503
  async getUsedSigningDescriptors(opts) {
18988
19504
  const message = {
@@ -19214,7 +19730,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
19214
19730
  };
19215
19731
  try {
19216
19732
  const response = await wallet.sendMessage(message);
19217
- return response.payload.vtxos.map(chunkG552MISJ_cjs.normalizeVtxo);
19733
+ return response.payload.vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
19218
19734
  } catch (e) {
19219
19735
  throw new Error(`Failed to get expiring vtxos: ${e}`);
19220
19736
  }
@@ -19326,12 +19842,12 @@ var OnchainWallet = class _OnchainWallet {
19326
19842
  * @returns Configured onchain wallet
19327
19843
  * @throws Error if the configured identity cannot produce a valid x-only public key
19328
19844
  */
19329
- static async create(identity, networkName = chunkG552MISJ_cjs.DEFAULT_NETWORK_NAME, provider) {
19845
+ static async create(identity, networkName = chunk2JV4VQ7C_cjs.DEFAULT_NETWORK_NAME, provider) {
19330
19846
  const pubkey = await identity.xOnlyPublicKey();
19331
19847
  if (!pubkey) {
19332
19848
  throw new Error("Invalid configured public key");
19333
19849
  }
19334
- const network = chunkG552MISJ_cjs.getNetwork(networkName);
19850
+ const network = chunk2JV4VQ7C_cjs.getNetwork(networkName);
19335
19851
  const onchainProvider = provider || new EsploraProvider(ESPLORA_URL[networkName]);
19336
19852
  const onchainP2TR = btcSigner.p2tr(pubkey, void 0, network);
19337
19853
  return new _OnchainWallet(identity, network, onchainP2TR, onchainProvider);
@@ -19437,7 +19953,7 @@ var OnchainWallet = class _OnchainWallet {
19437
19953
  if (!inputs) {
19438
19954
  throw new Error("Fee estimation failed");
19439
19955
  }
19440
- let tx = new chunkG552MISJ_cjs.Transaction();
19956
+ let tx = new chunk2JV4VQ7C_cjs.Transaction();
19441
19957
  for (const input of inputs) {
19442
19958
  tx.addInput({
19443
19959
  txid: input.txid,
@@ -19495,7 +20011,7 @@ var OnchainWallet = class _OnchainWallet {
19495
20011
  * @throws If the parent has no anchor, or funding cannot be selected/signed
19496
20012
  */
19497
20013
  async bumpAnchor(parentHex, feeRate) {
19498
- const parent = chunkG552MISJ_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
20014
+ const parent = chunk2JV4VQ7C_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
19499
20015
  const coins = (await this.getCoins()).filter((c) => c.status.confirmed);
19500
20016
  const child = await this.buildBumpPackage(parent, feeRate, coins);
19501
20017
  return [parent.hex, child.hex];
@@ -19949,6 +20465,10 @@ var ElectrumOnchainProvider = class {
19949
20465
  }
19950
20466
  throw new Error("Only 1 or 1P1C package can be broadcast");
19951
20467
  }
20468
+ async getRawTransaction(txid) {
20469
+ const [tx] = await this.chain.fetchTransactions([txid]);
20470
+ return base.hex.decode(tx.hex);
20471
+ }
19952
20472
  async getTxOutspends(txid) {
19953
20473
  const [txResult] = await this.chain.fetchTransactions([txid]);
19954
20474
  const tx = btcSigner.Transaction.fromRaw(base.hex.decode(txResult.hex), {
@@ -20254,13 +20774,190 @@ function childTxidFromHex(txHex) {
20254
20774
  });
20255
20775
  return tx.id;
20256
20776
  }
20777
+
20778
+ // src/providers/cachingArk.ts
20779
+ var DEFAULT_TTL_MS = 6e4;
20780
+ var CachingArkProvider = class {
20781
+ constructor(inner, ttlMs = DEFAULT_TTL_MS) {
20782
+ this.inner = inner;
20783
+ this.ttlMs = ttlMs;
20784
+ this.unsubscribe = inner.onServerInfoChanged?.((info) => {
20785
+ this.cached = info;
20786
+ this.expiresAt = Date.now() + this.ttlMs;
20787
+ this.generation++;
20788
+ }) ?? (() => {
20789
+ });
20790
+ }
20791
+ inner;
20792
+ ttlMs;
20793
+ cached;
20794
+ expiresAt = 0;
20795
+ inflight;
20796
+ /** Bumped on every event-driven cache write; see {@link getInfo}. */
20797
+ generation = 0;
20798
+ unsubscribe;
20799
+ /** Releases the inner provider's server-info subscription. */
20800
+ dispose() {
20801
+ this.unsubscribe();
20802
+ }
20803
+ get serverUrl() {
20804
+ const url = this.inner.serverUrl;
20805
+ return typeof url === "string" ? url : void 0;
20806
+ }
20807
+ async getInfo() {
20808
+ if (this.cached && Date.now() < this.expiresAt) return this.cached;
20809
+ if (!this.inflight) {
20810
+ const generation = this.generation;
20811
+ this.inflight = this.inner.getInfo().then((info) => {
20812
+ if (this.generation !== generation) return this.cached ?? info;
20813
+ this.cached = info;
20814
+ this.expiresAt = Date.now() + this.ttlMs;
20815
+ return info;
20816
+ }).finally(() => {
20817
+ this.inflight = void 0;
20818
+ });
20819
+ }
20820
+ return this.inflight;
20821
+ }
20822
+ submitTx(signedArkTx, checkpointTxs) {
20823
+ return this.inner.submitTx(signedArkTx, checkpointTxs);
20824
+ }
20825
+ finalizeTx(arkTxid, finalCheckpointTxs) {
20826
+ return this.inner.finalizeTx(arkTxid, finalCheckpointTxs);
20827
+ }
20828
+ registerIntent(intent) {
20829
+ return this.inner.registerIntent(intent);
20830
+ }
20831
+ deleteIntent(intent) {
20832
+ return this.inner.deleteIntent(intent);
20833
+ }
20834
+ confirmRegistration(intentId) {
20835
+ return this.inner.confirmRegistration(intentId);
20836
+ }
20837
+ submitTreeNonces(batchId, pubkey, nonces) {
20838
+ return this.inner.submitTreeNonces(batchId, pubkey, nonces);
20839
+ }
20840
+ submitTreeSignatures(batchId, pubkey, signatures) {
20841
+ return this.inner.submitTreeSignatures(batchId, pubkey, signatures);
20842
+ }
20843
+ submitSignedForfeitTxs(signedForfeitTxs, signedCommitmentTx) {
20844
+ return this.inner.submitSignedForfeitTxs(signedForfeitTxs, signedCommitmentTx);
20845
+ }
20846
+ getEventStream(signal, topics) {
20847
+ return this.inner.getEventStream(signal, topics);
20848
+ }
20849
+ getTransactionsStream(signal) {
20850
+ return this.inner.getTransactionsStream(signal);
20851
+ }
20852
+ getPendingTxs(intent) {
20853
+ return this.inner.getPendingTxs(intent);
20854
+ }
20855
+ onServerInfoChanged(listener) {
20856
+ return this.inner.onServerInfoChanged?.(listener) ?? (() => {
20857
+ });
20858
+ }
20859
+ };
20860
+ var PrevTxUnavailableError = class extends Error {
20861
+ constructor(message, txids = []) {
20862
+ super(message);
20863
+ this.txids = txids;
20864
+ this.name = "PrevTxUnavailableError";
20865
+ }
20866
+ txids;
20867
+ };
20868
+ async function resolvePrevTxs(txids, source, onchain) {
20869
+ const resolved = /* @__PURE__ */ new Map();
20870
+ const wanted = [...new Set(txids)];
20871
+ if (wanted.length === 0) return resolved;
20872
+ try {
20873
+ const { txs } = await source.getVirtualTxs(wanted);
20874
+ for (const psbt of txs) {
20875
+ const tx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbt));
20876
+ resolved.set(tx.id, tx.toBytes());
20877
+ }
20878
+ } catch (err) {
20879
+ if (!onchain) throw err;
20880
+ }
20881
+ let missing = wanted.filter((txid) => !resolved.has(txid));
20882
+ if (missing.length > 0 && onchain) {
20883
+ const raw = await Promise.all(
20884
+ missing.map(async (txid) => {
20885
+ try {
20886
+ return await onchain.getRawTransaction(txid);
20887
+ } catch {
20888
+ return void 0;
20889
+ }
20890
+ })
20891
+ );
20892
+ for (const [i, bytes] of raw.entries()) {
20893
+ if (bytes) resolved.set(missing[i], bytes);
20894
+ }
20895
+ missing = missing.filter((txid) => !resolved.has(txid));
20896
+ }
20897
+ if (missing.length > 0) {
20898
+ throw new PrevTxUnavailableError(
20899
+ `cannot resolve the previous transaction of ${missing.join(", ")}` + (onchain ? "" : " (no onchain source configured)"),
20900
+ missing
20901
+ );
20902
+ }
20903
+ return resolved;
20904
+ }
20905
+ async function attachPrevArkTxs(tx, txids, source, onchain) {
20906
+ const pending = [];
20907
+ for (let i = 0; i < tx.inputsLength; i++) {
20908
+ if (chunk2JV4VQ7C_cjs.getArkPsbtFields(tx, i, chunk2JV4VQ7C_cjs.PrevArkTxField).length === 0) pending.push(i);
20909
+ }
20910
+ if (pending.length === 0) return;
20911
+ const resolved = await resolvePrevTxs(
20912
+ pending.map((i) => txidAt(txids, i)),
20913
+ source,
20914
+ onchain
20915
+ );
20916
+ for (const i of pending) {
20917
+ chunk2JV4VQ7C_cjs.setArkPsbtField(tx, i, chunk2JV4VQ7C_cjs.PrevArkTxField, resolved.get(txidAt(txids, i)));
20918
+ }
20919
+ }
20920
+ async function attachPrevoutTxs(tx, source) {
20921
+ const pending = [];
20922
+ for (let i = 0; i < tx.inputsLength; i++) {
20923
+ if (chunk2JV4VQ7C_cjs.getArkPsbtFields(tx, i, chunk2JV4VQ7C_cjs.PrevoutTxField).length > 0) continue;
20924
+ const input = tx.getInput(i);
20925
+ if (!input?.txid) throw new PrevTxUnavailableError(`input ${i} has no outpoint`);
20926
+ pending.push({ index: i, txid: base.hex.encode(input.txid) });
20927
+ }
20928
+ if (pending.length === 0) return;
20929
+ const resolved = /* @__PURE__ */ new Map();
20930
+ for (const txid of new Set(pending.map((p) => p.txid))) {
20931
+ resolved.set(txid, await source.getRawTransaction(txid));
20932
+ }
20933
+ for (const { index, txid } of pending) {
20934
+ chunk2JV4VQ7C_cjs.setArkPsbtField(tx, index, chunk2JV4VQ7C_cjs.PrevoutTxField, resolved.get(txid));
20935
+ }
20936
+ }
20937
+ async function withPrevTxs(coins, source, onchain) {
20938
+ const pending = coins.filter((c) => !c.prevTx);
20939
+ if (pending.length === 0) return coins;
20940
+ const resolved = await resolvePrevTxs(
20941
+ pending.map((c) => c.txid),
20942
+ source,
20943
+ onchain
20944
+ );
20945
+ return coins.map((c) => c.prevTx ? c : { ...c, prevTx: resolved.get(c.txid) });
20946
+ }
20947
+ function txidAt(txids, index) {
20948
+ const txid = txids[index];
20949
+ if (txid === void 0) {
20950
+ throw new PrevTxUnavailableError(`no source txid supplied for input ${index}`);
20951
+ }
20952
+ return txid;
20953
+ }
20257
20954
  var TAG_BIP322 = "BIP0322-signed-message";
20258
20955
  exports.BIP322 = void 0;
20259
20956
  ((BIP3222) => {
20260
20957
  async function sign2(message, identity, network) {
20261
20958
  const xOnlyPubKey = await identity.xOnlyPublicKey();
20262
20959
  const payment = btcSigner.p2tr(xOnlyPubKey, void 0, network);
20263
- const toSpend = chunkG552MISJ_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
20960
+ const toSpend = chunk2JV4VQ7C_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
20264
20961
  const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
20265
20962
  const signed = await identity.sign(toSign, [0]);
20266
20963
  signed.finalizeIdx(0);
@@ -20318,7 +21015,7 @@ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
20318
21015
  if (sighashType !== btcSigner.SigHash.DEFAULT && sighashType !== btcSigner.SigHash.ALL) {
20319
21016
  return false;
20320
21017
  }
20321
- const toSpend = chunkG552MISJ_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
21018
+ const toSpend = chunk2JV4VQ7C_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
20322
21019
  const toSign = craftBIP322ToSignP2TR(toSpend, pkScript, pubkey);
20323
21020
  const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
20324
21021
  const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
@@ -20339,7 +21036,7 @@ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
20339
21036
  }
20340
21037
  const sighashType = sigWithHash[sigWithHash.length - 1];
20341
21038
  const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
20342
- const toSpend = chunkG552MISJ_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
21039
+ const toSpend = chunk2JV4VQ7C_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
20343
21040
  const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
20344
21041
  const scriptCode = btcSigner.OutScript.encode({ type: "pkh", hash: addressHash });
20345
21042
  const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
@@ -20392,7 +21089,7 @@ function encodeCompactSize(n) {
20392
21089
  return buf;
20393
21090
  }
20394
21091
  function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
20395
- const tx = new chunkG552MISJ_cjs.Transaction({ version: 0 });
21092
+ const tx = new chunk2JV4VQ7C_cjs.Transaction({ version: 0 });
20396
21093
  tx.addInput({
20397
21094
  txid: toSpend.id,
20398
21095
  index: 0,
@@ -20406,12 +21103,12 @@ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
20406
21103
  });
20407
21104
  tx.addOutput({
20408
21105
  amount: 0n,
20409
- script: chunkG552MISJ_cjs.OP_RETURN_EMPTY_PKSCRIPT
21106
+ script: chunk2JV4VQ7C_cjs.OP_RETURN_EMPTY_PKSCRIPT
20410
21107
  });
20411
21108
  return tx;
20412
21109
  }
20413
21110
  function craftBIP322ToSignSimple(toSpend, pkScript) {
20414
- const tx = new chunkG552MISJ_cjs.Transaction({ version: 0 });
21111
+ const tx = new chunk2JV4VQ7C_cjs.Transaction({ version: 0 });
20415
21112
  tx.addInput({
20416
21113
  txid: toSpend.id,
20417
21114
  index: 0,
@@ -20423,7 +21120,7 @@ function craftBIP322ToSignSimple(toSpend, pkScript) {
20423
21120
  });
20424
21121
  tx.addOutput({
20425
21122
  amount: 0n,
20426
- script: chunkG552MISJ_cjs.OP_RETURN_EMPTY_PKSCRIPT
21123
+ script: chunk2JV4VQ7C_cjs.OP_RETURN_EMPTY_PKSCRIPT
20427
21124
  });
20428
21125
  return tx;
20429
21126
  }
@@ -20554,7 +21251,7 @@ var RestEmulatorProvider = class {
20554
21251
  }
20555
21252
  };
20556
21253
  function finalizeVirtualTx(type, psbtBase64) {
20557
- const tx = chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
21254
+ const tx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
20558
21255
  if (type === "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */) {
20559
21256
  const input = tx.getInput(0);
20560
21257
  if (!input) {
@@ -20581,14 +21278,14 @@ var ExitPathError = class extends Error {
20581
21278
  reason;
20582
21279
  };
20583
21280
  function delayWeight(sequence) {
20584
- const t = chunkG552MISJ_cjs.sequenceToTimelock(sequence);
21281
+ const t = chunk2JV4VQ7C_cjs.sequenceToTimelock(sequence);
20585
21282
  return t.type === "blocks" ? Number(t.value) : Number(t.value) / 600;
20586
21283
  }
20587
21284
  async function resolveUnilateralPath(params) {
20588
21285
  const { vtxo, scriptHex, contractRepository } = params;
20589
21286
  const contract = contractRepository ? (await contractRepository.getContracts({ script: scriptHex }))[0] : void 0;
20590
21287
  if (contract) {
20591
- const handler = chunkBABJ77NG_cjs.contractHandlers.get(contract.type);
21288
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
20592
21289
  if (!handler) {
20593
21290
  throw new ExitPathError(
20594
21291
  "no-handler",
@@ -20611,12 +21308,12 @@ async function resolveUnilateralPath(params) {
20611
21308
  paths.sort((a, b) => delayWeight(a.sequence) - delayWeight(b.sequence));
20612
21309
  return { selection: paths[0], label: `${contract.type}:unilateral` };
20613
21310
  }
20614
- const decoded = chunkG552MISJ_cjs.VtxoScript.decode(vtxo.tapTree);
21311
+ const decoded = chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree);
20615
21312
  let best;
20616
21313
  for (const exit of decoded.exitPaths()) {
20617
21314
  const leaf = decoded.findLeaf(base.hex.encode(exit.script));
20618
21315
  if (!leaf) continue;
20619
- const sequence = chunkG552MISJ_cjs.timelockToSequence(exit.params.timelock);
21316
+ const sequence = chunk2JV4VQ7C_cjs.timelockToSequence(exit.params.timelock);
20620
21317
  const weight = delayWeight(sequence);
20621
21318
  if (!best || weight < best.weight) {
20622
21319
  best = { selection: { leaf, sequence }, weight };
@@ -20631,6 +21328,22 @@ async function resolveUnilateralPath(params) {
20631
21328
  return { selection: best.selection, label: "default:exit" };
20632
21329
  }
20633
21330
 
21331
+ // src/wallet/exitObserver.ts
21332
+ function exitObserverFor(manager) {
21333
+ return (outpoint) => manager.refreshOutpoints([outpoint]);
21334
+ }
21335
+ async function notifyExitObserved(onExitObserved, outpoint) {
21336
+ if (!onExitObserved) return;
21337
+ try {
21338
+ await onExitObserved(outpoint);
21339
+ } catch (e) {
21340
+ console.error(
21341
+ `exit observer failed for ${outpoint.txid}:${outpoint.vout} \u2014 the exit is unaffected`,
21342
+ e
21343
+ );
21344
+ }
21345
+ }
21346
+
20634
21347
  // src/wallet/unroll.ts
20635
21348
  function chainTxTypeToChainedExit2(t) {
20636
21349
  switch (t) {
@@ -20655,27 +21368,30 @@ exports.Unroll = void 0;
20655
21368
  })(Unroll2.StepType || (Unroll2.StepType = {}));
20656
21369
  class Session2 {
20657
21370
  /** Create an unroll session from a virtual output outpoint and its dependency chain. */
20658
- constructor(toUnroll, bumper, explorer, indexer, virtualTxRepository) {
21371
+ constructor(toUnroll, bumper, explorer, indexer, virtualTxRepository, onExitObserved) {
20659
21372
  this.toUnroll = toUnroll;
20660
21373
  this.bumper = bumper;
20661
21374
  this.explorer = explorer;
20662
21375
  this.indexer = indexer;
20663
21376
  this.virtualTxRepository = virtualTxRepository;
21377
+ this.onExitObserved = onExitObserved;
20664
21378
  }
20665
21379
  toUnroll;
20666
21380
  bumper;
20667
21381
  explorer;
20668
21382
  indexer;
20669
21383
  virtualTxRepository;
21384
+ onExitObserved;
20670
21385
  /** Create an unroll session by loading the virtual output chain from the indexer. */
20671
- static async create(toUnroll, bumper, explorer, indexer, virtualTxRepository) {
21386
+ static async create(toUnroll, bumper, explorer, indexer, virtualTxRepository, onExitObserved) {
20672
21387
  const { chain } = await indexer.getVtxoChain(toUnroll);
20673
21388
  return new Session2(
20674
21389
  { ...toUnroll, chain },
20675
21390
  bumper,
20676
21391
  explorer,
20677
21392
  indexer,
20678
- virtualTxRepository
21393
+ virtualTxRepository,
21394
+ onExitObserved
20679
21395
  );
20680
21396
  }
20681
21397
  /**
@@ -20711,6 +21427,14 @@ exports.Unroll = void 0;
20711
21427
  }
20712
21428
  /**
20713
21429
  * Get the next step to be executed
21430
+ *
21431
+ * @remarks
21432
+ * `do()` is the step, not a formality: every effect lives there, and at
21433
+ * `StepType.DONE` that includes firing {@link onExitObserved}. A caller
21434
+ * driving `next()` by hand must always await it — the async iterator
21435
+ * below does. Reading `type` and skipping `do()` leaves the exit
21436
+ * unobserved, and on the other step kinds unbroadcast.
21437
+ *
20714
21438
  * @returns The next step to be executed + the function to execute it
20715
21439
  */
20716
21440
  async next() {
@@ -20739,7 +21463,12 @@ exports.Unroll = void 0;
20739
21463
  return {
20740
21464
  type: 2 /* DONE */,
20741
21465
  vtxoTxid: this.toUnroll.txid,
20742
- do: () => Promise.resolve()
21466
+ // The observation rides on `do` rather than the iterator so
21467
+ // a caller driving `next()` by hand fires it too.
21468
+ do: () => notifyExitObserved(this.onExitObserved, {
21469
+ txid: this.toUnroll.txid,
21470
+ vout: this.toUnroll.vout
21471
+ })
20743
21472
  };
20744
21473
  }
20745
21474
  const virtualTxBase64 = await this.resolveVirtualTxBase64(nextTxToBroadcast);
@@ -20773,9 +21502,22 @@ exports.Unroll = void 0;
20773
21502
  }
20774
21503
  }
20775
21504
  Unroll2.Session = Session2;
21505
+ async function sessionFor(wallet, toUnroll, bumper) {
21506
+ const manager = await wallet.getContractManager();
21507
+ return Session2.create(
21508
+ toUnroll,
21509
+ bumper,
21510
+ wallet.onchainProvider,
21511
+ wallet.indexerProvider,
21512
+ wallet.virtualTxRepository,
21513
+ exitObserverFor(manager)
21514
+ );
21515
+ }
21516
+ Unroll2.sessionFor = sessionFor;
20776
21517
  async function completeUnroll(wallet, vtxoTxids, outputAddress) {
20777
21518
  const signedTx = await prepareUnrollTransaction(wallet, vtxoTxids, outputAddress);
20778
21519
  await wallet.onchainProvider.broadcastTransaction(signedTx.hex);
21520
+ await refreshSpentExitOutputs(wallet, signedTx);
20779
21521
  return signedTx.id;
20780
21522
  }
20781
21523
  Unroll2.completeUnroll = completeUnroll;
@@ -20791,9 +21533,9 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
20791
21533
  let totalAmount = 0n;
20792
21534
  const txWeightEstimator = TxWeightEstimator.create();
20793
21535
  for (const vtxo of vtxos) {
20794
- if (!vtxo.isUnrolled) {
21536
+ if (!chunk2JV4VQ7C_cjs.canSweepOnchain(vtxo)) {
20795
21537
  throw new Error(
20796
- `Vtxo ${vtxo.txid}:${vtxo.vout} is not fully unrolled, use unroll first`
21538
+ `Vtxo ${vtxo.txid}:${vtxo.vout} cannot be swept onchain: it is not fully unrolled (use unroll first), or its exit output was already spent`
20797
21539
  );
20798
21540
  }
20799
21541
  const txStatus = await wallet.onchainProvider.getTxStatus(vtxo.txid);
@@ -20802,14 +21544,14 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
20802
21544
  }
20803
21545
  const resolved = await resolveUnilateralPath({
20804
21546
  vtxo,
20805
- scriptHex: base.hex.encode(chunkG552MISJ_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
21547
+ scriptHex: base.hex.encode(chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
20806
21548
  contractRepository: wallet.contractRepository,
20807
21549
  walletPubKeyHex: base.hex.encode(await wallet.identity.xOnlyPublicKey()),
20808
21550
  currentTime: Date.now()
20809
21551
  });
20810
21552
  const spendingLeaf = resolved.selection.leaf;
20811
21553
  const sequence = resolved.selection.sequence;
20812
- const timelock = chunkG552MISJ_cjs.sequenceToTimelock(sequence);
21554
+ const timelock = chunk2JV4VQ7C_cjs.sequenceToTimelock(sequence);
20813
21555
  const elapsed = timelock.type === "blocks" ? chainTip.height >= txStatus.blockHeight + Number(timelock.value) : chainTip.time >= txStatus.blockTime + Number(timelock.value);
20814
21556
  if (!elapsed) {
20815
21557
  throw new Error(`no available exit path found for vtxo ${vtxo.txid}:${vtxo.vout}`);
@@ -20822,7 +21564,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
20822
21564
  sequence,
20823
21565
  witnessUtxo: {
20824
21566
  amount: BigInt(vtxo.value),
20825
- script: chunkG552MISJ_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
21567
+ script: chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
20826
21568
  },
20827
21569
  sighashType: btcSigner.SigHash.DEFAULT
20828
21570
  });
@@ -20832,7 +21574,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
20832
21574
  btcSigner.TaprootControlBlock.encode(spendingLeaf[0]).length
20833
21575
  );
20834
21576
  }
20835
- const tx = new chunkG552MISJ_cjs.Transaction({ version: 2 });
21577
+ const tx = new chunk2JV4VQ7C_cjs.Transaction({ version: 2 });
20836
21578
  for (const input of inputs) {
20837
21579
  tx.addInput(input);
20838
21580
  }
@@ -20854,6 +21596,22 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
20854
21596
  signedTx.finalize();
20855
21597
  return signedTx;
20856
21598
  }
21599
+ async function refreshSpentExitOutputs(wallet, signedTx) {
21600
+ const outpoints = [];
21601
+ for (let i = 0; i < signedTx.inputsLength; i++) {
21602
+ const input = signedTx.getInput(i);
21603
+ if (input.txid && input.index !== void 0) {
21604
+ outpoints.push({ txid: base.hex.encode(input.txid), vout: input.index });
21605
+ }
21606
+ }
21607
+ if (outpoints.length === 0) return;
21608
+ try {
21609
+ const manager = await wallet.getContractManager();
21610
+ await manager.refreshOutpoints(outpoints);
21611
+ } catch (e) {
21612
+ console.error("completeUnroll: failed to refresh the spent exit outputs", e);
21613
+ }
21614
+ }
20857
21615
  function sleep2(ms) {
20858
21616
  return new Promise((resolve) => setTimeout(resolve, ms));
20859
21617
  }
@@ -20899,7 +21657,7 @@ async function buildSignedSweep(params) {
20899
21657
  `uneconomic vtxo ${vtxo.txid}:${vtxo.vout}: value ${vtxo.value} - fee ${fee} < dust`
20900
21658
  );
20901
21659
  }
20902
- const tx = new chunkG552MISJ_cjs.Transaction({ version: 2 });
21660
+ const tx = new chunk2JV4VQ7C_cjs.Transaction({ version: 2 });
20903
21661
  tx.addInput({
20904
21662
  txid: vtxo.txid,
20905
21663
  index: vtxo.vout,
@@ -20924,7 +21682,7 @@ async function buildSignedSweep(params) {
20924
21682
  finalScriptWitness: [
20925
21683
  tapScriptSig[0][1],
20926
21684
  ...path.extraWitness,
20927
- chunkG552MISJ_cjs.scriptFromTapLeafScript(path.leaf),
21685
+ chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(path.leaf),
20928
21686
  btcSigner.TaprootControlBlock.encode(controlBlock)
20929
21687
  ]
20930
21688
  });
@@ -20932,7 +21690,7 @@ async function buildSignedSweep(params) {
20932
21690
  }
20933
21691
 
20934
21692
  // src/wallet/exit/estimate.ts
20935
- var CHILD_OUTPUT_DUST = 546;
21693
+ var CHILD_OUTPUT_DUST = CHILD_DUST_AMOUNT;
20936
21694
  function stepFundingAmount(stepFee) {
20937
21695
  return stepFee + CHILD_OUTPUT_DUST;
20938
21696
  }
@@ -20954,7 +21712,7 @@ async function resolveFeeRate(opts) {
20954
21712
  }
20955
21713
  async function selectExitVtxos(opts) {
20956
21714
  if (!opts.vtxos) return opts.wallet.getVtxos();
20957
- const res = await chunkG552MISJ_cjs.getNormalizedVtxos(opts.wallet.indexerProvider, { outpoints: opts.vtxos });
21715
+ const res = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(opts.wallet.indexerProvider, { outpoints: opts.vtxos });
20958
21716
  const tapTrees = /* @__PURE__ */ new Map();
20959
21717
  const out = [];
20960
21718
  for (const vtxo of res.vtxos) {
@@ -20969,7 +21727,7 @@ async function selectExitVtxos(opts) {
20969
21727
  `no contract registered for vtxo script ${vtxo.script} \u2014 register the contract before exiting`
20970
21728
  );
20971
21729
  }
20972
- const handler = chunkBABJ77NG_cjs.contractHandlers.get(contract.type);
21730
+ const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
20973
21731
  if (!handler) {
20974
21732
  throw new Error(`no contract handler registered for type '${contract.type}'`);
20975
21733
  }
@@ -20999,7 +21757,7 @@ async function computeExitLayout(opts, feeRate) {
20999
21757
  if (pendingNodes.length > 0) {
21000
21758
  const txs = await resolver.getVirtualTxs(pendingNodes.map((n) => n.txid));
21001
21759
  for (const psbt of txs) {
21002
- psbts.set(chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
21760
+ psbts.set(chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
21003
21761
  }
21004
21762
  }
21005
21763
  const childVsize = Number(
@@ -21035,7 +21793,7 @@ async function computeExitLayout(opts, feeRate) {
21035
21793
  try {
21036
21794
  const resolved = await resolveUnilateralPath({
21037
21795
  vtxo,
21038
- scriptHex: base.hex.encode(chunkG552MISJ_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
21796
+ scriptHex: base.hex.encode(chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
21039
21797
  contractRepository: wallet.contractRepository,
21040
21798
  walletPubKeyHex,
21041
21799
  currentTime: Date.now()
@@ -21054,7 +21812,7 @@ async function computeExitLayout(opts, feeRate) {
21054
21812
  });
21055
21813
  continue;
21056
21814
  }
21057
- const t = chunkG552MISJ_cjs.sequenceToTimelock(resolved.selection.sequence);
21815
+ const t = chunk2JV4VQ7C_cjs.sequenceToTimelock(resolved.selection.sequence);
21058
21816
  const delay = { type: t.type, value: Number(t.value) };
21059
21817
  infos.push({ outpoint, value: vtxo.value, sweepFee, path: resolved.label, delay });
21060
21818
  sweeps.push({ vtxo, resolved, sweepFee, delay });
@@ -21093,10 +21851,18 @@ async function computeExitLayout(opts, feeRate) {
21093
21851
  // splitter. funded: + 1 splitter tx and pre-signed children.
21094
21852
  txCount: (graph ? 0 : steps.length > 0 ? 1 : 0) + steps.length * 2 + sweeps.length,
21095
21853
  totalFeeSats: splitterFee + stepFees + sweepFees,
21096
- // graph funding is what the executor sends to its own fee address:
21097
- // just the CPFP fees (change recycles); funded also locks the
21098
- // per-child dust into the splitter.
21099
- fundingRequiredSats: graph ? stepFees : splitterFee + fundingTotal,
21854
+ // graph funding is what the executor sends to its own fee address: the
21855
+ // CPFP fees, plus one dust floor. Change recycles through that single
21856
+ // address, so each bump hands its remainder to the next and only the
21857
+ // *final* change has to clear `CHILD_DUST_AMOUNT` — but it does have to,
21858
+ // and `buildAnchorChild` throws rather than absorbing a short remainder
21859
+ // into the fee. Quoting bare fees quotes an amount that strands the last
21860
+ // bump and every sweep behind it.
21861
+ //
21862
+ // funded reserves the same floor per step instead of once overall (see
21863
+ // `stepFundingAmount`), because it pre-funds each child separately
21864
+ // through the splitter rather than recycling one output.
21865
+ fundingRequiredSats: graph ? steps.length > 0 ? stepFees + CHILD_OUTPUT_DUST : 0 : splitterFee + fundingTotal,
21100
21866
  recoveredSats: sweeps.reduce((s, x) => s + (x.vtxo.value - x.sweepFee), 0)
21101
21867
  };
21102
21868
  const expiries = pendingNodes.map((n) => n.expiresAt).filter((x) => x !== void 0);
@@ -21156,12 +21922,32 @@ var Executor = class {
21156
21922
  this.pollIntervalMs = opts?.pollIntervalMs ?? 5e3;
21157
21923
  this.feeWallet = opts?.feeWallet;
21158
21924
  this.signal = opts?.signal;
21925
+ this.onExitObserved = opts?.onExitObserved;
21159
21926
  }
21160
21927
  pkg;
21161
21928
  provider;
21162
21929
  pollIntervalMs;
21163
21930
  feeWallet;
21164
21931
  signal;
21932
+ onExitObserved;
21933
+ /**
21934
+ * Per-VTXO branch progress, which the executor otherwise does not track:
21935
+ * `dead` / `done` are per-step, and a VTXO is only onchain once EVERY
21936
+ * `package`/`bump` step naming it has confirmed. (`broadcast` — the funding
21937
+ * splitter — carries no `forVtxos` and serves no single VTXO.)
21938
+ */
21939
+ branchSteps() {
21940
+ const byVtxo = /* @__PURE__ */ new Map();
21941
+ this.pkg.steps.forEach((step, i) => {
21942
+ if (step.kind !== "package" && step.kind !== "bump") return;
21943
+ for (const vtxo of step.forVtxos) {
21944
+ let steps = byVtxo.get(vtxo);
21945
+ if (!steps) byVtxo.set(vtxo, steps = /* @__PURE__ */ new Set());
21946
+ steps.add(i);
21947
+ }
21948
+ });
21949
+ return byVtxo;
21950
+ }
21165
21951
  /**
21166
21952
  * Poll delay. Nearly all wall-clock time is spent here, so it must be the
21167
21953
  * thing that reacts to abort — checking only between polls would leave
@@ -21201,6 +21987,19 @@ var Executor = class {
21201
21987
  async *[Symbol.asyncIterator]() {
21202
21988
  throwIfAborted(this.signal);
21203
21989
  const dead = /* @__PURE__ */ new Set();
21990
+ const branchSteps = this.branchSteps();
21991
+ const onchainSteps = /* @__PURE__ */ new Set();
21992
+ const branchObserved = /* @__PURE__ */ new Set();
21993
+ const observeBranch = async (stepIndex, forVtxos) => {
21994
+ onchainSteps.add(stepIndex);
21995
+ for (const vtxo of forVtxos ?? []) {
21996
+ if (branchObserved.has(vtxo)) continue;
21997
+ const steps = branchSteps.get(vtxo);
21998
+ if (!steps || ![...steps].every((i) => onchainSteps.has(i))) continue;
21999
+ branchObserved.add(vtxo);
22000
+ await this.observe(vtxo);
22001
+ }
22002
+ };
21204
22003
  if (this.pkg.validUntil && Date.now() / 1e3 > this.pkg.validUntil) {
21205
22004
  yield {
21206
22005
  stepIndex: -1,
@@ -21230,6 +22029,7 @@ var Executor = class {
21230
22029
  const anchorTxid = step.kind === "package" || step.kind === "bump" ? step.parentTxid : step.txid;
21231
22030
  const existing = await this.status(anchorTxid);
21232
22031
  if (existing?.confirmed) {
22032
+ await observeBranch(i, forVtxos);
21233
22033
  yield {
21234
22034
  stepIndex: i,
21235
22035
  kind: step.kind,
@@ -21285,6 +22085,7 @@ var Executor = class {
21285
22085
  }
21286
22086
  }
21287
22087
  await this.waitConfirmed(anchorTxid);
22088
+ await observeBranch(i, forVtxos);
21288
22089
  yield {
21289
22090
  stepIndex: i,
21290
22091
  kind: step.kind,
@@ -21315,6 +22116,7 @@ var Executor = class {
21315
22116
  const swept = await this.status(step.txid);
21316
22117
  if (swept?.confirmed) {
21317
22118
  done.add(index);
22119
+ await this.observe(step.vtxo);
21318
22120
  yield {
21319
22121
  stepIndex: index,
21320
22122
  kind: "sweep",
@@ -21371,7 +22173,25 @@ var Executor = class {
21371
22173
  if (done.size < pending.length) await this.sleep();
21372
22174
  }
21373
22175
  }
22176
+ /** `"txid:vout"` -> outpoint, then hand it to the hook. A malformed entry is skipped. */
22177
+ async observe(outpoint) {
22178
+ if (!this.onExitObserved) return;
22179
+ const sep = outpoint.lastIndexOf(":");
22180
+ const rest = outpoint.slice(sep + 1);
22181
+ const vout = Number(rest);
22182
+ if (sep <= 0 || rest === "" || !Number.isInteger(vout)) return;
22183
+ await notifyExitObserved(this.onExitObserved, { txid: outpoint.slice(0, sep), vout });
22184
+ }
21374
22185
  };
22186
+
22187
+ // src/wallet/exit/execute.ts
22188
+ async function execute(wallet, pkg, opts) {
22189
+ const manager = await wallet.getContractManager();
22190
+ return new Executor(pkg, opts?.provider ?? wallet.onchainProvider, {
22191
+ ...opts,
22192
+ onExitObserved: opts?.onExitObserved ?? exitObserverFor(manager)
22193
+ });
22194
+ }
21375
22195
  async function prepare(opts) {
21376
22196
  const { wallet, onchainWallet } = opts;
21377
22197
  const feeRate = await resolveFeeRate(opts);
@@ -21393,7 +22213,7 @@ async function prepare(opts) {
21393
22213
  txid: sweep.vtxo.txid,
21394
22214
  vout: sweep.vtxo.vout,
21395
22215
  value: sweep.vtxo.value,
21396
- pkScript: chunkG552MISJ_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
22216
+ pkScript: chunk2JV4VQ7C_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
21397
22217
  },
21398
22218
  path: sweep.resolved.selection,
21399
22219
  outputAddress: opts.sweepAddress,
@@ -21446,7 +22266,10 @@ async function prepare(opts) {
21446
22266
  totals: {
21447
22267
  txCount: bumpSteps.length * 2 + sweepSteps.length,
21448
22268
  totalFeeSats: stepFees2 + sweepFees2,
21449
- fundingRequiredSats: stepFees2,
22269
+ // Fees plus the single dust floor the recycling change output
22270
+ // must keep clear; see the note in `estimate.ts`. Must match
22271
+ // the quote `estimate` gives for the same package.
22272
+ fundingRequiredSats: bumpSteps.length > 0 ? stepFees2 + CHILD_OUTPUT_DUST : 0,
21450
22273
  recoveredSats: recovered2
21451
22274
  },
21452
22275
  vtxos: layout.infos,
@@ -21478,7 +22301,7 @@ async function prepare(opts) {
21478
22301
  if (newFee <= splitterFee) break;
21479
22302
  splitterFee = newFee;
21480
22303
  }
21481
- const splitter = new chunkG552MISJ_cjs.Transaction({ version: 2 });
22304
+ const splitter = new chunk2JV4VQ7C_cjs.Transaction({ version: 2 });
21482
22305
  for (const coin of selected.inputs) {
21483
22306
  splitter.addInput({
21484
22307
  txid: coin.txid,
@@ -21615,47 +22438,48 @@ function isValidStep(step) {
21615
22438
  var UnilateralExit = {
21616
22439
  estimate,
21617
22440
  prepare,
22441
+ execute,
21618
22442
  Executor
21619
22443
  };
21620
22444
 
21621
22445
  // src/arkade/index.ts
21622
22446
  var arkade_exports = {};
21623
22447
  chunk5BLDMQED_cjs.__export(arkade_exports, {
21624
- ARKADE_OP: () => chunkBABJ77NG_cjs.ARKADE_OP,
21625
- ARKADE_OPCODES: () => chunkBABJ77NG_cjs.ARKADE_OPCODES,
21626
- ARKADE_OPCODE_NAMES: () => chunkBABJ77NG_cjs.ARKADE_OPCODE_NAMES,
21627
- ARKADE_OPCODE_VALUES: () => chunkBABJ77NG_cjs.ARKADE_OPCODE_VALUES,
21628
- ARKADE_OPS: () => chunkBABJ77NG_cjs.ARKADE_OPS,
22448
+ ARKADE_OP: () => chunkOIZ2V2VD_cjs.ARKADE_OP,
22449
+ ARKADE_OPCODES: () => chunkOIZ2V2VD_cjs.ARKADE_OPCODES,
22450
+ ARKADE_OPCODE_NAMES: () => chunkOIZ2V2VD_cjs.ARKADE_OPCODE_NAMES,
22451
+ ARKADE_OPCODE_VALUES: () => chunkOIZ2V2VD_cjs.ARKADE_OPCODE_VALUES,
22452
+ ARKADE_OPS: () => chunkOIZ2V2VD_cjs.ARKADE_OPS,
21629
22453
  Arkade: () => Arkade,
21630
22454
  ArkadeContract: () => ArkadeContract,
21631
- ArkadeProgramScript: () => chunkBABJ77NG_cjs.ArkadeProgramScript,
21632
- ArkadeScript: () => chunkBABJ77NG_cjs.ArkadeScript,
22455
+ ArkadeProgramScript: () => chunkOIZ2V2VD_cjs.ArkadeProgramScript,
22456
+ ArkadeScript: () => chunkOIZ2V2VD_cjs.ArkadeScript,
21633
22457
  ArkadeTransactionBuilder: () => ArkadeTransactionBuilder,
21634
- BigNum: () => chunkBABJ77NG_cjs.bignum_exports,
22458
+ BigNum: () => chunkOIZ2V2VD_cjs.bignum_exports,
21635
22459
  OP: () => btcSigner.OP,
21636
- OPCODE_NAMES: () => chunkBABJ77NG_cjs.OPCODE_NAMES,
21637
- OPCODE_VALUES: () => chunkBABJ77NG_cjs.OPCODE_VALUES,
21638
- SUPPORTED_PROGRAM_VERSION: () => chunkBABJ77NG_cjs.SUPPORTED_PROGRAM_VERSION,
22460
+ OPCODE_NAMES: () => chunkOIZ2V2VD_cjs.OPCODE_NAMES,
22461
+ OPCODE_VALUES: () => chunkOIZ2V2VD_cjs.OPCODE_VALUES,
22462
+ SUPPORTED_PROGRAM_VERSION: () => chunkOIZ2V2VD_cjs.SUPPORTED_PROGRAM_VERSION,
21639
22463
  Script: () => btcSigner.Script,
21640
- arkadeScriptHash: () => chunkBABJ77NG_cjs.arkadeScriptHash,
21641
- arkadeWitnessHash: () => chunkBABJ77NG_cjs.arkadeWitnessHash,
21642
- asmToBytes: () => chunkBABJ77NG_cjs.asmToBytes,
21643
- bytesToASM: () => chunkBABJ77NG_cjs.bytesToASM,
21644
- computeArkadeScriptPublicKey: () => chunkBABJ77NG_cjs.computeArkadeScriptPublicKey,
22464
+ arkadeScriptHash: () => chunkOIZ2V2VD_cjs.arkadeScriptHash,
22465
+ arkadeWitnessHash: () => chunkOIZ2V2VD_cjs.arkadeWitnessHash,
22466
+ asmToBytes: () => chunkOIZ2V2VD_cjs.asmToBytes,
22467
+ bytesToASM: () => chunkOIZ2V2VD_cjs.bytesToASM,
22468
+ computeArkadeScriptPublicKey: () => chunkOIZ2V2VD_cjs.computeArkadeScriptPublicKey,
21645
22469
  createArkadeBatchHandler: () => createArkadeBatchHandler,
21646
- deserializeArkadeContractParams: () => chunkBABJ77NG_cjs.deserializeArkadeContractParams,
21647
- fromASM: () => chunkBABJ77NG_cjs.fromASM,
21648
- getOpcodeName: () => chunkBABJ77NG_cjs.getOpcodeName,
21649
- getOpcodeValue: () => chunkBABJ77NG_cjs.getOpcodeValue,
21650
- parseArtifact: () => chunkBABJ77NG_cjs.parseArtifact,
21651
- resolveAsm: () => chunkBABJ77NG_cjs.resolveAsm,
21652
- serializeArkadeContractParams: () => chunkBABJ77NG_cjs.serializeArkadeContractParams,
21653
- stringifyArtifact: () => chunkBABJ77NG_cjs.stringifyArtifact,
21654
- toASM: () => chunkBABJ77NG_cjs.toASM,
21655
- validateProgram: () => chunkBABJ77NG_cjs.validateProgram,
21656
- witnessRefToBytes: () => chunkBABJ77NG_cjs.witnessRefToBytes
22470
+ deserializeArkadeContractParams: () => chunkOIZ2V2VD_cjs.deserializeArkadeContractParams,
22471
+ fromASM: () => chunkOIZ2V2VD_cjs.fromASM,
22472
+ getOpcodeName: () => chunkOIZ2V2VD_cjs.getOpcodeName,
22473
+ getOpcodeValue: () => chunkOIZ2V2VD_cjs.getOpcodeValue,
22474
+ parseArtifact: () => chunkOIZ2V2VD_cjs.parseArtifact,
22475
+ resolveAsm: () => chunkOIZ2V2VD_cjs.resolveAsm,
22476
+ serializeArkadeContractParams: () => chunkOIZ2V2VD_cjs.serializeArkadeContractParams,
22477
+ stringifyArtifact: () => chunkOIZ2V2VD_cjs.stringifyArtifact,
22478
+ toASM: () => chunkOIZ2V2VD_cjs.toASM,
22479
+ validateProgram: () => chunkOIZ2V2VD_cjs.validateProgram,
22480
+ witnessRefToBytes: () => chunkOIZ2V2VD_cjs.witnessRefToBytes
21657
22481
  });
21658
- var isVtxoCoin = (input) => chunkG552MISJ_cjs.isVirtualCoin(input);
22482
+ var isVtxoCoin = (input) => chunk2JV4VQ7C_cjs.isVirtualCoin(input);
21659
22483
  function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message, session, arkProvider, emulator, network, recipients, batchExpiryPolicy) {
21660
22484
  let batchId;
21661
22485
  let sweepTapTreeRoot;
@@ -21676,21 +22500,23 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
21676
22500
  );
21677
22501
  await arkProvider.confirmRegistration(intentId);
21678
22502
  batchId = event.id;
21679
- const sweepTapscript = chunkG552MISJ_cjs.CSVMultisigTapscript.encode({
22503
+ const sweepTapscript = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.encode({
21680
22504
  timelock,
21681
- pubkeys: [base.hex.decode(info.forfeitPubkey).subarray(1)]
22505
+ pubkeys: [chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info.forfeitPubkey), "forfeit key")]
21682
22506
  }).script;
21683
22507
  sweepTapTreeRoot = payment_js.tapLeafHash(sweepTapscript);
21684
22508
  return { skip: false };
21685
22509
  },
21686
22510
  onTreeSigningStarted: async (event, vtxoTree) => {
21687
22511
  const signerPubKey = await session.getPublicKey();
21688
- const xonlySignerPubKey = signerPubKey.subarray(1);
21689
- const xOnlyPubkeys = event.cosignersPublicKeys.map((k) => k.slice(2));
22512
+ const xonlySignerPubKey = chunkOIZ2V2VD_cjs.toXOnly(signerPubKey, "signer key");
22513
+ const xOnlyPubkeys = event.cosignersPublicKeys.map(
22514
+ (k) => base.hex.encode(chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
22515
+ );
21690
22516
  if (!xOnlyPubkeys.includes(base.hex.encode(xonlySignerPubKey))) {
21691
22517
  return { skip: true };
21692
22518
  }
21693
- const commitmentTx = chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(event.unsignedCommitmentTx));
22519
+ const commitmentTx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(event.unsignedCommitmentTx));
21694
22520
  validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
21695
22521
  if (recipients && recipients.length > 0) {
21696
22522
  validateBatchRecipients(commitmentTx, vtxoTree.leaves(), recipients, network);
@@ -21722,7 +22548,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
21722
22548
  if (connectorTree) {
21723
22549
  validateConnectorsTxGraph(event.commitmentTx, connectorTree);
21724
22550
  }
21725
- let commitmentPsbt = chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
22551
+ let commitmentPsbt = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
21726
22552
  assertFinalCommitmentMatchesValidated(
21727
22553
  commitmentPsbt,
21728
22554
  validatedCommitmentTxid,
@@ -21757,7 +22583,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
21757
22583
  boardingIndices.push(boardingIdx);
21758
22584
  continue;
21759
22585
  }
21760
- if (chunkG552MISJ_cjs.isRecoverable(input) || isSubdust(input, info.dust)) {
22586
+ if (chunk2JV4VQ7C_cjs.isRecoverable(input) || isSubdust(input, info.dust)) {
21761
22587
  continue;
21762
22588
  }
21763
22589
  if (connectorIndex >= connectorLeaves.length) {
@@ -21778,7 +22604,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
21778
22604
  index: input.vout,
21779
22605
  witnessUtxo: {
21780
22606
  amount: BigInt(input.value),
21781
- script: chunkG552MISJ_cjs.VtxoScript.decode(input.tapTree).pkScript
22607
+ script: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
21782
22608
  },
21783
22609
  sighashType: btcSigner.SigHash.DEFAULT,
21784
22610
  tapLeafScript: [input.forfeitTapLeafScript]
@@ -21869,17 +22695,16 @@ var Arkade = class _Arkade {
21869
22695
  /** Connect and resolve the server key, checkpoint closure and (if present) the co-signer key. */
21870
22696
  static async connect(opts) {
21871
22697
  const info = await opts.arkade.getInfo();
21872
- const serverKey = base.hex.decode(info.signerPubkey).slice(1);
21873
- const checkpoint = chunkG552MISJ_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
21874
- const network = opts.network ?? chunkG552MISJ_cjs.DEFAULT_NETWORK;
22698
+ const serverKey = chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
22699
+ const checkpoint = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
22700
+ const network = opts.network ?? chunk2JV4VQ7C_cjs.DEFAULT_NETWORK;
21875
22701
  let emulatorKey;
21876
22702
  if (opts.emulator) {
21877
- emulatorKey = base.hex.decode(chunkG552MISJ_cjs.resolveEmulatorPubkey(network, opts.emulatorPubkey));
22703
+ emulatorKey = base.hex.decode(chunk2JV4VQ7C_cjs.resolveEmulatorPubkey(network, opts.emulatorPubkey));
21878
22704
  }
21879
22705
  let userKey;
21880
22706
  if (opts.identity) {
21881
- const pub = await opts.identity.xOnlyPublicKey();
21882
- userKey = pub.length === 33 ? pub.slice(1) : pub;
22707
+ userKey = chunkOIZ2V2VD_cjs.toXOnly(await opts.identity.xOnlyPublicKey(), "identity key");
21883
22708
  }
21884
22709
  return new _Arkade({
21885
22710
  arkProvider: opts.arkade,
@@ -21905,7 +22730,7 @@ var Arkade = class _Arkade {
21905
22730
  * key respectively; explicit args always win.
21906
22731
  */
21907
22732
  contract(program, args = {}) {
21908
- const declared = (program.params ?? []).map(chunkBABJ77NG_cjs.inputName);
22733
+ const declared = (program.params ?? []).map(chunkOIZ2V2VD_cjs.inputName);
21909
22734
  if (declared.includes("server") && args.server === void 0) {
21910
22735
  args = { ...args, server: this.serverKey };
21911
22736
  }
@@ -21925,7 +22750,7 @@ var ArkadeContract = class _ArkadeContract {
21925
22750
  userKey: client.userKey,
21926
22751
  emulatorKey: client.emulatorKey
21927
22752
  };
21928
- this.vtxoScript = new chunkBABJ77NG_cjs.ArkadeProgramScript(program, args, this.keys);
22753
+ this.vtxoScript = new chunkOIZ2V2VD_cjs.ArkadeProgramScript(program, args, this.keys);
21929
22754
  this.tapTree = this.vtxoScript.encode();
21930
22755
  this.compiled = this.vtxoScript.compiled;
21931
22756
  }
@@ -21953,7 +22778,7 @@ var ArkadeContract = class _ArkadeContract {
21953
22778
  `ArkadeContract.fromContract: expected contract type 'arkade', got '${contract.type}'`
21954
22779
  );
21955
22780
  }
21956
- const typed = chunkBABJ77NG_cjs.deserializeArkadeContractParams(contract.params);
22781
+ const typed = chunkOIZ2V2VD_cjs.deserializeArkadeContractParams(contract.params);
21957
22782
  return new _ArkadeContract(client, typed.program, typed.args, {
21958
22783
  serverKey: typed.serverKey,
21959
22784
  userKey: typed.userKey,
@@ -21994,7 +22819,7 @@ var ArkadeContract = class _ArkadeContract {
21994
22819
  toContractParams() {
21995
22820
  return {
21996
22821
  type: "arkade",
21997
- params: chunkBABJ77NG_cjs.serializeArkadeContractParams({
22822
+ params: chunkOIZ2V2VD_cjs.serializeArkadeContractParams({
21998
22823
  program: this.program,
21999
22824
  args: this.args,
22000
22825
  serverKey: this.keys.serverKey,
@@ -22039,13 +22864,15 @@ var ArkadeContract = class _ArkadeContract {
22039
22864
  const [registered] = await manager.getContracts({ script: scriptHex });
22040
22865
  if (registered) {
22041
22866
  const [withVtxos] = await manager.getContractsWithVtxos({ script: scriptHex });
22042
- return (withVtxos?.vtxos ?? []).filter((v) => !chunkG552MISJ_cjs.hasTerminalSpend(v));
22867
+ return (withVtxos?.vtxos ?? []).filter(
22868
+ (v) => !chunk2JV4VQ7C_cjs.hasTerminalSpend(v) && !v.isUnrolled
22869
+ );
22043
22870
  }
22044
22871
  }
22045
22872
  if (!this.client.indexer) {
22046
22873
  throw new Error("ArkadeContract.getUtxos: an indexer is required");
22047
22874
  }
22048
- const { vtxos } = await chunkG552MISJ_cjs.getNormalizedVtxos(this.client.indexer, {
22875
+ const { vtxos } = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(this.client.indexer, {
22049
22876
  scripts: [scriptHex],
22050
22877
  spendableOnly: true
22051
22878
  });
@@ -22147,12 +22974,25 @@ var ArkadeTransactionBuilder = class {
22147
22974
  this.contract.client.checkpoint
22148
22975
  );
22149
22976
  if (coin.sourceTx) {
22150
- chunkG552MISJ_cjs.setArkPsbtField(arkTx, 0, chunkG552MISJ_cjs.PrevArkTxField, coin.sourceTx);
22977
+ chunk2JV4VQ7C_cjs.setArkPsbtField(arkTx, 0, chunk2JV4VQ7C_cjs.PrevArkTxField, coin.sourceTx);
22978
+ }
22979
+ if (this.fn.arkadeScript) {
22980
+ const indexer = this.contract.client.indexer;
22981
+ if (!indexer) {
22982
+ throw new PrevTxUnavailableError(
22983
+ "covenant spends require an `indexer` on the Arkade client to resolve the previous ark tx of each input"
22984
+ );
22985
+ }
22986
+ await attachPrevArkTxs(
22987
+ arkTx,
22988
+ [coin.txid, ...this.fundingCoins.map((c) => c.txid)],
22989
+ indexer
22990
+ );
22151
22991
  }
22152
22992
  const condition = (def.tapscript.witness ?? []).map((w) => this.witnessBytes(w));
22153
22993
  if (condition.length > 0) {
22154
- chunkG552MISJ_cjs.setArkPsbtField(arkTx, 0, chunkG552MISJ_cjs.ConditionWitness, condition);
22155
- chunkG552MISJ_cjs.setArkPsbtField(checkpoints[0], 0, chunkG552MISJ_cjs.ConditionWitness, condition);
22994
+ chunk2JV4VQ7C_cjs.setArkPsbtField(arkTx, 0, chunk2JV4VQ7C_cjs.ConditionWitness, condition);
22995
+ chunk2JV4VQ7C_cjs.setArkPsbtField(checkpoints[0], 0, chunk2JV4VQ7C_cjs.ConditionWitness, condition);
22156
22996
  }
22157
22997
  const packets = [];
22158
22998
  if (this.assetSpecs.length > 0) {
@@ -22191,7 +23031,7 @@ var ArkadeTransactionBuilder = class {
22191
23031
  base.base64.encode(signedArk2.toPSBT()),
22192
23032
  signedCps.map((c) => base.base64.encode(c.toPSBT()))
22193
23033
  );
22194
- const txid = chunkG552MISJ_cjs.Transaction.fromPSBT(base.base64.decode(res2.signedArkTx)).id;
23034
+ const txid = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(res2.signedArkTx)).id;
22195
23035
  return {
22196
23036
  txid,
22197
23037
  signedArkTx: res2.signedArkTx,
@@ -22250,23 +23090,23 @@ var ArkadeTransactionBuilder = class {
22250
23090
  }
22251
23091
  buildAssetPacket() {
22252
23092
  const groups = this.assetSpecs.map((s) => {
22253
- const id = typeof s.assetId === "string" ? chunkXN55B6EP_cjs.AssetId.fromString(s.assetId) : chunkXN55B6EP_cjs.AssetId.fromBytes(s.assetId);
22254
- return chunkXN55B6EP_cjs.AssetGroup.create(
23093
+ const id = typeof s.assetId === "string" ? chunkCO3KKSWM_cjs.AssetId.fromString(s.assetId) : chunkCO3KKSWM_cjs.AssetId.fromBytes(s.assetId);
23094
+ return chunkCO3KKSWM_cjs.AssetGroup.create(
22255
23095
  id,
22256
23096
  null,
22257
- s.inputs.map((i) => chunkXN55B6EP_cjs.AssetInput.create(i.vin, i.amount)),
22258
- s.outputs.map((o) => chunkXN55B6EP_cjs.AssetOutput.create(o.vout, o.amount)),
22259
- (s.metadata ?? []).map((m) => chunkXN55B6EP_cjs.Metadata.create(m.key, m.value))
23097
+ s.inputs.map((i) => chunkCO3KKSWM_cjs.AssetInput.create(i.vin, i.amount)),
23098
+ s.outputs.map((o) => chunkCO3KKSWM_cjs.AssetOutput.create(o.vout, o.amount)),
23099
+ (s.metadata ?? []).map((m) => chunkCO3KKSWM_cjs.Metadata.create(m.key, m.value))
22260
23100
  );
22261
23101
  });
22262
- return chunkXN55B6EP_cjs.Packet.create(groups);
23102
+ return chunkCO3KKSWM_cjs.Packet.create(groups);
22263
23103
  }
22264
23104
  witnessBytes(ref) {
22265
- return chunkBABJ77NG_cjs.witnessRefToBytes(ref, this.args, this.contract.args);
23105
+ return chunkOIZ2V2VD_cjs.witnessRefToBytes(ref, this.args, this.contract.args);
22266
23106
  }
22267
23107
  };
22268
23108
  function bindInputs(fn, callArgs) {
22269
- const names = (fn.def.inputs ?? []).map(chunkBABJ77NG_cjs.inputName);
23109
+ const names = (fn.def.inputs ?? []).map(chunkOIZ2V2VD_cjs.inputName);
22270
23110
  if (callArgs.length !== names.length) {
22271
23111
  throw new Error(`${fn.name}: expected ${names.length} argument(s), got ${callArgs.length}`);
22272
23112
  }
@@ -22666,6 +23506,7 @@ exports.AssetManager = AssetManager;
22666
23506
  exports.BIP21 = BIP21;
22667
23507
  exports.BIP21Error = BIP21Error;
22668
23508
  exports.BLOCKED_UPGRADE_TIMEOUT_MS = BLOCKED_UPGRADE_TIMEOUT_MS;
23509
+ exports.CachingArkProvider = CachingArkProvider;
22669
23510
  exports.ChainedTxType = ChainedTxType;
22670
23511
  exports.ConnectionDisposedError = ConnectionDisposedError;
22671
23512
  exports.ContractManager = ContractManager;
@@ -22716,6 +23557,7 @@ exports.MnemonicIdentity = MnemonicIdentity;
22716
23557
  exports.OnchainWallet = OnchainWallet;
22717
23558
  exports.P2A = P2A;
22718
23559
  exports.PaymentRouter = PaymentRouter;
23560
+ exports.PrevTxUnavailableError = PrevTxUnavailableError;
22719
23561
  exports.REGTEST_MIN_BATCH_EXPIRY_SECONDS = REGTEST_MIN_BATCH_EXPIRY_SECONDS;
22720
23562
  exports.REGTEST_MIN_CHECKPOINT_EXIT_DELAY_SECONDS = REGTEST_MIN_CHECKPOINT_EXIT_DELAY_SECONDS;
22721
23563
  exports.Ramps = Ramps;
@@ -22741,6 +23583,7 @@ exports.UnilateralExit = UnilateralExit;
22741
23583
  exports.UnknownPacket = UnknownPacket;
22742
23584
  exports.VtxoManager = VtxoManager;
22743
23585
  exports.Wallet = Wallet2;
23586
+ exports.WalletCannotAllocateAddressError = WalletCannotAllocateAddressError;
22744
23587
  exports.WalletCannotSignError = WalletCannotSignError;
22745
23588
  exports.WalletMessageHandler = WalletMessageHandler;
22746
23589
  exports.WalletNotInitializedError = WalletNotInitializedError;
@@ -22757,6 +23600,8 @@ exports.assertSubmittedArkTxid = assertSubmittedArkTxid;
22757
23600
  exports.assertValidBatchExpiry = assertValidBatchExpiry;
22758
23601
  exports.assertValidServerUnrollScript = assertValidServerUnrollScript;
22759
23602
  exports.assetMintResolver = assetMintResolver;
23603
+ exports.attachPrevArkTxs = attachPrevArkTxs;
23604
+ exports.attachPrevoutTxs = attachPrevoutTxs;
22760
23605
  exports.awaitTransaction = awaitTransaction;
22761
23606
  exports.boardingResolver = boardingResolver;
22762
23607
  exports.btcTarget = btcTarget;
@@ -22788,7 +23633,9 @@ exports.deserializeExitPackage = deserializeExitPackage;
22788
23633
  exports.deserializeUtxo = deserializeUtxo;
22789
23634
  exports.deserializeVtxo = deserializeVtxo;
22790
23635
  exports.encodeArkContract = encodeArkContract;
23636
+ exports.exitObserverFor = exitObserverFor;
22791
23637
  exports.extendVirtualCoinForContract = extendVirtualCoinForContract;
23638
+ exports.extractArkProviderUrl = extractArkProviderUrl;
22792
23639
  exports.gateExclusion = gateExclusion;
22793
23640
  exports.gatedContracts = gatedContracts;
22794
23641
  exports.getAllByIndexValues = getAllByIndexValues;
@@ -22799,6 +23646,7 @@ exports.hasCandidates = hasCandidates;
22799
23646
  exports.intentMatchesFilter = intentMatchesFilter;
22800
23647
  exports.intentPageBounds = intentPageBounds;
22801
23648
  exports.invoiceTarget = invoiceTarget;
23649
+ exports.isAddressAllocationCapable = isAddressAllocationCapable;
22802
23650
  exports.isArkContract = isArkContract;
22803
23651
  exports.isBatchSignable = isBatchSignable;
22804
23652
  exports.isBtcAddress = isBtcAddress;
@@ -22826,6 +23674,7 @@ exports.makeHandle = makeHandle;
22826
23674
  exports.matchServerCheckpoints = matchServerCheckpoints;
22827
23675
  exports.mergeChainedTxType = mergeChainedTxType;
22828
23676
  exports.migrateWalletRepository = migrateWalletRepository;
23677
+ exports.notifyExitObserved = notifyExitObserved;
22829
23678
  exports.onchainRail = onchainRail;
22830
23679
  exports.openDatabase = openDatabase;
22831
23680
  exports.outpointExclusion = outpointExclusion;
@@ -22837,6 +23686,7 @@ exports.requiresMigration = requiresMigration;
22837
23686
  exports.resolveBatchExpiryPolicy = resolveBatchExpiryPolicy;
22838
23687
  exports.resolveCheckpointExitDelayPolicy = resolveCheckpointExitDelayPolicy;
22839
23688
  exports.resolveDescriptorSigner = resolveDescriptorSigner;
23689
+ exports.resolvePrevTxs = resolvePrevTxs;
22840
23690
  exports.resolveSendAmount = resolveSendAmount;
22841
23691
  exports.rollbackMigration = rollbackMigration;
22842
23692
  exports.saveVtxosForContract = saveVtxosForContract;
@@ -22860,5 +23710,6 @@ exports.validateVtxoTxGraph = validateVtxoTxGraph;
22860
23710
  exports.verifyTapscriptSignatures = verifyTapscriptSignatures;
22861
23711
  exports.waitForIncomingFunds = waitForIncomingFunds;
22862
23712
  exports.warnAndFilterVtxosForScript = warnAndFilterVtxosForScript;
22863
- //# sourceMappingURL=chunk-GFZNEMGL.cjs.map
22864
- //# sourceMappingURL=chunk-GFZNEMGL.cjs.map
23713
+ exports.withPrevTxs = withPrevTxs;
23714
+ //# sourceMappingURL=chunk-MJUTO3PY.cjs.map
23715
+ //# sourceMappingURL=chunk-MJUTO3PY.cjs.map