@arkade-os/sdk 0.4.44 → 0.4.46

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 (88) hide show
  1. package/README.md +35 -0
  2. package/dist/adapters/expo.cjs +5 -5
  3. package/dist/adapters/expo.d.cts +2 -2
  4. package/dist/adapters/expo.d.ts +2 -2
  5. package/dist/adapters/expo.js +3 -3
  6. package/dist/adapters/indexedDB.cjs +5 -5
  7. package/dist/adapters/indexedDB.js +4 -4
  8. package/dist/{ark-I8jfe5VE.d.cts → ark-C9ognsOV.d.cts} +94 -2
  9. package/dist/{ark-I8jfe5VE.d.ts → ark-C9ognsOV.d.ts} +94 -2
  10. package/dist/{asyncStorageTaskQueue-BtSOVZFn.d.ts → asyncStorageTaskQueue-BAKZ5cS5.d.ts} +2 -2
  11. package/dist/{asyncStorageTaskQueue-Dap7qUlF.d.cts → asyncStorageTaskQueue-CmBYVlxw.d.cts} +2 -2
  12. package/dist/{chunk-32YKLQPS.cjs → chunk-4KXOCVXP.cjs} +32 -29
  13. package/dist/chunk-4KXOCVXP.cjs.map +1 -0
  14. package/dist/{chunk-RJ6XVCX4.cjs → chunk-6TQJOD72.cjs} +7 -7
  15. package/dist/{chunk-RJ6XVCX4.cjs.map → chunk-6TQJOD72.cjs.map} +1 -1
  16. package/dist/{chunk-UBYY2TPK.cjs → chunk-7IYIFMF4.cjs} +178 -79
  17. package/dist/chunk-7IYIFMF4.cjs.map +1 -0
  18. package/dist/{chunk-LJ35HPJW.js → chunk-CWJ7ZCP7.js} +171 -75
  19. package/dist/chunk-CWJ7ZCP7.js.map +1 -0
  20. package/dist/{chunk-XIVCG6EP.cjs → chunk-D46YDM36.cjs} +1173 -425
  21. package/dist/chunk-D46YDM36.cjs.map +1 -0
  22. package/dist/{chunk-BE5MUB7T.js → chunk-FWG4TSPN.js} +7 -2
  23. package/dist/chunk-FWG4TSPN.js.map +1 -0
  24. package/dist/{chunk-V7WIZR2B.js → chunk-JTCQ6QXQ.js} +4 -4
  25. package/dist/{chunk-V7WIZR2B.js.map → chunk-JTCQ6QXQ.js.map} +1 -1
  26. package/dist/{chunk-HXDZ2QTW.cjs → chunk-MQB5H4X5.cjs} +7 -2
  27. package/dist/chunk-MQB5H4X5.cjs.map +1 -0
  28. package/dist/{chunk-FMI2GKYO.js → chunk-P6VBP3CT.js} +977 -231
  29. package/dist/chunk-P6VBP3CT.js.map +1 -0
  30. package/dist/{chunk-YNEDJTX2.js → chunk-QKC2T54O.js} +6 -3
  31. package/dist/chunk-QKC2T54O.js.map +1 -0
  32. package/dist/{chunk-LCQQPOIT.js → chunk-R2SVAM5Q.js} +3 -3
  33. package/dist/{chunk-LCQQPOIT.js.map → chunk-R2SVAM5Q.js.map} +1 -1
  34. package/dist/{chunk-X37EKDIH.cjs → chunk-SOXGAA52.cjs} +14 -14
  35. package/dist/{chunk-X37EKDIH.cjs.map → chunk-SOXGAA52.cjs.map} +1 -1
  36. package/dist/contracts/handlers/index.cjs +7 -7
  37. package/dist/contracts/handlers/index.d.cts +3 -3
  38. package/dist/contracts/handlers/index.d.ts +3 -3
  39. package/dist/contracts/handlers/index.js +2 -2
  40. package/dist/{delegate-BRqbh2fW.d.cts → delegate-DVEgyRwI.d.cts} +1 -1
  41. package/dist/{delegate-CgjVjYOP.d.ts → delegate-aOd5qINr.d.ts} +1 -1
  42. package/dist/{index-DvWNB_rl.d.ts → index-CPzL4tqg.d.ts} +2 -2
  43. package/dist/{index-DHuXlDEg.d.cts → index-D8vmtWWO.d.cts} +2 -2
  44. package/dist/index.cjs +176 -156
  45. package/dist/index.d.cts +45 -20
  46. package/dist/index.d.ts +45 -20
  47. package/dist/index.js +4 -4
  48. package/dist/repositories/realm/index.cjs +23 -19
  49. package/dist/repositories/realm/index.cjs.map +1 -1
  50. package/dist/repositories/realm/index.d.cts +2 -2
  51. package/dist/repositories/realm/index.d.ts +2 -2
  52. package/dist/repositories/realm/index.js +9 -5
  53. package/dist/repositories/realm/index.js.map +1 -1
  54. package/dist/repositories/sqlite/index.cjs +22 -18
  55. package/dist/repositories/sqlite/index.cjs.map +1 -1
  56. package/dist/repositories/sqlite/index.d.cts +2 -2
  57. package/dist/repositories/sqlite/index.d.ts +2 -2
  58. package/dist/repositories/sqlite/index.js +9 -5
  59. package/dist/repositories/sqlite/index.js.map +1 -1
  60. package/dist/{taskRunner-Bptw9UMa.d.ts → taskRunner-B48-V-Pb.d.ts} +2 -2
  61. package/dist/{taskRunner-CeFxKhSH.d.cts → taskRunner-nNecmQ2C.d.cts} +2 -2
  62. package/dist/wallet/expo/background.cjs +14 -14
  63. package/dist/wallet/expo/background.d.cts +3 -3
  64. package/dist/wallet/expo/background.d.ts +3 -3
  65. package/dist/wallet/expo/background.js +6 -6
  66. package/dist/wallet/expo/index.cjs +27 -14
  67. package/dist/wallet/expo/index.cjs.map +1 -1
  68. package/dist/wallet/expo/index.d.cts +11 -4
  69. package/dist/wallet/expo/index.d.ts +11 -4
  70. package/dist/wallet/expo/index.js +18 -5
  71. package/dist/wallet/expo/index.js.map +1 -1
  72. package/dist/{wallet-BsqRU8KM.d.cts → wallet-BUg3D4WJ.d.cts} +139 -3
  73. package/dist/{wallet-D9z7wssl.d.ts → wallet-DM0oShTu.d.ts} +139 -3
  74. package/dist/worker/expo/index.cjs +10 -9
  75. package/dist/worker/expo/index.cjs.map +1 -1
  76. package/dist/worker/expo/index.d.cts +4 -4
  77. package/dist/worker/expo/index.d.ts +4 -4
  78. package/dist/worker/expo/index.js +6 -5
  79. package/dist/worker/expo/index.js.map +1 -1
  80. package/package.json +2 -2
  81. package/dist/chunk-32YKLQPS.cjs.map +0 -1
  82. package/dist/chunk-BE5MUB7T.js.map +0 -1
  83. package/dist/chunk-FMI2GKYO.js.map +0 -1
  84. package/dist/chunk-HXDZ2QTW.cjs.map +0 -1
  85. package/dist/chunk-LJ35HPJW.js.map +0 -1
  86. package/dist/chunk-UBYY2TPK.cjs.map +0 -1
  87. package/dist/chunk-XIVCG6EP.cjs.map +0 -1
  88. package/dist/chunk-YNEDJTX2.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkUBYY2TPK_cjs = require('./chunk-UBYY2TPK.cjs');
4
- var chunk32YKLQPS_cjs = require('./chunk-32YKLQPS.cjs');
5
- var chunkHXDZ2QTW_cjs = require('./chunk-HXDZ2QTW.cjs');
3
+ var chunk7IYIFMF4_cjs = require('./chunk-7IYIFMF4.cjs');
4
+ var chunk4KXOCVXP_cjs = require('./chunk-4KXOCVXP.cjs');
5
+ var chunkMQB5H4X5_cjs = require('./chunk-MQB5H4X5.cjs');
6
6
  var utils_js = require('@scure/btc-signer/utils.js');
7
7
  var btcSigner = require('@scure/btc-signer');
8
8
  var base = require('@scure/base');
@@ -84,6 +84,8 @@ var PartialSig = class _PartialSig {
84
84
  throw new PartialSignatureError("Invalid R length");
85
85
  }
86
86
  }
87
+ s;
88
+ R;
87
89
  /**
88
90
  * Encodes the partial signature into bytes
89
91
  * Returns a 32-byte array containing just the s value
@@ -133,6 +135,7 @@ var TreeSignerSession = class _TreeSignerSession {
133
135
  constructor(secretKey) {
134
136
  this.secretKey = secretKey;
135
137
  }
138
+ secretKey;
136
139
  static NOT_INITIALIZED = new Error("session not initialized, call init method");
137
140
  myNonces = null;
138
141
  aggregateNonces = null;
@@ -181,7 +184,7 @@ var TreeSignerSession = class _TreeSignerSession {
181
184
  noncesByPubkey.set(base.hex.encode(myPublicKey.subarray(1)), myNonce);
182
185
  const tx = this.graph.find(txid);
183
186
  if (!tx) throw new Error(`missing tx for txid ${txid}`);
184
- const cosigners = chunkUBYY2TPK_cjs.getArkPsbtFields(tx.root, 0, chunkUBYY2TPK_cjs.CosignerPublicKey).map(
187
+ const cosigners = chunk7IYIFMF4_cjs.getArkPsbtFields(tx.root, 0, chunk7IYIFMF4_cjs.CosignerPublicKey).map(
185
188
  (c) => base.hex.encode(c.key.subarray(1))
186
189
  // xonly pubkey
187
190
  );
@@ -233,7 +236,7 @@ var TreeSignerSession = class _TreeSignerSession {
233
236
  if (!aggNonce) throw new Error("missing aggregate nonce");
234
237
  const prevoutAmounts = [];
235
238
  const prevoutScripts = [];
236
- const cosigners = chunkUBYY2TPK_cjs.getArkPsbtFields(g.root, 0, chunkUBYY2TPK_cjs.CosignerPublicKey).map((c) => c.key);
239
+ const cosigners = chunk7IYIFMF4_cjs.getArkPsbtFields(g.root, 0, chunk7IYIFMF4_cjs.CosignerPublicKey).map((c) => c.key);
237
240
  const { finalKey } = aggregateKeys(cosigners, true, {
238
241
  taprootTweak: this.scriptRoot
239
242
  });
@@ -359,6 +362,7 @@ var ReadonlySingleKey = class _ReadonlySingleKey {
359
362
  throw new Error("Invalid public key length");
360
363
  }
361
364
  }
365
+ publicKey;
362
366
  /**
363
367
  * Create a ReadonlySingleKey from a compressed public key.
364
368
  *
@@ -411,7 +415,7 @@ var SeedIdentity = class _SeedIdentity {
411
415
  let network;
412
416
  if ("descriptor" in opts && typeof opts.descriptor === "string") {
413
417
  descriptor = opts.descriptor;
414
- network = chunk32YKLQPS_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
418
+ network = chunk4KXOCVXP_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
415
419
  } else {
416
420
  network = opts.isMainnet ?? true ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
417
421
  descriptor = descriptorsScure.scriptExpressions.trBIP32({
@@ -496,7 +500,7 @@ var SeedIdentity = class _SeedIdentity {
496
500
  * `StaticDescriptorProvider` for legacy single-key wallets.
497
501
  */
498
502
  isOurs(descriptor) {
499
- return chunk32YKLQPS_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
503
+ return chunk4KXOCVXP_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
500
504
  }
501
505
  /**
502
506
  * Signs each request with the key derived from its descriptor.
@@ -533,7 +537,7 @@ var SeedIdentity = class _SeedIdentity {
533
537
  }
534
538
  // ── internal helpers ─────────────────────────────────────────────
535
539
  derivePrivateKeyForDescriptor(descriptor) {
536
- const network = chunk32YKLQPS_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
540
+ const network = chunk4KXOCVXP_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
537
541
  const expansion = descriptorsScure.expand({ descriptor, network });
538
542
  if (expansion.isRanged) {
539
543
  throw new Error(
@@ -619,7 +623,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
619
623
  */
620
624
  descriptor;
621
625
  constructor(descriptor) {
622
- const network = chunk32YKLQPS_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
626
+ const network = chunk4KXOCVXP_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
623
627
  let expansion;
624
628
  try {
625
629
  expansion = descriptorsScure.expand({ descriptor, network, index: 0 });
@@ -669,7 +673,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
669
673
  * `StaticDescriptorProvider` for legacy single-key wallets.
670
674
  */
671
675
  isOurs(descriptor) {
672
- return chunk32YKLQPS_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
676
+ return chunk4KXOCVXP_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
673
677
  }
674
678
  };
675
679
  function serializeSeedOwnedSigningIdentity(identity) {
@@ -970,6 +974,7 @@ var RestDelegateProvider = class {
970
974
  constructor(url) {
971
975
  this.url = url;
972
976
  }
977
+ url;
973
978
  /**
974
979
  * Submit a delegation request to the remote delegation service.
975
980
  *
@@ -980,14 +985,14 @@ var RestDelegateProvider = class {
980
985
  */
981
986
  async delegate(intent, forfeitTxs, options) {
982
987
  const url = `${this.url}/v1/delegate`;
983
- const response = await chunkUBYY2TPK_cjs.baseFetch(url, {
988
+ const response = await chunk7IYIFMF4_cjs.baseFetch(url, {
984
989
  method: "POST",
985
990
  headers: {
986
991
  "Content-Type": "application/json"
987
992
  },
988
993
  body: JSON.stringify({
989
994
  intent: {
990
- message: chunkUBYY2TPK_cjs.Intent.encodeMessage(intent.message),
995
+ message: chunk7IYIFMF4_cjs.Intent.encodeMessage(intent.message),
991
996
  proof: intent.proof
992
997
  },
993
998
  forfeit_txs: forfeitTxs,
@@ -1007,7 +1012,7 @@ var RestDelegateProvider = class {
1007
1012
  */
1008
1013
  async getDelegateInfo() {
1009
1014
  const url = `${this.url}/v1/delegator/info`;
1010
- const response = await chunkUBYY2TPK_cjs.baseFetch(url);
1015
+ const response = await chunk7IYIFMF4_cjs.baseFetch(url);
1011
1016
  if (!response.ok) {
1012
1017
  const errorText2 = await response.text();
1013
1018
  throw new Error(`Failed to get delegate info: ${errorText2}`);
@@ -1034,22 +1039,23 @@ var ESPLORA_URL = {
1034
1039
  regtest: "http://localhost:3000/api"
1035
1040
  };
1036
1041
  var EsploraProvider = class {
1037
- constructor(baseUrl = ESPLORA_URL[chunkHXDZ2QTW_cjs.DEFAULT_NETWORK_NAME], opts) {
1042
+ constructor(baseUrl = ESPLORA_URL[chunkMQB5H4X5_cjs.DEFAULT_NETWORK_NAME], opts) {
1038
1043
  this.baseUrl = baseUrl;
1039
1044
  this.pollingInterval = opts?.pollingInterval ?? 15e3;
1040
1045
  this.forcePolling = opts?.forcePolling ?? false;
1041
1046
  }
1047
+ baseUrl;
1042
1048
  pollingInterval;
1043
1049
  forcePolling;
1044
1050
  async getCoins(address) {
1045
- const response = await chunkUBYY2TPK_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
1051
+ const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
1046
1052
  if (!response.ok) {
1047
1053
  throw new Error(`Failed to fetch UTXOs: ${response.statusText}`);
1048
1054
  }
1049
1055
  return response.json();
1050
1056
  }
1051
1057
  async getFeeRate() {
1052
- const response = await chunkUBYY2TPK_cjs.baseFetch(`${this.baseUrl}/fee-estimates`);
1058
+ const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/fee-estimates`);
1053
1059
  if (response.status === 404) {
1054
1060
  return void 0;
1055
1061
  }
@@ -1070,7 +1076,7 @@ var EsploraProvider = class {
1070
1076
  }
1071
1077
  }
1072
1078
  async getTxOutspends(txid) {
1073
- const response = await chunkUBYY2TPK_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
1079
+ const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
1074
1080
  if (!response.ok) {
1075
1081
  const error = await response.text();
1076
1082
  throw new Error(`Failed to get transaction outspends: ${error}`);
@@ -1078,7 +1084,7 @@ var EsploraProvider = class {
1078
1084
  return response.json();
1079
1085
  }
1080
1086
  async getTransactions(address) {
1081
- const response = await chunkUBYY2TPK_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
1087
+ const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
1082
1088
  if (!response.ok) {
1083
1089
  const error = await response.text();
1084
1090
  throw new Error(`Failed to get transactions: ${error}`);
@@ -1086,7 +1092,7 @@ var EsploraProvider = class {
1086
1092
  return response.json();
1087
1093
  }
1088
1094
  async getTxStatus(txid) {
1089
- const txresponse = await chunkUBYY2TPK_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
1095
+ const txresponse = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
1090
1096
  if (!txresponse.ok) {
1091
1097
  throw new Error(txresponse.statusText);
1092
1098
  }
@@ -1094,7 +1100,7 @@ var EsploraProvider = class {
1094
1100
  if (!tx.status.confirmed) {
1095
1101
  return { confirmed: false };
1096
1102
  }
1097
- const response = await chunkUBYY2TPK_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
1103
+ const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
1098
1104
  if (!response.ok) {
1099
1105
  throw new Error(`Failed to get transaction status: ${response.statusText}`);
1100
1106
  }
@@ -1178,7 +1184,7 @@ var EsploraProvider = class {
1178
1184
  return stopFunc;
1179
1185
  }
1180
1186
  async getChainTip() {
1181
- const tipBlocks = await chunkUBYY2TPK_cjs.baseFetch(`${this.baseUrl}/blocks`);
1187
+ const tipBlocks = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/blocks`);
1182
1188
  if (!tipBlocks.ok) {
1183
1189
  throw new Error(`Failed to get chain tip: ${tipBlocks.statusText}`);
1184
1190
  }
@@ -1197,7 +1203,7 @@ var EsploraProvider = class {
1197
1203
  };
1198
1204
  }
1199
1205
  async broadcastPackage(parent, child) {
1200
- const response = await chunkUBYY2TPK_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
1206
+ const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
1201
1207
  method: "POST",
1202
1208
  headers: {
1203
1209
  "Content-Type": "application/json"
@@ -1211,7 +1217,7 @@ var EsploraProvider = class {
1211
1217
  return response.json();
1212
1218
  }
1213
1219
  async broadcastTx(tx) {
1214
- const response = await chunkUBYY2TPK_cjs.baseFetch(`${this.baseUrl}/tx`, {
1220
+ const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/tx`, {
1215
1221
  method: "POST",
1216
1222
  headers: {
1217
1223
  "Content-Type": "text/plain"
@@ -1373,7 +1379,7 @@ function findP2AOutput(tx) {
1373
1379
  var CHILD_DUST_AMOUNT = 546;
1374
1380
  function buildAnchorChild(params) {
1375
1381
  const { parent, feeRate, fundingCoins, changeAddress, tapInternalKey, network } = params;
1376
- const child = new chunkUBYY2TPK_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
1382
+ const child = new chunk7IYIFMF4_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
1377
1383
  child.addInput(findP2AOutput(parent));
1378
1384
  const estimator = TxWeightEstimator.create().addP2AInput();
1379
1385
  for (const _ of fundingCoins) {
@@ -1421,7 +1427,7 @@ function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
1421
1427
  );
1422
1428
  }
1423
1429
  function buildForfeitTxWithOutput(inputs, output, txLocktime) {
1424
- const tx = new chunkUBYY2TPK_cjs.Transaction({
1430
+ const tx = new chunk7IYIFMF4_cjs.Transaction({
1425
1431
  version: 3,
1426
1432
  lockTime: txLocktime
1427
1433
  });
@@ -1497,7 +1503,7 @@ function validateVtxoTxGraph(graph, roundTransaction, sweepTapTreeRoot) {
1497
1503
  if (previousScriptKey.length !== 32) {
1498
1504
  throw new Error(`parent output ${childIndex} has invalid script`);
1499
1505
  }
1500
- const cosigners = chunkUBYY2TPK_cjs.getArkPsbtFields(child.root, 0, chunkUBYY2TPK_cjs.CosignerPublicKey);
1506
+ const cosigners = chunk7IYIFMF4_cjs.getArkPsbtFields(child.root, 0, chunk7IYIFMF4_cjs.CosignerPublicKey);
1501
1507
  if (cosigners.length === 0) {
1502
1508
  throw ErrMissingCosignersPublicKeys;
1503
1509
  }
@@ -1518,6 +1524,8 @@ var UnknownPacket = class {
1518
1524
  this.packetType = packetType;
1519
1525
  this.data = data;
1520
1526
  }
1527
+ packetType;
1528
+ data;
1521
1529
  type() {
1522
1530
  return this.packetType;
1523
1531
  }
@@ -1538,6 +1546,7 @@ var Extension = class _Extension {
1538
1546
  constructor(packets) {
1539
1547
  this.packets = packets;
1540
1548
  }
1549
+ packets;
1541
1550
  static create(packets) {
1542
1551
  if (packets.length === 0) {
1543
1552
  throw new Error("missing packets");
@@ -1597,7 +1606,7 @@ var Extension = class _Extension {
1597
1606
  `expected magic prefix ${base.hex.encode(ARKADE_MAGIC)}, got ${base.hex.encode(payload.slice(0, Math.min(payload.length, ARKADE_MAGIC.length)))}`
1598
1607
  );
1599
1608
  }
1600
- const reader = new chunkUBYY2TPK_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
1609
+ const reader = new chunk7IYIFMF4_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
1601
1610
  const packets = [];
1602
1611
  while (reader.remaining() > 0) {
1603
1612
  const packetType = reader.readByte();
@@ -1671,7 +1680,7 @@ var Extension = class _Extension {
1671
1680
  */
1672
1681
  getAssetPacket() {
1673
1682
  for (const p of this.packets) {
1674
- if (p instanceof chunkUBYY2TPK_cjs.Packet) {
1683
+ if (p instanceof chunk7IYIFMF4_cjs.Packet) {
1675
1684
  return p;
1676
1685
  }
1677
1686
  }
@@ -1679,8 +1688,8 @@ var Extension = class _Extension {
1679
1688
  }
1680
1689
  };
1681
1690
  function parsePacket(packetType, data) {
1682
- if (packetType === chunkUBYY2TPK_cjs.Packet.PACKET_TYPE) {
1683
- return chunkUBYY2TPK_cjs.Packet.fromBytes(data);
1691
+ if (packetType === chunk7IYIFMF4_cjs.Packet.PACKET_TYPE) {
1692
+ return chunk7IYIFMF4_cjs.Packet.fromBytes(data);
1684
1693
  }
1685
1694
  return new UnknownPacket(packetType, data);
1686
1695
  }
@@ -1738,7 +1747,7 @@ function validateBatchRecipients(commitmentTx, vtxoTreeLeaves, recipients, netwo
1738
1747
  for (const recipient of recipients) {
1739
1748
  let arkAddress;
1740
1749
  try {
1741
- arkAddress = chunkHXDZ2QTW_cjs.ArkAddress.decode(recipient.address);
1750
+ arkAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(recipient.address);
1742
1751
  } catch {
1743
1752
  validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
1744
1753
  continue;
@@ -1976,6 +1985,7 @@ function isExpired(vtxo) {
1976
1985
  return expiry <= Date.now();
1977
1986
  }
1978
1987
  function isSubdust(vtxo, dust) {
1988
+ if (typeof vtxo === "bigint") return vtxo < dust;
1979
1989
  return vtxo.value < dust;
1980
1990
  }
1981
1991
 
@@ -1987,7 +1997,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
1987
1997
  const existing = inputsByAssetId.get(asset.assetId);
1988
1998
  inputsByAssetId.set(asset.assetId, [
1989
1999
  ...existing ?? [],
1990
- chunkUBYY2TPK_cjs.AssetInput.create(inputIndex, asset.amount)
2000
+ chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount)
1991
2001
  ]);
1992
2002
  }
1993
2003
  }
@@ -1999,7 +2009,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
1999
2009
  const existing = outputsByAssetId.get(asset.assetId);
2000
2010
  outputsByAssetId.set(asset.assetId, [
2001
2011
  ...existing ?? [],
2002
- chunkUBYY2TPK_cjs.AssetOutput.create(outputIndex, asset.amount)
2012
+ chunk7IYIFMF4_cjs.AssetOutput.create(outputIndex, asset.amount)
2003
2013
  ]);
2004
2014
  }
2005
2015
  }
@@ -2010,7 +2020,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
2010
2020
  const existing = outputsByAssetId.get(asset.assetId);
2011
2021
  outputsByAssetId.set(asset.assetId, [
2012
2022
  ...existing ?? [],
2013
- chunkUBYY2TPK_cjs.AssetOutput.create(outputIndex, asset.amount)
2023
+ chunk7IYIFMF4_cjs.AssetOutput.create(outputIndex, asset.amount)
2014
2024
  ]);
2015
2025
  }
2016
2026
  }
@@ -2019,11 +2029,11 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
2019
2029
  for (const assetIdStr of allAssetIds) {
2020
2030
  const inputs = inputsByAssetId.get(assetIdStr);
2021
2031
  const outputs = outputsByAssetId.get(assetIdStr);
2022
- const assetId = chunkUBYY2TPK_cjs.AssetId.fromString(assetIdStr);
2023
- const group = chunkUBYY2TPK_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
2032
+ const assetId = chunk7IYIFMF4_cjs.AssetId.fromString(assetIdStr);
2033
+ const group = chunk7IYIFMF4_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
2024
2034
  groups.push(group);
2025
2035
  }
2026
- return chunkUBYY2TPK_cjs.Packet.create(groups);
2036
+ return chunk7IYIFMF4_cjs.Packet.create(groups);
2027
2037
  }
2028
2038
  function selectCoinsWithAsset(coins, assetId, requiredAmount) {
2029
2039
  const coinsWithAsset = coins.filter((coin) => coin.assets?.some((a) => a.assetId === assetId));
@@ -2128,8 +2138,8 @@ function buildOffchainTx(inputs, outputs, serverUnrollScript) {
2128
2138
  function buildVirtualTx(inputs, outputs) {
2129
2139
  let lockTime = 0n;
2130
2140
  for (const input of inputs) {
2131
- const tapscript = chunkHXDZ2QTW_cjs.decodeTapscript(chunkHXDZ2QTW_cjs.scriptFromTapLeafScript(input.tapLeafScript));
2132
- if (chunkHXDZ2QTW_cjs.CLTVMultisigTapscript.is(tapscript)) {
2141
+ const tapscript = chunkMQB5H4X5_cjs.decodeTapscript(chunkMQB5H4X5_cjs.scriptFromTapLeafScript(input.tapLeafScript));
2142
+ if (chunkMQB5H4X5_cjs.CLTVMultisigTapscript.is(tapscript)) {
2133
2143
  if (lockTime !== 0n) {
2134
2144
  if (isSeconds(lockTime) !== isSeconds(tapscript.params.absoluteTimelock)) {
2135
2145
  throw new Error("cannot mix seconds and blocks locktime");
@@ -2140,7 +2150,7 @@ function buildVirtualTx(inputs, outputs) {
2140
2150
  }
2141
2151
  }
2142
2152
  }
2143
- const tx = new chunkUBYY2TPK_cjs.Transaction({
2153
+ const tx = new chunk7IYIFMF4_cjs.Transaction({
2144
2154
  version: 3,
2145
2155
  lockTime: Number(lockTime)
2146
2156
  });
@@ -2150,12 +2160,12 @@ function buildVirtualTx(inputs, outputs) {
2150
2160
  index: input.vout,
2151
2161
  sequence: lockTime ? btcSigner.DEFAULT_SEQUENCE - 1 : void 0,
2152
2162
  witnessUtxo: {
2153
- script: chunkHXDZ2QTW_cjs.VtxoScript.decode(input.tapTree).pkScript,
2163
+ script: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript,
2154
2164
  amount: BigInt(input.value)
2155
2165
  },
2156
2166
  tapLeafScript: [input.tapLeafScript]
2157
2167
  });
2158
- chunkUBYY2TPK_cjs.setArkPsbtField(tx, i, chunkUBYY2TPK_cjs.VtxoTaprootTree, input.tapTree);
2168
+ chunk7IYIFMF4_cjs.setArkPsbtField(tx, i, chunk7IYIFMF4_cjs.VtxoTaprootTree, input.tapTree);
2159
2169
  }
2160
2170
  for (const output of outputs) {
2161
2171
  tx.addOutput(output);
@@ -2164,8 +2174,8 @@ function buildVirtualTx(inputs, outputs) {
2164
2174
  return tx;
2165
2175
  }
2166
2176
  function buildCheckpointTx(vtxo, serverUnrollScript) {
2167
- const collaborativeClosure = chunkHXDZ2QTW_cjs.decodeTapscript(chunkHXDZ2QTW_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
2168
- const checkpointVtxoScript = new chunkHXDZ2QTW_cjs.VtxoScript([
2177
+ const collaborativeClosure = chunkMQB5H4X5_cjs.decodeTapscript(chunkMQB5H4X5_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
2178
+ const checkpointVtxoScript = new chunkMQB5H4X5_cjs.VtxoScript([
2169
2179
  serverUnrollScript.script,
2170
2180
  collaborativeClosure.script
2171
2181
  ]);
@@ -2309,7 +2319,7 @@ function combineTapscriptSigs(signedTx, originalTx) {
2309
2319
  }
2310
2320
  function isValidArkAddress(address) {
2311
2321
  try {
2312
- chunkHXDZ2QTW_cjs.ArkAddress.decode(address);
2322
+ chunkMQB5H4X5_cjs.ArkAddress.decode(address);
2313
2323
  return true;
2314
2324
  } catch (e) {
2315
2325
  return false;
@@ -2334,6 +2344,7 @@ var FeeAmount = class _FeeAmount {
2334
2344
  constructor(value) {
2335
2345
  this.value = value;
2336
2346
  }
2347
+ value;
2337
2348
  static ZERO = new _FeeAmount(0);
2338
2349
  /** Returns the fee amount rounded up to whole satoshis. */
2339
2350
  get satoshis() {
@@ -2358,6 +2369,7 @@ var Estimator = class {
2358
2369
  this.intentOffchainOutput = config.offchainOutput ? parseProgram(config.offchainOutput, IntentOutputEnv) : void 0;
2359
2370
  this.intentOnchainOutput = config.onchainOutput ? parseProgram(config.onchainOutput, IntentOutputEnv) : void 0;
2360
2371
  }
2372
+ config;
2361
2373
  intentOffchainInput;
2362
2374
  intentOnchainInput;
2363
2375
  intentOffchainOutput;
@@ -2482,7 +2494,7 @@ function extendCoinWithTapscript(boardingTapscript, utxo) {
2482
2494
  };
2483
2495
  }
2484
2496
  function deriveContractTapscripts(contract) {
2485
- const handler = chunk32YKLQPS_cjs.contractHandlers.get(contract.type);
2497
+ const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
2486
2498
  if (!handler) {
2487
2499
  throw new Error(`No handler for contract type '${contract.type}'`);
2488
2500
  }
@@ -2552,7 +2564,7 @@ function validateRecipients(recipients, dustAmount) {
2552
2564
  for (const recipient of recipients) {
2553
2565
  let address;
2554
2566
  try {
2555
- address = chunkHXDZ2QTW_cjs.ArkAddress.decode(recipient.address);
2567
+ address = chunkMQB5H4X5_cjs.ArkAddress.decode(recipient.address);
2556
2568
  } catch (e) {
2557
2569
  throw new Error(`Invalid Arkade address: ${recipient.address}`);
2558
2570
  }
@@ -2760,6 +2772,8 @@ var VtxoManager = class _VtxoManager {
2760
2772
  }
2761
2773
  this.contractEventsSubscriptionReady = this.initializeSubscription();
2762
2774
  }
2775
+ wallet;
2776
+ renewalConfig;
2763
2777
  settlementConfig;
2764
2778
  contractEventsSubscriptionReady;
2765
2779
  disposePromise;
@@ -3157,11 +3171,11 @@ var VtxoManager = class _VtxoManager {
3157
3171
  `Sweep not economical: output ${outputAmount} sats after ${fee} sats fee is below dust (${dustAmount} sats)`
3158
3172
  );
3159
3173
  }
3160
- const tx = new chunkUBYY2TPK_cjs.Transaction();
3174
+ const tx = new chunk7IYIFMF4_cjs.Transaction();
3161
3175
  for (const utxo of expiredUtxos) {
3162
- const utxoScript = chunkHXDZ2QTW_cjs.VtxoScript.decode(utxo.tapTree);
3176
+ const utxoScript = chunkMQB5H4X5_cjs.VtxoScript.decode(utxo.tapTree);
3163
3177
  const utxoExitLeaf = utxoScript.leaves.find(
3164
- (leaf) => chunkHXDZ2QTW_cjs.CSVMultisigTapscript.isScriptValid(chunkHXDZ2QTW_cjs.scriptFromTapLeafScript(leaf)) === true
3178
+ (leaf) => chunkMQB5H4X5_cjs.CSVMultisigTapscript.isScriptValid(chunkMQB5H4X5_cjs.scriptFromTapLeafScript(leaf)) === true
3165
3179
  );
3166
3180
  if (!utxoExitLeaf) {
3167
3181
  throw new Error(
@@ -3176,7 +3190,7 @@ var VtxoManager = class _VtxoManager {
3176
3190
  amount: BigInt(utxo.value)
3177
3191
  },
3178
3192
  tapLeafScript: [utxoExitLeaf],
3179
- sequence: chunkHXDZ2QTW_cjs.getSequence(utxoExitLeaf)
3193
+ sequence: chunkMQB5H4X5_cjs.getSequence(utxoExitLeaf)
3180
3194
  });
3181
3195
  }
3182
3196
  tx.addOutputAddress(boardingAddress, outputAmount, this.getNetwork());
@@ -3665,7 +3679,7 @@ var VtxoManager = class _VtxoManager {
3665
3679
  /** Decodes the boarding tapscript exit path to extract the CSV timelock. */
3666
3680
  getBoardingTimelock() {
3667
3681
  const wallet = this.getSweepWallet();
3668
- const exitScript = chunkHXDZ2QTW_cjs.CSVMultisigTapscript.decode(
3682
+ const exitScript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(
3669
3683
  base.hex.decode(wallet.boardingTapscript.exitScript)
3670
3684
  );
3671
3685
  return exitScript.params.timelock;
@@ -3796,8 +3810,8 @@ var VtxoManager = class _VtxoManager {
3796
3810
  * or doesn't carry the metadata.
3797
3811
  */
3798
3812
  extractSpentOutpoint(error) {
3799
- const ark = chunkUBYY2TPK_cjs.maybeArkError(error);
3800
- if (!ark || ark.name !== "VTXO_ALREADY_SPENT") return void 0;
3813
+ const ark = chunk7IYIFMF4_cjs.maybeArkError(error);
3814
+ if (!chunk7IYIFMF4_cjs.isArkError(ark, chunk7IYIFMF4_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
3801
3815
  const raw = ark.metadata?.vtxo_outpoint;
3802
3816
  if (typeof raw !== "string") return void 0;
3803
3817
  const [txid, voutStr] = raw.split(":");
@@ -4011,7 +4025,7 @@ var VtxoManager = class _VtxoManager {
4011
4025
  const arkAddress = await this.wallet.getAddress();
4012
4026
  const outputFee = estimator.evalOffchainOutput({
4013
4027
  amount: totalAmount,
4014
- script: base.hex.encode(chunkHXDZ2QTW_cjs.ArkAddress.decode(arkAddress).pkScript)
4028
+ script: base.hex.encode(chunkMQB5H4X5_cjs.ArkAddress.decode(arkAddress).pkScript)
4015
4029
  });
4016
4030
  totalAmount -= BigInt(outputFee.satoshis);
4017
4031
  if (totalAmount < dustAmount) return;
@@ -4091,7 +4105,7 @@ var ArkNote = class _ArkNote {
4091
4105
  this.value = value;
4092
4106
  this.HRP = HRP;
4093
4107
  const preimageHash = utils_js.sha256(this.preimage);
4094
- this.vtxoScript = new chunkHXDZ2QTW_cjs.VtxoScript([noteTapscript(preimageHash)]);
4108
+ this.vtxoScript = new chunkMQB5H4X5_cjs.VtxoScript([noteTapscript(preimageHash)]);
4095
4109
  const leaf = this.vtxoScript.leaves[0];
4096
4110
  this.txid = base.hex.encode(new Uint8Array(preimageHash).reverse());
4097
4111
  this.tapTree = this.vtxoScript.encode();
@@ -4101,6 +4115,9 @@ var ArkNote = class _ArkNote {
4101
4115
  this.status = { confirmed: true };
4102
4116
  this.extraWitness = [this.preimage];
4103
4117
  }
4118
+ preimage;
4119
+ value;
4120
+ HRP;
4104
4121
  static DefaultHRP = "arknote";
4105
4122
  static PreimageLength = 32;
4106
4123
  // 32 bytes for the preimage
@@ -4309,11 +4326,603 @@ function wrapHandlerWithIntentPersistence(base, deps) {
4309
4326
  }
4310
4327
  };
4311
4328
  }
4329
+
4330
+ // src/repositories/virtualTxRepository.ts
4331
+ var ChainedTxType = /* @__PURE__ */ ((ChainedTxType2) => {
4332
+ ChainedTxType2[ChainedTxType2["Unspecified"] = 0] = "Unspecified";
4333
+ ChainedTxType2[ChainedTxType2["Commitment"] = 1] = "Commitment";
4334
+ ChainedTxType2[ChainedTxType2["Ark"] = 2] = "Ark";
4335
+ ChainedTxType2[ChainedTxType2["Tree"] = 3] = "Tree";
4336
+ ChainedTxType2[ChainedTxType2["Checkpoint"] = 4] = "Checkpoint";
4337
+ return ChainedTxType2;
4338
+ })(ChainedTxType || {});
4339
+ function mergeChainedTxType(incoming, prev) {
4340
+ if (incoming !== 0 /* Unspecified */) return incoming;
4341
+ return prev ?? 0 /* Unspecified */;
4342
+ }
4343
+
4344
+ // src/wallet/exit/chain.ts
4345
+ var isCommitment = (t) => t === "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */ || t === "INDEXER_CHAINED_TX_TYPE_UNSPECIFIED" /* UNSPECIFIED */;
4346
+ async function buildExitDag(params) {
4347
+ const byTxid = /* @__PURE__ */ new Map();
4348
+ for (const vtxo of params.vtxos) {
4349
+ const outpoint = `${vtxo.txid}:${vtxo.vout}`;
4350
+ const chain = await params.chain.getVtxoChain({ txid: vtxo.txid, vout: vtxo.vout });
4351
+ for (const chainTx of chain) {
4352
+ const existing = byTxid.get(chainTx.txid);
4353
+ if (existing) {
4354
+ existing.forVtxos.add(outpoint);
4355
+ } else {
4356
+ byTxid.set(chainTx.txid, { ...chainTx, forVtxos: /* @__PURE__ */ new Set([outpoint]) });
4357
+ }
4358
+ }
4359
+ }
4360
+ const pending = new Map(
4361
+ [...byTxid.values()].filter((tx) => !isCommitment(tx.type)).map((tx) => [tx.txid, tx])
4362
+ );
4363
+ const inDegree = /* @__PURE__ */ new Map();
4364
+ for (const tx of pending.values()) {
4365
+ const parents = tx.spends.filter((p) => pending.has(p));
4366
+ inDegree.set(tx.txid, parents.length);
4367
+ }
4368
+ const order = [];
4369
+ const queue = [...pending.values()].filter((tx) => inDegree.get(tx.txid) === 0).sort((a, b) => a.txid.localeCompare(b.txid));
4370
+ while (queue.length > 0) {
4371
+ const tx = queue.shift();
4372
+ order.push(tx);
4373
+ const children = [...pending.values()].filter((c) => c.spends.includes(tx.txid)).sort((a, b) => a.txid.localeCompare(b.txid));
4374
+ for (const child of children) {
4375
+ const deg = inDegree.get(child.txid) - 1;
4376
+ inDegree.set(child.txid, deg);
4377
+ if (deg === 0) queue.push(child);
4378
+ }
4379
+ }
4380
+ if (order.length !== pending.size) {
4381
+ throw new Error("inconsistent vtxo chain from indexer (cycle detected)");
4382
+ }
4383
+ const nodes = [];
4384
+ for (const tx of order) {
4385
+ let confirmed = false;
4386
+ try {
4387
+ const status = await params.onchain.getTxStatus(tx.txid);
4388
+ confirmed = status.confirmed;
4389
+ } catch {
4390
+ confirmed = false;
4391
+ }
4392
+ const expires = Number(tx.expiresAt);
4393
+ nodes.push({
4394
+ txid: tx.txid,
4395
+ type: tx.type,
4396
+ expiresAt: Number.isFinite(expires) && expires > 0 ? expires : void 0,
4397
+ forVtxos: [...tx.forVtxos].sort(),
4398
+ confirmed
4399
+ });
4400
+ }
4401
+ return nodes;
4402
+ }
4403
+ function topoSortByDeps(items, idOf, depsOf) {
4404
+ const produced = new Set(items.map(idOf));
4405
+ const emitted = /* @__PURE__ */ new Set();
4406
+ const ordered = [];
4407
+ let remaining = items;
4408
+ while (remaining.length > 0) {
4409
+ const next = [];
4410
+ let progress = false;
4411
+ for (const item of remaining) {
4412
+ if (depsOf(item).every((d) => !produced.has(d) || emitted.has(d))) {
4413
+ ordered.push(item);
4414
+ emitted.add(idOf(item));
4415
+ progress = true;
4416
+ } else {
4417
+ next.push(item);
4418
+ }
4419
+ }
4420
+ if (!progress) {
4421
+ throw new Error("topological sort: cycle or unsatisfiable dependency");
4422
+ }
4423
+ remaining = next;
4424
+ }
4425
+ return ordered;
4426
+ }
4427
+
4428
+ // src/wallet/exit/capture.ts
4429
+ var DEFAULT_MIN_EXIT_WORTH_SATS = 1e3;
4430
+ var DEFAULT_EXIT_CAPTURE_MODE = "lite";
4431
+ function chainTxTypeToChainedExit(t) {
4432
+ switch (t) {
4433
+ case "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */:
4434
+ return 1 /* Commitment */;
4435
+ case "INDEXER_CHAINED_TX_TYPE_ARK" /* ARK */:
4436
+ return 2 /* Ark */;
4437
+ case "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */:
4438
+ return 3 /* Tree */;
4439
+ case "INDEXER_CHAINED_TX_TYPE_CHECKPOINT" /* CHECKPOINT */:
4440
+ return 4 /* Checkpoint */;
4441
+ default:
4442
+ return 0 /* Unspecified */;
4443
+ }
4444
+ }
4445
+ function orderAncestryFirst(chain) {
4446
+ const ids = new Set(chain.map((c) => c.txid));
4447
+ return topoSortByDeps(
4448
+ chain,
4449
+ (c) => c.txid,
4450
+ (c) => c.spends.filter((s) => ids.has(s))
4451
+ );
4452
+ }
4453
+ async function captureExitBranch(params) {
4454
+ const { resolver, repository, vtxo, value, mode, minExitWorthSats } = params;
4455
+ if (value < minExitWorthSats) return;
4456
+ if (await repository.hasBranch(vtxo)) return;
4457
+ const ordered = orderAncestryFirst(await resolver.getVtxoChain(vtxo));
4458
+ const psbtByTxid = /* @__PURE__ */ new Map();
4459
+ if (mode === "full") {
4460
+ const nonCommitment = ordered.filter((c) => chainTxTypeToChainedExit(c.type) !== 1 /* Commitment */).map((c) => c.txid);
4461
+ if (nonCommitment.length > 0) {
4462
+ for (const psbt of await resolver.getVirtualTxs(nonCommitment)) {
4463
+ psbtByTxid.set(chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
4464
+ }
4465
+ }
4466
+ }
4467
+ const virtualTxs = ordered.map((c) => {
4468
+ const expires = Number(c.expiresAt);
4469
+ return {
4470
+ txid: c.txid,
4471
+ psbt: psbtByTxid.get(c.txid) ?? null,
4472
+ expiresAt: Number.isFinite(expires) && expires > 0 ? expires : null,
4473
+ type: chainTxTypeToChainedExit(c.type)
4474
+ };
4475
+ });
4476
+ const branch = ordered.map((c, i) => ({
4477
+ vtxoTxid: vtxo.txid,
4478
+ vtxoVout: vtxo.vout,
4479
+ virtualTxid: c.txid,
4480
+ position: i
4481
+ }));
4482
+ await repository.upsertVirtualTxs(virtualTxs);
4483
+ await repository.setBranch(vtxo, branch);
4484
+ }
4485
+ async function pruneExitBranches(repository, outpoints) {
4486
+ for (const outpoint of outpoints) {
4487
+ try {
4488
+ await repository.pruneForSpentVtxo(outpoint);
4489
+ } catch {
4490
+ }
4491
+ }
4492
+ }
4493
+ var IndexerExitDataSource = class {
4494
+ constructor(indexer) {
4495
+ this.indexer = indexer;
4496
+ }
4497
+ indexer;
4498
+ name = "indexer";
4499
+ async getVtxoChain(vtxo) {
4500
+ const chain = [];
4501
+ let pageIndex = 0;
4502
+ let hasMore = true;
4503
+ while (hasMore) {
4504
+ const { chain: page, page: meta } = await this.indexer.getVtxoChain(
4505
+ { txid: vtxo.txid, vout: vtxo.vout },
4506
+ { pageIndex, pageSize: chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE }
4507
+ );
4508
+ chain.push(...page);
4509
+ hasMore = meta ? page.length === chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE : false;
4510
+ pageIndex++;
4511
+ }
4512
+ return chain;
4513
+ }
4514
+ async getVirtualTxs(txids) {
4515
+ const out = /* @__PURE__ */ new Map();
4516
+ let pageIndex = 0;
4517
+ let hasMore = true;
4518
+ while (hasMore) {
4519
+ const { txs, page } = await this.indexer.getVirtualTxs(txids, {
4520
+ pageIndex,
4521
+ pageSize: chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE
4522
+ });
4523
+ for (const psbt of txs) {
4524
+ out.set(chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
4525
+ }
4526
+ hasMore = page ? txs.length === chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE : false;
4527
+ pageIndex++;
4528
+ }
4529
+ return out;
4530
+ }
4531
+ };
4532
+ function chainedTxTypeToChainTxType(t) {
4533
+ switch (t) {
4534
+ case 1 /* Commitment */:
4535
+ return "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */;
4536
+ case 2 /* Ark */:
4537
+ return "INDEXER_CHAINED_TX_TYPE_ARK" /* ARK */;
4538
+ case 3 /* Tree */:
4539
+ return "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */;
4540
+ case 4 /* Checkpoint */:
4541
+ return "INDEXER_CHAINED_TX_TYPE_CHECKPOINT" /* CHECKPOINT */;
4542
+ default:
4543
+ return "INDEXER_CHAINED_TX_TYPE_UNSPECIFIED" /* UNSPECIFIED */;
4544
+ }
4545
+ }
4546
+ function psbtInputTxids(psbtBase64) {
4547
+ const tx = chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
4548
+ const ids = [];
4549
+ for (let i = 0; i < tx.inputsLength; i++) {
4550
+ const txid = tx.getInput(i).txid;
4551
+ if (txid) ids.push(base.hex.encode(txid));
4552
+ }
4553
+ return ids;
4554
+ }
4555
+ var RepositoryExitDataSource = class {
4556
+ constructor(repo) {
4557
+ this.repo = repo;
4558
+ }
4559
+ repo;
4560
+ name = "repository";
4561
+ async getVtxoChain(vtxo) {
4562
+ const branch = await this.repo.getBranch(vtxo);
4563
+ if (branch.length === 0) return null;
4564
+ const chain = [];
4565
+ for (const v of branch) {
4566
+ const type = chainedTxTypeToChainTxType(v.type);
4567
+ let spends = [];
4568
+ if (v.type !== 1 /* Commitment */) {
4569
+ if (!v.psbt) return null;
4570
+ spends = psbtInputTxids(v.psbt);
4571
+ }
4572
+ chain.push({
4573
+ txid: v.txid,
4574
+ type,
4575
+ expiresAt: v.expiresAt != null ? String(v.expiresAt) : "",
4576
+ spends
4577
+ });
4578
+ }
4579
+ return chain;
4580
+ }
4581
+ async getVirtualTxs(txids) {
4582
+ const out = /* @__PURE__ */ new Map();
4583
+ for (const txid of txids) {
4584
+ const stored = await this.repo.getVirtualTx(txid);
4585
+ if (stored?.psbt) out.set(txid, stored.psbt);
4586
+ }
4587
+ return out;
4588
+ }
4589
+ };
4590
+
4591
+ // src/wallet/exit/resolver.ts
4592
+ var OrderedExitChainResolver = class {
4593
+ constructor(sources, persist) {
4594
+ this.sources = sources;
4595
+ this.persist = persist;
4596
+ }
4597
+ sources;
4598
+ persist;
4599
+ async getVtxoChain(vtxo) {
4600
+ let lastErr;
4601
+ for (const source of this.sources) {
4602
+ try {
4603
+ const chain = await source.getVtxoChain(vtxo);
4604
+ if (chain) return chain;
4605
+ } catch (e) {
4606
+ lastErr = e;
4607
+ }
4608
+ }
4609
+ if (lastErr) throw lastErr;
4610
+ throw new Error(`no exit-data source resolved the chain for ${vtxo.txid}:${vtxo.vout}`);
4611
+ }
4612
+ async getVirtualTxs(txids) {
4613
+ const found = /* @__PURE__ */ new Map();
4614
+ let remaining = txids;
4615
+ for (const [i, source] of this.sources.entries()) {
4616
+ if (remaining.length === 0) break;
4617
+ let got;
4618
+ try {
4619
+ got = await source.getVirtualTxs(remaining);
4620
+ } catch {
4621
+ continue;
4622
+ }
4623
+ const fresh = [];
4624
+ for (const [txid, psbt] of got) {
4625
+ if (found.has(txid)) continue;
4626
+ found.set(txid, psbt);
4627
+ fresh.push({ txid, psbt, expiresAt: null, type: 0 /* Unspecified */ });
4628
+ }
4629
+ if (i > 0 && this.persist && fresh.length > 0) {
4630
+ try {
4631
+ await this.persist.upsertVirtualTxs(fresh);
4632
+ } catch {
4633
+ }
4634
+ }
4635
+ remaining = txids.filter((t) => !found.has(t));
4636
+ }
4637
+ return [...found.values()];
4638
+ }
4639
+ };
4640
+ function createExitChainResolver(params) {
4641
+ const sources = [];
4642
+ if (params.repository) sources.push(new RepositoryExitDataSource(params.repository));
4643
+ if (params.extraSources) sources.push(...params.extraSources);
4644
+ sources.push(new IndexerExitDataSource(params.indexer));
4645
+ return new OrderedExitChainResolver(sources, params.repository);
4646
+ }
4647
+
4648
+ // src/providers/availability.ts
4649
+ function isRetryableProviderError(error) {
4650
+ return error instanceof chunk7IYIFMF4_cjs.ProviderUnavailableError || error instanceof chunk7IYIFMF4_cjs.FetchError || chunk7IYIFMF4_cjs.isFetchTimeoutError(error);
4651
+ }
4652
+
4653
+ // src/utils/syncCursors.ts
4654
+ var SAFETY_LAG_MS = 3e4;
4655
+ var OVERLAP_MS = 24 * 60 * 60 * 1e3;
4656
+ var walletStateLocks = /* @__PURE__ */ new WeakMap();
4657
+ async function updateWalletState(repo, updater) {
4658
+ const prev = walletStateLocks.get(repo) ?? Promise.resolve();
4659
+ const op = prev.then(async () => {
4660
+ const state = await repo.getWalletState() ?? {};
4661
+ await repo.saveWalletState(updater(state));
4662
+ });
4663
+ walletStateLocks.set(
4664
+ repo,
4665
+ op.catch(() => {
4666
+ })
4667
+ );
4668
+ return op;
4669
+ }
4670
+ var CURSOR_MIGRATED_KEY = "vtxoCursorMigrated";
4671
+ function hasMigrationMarker(state) {
4672
+ return state?.settings?.[CURSOR_MIGRATED_KEY] === true;
4673
+ }
4674
+ async function getSyncCursor(repo) {
4675
+ const state = await repo.getWalletState();
4676
+ if (!hasMigrationMarker(state)) return 0;
4677
+ return state?.lastSyncTime ?? 0;
4678
+ }
4679
+ async function advanceSyncCursor(repo, lastUpdatedAt) {
4680
+ await updateWalletState(repo, (state) => {
4681
+ const current = hasMigrationMarker(state) ? state.lastSyncTime ?? 0 : 0;
4682
+ return {
4683
+ ...state,
4684
+ lastSyncTime: Math.max(current, lastUpdatedAt),
4685
+ settings: {
4686
+ ...state.settings ?? {},
4687
+ [CURSOR_MIGRATED_KEY]: true
4688
+ }
4689
+ };
4690
+ });
4691
+ }
4692
+ async function clearSyncCursor(repo) {
4693
+ await updateWalletState(repo, (state) => {
4694
+ const { [CURSOR_MIGRATED_KEY]: _, ...restSettings } = state.settings ?? {};
4695
+ return {
4696
+ ...state,
4697
+ lastSyncTime: void 0,
4698
+ settings: restSettings
4699
+ };
4700
+ });
4701
+ }
4702
+ function computeSyncWindow(cursor) {
4703
+ const after = Math.max(0, cursor - OVERLAP_MS);
4704
+ return { after };
4705
+ }
4706
+ function cursorCutoff(requestStartedAt) {
4707
+ return (requestStartedAt ?? Date.now()) - SAFETY_LAG_MS;
4708
+ }
4709
+
4710
+ // src/wallet/arkInfoSnapshot.ts
4711
+ var ARK_INFO_SNAPSHOT_KEY = "arkInfoSnapshot";
4712
+ var MalformedArkInfoSnapshotError = class extends Error {
4713
+ constructor(message, options) {
4714
+ super(message, { cause: options?.cause });
4715
+ this.name = "MalformedArkInfoSnapshotError";
4716
+ }
4717
+ };
4718
+ var CURRENT_VERSION = 1;
4719
+ function serializeArkInfoSnapshot(info, savedAt) {
4720
+ return {
4721
+ version: CURRENT_VERSION,
4722
+ savedAt,
4723
+ source: "arkade.getInfo",
4724
+ arkInfo: {
4725
+ network: info.network,
4726
+ signerPubkey: info.signerPubkey,
4727
+ checkpointTapscript: info.checkpointTapscript,
4728
+ forfeitAddress: info.forfeitAddress,
4729
+ forfeitPubkey: info.forfeitPubkey,
4730
+ unilateralExitDelay: info.unilateralExitDelay.toString(),
4731
+ boardingExitDelay: info.boardingExitDelay.toString(),
4732
+ sessionDuration: info.sessionDuration.toString(),
4733
+ dust: info.dust.toString(),
4734
+ fees: info.fees,
4735
+ digest: info.digest,
4736
+ version: info.version,
4737
+ vtxoMinAmount: info.vtxoMinAmount.toString(),
4738
+ vtxoMaxAmount: info.vtxoMaxAmount.toString(),
4739
+ utxoMinAmount: info.utxoMinAmount.toString(),
4740
+ utxoMaxAmount: info.utxoMaxAmount.toString(),
4741
+ deprecatedSigners: info.deprecatedSigners.map((s) => ({
4742
+ pubkey: s.pubkey,
4743
+ cutoffDate: s.cutoffDate.toString()
4744
+ })),
4745
+ scheduledSession: info.scheduledSession ? {
4746
+ duration: info.scheduledSession.duration.toString(),
4747
+ fees: info.scheduledSession.fees,
4748
+ nextEndTime: info.scheduledSession.nextEndTime.toString(),
4749
+ nextStartTime: info.scheduledSession.nextStartTime.toString(),
4750
+ period: info.scheduledSession.period.toString()
4751
+ } : void 0
4752
+ }
4753
+ };
4754
+ }
4755
+ function hydrateArkInfo(snapshot) {
4756
+ const a = snapshot.arkInfo;
4757
+ return {
4758
+ boardingExitDelay: BigInt(a.boardingExitDelay),
4759
+ checkpointTapscript: a.checkpointTapscript,
4760
+ deprecatedSigners: a.deprecatedSigners.map((s) => ({
4761
+ cutoffDate: BigInt(s.cutoffDate),
4762
+ pubkey: s.pubkey
4763
+ })),
4764
+ digest: a.digest,
4765
+ dust: BigInt(a.dust),
4766
+ fees: a.fees,
4767
+ forfeitAddress: a.forfeitAddress,
4768
+ forfeitPubkey: a.forfeitPubkey,
4769
+ network: a.network,
4770
+ scheduledSession: a.scheduledSession ? {
4771
+ duration: BigInt(a.scheduledSession.duration),
4772
+ fees: a.scheduledSession.fees,
4773
+ nextEndTime: BigInt(a.scheduledSession.nextEndTime),
4774
+ nextStartTime: BigInt(a.scheduledSession.nextStartTime),
4775
+ period: BigInt(a.scheduledSession.period)
4776
+ } : void 0,
4777
+ serviceStatus: {},
4778
+ sessionDuration: BigInt(a.sessionDuration),
4779
+ signerPubkey: a.signerPubkey,
4780
+ unilateralExitDelay: BigInt(a.unilateralExitDelay),
4781
+ utxoMaxAmount: BigInt(a.utxoMaxAmount),
4782
+ utxoMinAmount: BigInt(a.utxoMinAmount),
4783
+ version: a.version,
4784
+ vtxoMaxAmount: BigInt(a.vtxoMaxAmount),
4785
+ vtxoMinAmount: BigInt(a.vtxoMinAmount)
4786
+ };
4787
+ }
4788
+ var DECIMAL_STRING = /^-?\d+$/;
4789
+ function assertString(value, path) {
4790
+ if (typeof value !== "string") {
4791
+ throw new MalformedArkInfoSnapshotError(`${path} must be a string`);
4792
+ }
4793
+ }
4794
+ function assertDecimalString(value, path) {
4795
+ assertString(value, path);
4796
+ if (!DECIMAL_STRING.test(value)) {
4797
+ throw new MalformedArkInfoSnapshotError(`${path} must be a decimal integer string`);
4798
+ }
4799
+ }
4800
+ function assertFeeInfo(value, path) {
4801
+ if (typeof value !== "object" || value === null) {
4802
+ throw new MalformedArkInfoSnapshotError(`${path} must be an object`);
4803
+ }
4804
+ const fees = value;
4805
+ assertString(fees.txFeeRate, `${path}.txFeeRate`);
4806
+ if (typeof fees.intentFee !== "object" || fees.intentFee === null) {
4807
+ throw new MalformedArkInfoSnapshotError(`${path}.intentFee must be an object`);
4808
+ }
4809
+ }
4810
+ function parseStoredArkInfoSnapshot(raw) {
4811
+ if (typeof raw !== "object" || raw === null) {
4812
+ throw new MalformedArkInfoSnapshotError("snapshot must be an object");
4813
+ }
4814
+ const snap = raw;
4815
+ if (snap.version !== CURRENT_VERSION) {
4816
+ throw new MalformedArkInfoSnapshotError(
4817
+ `unsupported snapshot version: ${String(snap.version)}`
4818
+ );
4819
+ }
4820
+ if (typeof snap.savedAt !== "number") {
4821
+ throw new MalformedArkInfoSnapshotError("savedAt must be a number");
4822
+ }
4823
+ if (snap.source !== "arkade.getInfo") {
4824
+ throw new MalformedArkInfoSnapshotError(`unexpected source: ${String(snap.source)}`);
4825
+ }
4826
+ if (typeof snap.arkInfo !== "object" || snap.arkInfo === null) {
4827
+ throw new MalformedArkInfoSnapshotError("arkInfo must be an object");
4828
+ }
4829
+ const a = snap.arkInfo;
4830
+ for (const field of [
4831
+ "network",
4832
+ "signerPubkey",
4833
+ "checkpointTapscript",
4834
+ "forfeitAddress",
4835
+ "forfeitPubkey",
4836
+ "digest",
4837
+ "version"
4838
+ ]) {
4839
+ assertString(a[field], `arkInfo.${field}`);
4840
+ }
4841
+ for (const field of [
4842
+ "unilateralExitDelay",
4843
+ "boardingExitDelay",
4844
+ "sessionDuration",
4845
+ "dust",
4846
+ "vtxoMinAmount",
4847
+ "vtxoMaxAmount",
4848
+ "utxoMinAmount",
4849
+ "utxoMaxAmount"
4850
+ ]) {
4851
+ assertDecimalString(a[field], `arkInfo.${field}`);
4852
+ }
4853
+ assertFeeInfo(a.fees, "arkInfo.fees");
4854
+ if (!Array.isArray(a.deprecatedSigners)) {
4855
+ throw new MalformedArkInfoSnapshotError("arkInfo.deprecatedSigners must be an array");
4856
+ }
4857
+ a.deprecatedSigners.forEach((s, i) => {
4858
+ if (typeof s !== "object" || s === null) {
4859
+ throw new MalformedArkInfoSnapshotError(
4860
+ `arkInfo.deprecatedSigners[${i}] must be an object`
4861
+ );
4862
+ }
4863
+ const signer = s;
4864
+ assertString(signer.pubkey, `arkInfo.deprecatedSigners[${i}].pubkey`);
4865
+ assertDecimalString(signer.cutoffDate, `arkInfo.deprecatedSigners[${i}].cutoffDate`);
4866
+ });
4867
+ if (a.scheduledSession !== void 0) {
4868
+ if (typeof a.scheduledSession !== "object" || a.scheduledSession === null) {
4869
+ throw new MalformedArkInfoSnapshotError("arkInfo.scheduledSession must be an object");
4870
+ }
4871
+ const s = a.scheduledSession;
4872
+ for (const field of ["duration", "nextEndTime", "nextStartTime", "period"]) {
4873
+ assertDecimalString(s[field], `arkInfo.scheduledSession.${field}`);
4874
+ }
4875
+ assertFeeInfo(s.fees, "arkInfo.scheduledSession.fees");
4876
+ }
4877
+ return raw;
4878
+ }
4879
+ async function loadArkInfoSnapshot(repo) {
4880
+ const state = await repo.getWalletState();
4881
+ const raw = state?.settings?.[ARK_INFO_SNAPSHOT_KEY];
4882
+ if (raw === void 0 || raw === null) return null;
4883
+ return parseStoredArkInfoSnapshot(raw);
4884
+ }
4885
+ async function saveArkInfoSnapshot(repo, info, savedAt) {
4886
+ const snapshot = serializeArkInfoSnapshot(info, savedAt);
4887
+ await updateWalletState(repo, (state) => ({
4888
+ ...state,
4889
+ settings: {
4890
+ ...state.settings ?? {},
4891
+ [ARK_INFO_SNAPSHOT_KEY]: snapshot
4892
+ }
4893
+ }));
4894
+ }
4895
+ async function resolveArkInfo(arkProvider, walletRepository) {
4896
+ let info;
4897
+ try {
4898
+ info = await arkProvider.getInfo();
4899
+ } catch (err) {
4900
+ if (!isRetryableProviderError(err)) throw err;
4901
+ const snapshot = await loadArkInfoSnapshot(walletRepository);
4902
+ if (!snapshot) {
4903
+ throw new chunk7IYIFMF4_cjs.ProviderUnavailableError(
4904
+ "Arkade server info is unavailable and no cached snapshot exists",
4905
+ { cause: err }
4906
+ );
4907
+ }
4908
+ return { info: hydrateArkInfo(snapshot), source: "cache", lastOnlineAt: snapshot.savedAt };
4909
+ }
4910
+ return { info, source: "live" };
4911
+ }
4912
+ async function saveValidatedArkInfoSnapshot(repo, info, savedAt) {
4913
+ try {
4914
+ await saveArkInfoSnapshot(repo, info, savedAt);
4915
+ } catch (err) {
4916
+ console.warn("Failed to persist Ark info snapshot", err);
4917
+ }
4918
+ }
4312
4919
  var TxTree = class {
4313
4920
  constructor(root, children = /* @__PURE__ */ new Map()) {
4314
4921
  this.root = root;
4315
4922
  this.children = children;
4316
4923
  }
4924
+ root;
4925
+ children;
4317
4926
  static create(chunks) {
4318
4927
  if (chunks.length === 0) {
4319
4928
  throw new Error("empty chunks");
@@ -4785,6 +5394,7 @@ var ReadonlyAssetManager = class {
4785
5394
  constructor(indexer) {
4786
5395
  this.indexer = indexer;
4787
5396
  }
5397
+ indexer;
4788
5398
  async getAssetDetails(assetId) {
4789
5399
  return this.indexer.getAssetDetails(assetId);
4790
5400
  }
@@ -4794,6 +5404,7 @@ var AssetManager = class extends ReadonlyAssetManager {
4794
5404
  super(wallet.indexerProvider);
4795
5405
  this.wallet = wallet;
4796
5406
  }
5407
+ wallet;
4797
5408
  /**
4798
5409
  * Issue a new asset.
4799
5410
  * @param params - Parameters for asset issuance
@@ -4824,7 +5435,7 @@ var AssetManager = class extends ReadonlyAssetManager {
4824
5435
  const virtualCoins = await this.wallet.getVtxos({
4825
5436
  withRecoverable: false
4826
5437
  });
4827
- const controlAssetRef = params.controlAssetId ? chunkUBYY2TPK_cjs.AssetRef.fromId(chunkUBYY2TPK_cjs.AssetId.fromString(params.controlAssetId)) : null;
5438
+ const controlAssetRef = params.controlAssetId ? chunk7IYIFMF4_cjs.AssetRef.fromId(chunk7IYIFMF4_cjs.AssetId.fromString(params.controlAssetId)) : null;
4828
5439
  const coinSelection = selectVirtualCoins(virtualCoins, Number(this.wallet.dustAmount));
4829
5440
  let totalBtcSelected = 0n;
4830
5441
  const assetChanges = /* @__PURE__ */ new Map();
@@ -4837,8 +5448,8 @@ var AssetManager = class extends ReadonlyAssetManager {
4837
5448
  }
4838
5449
  }
4839
5450
  const groups = [];
4840
- const issuedAssetOutput = chunkUBYY2TPK_cjs.AssetOutput.create(0, params.amount);
4841
- const issuedAssetGroup = chunkUBYY2TPK_cjs.AssetGroup.create(
5451
+ const issuedAssetOutput = chunk7IYIFMF4_cjs.AssetOutput.create(0, params.amount);
5452
+ const issuedAssetGroup = chunk7IYIFMF4_cjs.AssetGroup.create(
4842
5453
  null,
4843
5454
  controlAssetRef,
4844
5455
  [],
@@ -4853,28 +5464,28 @@ var AssetManager = class extends ReadonlyAssetManager {
4853
5464
  for (const [inputIndex, assets] of assetInputs) {
4854
5465
  for (const asset of assets) {
4855
5466
  if (asset.assetId !== assetId) continue;
4856
- changeInputs.push(chunkUBYY2TPK_cjs.AssetInput.create(inputIndex, asset.amount));
5467
+ changeInputs.push(chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount));
4857
5468
  }
4858
5469
  }
4859
5470
  groups.push(
4860
- chunkUBYY2TPK_cjs.AssetGroup.create(
4861
- chunkUBYY2TPK_cjs.AssetId.fromString(assetId),
5471
+ chunk7IYIFMF4_cjs.AssetGroup.create(
5472
+ chunk7IYIFMF4_cjs.AssetId.fromString(assetId),
4862
5473
  null,
4863
5474
  changeInputs,
4864
- [chunkUBYY2TPK_cjs.AssetOutput.create(0, amount)],
5475
+ [chunk7IYIFMF4_cjs.AssetOutput.create(0, amount)],
4865
5476
  []
4866
5477
  )
4867
5478
  );
4868
5479
  }
4869
5480
  }
4870
5481
  const address = await this.wallet.getAddress();
4871
- const outputAddress = chunkHXDZ2QTW_cjs.ArkAddress.decode(address);
5482
+ const outputAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(address);
4872
5483
  const outputs = [
4873
5484
  {
4874
5485
  script: outputAddress.pkScript,
4875
5486
  amount: BigInt(totalBtcSelected)
4876
5487
  },
4877
- Extension.create([chunkUBYY2TPK_cjs.Packet.create(groups)]).txOut()
5488
+ Extension.create([chunk7IYIFMF4_cjs.Packet.create(groups)]).txOut()
4878
5489
  ];
4879
5490
  const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(
4880
5491
  coinSelection.inputs,
@@ -4882,7 +5493,7 @@ var AssetManager = class extends ReadonlyAssetManager {
4882
5493
  );
4883
5494
  return {
4884
5495
  arkTxId: arkTxid,
4885
- assetId: chunkUBYY2TPK_cjs.AssetId.create(arkTxid, 0).toString()
5496
+ assetId: chunk7IYIFMF4_cjs.AssetId.create(arkTxid, 0).toString()
4886
5497
  };
4887
5498
  }
4888
5499
  /**
@@ -4954,16 +5565,16 @@ var AssetManager = class extends ReadonlyAssetManager {
4954
5565
  for (const [inputIndex, assets] of assetInputs) {
4955
5566
  for (const asset of assets) {
4956
5567
  if (asset.assetId !== params.assetId) continue;
4957
- reissueInputs.push(chunkUBYY2TPK_cjs.AssetInput.create(inputIndex, asset.amount));
5568
+ reissueInputs.push(chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount));
4958
5569
  }
4959
5570
  }
4960
5571
  const totalAssetAmount = assetToReissueAmount + params.amount;
4961
- const reissueAssetIdObj = chunkUBYY2TPK_cjs.AssetId.fromString(params.assetId);
4962
- const reissueAssetGroup = chunkUBYY2TPK_cjs.AssetGroup.create(
5572
+ const reissueAssetIdObj = chunk7IYIFMF4_cjs.AssetId.fromString(params.assetId);
5573
+ const reissueAssetGroup = chunk7IYIFMF4_cjs.AssetGroup.create(
4963
5574
  reissueAssetIdObj,
4964
5575
  null,
4965
5576
  reissueInputs,
4966
- [chunkUBYY2TPK_cjs.AssetOutput.create(0, totalAssetAmount)],
5577
+ [chunk7IYIFMF4_cjs.AssetOutput.create(0, totalAssetAmount)],
4967
5578
  []
4968
5579
  );
4969
5580
  const groups = [reissueAssetGroup];
@@ -4972,27 +5583,27 @@ var AssetManager = class extends ReadonlyAssetManager {
4972
5583
  for (const [inputIndex, assets] of assetInputs) {
4973
5584
  for (const asset of assets) {
4974
5585
  if (asset.assetId !== assetId) continue;
4975
- changeInputs.push(chunkUBYY2TPK_cjs.AssetInput.create(inputIndex, asset.amount));
5586
+ changeInputs.push(chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount));
4976
5587
  }
4977
5588
  }
4978
5589
  groups.push(
4979
- chunkUBYY2TPK_cjs.AssetGroup.create(
4980
- chunkUBYY2TPK_cjs.AssetId.fromString(assetId),
5590
+ chunk7IYIFMF4_cjs.AssetGroup.create(
5591
+ chunk7IYIFMF4_cjs.AssetId.fromString(assetId),
4981
5592
  null,
4982
5593
  changeInputs,
4983
- [chunkUBYY2TPK_cjs.AssetOutput.create(0, amount)],
5594
+ [chunk7IYIFMF4_cjs.AssetOutput.create(0, amount)],
4984
5595
  []
4985
5596
  )
4986
5597
  );
4987
5598
  }
4988
5599
  const address = await this.wallet.getAddress();
4989
- const outputAddress = chunkHXDZ2QTW_cjs.ArkAddress.decode(address);
5600
+ const outputAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(address);
4990
5601
  const outputs = [
4991
5602
  {
4992
5603
  script: outputAddress.pkScript,
4993
5604
  amount: BigInt(totalBtcSelected)
4994
5605
  },
4995
- Extension.create([chunkUBYY2TPK_cjs.Packet.create(groups)]).txOut()
5606
+ Extension.create([chunk7IYIFMF4_cjs.Packet.create(groups)]).txOut()
4996
5607
  ];
4997
5608
  const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
4998
5609
  return arkTxid;
@@ -5059,27 +5670,27 @@ var AssetManager = class extends ReadonlyAssetManager {
5059
5670
  for (const [inputIndex, assets] of assetInputs) {
5060
5671
  for (const asset of assets) {
5061
5672
  if (asset.assetId !== assetId) continue;
5062
- changeInputs.push(chunkUBYY2TPK_cjs.AssetInput.create(inputIndex, asset.amount));
5673
+ changeInputs.push(chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount));
5063
5674
  }
5064
5675
  }
5065
5676
  groups.push(
5066
- chunkUBYY2TPK_cjs.AssetGroup.create(
5067
- chunkUBYY2TPK_cjs.AssetId.fromString(assetId),
5677
+ chunk7IYIFMF4_cjs.AssetGroup.create(
5678
+ chunk7IYIFMF4_cjs.AssetId.fromString(assetId),
5068
5679
  null,
5069
5680
  changeInputs,
5070
- amount > 0n ? [chunkUBYY2TPK_cjs.AssetOutput.create(0, amount)] : [],
5681
+ amount > 0n ? [chunk7IYIFMF4_cjs.AssetOutput.create(0, amount)] : [],
5071
5682
  []
5072
5683
  )
5073
5684
  );
5074
5685
  }
5075
5686
  const address = await this.wallet.getAddress();
5076
- const outputAddress = chunkHXDZ2QTW_cjs.ArkAddress.decode(address);
5687
+ const outputAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(address);
5077
5688
  const outputs = [
5078
5689
  {
5079
5690
  script: outputAddress.pkScript,
5080
5691
  amount: BigInt(totalBtcSelected)
5081
5692
  },
5082
- Extension.create([chunkUBYY2TPK_cjs.Packet.create(groups)]).txOut()
5693
+ Extension.create([chunk7IYIFMF4_cjs.Packet.create(groups)]).txOut()
5083
5694
  ];
5084
5695
  const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
5085
5696
  return arkTxid;
@@ -5104,7 +5715,7 @@ function castMetadata(metadata) {
5104
5715
  } else {
5105
5716
  throw new Error("Invalid metadata value type");
5106
5717
  }
5107
- md.push(chunkUBYY2TPK_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
5718
+ md.push(chunk7IYIFMF4_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
5108
5719
  }
5109
5720
  return md;
5110
5721
  }
@@ -5115,6 +5726,9 @@ var DelegateManagerImpl = class {
5115
5726
  this.arkInfoProvider = arkInfoProvider;
5116
5727
  this.identity = identity;
5117
5728
  }
5729
+ delegateProvider;
5730
+ arkInfoProvider;
5731
+ identity;
5118
5732
  async getDelegateInfo() {
5119
5733
  return this.delegateProvider.getDelegateInfo();
5120
5734
  }
@@ -5122,7 +5736,7 @@ var DelegateManagerImpl = class {
5122
5736
  if (vtxos.length === 0) {
5123
5737
  return { delegated: [], failed: [] };
5124
5738
  }
5125
- const destinationScript = chunkHXDZ2QTW_cjs.ArkAddress.decode(destination).pkScript;
5739
+ const destinationScript = chunkMQB5H4X5_cjs.ArkAddress.decode(destination).pkScript;
5126
5740
  const arkInfo = await this.arkInfoProvider.getInfo();
5127
5741
  const delegateInfo = await this.delegateProvider.getDelegateInfo();
5128
5742
  const eligible = vtxos.filter(
@@ -5270,7 +5884,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
5270
5884
  const delegateFee = BigInt(Number(fee));
5271
5885
  if (delegateFee > 0n) {
5272
5886
  outputs.push({
5273
- script: chunkHXDZ2QTW_cjs.ArkAddress.decode(delegateAddress).pkScript,
5887
+ script: chunkMQB5H4X5_cjs.ArkAddress.decode(delegateAddress).pkScript,
5274
5888
  amount: delegateFee
5275
5889
  });
5276
5890
  }
@@ -5281,12 +5895,12 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
5281
5895
  script: base.hex.encode(output.script)
5282
5896
  }).satoshis;
5283
5897
  }, 0);
5284
- if (amount - BigInt(outputFee) <= dust) {
5898
+ if (isSubdust(amount - BigInt(outputFee), dust)) {
5285
5899
  throw new Error("Amount is below dust limit, cannot delegate");
5286
5900
  }
5287
5901
  amount -= BigInt(outputFee);
5288
5902
  amount -= delegateFee;
5289
- if (amount <= dust) {
5903
+ if (isSubdust(amount, dust)) {
5290
5904
  throw new Error("Amount is below dust limit, cannot delegate");
5291
5905
  }
5292
5906
  outputs.push({
@@ -5303,7 +5917,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
5303
5917
  destinationScript
5304
5918
  );
5305
5919
  const forfeitOutputScript = btcSigner.OutScript.encode(
5306
- btcSigner.Address(chunkHXDZ2QTW_cjs.getNetwork(network)).decode(forfeitAddress)
5920
+ btcSigner.Address(chunkMQB5H4X5_cjs.getNetwork(network)).decode(forfeitAddress)
5307
5921
  );
5308
5922
  const forfeits = await Promise.all(
5309
5923
  vtxos.filter((v) => !isRecoverable(v)).map(async (coin) => {
@@ -5331,7 +5945,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
5331
5945
  index: input.vout,
5332
5946
  witnessUtxo: {
5333
5947
  amount: BigInt(input.value),
5334
- script: chunkHXDZ2QTW_cjs.VtxoScript.decode(input.tapTree).pkScript
5948
+ script: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript
5335
5949
  },
5336
5950
  sighashType: btcSigner.SigHash.ALL_ANYONECANPAY,
5337
5951
  tapLeafScript: [delegateTapLeaf]
@@ -5389,7 +6003,7 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
5389
6003
  expire_at: 0,
5390
6004
  cosigners_public_keys: cosignerPubKeys
5391
6005
  };
5392
- const proof = chunkUBYY2TPK_cjs.Intent.create(message, coins, outputs);
6006
+ const proof = chunk7IYIFMF4_cjs.Intent.create(message, coins, outputs);
5393
6007
  const signedProof = await identity.sign(proof);
5394
6008
  return {
5395
6009
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -5407,10 +6021,10 @@ function getDayTimestamp(timestamp) {
5407
6021
  function findDelegateTapLeaf(vtxo, delegatePubkey) {
5408
6022
  if (!vtxo.tapTree) return void 0;
5409
6023
  const pk = delegatePubkey.length === 66 ? delegatePubkey.slice(2) : delegatePubkey;
5410
- const vtxoScript = chunkHXDZ2QTW_cjs.VtxoScript.decode(vtxo.tapTree);
6024
+ const vtxoScript = chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree);
5411
6025
  return vtxoScript.leaves.find((tapLeaf) => {
5412
- const arkTapscript = chunkHXDZ2QTW_cjs.decodeTapscript(chunkHXDZ2QTW_cjs.scriptFromTapLeafScript(tapLeaf));
5413
- if (!chunkHXDZ2QTW_cjs.MultisigTapscript.is(arkTapscript)) return false;
6026
+ const arkTapscript = chunkMQB5H4X5_cjs.decodeTapscript(chunkMQB5H4X5_cjs.scriptFromTapLeafScript(tapLeaf));
6027
+ if (!chunkMQB5H4X5_cjs.MultisigTapscript.is(arkTapscript)) return false;
5414
6028
  return arkTapscript.params.pubkeys.map(base.hex.encode).includes(pk);
5415
6029
  });
5416
6030
  }
@@ -5418,20 +6032,6 @@ function isAnnotated(v) {
5418
6032
  return v.tapTree !== void 0 && v.forfeitTapLeafScript !== void 0 && v.intentTapLeafScript !== void 0;
5419
6033
  }
5420
6034
 
5421
- // src/repositories/virtualTxRepository.ts
5422
- var ChainedTxType = /* @__PURE__ */ ((ChainedTxType2) => {
5423
- ChainedTxType2[ChainedTxType2["Unspecified"] = 0] = "Unspecified";
5424
- ChainedTxType2[ChainedTxType2["Commitment"] = 1] = "Commitment";
5425
- ChainedTxType2[ChainedTxType2["Ark"] = 2] = "Ark";
5426
- ChainedTxType2[ChainedTxType2["Tree"] = 3] = "Tree";
5427
- ChainedTxType2[ChainedTxType2["Checkpoint"] = 4] = "Checkpoint";
5428
- return ChainedTxType2;
5429
- })(ChainedTxType || {});
5430
- function mergeChainedTxType(incoming, prev) {
5431
- if (incoming !== 0 /* Unspecified */) return incoming;
5432
- return prev ?? 0 /* Unspecified */;
5433
- }
5434
-
5435
6035
  // src/repositories/inMemory/intentRepository.ts
5436
6036
  var InMemoryIntentRepository = class {
5437
6037
  version = 1;
@@ -5612,7 +6212,7 @@ async function closeDatabase(dbName) {
5612
6212
  return true;
5613
6213
  }
5614
6214
  function scriptFromArkAddress(address) {
5615
- return base.hex.encode(chunkHXDZ2QTW_cjs.ArkAddress.decode(address).pkScript);
6215
+ return base.hex.encode(chunkMQB5H4X5_cjs.ArkAddress.decode(address).pkScript);
5616
6216
  }
5617
6217
 
5618
6218
  // src/repositories/indexedDB/schema.ts
@@ -5897,6 +6497,7 @@ var IndexedDBVirtualTxRepository = class {
5897
6497
  constructor(dbName = DEFAULT_DB_NAME) {
5898
6498
  this.dbName = dbName;
5899
6499
  }
6500
+ dbName;
5900
6501
  version = 1;
5901
6502
  db = null;
5902
6503
  async getDB() {
@@ -6026,6 +6627,7 @@ var IndexedDBIntentRepository = class {
6026
6627
  constructor(dbName = DEFAULT_DB_NAME) {
6027
6628
  this.dbName = dbName;
6028
6629
  }
6630
+ dbName;
6029
6631
  version = 1;
6030
6632
  db = null;
6031
6633
  async getDB() {
@@ -6336,6 +6938,7 @@ var IndexedDBContractRepository = class {
6336
6938
  constructor(dbName = DEFAULT_DB_NAME) {
6337
6939
  this.dbName = dbName;
6338
6940
  }
6941
+ dbName;
6339
6942
  version = 1;
6340
6943
  db = null;
6341
6944
  async clear() {
@@ -6502,6 +7105,7 @@ var IndexedDBWalletRepository = class {
6502
7105
  constructor(dbName = DEFAULT_DB_NAME) {
6503
7106
  this.dbName = dbName;
6504
7107
  }
7108
+ dbName;
6505
7109
  version = 1;
6506
7110
  db = null;
6507
7111
  async clear() {
@@ -7487,7 +8091,7 @@ var ContractWatcher = class {
7487
8091
  this.connectionState = "connected";
7488
8092
  this.reconnectAttempts = 0;
7489
8093
  this.listenLoop().catch((e) => {
7490
- if (chunkUBYY2TPK_cjs.isEventSourceError(e)) {
8094
+ if (chunk7IYIFMF4_cjs.isEventSourceError(e)) {
7491
8095
  console.debug("ContractWatcher subscription disconnected; reconnecting");
7492
8096
  } else {
7493
8097
  console.error(e);
@@ -7822,90 +8426,33 @@ async function reconcileIntents(deps) {
7822
8426
  for (const intent of intents) {
7823
8427
  try {
7824
8428
  const next = await classifyIntent(intent, vtxosByOutpoint, nowMs);
7825
- if (!next) continue;
7826
- const [fresh] = await deps.intentRepository.getIntents({
7827
- intentTxIds: [intent.intentTxId]
7828
- });
7829
- if (!fresh || fresh.state !== intent.state) continue;
7830
- await deps.intentRepository.saveIntent(next);
7831
- } catch (e) {
7832
- console.error(`reconcileIntents: failed to reconcile intent ${intent.intentTxId}`, e);
7833
- }
7834
- }
7835
- }
7836
- function terminal(intent, state, now, patch) {
7837
- return { ...intent, ...patch, state, updatedAt: now };
7838
- }
7839
- function outpointKey(o) {
7840
- return `${o.txid}:${o.vout}`;
7841
- }
7842
- function dedupeOutpoints(outpoints) {
7843
- const seen = /* @__PURE__ */ new Set();
7844
- const out = [];
7845
- for (const o of outpoints) {
7846
- const k = outpointKey(o);
7847
- if (seen.has(k)) continue;
7848
- seen.add(k);
7849
- out.push(o);
7850
- }
7851
- return out;
7852
- }
7853
-
7854
- // src/utils/syncCursors.ts
7855
- var SAFETY_LAG_MS = 3e4;
7856
- var OVERLAP_MS = 24 * 60 * 60 * 1e3;
7857
- var walletStateLocks = /* @__PURE__ */ new WeakMap();
7858
- async function updateWalletState(repo, updater) {
7859
- const prev = walletStateLocks.get(repo) ?? Promise.resolve();
7860
- const op = prev.then(async () => {
7861
- const state = await repo.getWalletState() ?? {};
7862
- await repo.saveWalletState(updater(state));
7863
- });
7864
- walletStateLocks.set(
7865
- repo,
7866
- op.catch(() => {
7867
- })
7868
- );
7869
- return op;
7870
- }
7871
- var CURSOR_MIGRATED_KEY = "vtxoCursorMigrated";
7872
- function hasMigrationMarker(state) {
7873
- return state?.settings?.[CURSOR_MIGRATED_KEY] === true;
7874
- }
7875
- async function getSyncCursor(repo) {
7876
- const state = await repo.getWalletState();
7877
- if (!hasMigrationMarker(state)) return 0;
7878
- return state?.lastSyncTime ?? 0;
7879
- }
7880
- async function advanceSyncCursor(repo, lastUpdatedAt) {
7881
- await updateWalletState(repo, (state) => {
7882
- const current = hasMigrationMarker(state) ? state.lastSyncTime ?? 0 : 0;
7883
- return {
7884
- ...state,
7885
- lastSyncTime: Math.max(current, lastUpdatedAt),
7886
- settings: {
7887
- ...state.settings ?? {},
7888
- [CURSOR_MIGRATED_KEY]: true
7889
- }
7890
- };
7891
- });
8429
+ if (!next) continue;
8430
+ const [fresh] = await deps.intentRepository.getIntents({
8431
+ intentTxIds: [intent.intentTxId]
8432
+ });
8433
+ if (!fresh || fresh.state !== intent.state) continue;
8434
+ await deps.intentRepository.saveIntent(next);
8435
+ } catch (e) {
8436
+ console.error(`reconcileIntents: failed to reconcile intent ${intent.intentTxId}`, e);
8437
+ }
8438
+ }
7892
8439
  }
7893
- async function clearSyncCursor(repo) {
7894
- await updateWalletState(repo, (state) => {
7895
- const { [CURSOR_MIGRATED_KEY]: _, ...restSettings } = state.settings ?? {};
7896
- return {
7897
- ...state,
7898
- lastSyncTime: void 0,
7899
- settings: restSettings
7900
- };
7901
- });
8440
+ function terminal(intent, state, now, patch) {
8441
+ return { ...intent, ...patch, state, updatedAt: now };
7902
8442
  }
7903
- function computeSyncWindow(cursor) {
7904
- const after = Math.max(0, cursor - OVERLAP_MS);
7905
- return { after };
8443
+ function outpointKey(o) {
8444
+ return `${o.txid}:${o.vout}`;
7906
8445
  }
7907
- function cursorCutoff(requestStartedAt) {
7908
- return (requestStartedAt ?? Date.now()) - SAFETY_LAG_MS;
8446
+ function dedupeOutpoints(outpoints) {
8447
+ const seen = /* @__PURE__ */ new Set();
8448
+ const out = [];
8449
+ for (const o of outpoints) {
8450
+ const k = outpointKey(o);
8451
+ if (seen.has(k)) continue;
8452
+ seen.add(k);
8453
+ out.push(o);
8454
+ }
8455
+ return out;
7909
8456
  }
7910
8457
 
7911
8458
  // src/contracts/contractManager.ts
@@ -7920,6 +8467,10 @@ var ContractManager = class _ContractManager {
7920
8467
  initialized = false;
7921
8468
  eventCallbacks = /* @__PURE__ */ new Set();
7922
8469
  stopWatcherFn;
8470
+ /** `undefined` while online; the failure reason once a sync degrades. */
8471
+ syncDegradedReason;
8472
+ /** Epoch-ms of the last successful provider sync, if any. */
8473
+ lastSyncedAt;
7923
8474
  constructor(config) {
7924
8475
  this.config = config;
7925
8476
  this.watcher = new ContractWatcher({
@@ -7942,6 +8493,26 @@ var ContractManager = class _ContractManager {
7942
8493
  await cm.initialize();
7943
8494
  return cm;
7944
8495
  }
8496
+ /**
8497
+ * Latest provider-sync health. See {@link ContractSyncState}. Degradation is
8498
+ * recorded by {@link initialize}, {@link getContractsWithVtxos}, and
8499
+ * {@link createContract}; it flips back to `online` on the next successful
8500
+ * sync. Purely a freshness signal — not a source of truth for wallet data.
8501
+ */
8502
+ getSyncState() {
8503
+ return this.syncDegradedReason === void 0 ? { mode: "online", lastSyncedAt: this.lastSyncedAt } : {
8504
+ mode: "degraded",
8505
+ reason: this.syncDegradedReason,
8506
+ lastSyncedAt: this.lastSyncedAt
8507
+ };
8508
+ }
8509
+ markSyncOnline() {
8510
+ this.syncDegradedReason = void 0;
8511
+ this.lastSyncedAt = Date.now();
8512
+ }
8513
+ markSyncDegraded(err) {
8514
+ this.syncDegradedReason = err instanceof Error ? err.message : String(err);
8515
+ }
7945
8516
  async initialize() {
7946
8517
  if (this.initialized) {
7947
8518
  return;
@@ -7950,7 +8521,13 @@ var ContractManager = class _ContractManager {
7950
8521
  for (const contract of contracts) {
7951
8522
  await this.watcher.addContract(contract);
7952
8523
  }
7953
- await this.reconcileWatched();
8524
+ try {
8525
+ await this.reconcileWatched();
8526
+ this.markSyncOnline();
8527
+ } catch (err) {
8528
+ if (!isRetryableProviderError(err)) throw err;
8529
+ this.markSyncDegraded(err);
8530
+ }
7954
8531
  this.initialized = true;
7955
8532
  this.stopWatcherFn = await this.watcher.startWatching((event) => {
7956
8533
  this.handleContractEvent(event).catch((error) => {
@@ -8004,7 +8581,13 @@ var ContractManager = class _ContractManager {
8004
8581
  async createContract(params) {
8005
8582
  const { contract, persisted } = await this.upsertContract(params);
8006
8583
  if (persisted) {
8007
- await this.fetchContractVxosFromIndexer([contract]);
8584
+ try {
8585
+ await this.fetchContractVxosFromIndexer([contract]);
8586
+ this.markSyncOnline();
8587
+ } catch (err) {
8588
+ if (!isRetryableProviderError(err)) throw err;
8589
+ this.markSyncDegraded(err);
8590
+ }
8008
8591
  await this.watcher.addContract(contract);
8009
8592
  }
8010
8593
  return contract;
@@ -8034,7 +8617,7 @@ var ContractManager = class _ContractManager {
8034
8617
  * `persisted` is `true`.
8035
8618
  */
8036
8619
  async upsertContract(params) {
8037
- const handler = chunk32YKLQPS_cjs.contractHandlers.get(params.type);
8620
+ const handler = chunk4KXOCVXP_cjs.contractHandlers.get(params.type);
8038
8621
  if (!handler) {
8039
8622
  throw new Error(`No handler registered for contract type '${params.type}'`);
8040
8623
  }
@@ -8117,7 +8700,7 @@ var ContractManager = class _ContractManager {
8117
8700
  `scanContracts: batchSize must be a positive integer (got ${String(opts.batchSize)})`
8118
8701
  );
8119
8702
  }
8120
- const registered = chunk32YKLQPS_cjs.contractHandlers.getRegisteredTypes().map((t) => chunk32YKLQPS_cjs.contractHandlers.get(t)).filter(isDiscoverable);
8703
+ const registered = chunk4KXOCVXP_cjs.contractHandlers.getRegisteredTypes().map((t) => chunk4KXOCVXP_cjs.contractHandlers.get(t)).filter(isDiscoverable);
8121
8704
  const discoverables = [
8122
8705
  ...registered.filter((h) => h.type === "boarding"),
8123
8706
  ...registered.filter((h) => h.type !== "boarding")
@@ -8203,7 +8786,13 @@ var ContractManager = class _ContractManager {
8203
8786
  }
8204
8787
  async getContractsWithVtxos(filter, pageSize) {
8205
8788
  const contracts = await this.getContracts(filter);
8206
- await this.syncContracts({ contracts, pageSize });
8789
+ try {
8790
+ await this.syncContracts({ contracts, pageSize });
8791
+ this.markSyncOnline();
8792
+ } catch (err) {
8793
+ if (!isRetryableProviderError(err)) throw err;
8794
+ this.markSyncDegraded(err);
8795
+ }
8207
8796
  const vtxos = await this.getVtxosForContracts(contracts);
8208
8797
  return contracts.map((contract) => ({
8209
8798
  contract,
@@ -8301,7 +8890,7 @@ var ContractManager = class _ContractManager {
8301
8890
  const { contractScript, collaborative = true, walletPubKey, vtxo } = options;
8302
8891
  const [contract] = await this.getContracts({ script: contractScript });
8303
8892
  if (!contract) return [];
8304
- const handler = chunk32YKLQPS_cjs.contractHandlers.get(contract.type);
8893
+ const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
8305
8894
  if (!handler) return [];
8306
8895
  const script = handler.createScript(contract.params);
8307
8896
  const context = {
@@ -8321,7 +8910,7 @@ var ContractManager = class _ContractManager {
8321
8910
  const { contractScript, collaborative = true, walletPubKey } = options;
8322
8911
  const [contract] = await this.getContracts({ script: contractScript });
8323
8912
  if (!contract) return [];
8324
- const handler = chunk32YKLQPS_cjs.contractHandlers.get(contract.type);
8913
+ const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
8325
8914
  if (!handler) return [];
8326
8915
  const script = handler.createScript(contract.params);
8327
8916
  const context = {
@@ -8441,15 +9030,33 @@ var ContractManager = class _ContractManager {
8441
9030
  * Handle events from the watcher.
8442
9031
  */
8443
9032
  async handleContractEvent(event) {
8444
- switch (event.type) {
8445
- // Delta-sync only the changed virtual outputs for this contract.
8446
- case "vtxo_received":
8447
- case "vtxo_spent":
8448
- await this.syncContracts({ contracts: [event.contract] });
8449
- break;
8450
- case "connection_reset":
8451
- await this.reconcileWatched();
8452
- break;
9033
+ try {
9034
+ switch (event.type) {
9035
+ // Delta-sync only the changed virtual outputs for this contract.
9036
+ case "vtxo_received":
9037
+ await this.syncContracts({ contracts: [event.contract] });
9038
+ this.markSyncOnline();
9039
+ break;
9040
+ case "vtxo_spent":
9041
+ await this.syncContracts({ contracts: [event.contract] });
9042
+ this.markSyncOnline();
9043
+ if (this.config.onVtxosSpent) {
9044
+ try {
9045
+ await this.config.onVtxosSpent(
9046
+ event.vtxos.map((v) => ({ txid: v.txid, vout: v.vout }))
9047
+ );
9048
+ } catch {
9049
+ }
9050
+ }
9051
+ break;
9052
+ case "connection_reset":
9053
+ await this.reconcileWatched();
9054
+ this.markSyncOnline();
9055
+ break;
9056
+ }
9057
+ } catch (err) {
9058
+ if (!isRetryableProviderError(err)) throw err;
9059
+ this.markSyncDegraded(err);
8453
9060
  }
8454
9061
  this.emitEvent(event);
8455
9062
  }
@@ -8531,6 +9138,12 @@ var ContractManager = class _ContractManager {
8531
9138
  contract,
8532
9139
  filtered
8533
9140
  );
9141
+ if (this.config.onVtxosPersisted) {
9142
+ try {
9143
+ await this.config.onVtxosPersisted(contract, filtered);
9144
+ } catch {
9145
+ }
9146
+ }
8534
9147
  }
8535
9148
  }
8536
9149
  async fetchContractVxosFromIndexer(contracts, pageSize, syncWindow) {
@@ -8551,11 +9164,20 @@ var ContractManager = class _ContractManager {
8551
9164
  contract,
8552
9165
  filtered
8553
9166
  );
9167
+ if (this.config.onVtxosPersisted) {
9168
+ try {
9169
+ await this.config.onVtxosPersisted(
9170
+ contract,
9171
+ filtered
9172
+ );
9173
+ } catch {
9174
+ }
9175
+ }
8554
9176
  }
8555
9177
  }
8556
9178
  return result;
8557
9179
  }
8558
- async fetchContractVtxosBulk(contracts, pageSize = chunk32YKLQPS_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
9180
+ async fetchContractVtxosBulk(contracts, pageSize = chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
8559
9181
  if (contracts.length === 0) {
8560
9182
  return /* @__PURE__ */ new Map();
8561
9183
  }
@@ -8629,6 +9251,8 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
8629
9251
  this.identity = identity;
8630
9252
  this.walletRepository = walletRepository;
8631
9253
  }
9254
+ identity;
9255
+ walletRepository;
8632
9256
  /**
8633
9257
  * Construct an HDDescriptorProvider. No I/O is performed here;
8634
9258
  * persisted state is read lazily on the first call to
@@ -8731,7 +9355,7 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
8731
9355
  */
8732
9356
  materializeDescriptorAt(index) {
8733
9357
  const descriptor = this.identity.descriptor;
8734
- const network = chunk32YKLQPS_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
9358
+ const network = chunk4KXOCVXP_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
8735
9359
  const expansion = descriptorsScure.expand({ descriptor, network, index });
8736
9360
  const keyInfo = expansion.expansionMap?.["@0"];
8737
9361
  if (!keyInfo?.keyExpression) {
@@ -8821,6 +9445,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
8821
9445
  this.currentTaggedScript = priorTaggedScript;
8822
9446
  this.logger = logger ?? console;
8823
9447
  }
9448
+ provider;
8824
9449
  unsubscribe;
8825
9450
  chain = Promise.resolve();
8826
9451
  /**
@@ -8874,7 +9499,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
8874
9499
  const provider = await resolveDescriptorProvider(config, setup.walletRepository);
8875
9500
  if (!provider) return void 0;
8876
9501
  const allowSilentFallback = (config.walletMode ?? "auto") === "auto";
8877
- const expectedContractType = setup.offchainTapscript instanceof chunk32YKLQPS_cjs.DelegateVtxo.Script ? "delegate" : "default";
9502
+ const expectedContractType = setup.offchainTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script ? "delegate" : "default";
8878
9503
  const factoryOpts = {
8879
9504
  walletRepository: setup.walletRepository,
8880
9505
  contractRepository: setup.contractRepository,
@@ -9057,7 +9682,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
9057
9682
  const newAddress = newTapscript.address(wallet.network.hrp, wallet.arkServerPublicKey).encode();
9058
9683
  const manager = await wallet.getContractManager();
9059
9684
  const csvTimelock = newTapscript.options.csvTimelock;
9060
- const csvTimelockStr = chunkHXDZ2QTW_cjs.timelockToSequence(csvTimelock).toString();
9685
+ const csvTimelockStr = chunkMQB5H4X5_cjs.timelockToSequence(csvTimelock).toString();
9061
9686
  const serverPubKeyHex = base.hex.encode(newTapscript.options.serverPubKey);
9062
9687
  const baseParams = {
9063
9688
  script: newScript,
@@ -9071,11 +9696,11 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
9071
9696
  // produce unsigned PSBTs that the server rejects with
9072
9697
  // `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
9073
9698
  metadata: {
9074
- source: chunk32YKLQPS_cjs.WALLET_RECEIVE_SOURCE,
9699
+ source: chunk4KXOCVXP_cjs.WALLET_RECEIVE_SOURCE,
9075
9700
  signingDescriptor: descriptor
9076
9701
  }
9077
9702
  };
9078
- if (newTapscript instanceof chunk32YKLQPS_cjs.DelegateVtxo.Script) {
9703
+ if (newTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script) {
9079
9704
  await manager.createContract({
9080
9705
  ...baseParams,
9081
9706
  type: "delegate",
@@ -9107,7 +9732,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
9107
9732
  };
9108
9733
  function deriveLeafPubkey(descriptor) {
9109
9734
  try {
9110
- return chunk32YKLQPS_cjs.deriveDescriptorLeafPubKey(descriptor);
9735
+ return chunk4KXOCVXP_cjs.deriveDescriptorLeafPubKey(descriptor);
9111
9736
  } catch (e) {
9112
9737
  throw new NonRangeableDescriptorError(
9113
9738
  "Cannot derive leaf pubkey: descriptor is not a materialized, parsable tr(...) shape.",
@@ -9116,10 +9741,10 @@ function deriveLeafPubkey(descriptor) {
9116
9741
  }
9117
9742
  }
9118
9743
  function rebuildTapscript(current, pubKey) {
9119
- if (current instanceof chunk32YKLQPS_cjs.DelegateVtxo.Script) {
9120
- return new chunk32YKLQPS_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
9744
+ if (current instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script) {
9745
+ return new chunk4KXOCVXP_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
9121
9746
  }
9122
- return new chunk32YKLQPS_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
9747
+ return new chunk4KXOCVXP_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
9123
9748
  }
9124
9749
  async function pickActiveReceive(contractRepository, serverPubKey, expectedType) {
9125
9750
  const candidates = await contractRepository.getContracts({
@@ -9128,7 +9753,7 @@ async function pickActiveReceive(contractRepository, serverPubKey, expectedType)
9128
9753
  });
9129
9754
  const serverPubKeyHex = base.hex.encode(serverPubKey);
9130
9755
  const matching = candidates.filter(
9131
- (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunk32YKLQPS_cjs.WALLET_RECEIVE_SOURCE
9756
+ (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunk4KXOCVXP_cjs.WALLET_RECEIVE_SOURCE
9132
9757
  ).sort((a, b) => {
9133
9758
  if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
9134
9759
  return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
@@ -9174,6 +9799,8 @@ var MissingSigningDescriptorError = class extends Error {
9174
9799
  this.contractScript = contractScript;
9175
9800
  this.contractType = contractType;
9176
9801
  }
9802
+ contractScript;
9803
+ contractType;
9177
9804
  name = "MissingSigningDescriptorError";
9178
9805
  };
9179
9806
  var DescriptorSigningProviderMissingError = class extends Error {
@@ -9189,6 +9816,7 @@ var InputSignerRouter = class {
9189
9816
  constructor(deps) {
9190
9817
  this.deps = deps;
9191
9818
  }
9819
+ deps;
9192
9820
  /**
9193
9821
  * Resolve each job to its target signer without invoking signing. The
9194
9822
  * returned plan is the single source of truth for both {@link sign} and
@@ -9301,12 +9929,12 @@ var InputSignerRouter = class {
9301
9929
  };
9302
9930
 
9303
9931
  // src/wallet/wallet.ts
9304
- var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl || chunkHXDZ2QTW_cjs.DEFAULT_ARKADE_SERVER_URL;
9932
+ var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl || chunkMQB5H4X5_cjs.DEFAULT_ARKADE_SERVER_URL;
9305
9933
  function intentProofJobs(coins) {
9306
9934
  if (coins.length === 0) return [];
9307
9935
  const coinJobs = coins.map((coin, i) => ({
9308
9936
  index: i + 1,
9309
- lookupScript: chunkHXDZ2QTW_cjs.VtxoScript.decode(coin.tapTree).pkScript
9937
+ lookupScript: chunkMQB5H4X5_cjs.VtxoScript.decode(coin.tapTree).pkScript
9310
9938
  }));
9311
9939
  return [{ index: 0, lookupScript: coinJobs[0].lookupScript }, ...coinJobs];
9312
9940
  }
@@ -9330,7 +9958,7 @@ function dedupeTimelocks(timelocks) {
9330
9958
  const seen = /* @__PURE__ */ new Set();
9331
9959
  const deduped = [];
9332
9960
  for (const timelock of timelocks) {
9333
- const sequence = chunkHXDZ2QTW_cjs.timelockToSequence(timelock).toString();
9961
+ const sequence = chunkMQB5H4X5_cjs.timelockToSequence(timelock).toString();
9334
9962
  if (seen.has(sequence)) continue;
9335
9963
  seen.add(sequence);
9336
9964
  deduped.push(timelock);
@@ -9347,7 +9975,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
9347
9975
  state: "active"
9348
9976
  });
9349
9977
  const newest = candidates.filter(
9350
- (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunk32YKLQPS_cjs.WALLET_RECEIVE_SOURCE
9978
+ (c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunk4KXOCVXP_cjs.WALLET_RECEIVE_SOURCE
9351
9979
  ).sort((a, b) => {
9352
9980
  if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
9353
9981
  return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
@@ -9355,7 +9983,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
9355
9983
  if (!newest?.params.pubKey) return baseline;
9356
9984
  try {
9357
9985
  const pubKey = base.hex.decode(newest.params.pubKey);
9358
- return new chunk32YKLQPS_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
9986
+ return new chunk4KXOCVXP_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
9359
9987
  } catch (e) {
9360
9988
  console.warn("Skipping malformed boarding contract at boot", newest.script, e);
9361
9989
  return baseline;
@@ -9407,6 +10035,14 @@ var ReadonlyWallet = class _ReadonlyWallet {
9407
10035
  this._assetManager = new ReadonlyAssetManager(this.indexerProvider);
9408
10036
  this.walletContractTimelocks = walletContractTimelocks && walletContractTimelocks.length > 0 ? dedupeTimelocks(walletContractTimelocks) : [this.offchainTapscript.options.csvTimelock];
9409
10037
  }
10038
+ identity;
10039
+ network;
10040
+ onchainProvider;
10041
+ indexerProvider;
10042
+ dustAmount;
10043
+ walletRepository;
10044
+ contractRepository;
10045
+ delegateProvider;
9410
10046
  _contractManager;
9411
10047
  _contractManagerInitializing;
9412
10048
  watcherConfig;
@@ -9424,6 +10060,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
9424
10060
  * (ContractManager isn't given it); `undefined` ⇒ no-op.
9425
10061
  */
9426
10062
  virtualTxRepository;
10063
+ /** Opt-in exit-data capture settings; see {@link StorageConfig.exitDataCapture}. */
10064
+ exitDataCapture;
9427
10065
  _assetManager;
9428
10066
  walletContractTimelocks;
9429
10067
  // Outpoints ("txid:vout") committed to an in-flight settle/send. Filtered
@@ -9466,6 +10104,72 @@ var ReadonlyWallet = class _ReadonlyWallet {
9466
10104
  * construction-time snapshot for their lifetime.
9467
10105
  */
9468
10106
  _arkServerPublicKey;
10107
+ /**
10108
+ * Whether this wallet was constructed from live operator server-info
10109
+ * (`"live"`) or from a cached snapshot because the operator was unreachable
10110
+ * (`"cache"`). Freshness signal for {@link getProviderConnectionState}.
10111
+ */
10112
+ _serverInfoSource = "live";
10113
+ /**
10114
+ * Epoch-ms of the last known live operator contact: construction time on the
10115
+ * `live` boot path, the cached snapshot's `savedAt` on the `cache` path.
10116
+ */
10117
+ _serverInfoLastOnlineAt;
10118
+ /** @see {@link _serverInfoSource} */
10119
+ get serverInfoSource() {
10120
+ return this._serverInfoSource;
10121
+ }
10122
+ /**
10123
+ * Composed provider-connection freshness: the boot server-info source
10124
+ * (Arkade) combined with the contract-manager's indexer-sync health, if the
10125
+ * manager has been initialized. Reads no live provider state — it never
10126
+ * forces a `ContractManager` to construct — so it is safe for readonly
10127
+ * callers that only use address/balance APIs.
10128
+ *
10129
+ * - Boot fell back to a cached snapshot → degraded on `arkade` (`cache`).
10130
+ * - Otherwise, if the contract manager has degraded to repository data →
10131
+ * degraded on `indexer` (`repository`).
10132
+ * - Otherwise online.
10133
+ *
10134
+ * This only describes sync freshness; wallet balances/VTXOs are always read
10135
+ * from the repository regardless of this state.
10136
+ */
10137
+ getProviderConnectionState() {
10138
+ if (this._serverInfoSource === "cache") {
10139
+ return {
10140
+ mode: "degraded",
10141
+ source: "cache",
10142
+ provider: "arkade",
10143
+ reason: "constructed from cached server-info; operator was unreachable at boot",
10144
+ lastOnlineAt: this._serverInfoLastOnlineAt
10145
+ };
10146
+ }
10147
+ const sync = this._contractManager?.getSyncState();
10148
+ if (sync?.mode === "degraded") {
10149
+ return {
10150
+ mode: "degraded",
10151
+ source: "repository",
10152
+ provider: "indexer",
10153
+ reason: sync.reason,
10154
+ lastOnlineAt: sync.lastSyncedAt ?? this._serverInfoLastOnlineAt
10155
+ };
10156
+ }
10157
+ return {
10158
+ mode: "online",
10159
+ source: "live",
10160
+ lastOnlineAt: sync?.lastSyncedAt ?? this._serverInfoLastOnlineAt ?? 0
10161
+ };
10162
+ }
10163
+ /**
10164
+ * The contract-manager's current provider-sync health **without forcing it
10165
+ * to initialize** — reads the already-constructed manager, or reports
10166
+ * `online` when none exists yet. Unlike {@link getContractManager}, this
10167
+ * never triggers a remote sync, so it is safe on a pure diagnostics path
10168
+ * (e.g. the service-worker sync-state message).
10169
+ */
10170
+ getContractSyncState() {
10171
+ return this._contractManager?.getSyncState() ?? { mode: "online" };
10172
+ }
9469
10173
  /**
9470
10174
  * x-only hex of the operator's deprecated signer keys (from
9471
10175
  * `ArkInfo.deprecatedSigners`), cached for the OFFLINE read/watch paths.
@@ -9581,7 +10285,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
9581
10285
  */
9582
10286
  static async setupWalletConfig(config, pubKey) {
9583
10287
  const arkadeServerUrl = getArkadeServerUrl(config);
9584
- const arkProvider = config.arkProvider || new chunkUBYY2TPK_cjs.RestArkProvider(arkadeServerUrl);
10288
+ const arkProvider = config.arkProvider || new chunk7IYIFMF4_cjs.RestArkProvider(arkadeServerUrl);
9585
10289
  let indexerProvider = config.indexerProvider;
9586
10290
  if (!indexerProvider) {
9587
10291
  let indexerUrl = config.indexerUrl;
@@ -9598,10 +10302,16 @@ var ReadonlyWallet = class _ReadonlyWallet {
9598
10302
  indexerUrl = arkadeServerUrl;
9599
10303
  }
9600
10304
  }
9601
- indexerProvider = new chunkUBYY2TPK_cjs.RestIndexerProvider(indexerUrl);
10305
+ indexerProvider = new chunk7IYIFMF4_cjs.RestIndexerProvider(indexerUrl);
9602
10306
  }
9603
- const info = await arkProvider.getInfo();
9604
- const network = chunkHXDZ2QTW_cjs.getNetwork(info.network);
10307
+ const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
10308
+ const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
10309
+ const {
10310
+ info,
10311
+ source: serverInfoSource,
10312
+ lastOnlineAt: serverInfoLastOnlineAt
10313
+ } = await resolveArkInfo(arkProvider, walletRepository);
10314
+ const network = chunkMQB5H4X5_cjs.getNetwork(info.network);
9605
10315
  if ("descriptor" in config.identity) {
9606
10316
  const descriptor = config.identity.descriptor;
9607
10317
  const identityIsMainnet = !descriptor.includes("tpub");
@@ -9648,14 +10358,12 @@ var ReadonlyWallet = class _ReadonlyWallet {
9648
10358
  serverPubKey,
9649
10359
  csvTimelock: exitTimelock
9650
10360
  };
9651
- const offchainTapscript = !delegatePubKey ? new chunk32YKLQPS_cjs.DefaultVtxo.Script(offchainOptions) : new chunk32YKLQPS_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
9652
- const boardingTapscript = chunk32YKLQPS_cjs.BoardingContractHandler.createScript({
10361
+ const offchainTapscript = !delegatePubKey ? new chunk4KXOCVXP_cjs.DefaultVtxo.Script(offchainOptions) : new chunk4KXOCVXP_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
10362
+ const boardingTapscript = chunk4KXOCVXP_cjs.BoardingContractHandler.createScript({
9653
10363
  pubKey: base.hex.encode(pubKey),
9654
10364
  serverPubKey: base.hex.encode(serverPubKey),
9655
- csvTimelock: chunkHXDZ2QTW_cjs.timelockToSequence(boardingTimelock).toString()
10365
+ csvTimelock: chunkMQB5H4X5_cjs.timelockToSequence(boardingTimelock).toString()
9656
10366
  });
9657
- const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
9658
- const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
9659
10367
  return {
9660
10368
  arkProvider,
9661
10369
  indexerProvider,
@@ -9669,6 +10377,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
9669
10377
  walletRepository,
9670
10378
  contractRepository,
9671
10379
  info,
10380
+ serverInfoSource,
10381
+ serverInfoLastOnlineAt,
9672
10382
  delegateProvider: config.delegateProvider || config.delegatorProvider,
9673
10383
  /** @deprecated alias for `delegateProvider` */
9674
10384
  delegatorProvider: config.delegateProvider || config.delegatorProvider,
@@ -9704,6 +10414,15 @@ var ReadonlyWallet = class _ReadonlyWallet {
9704
10414
  );
9705
10415
  wallet.intentRepository = config.storage?.intentRepository;
9706
10416
  wallet.virtualTxRepository = config.storage?.virtualTxRepository;
10417
+ wallet.exitDataCapture = config.storage?.exitDataCapture;
10418
+ wallet._serverInfoSource = setup.serverInfoSource;
10419
+ if (setup.serverInfoSource === "live") {
10420
+ const now = Date.now();
10421
+ await saveValidatedArkInfoSnapshot(setup.walletRepository, setup.info, now);
10422
+ wallet._serverInfoLastOnlineAt = now;
10423
+ } else {
10424
+ wallet._serverInfoLastOnlineAt = setup.serverInfoLastOnlineAt;
10425
+ }
9707
10426
  wallet.refreshDeprecatedSigners(setup.info);
9708
10427
  return wallet;
9709
10428
  }
@@ -9834,7 +10553,10 @@ var ReadonlyWallet = class _ReadonlyWallet {
9834
10553
  const response = await contractManager.getContractsWithVtxos();
9835
10554
  const allVtxos = response.flatMap((_) => _.vtxos);
9836
10555
  const { boardingTxs, commitmentsToIgnore } = await this.getBoardingTxs();
9837
- const getTxCreatedAt = (txid) => this.indexerProvider.getVtxos({ outpoints: [{ txid, vout: 0 }] }).then((res) => res.vtxos[0]?.createdAt.getTime());
10556
+ const getTxCreatedAt = (txid) => this.indexerProvider.getVtxos({ outpoints: [{ txid, vout: 0 }] }).then((res) => res.vtxos[0]?.createdAt.getTime()).catch((err) => {
10557
+ if (isRetryableProviderError(err)) return void 0;
10558
+ throw err;
10559
+ });
9838
10560
  return buildTransactionHistory(allVtxos, boardingTxs, commitmentsToIgnore, getTxCreatedAt);
9839
10561
  }
9840
10562
  /**
@@ -9974,9 +10696,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
9974
10696
  async getBoardingTapscripts(allowedSigners) {
9975
10697
  const byScript = /* @__PURE__ */ new Map();
9976
10698
  const add = (s) => byScript.set(base.hex.encode(s.pkScript), s);
9977
- const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunk32YKLQPS_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
10699
+ const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
9978
10700
  add(
9979
- new chunk32YKLQPS_cjs.DefaultVtxo.Script({
10701
+ new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
9980
10702
  pubKey: await this.identity.xOnlyPublicKey(),
9981
10703
  serverPubKey: this.boardingTapscript.options.serverPubKey,
9982
10704
  csvTimelock: boardingCsv
@@ -9991,7 +10713,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
9991
10713
  for (const c of boardingContracts) {
9992
10714
  if (!allowed.has(toXOnlySignerHex(c.params.serverPubKey))) continue;
9993
10715
  try {
9994
- add(chunk32YKLQPS_cjs.BoardingContractHandler.createScript(c.params));
10716
+ add(chunk4KXOCVXP_cjs.BoardingContractHandler.createScript(c.params));
9995
10717
  } catch (e) {
9996
10718
  console.warn("Skipping malformed boarding contract", c.script, e);
9997
10719
  }
@@ -10029,7 +10751,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
10029
10751
  // Per-row CSV delay decoded from THIS tapscript's exit leaf —
10030
10752
  // not the wallet's current boarding timelock, which a signer
10031
10753
  // rotation may have changed.
10032
- csvTimelock: chunkHXDZ2QTW_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
10754
+ csvTimelock: chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
10033
10755
  coins: utxos
10034
10756
  });
10035
10757
  }
@@ -10195,7 +10917,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
10195
10917
  });
10196
10918
  for (const contract of contracts) {
10197
10919
  if (map.has(contract.script)) continue;
10198
- const handler = chunk32YKLQPS_cjs.contractHandlers.get(contract.type);
10920
+ const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
10199
10921
  if (handler) {
10200
10922
  const script = handler.createScript(contract.params);
10201
10923
  map.set(contract.script, script);
@@ -10253,15 +10975,43 @@ var ReadonlyWallet = class _ReadonlyWallet {
10253
10975
  }
10254
10976
  }
10255
10977
  async initializeContractManager() {
10978
+ const virtualTxRepository = this.virtualTxRepository;
10979
+ let onVtxosPersisted;
10980
+ let onVtxosSpent;
10981
+ if (virtualTxRepository) {
10982
+ const capture = this.exitDataCapture;
10983
+ const resolver = createExitChainResolver({
10984
+ indexer: this.indexerProvider,
10985
+ repository: virtualTxRepository,
10986
+ extraSources: capture?.sources
10987
+ });
10988
+ onVtxosPersisted = async (_contract, vtxos) => {
10989
+ for (const v of vtxos) {
10990
+ if (v.virtualStatus.state === "spent") continue;
10991
+ await captureExitBranch({
10992
+ resolver,
10993
+ repository: virtualTxRepository,
10994
+ vtxo: { txid: v.txid, vout: v.vout },
10995
+ value: v.value,
10996
+ mode: capture?.mode ?? DEFAULT_EXIT_CAPTURE_MODE,
10997
+ minExitWorthSats: capture?.minExitWorthSats ?? DEFAULT_MIN_EXIT_WORTH_SATS
10998
+ }).catch(() => {
10999
+ });
11000
+ }
11001
+ };
11002
+ onVtxosSpent = (vtxos) => pruneExitBranches(virtualTxRepository, vtxos);
11003
+ }
10256
11004
  const manager = await ContractManager.create({
10257
11005
  indexerProvider: this.indexerProvider,
10258
11006
  contractRepository: this.contractRepository,
10259
11007
  walletRepository: this.walletRepository,
10260
11008
  intentRepository: this.intentRepository,
11009
+ onVtxosPersisted,
11010
+ onVtxosSpent,
10261
11011
  watcherConfig: this.watcherConfig
10262
11012
  });
10263
11013
  const baselinePubkey = await this.identity.xOnlyPublicKey();
10264
- const delegatePubKey = this.offchainTapscript instanceof chunk32YKLQPS_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
11014
+ const delegatePubKey = this.offchainTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
10265
11015
  const baselineSigners = [
10266
11016
  this.offchainTapscript.options.serverPubKey,
10267
11017
  ...[...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h))
@@ -10269,8 +11019,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
10269
11019
  const seenBaselineScripts = /* @__PURE__ */ new Set();
10270
11020
  for (const serverPubKey of baselineSigners) {
10271
11021
  for (const csvTimelock of this.walletContractTimelocks) {
10272
- const csvTimelockStr = chunkHXDZ2QTW_cjs.timelockToSequence(csvTimelock).toString();
10273
- const defaultScript = new chunk32YKLQPS_cjs.DefaultVtxo.Script({
11022
+ const csvTimelockStr = chunkMQB5H4X5_cjs.timelockToSequence(csvTimelock).toString();
11023
+ const defaultScript = new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
10274
11024
  pubKey: baselinePubkey,
10275
11025
  serverPubKey,
10276
11026
  csvTimelock
@@ -10291,7 +11041,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
10291
11041
  });
10292
11042
  }
10293
11043
  if (delegatePubKey) {
10294
- const delegateScript = new chunk32YKLQPS_cjs.DelegateVtxo.Script({
11044
+ const delegateScript = new chunk4KXOCVXP_cjs.DelegateVtxo.Script({
10295
11045
  pubKey: baselinePubkey,
10296
11046
  serverPubKey,
10297
11047
  delegatePubKey,
@@ -10315,9 +11065,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
10315
11065
  }
10316
11066
  }
10317
11067
  }
10318
- const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunk32YKLQPS_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
11068
+ const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
10319
11069
  for (const serverPubKey of baselineSigners) {
10320
- const baselineBoarding = new chunk32YKLQPS_cjs.DefaultVtxo.Script({
11070
+ const baselineBoarding = new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
10321
11071
  pubKey: baselinePubkey,
10322
11072
  serverPubKey,
10323
11073
  csvTimelock: boardingCsvTimelock
@@ -10330,7 +11080,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
10330
11080
  params: {
10331
11081
  pubKey: base.hex.encode(baselineBoarding.options.pubKey),
10332
11082
  serverPubKey: base.hex.encode(serverPubKey),
10333
- csvTimelock: chunkHXDZ2QTW_cjs.timelockToSequence(boardingCsvTimelock).toString()
11083
+ csvTimelock: chunkMQB5H4X5_cjs.timelockToSequence(boardingCsvTimelock).toString()
10334
11084
  },
10335
11085
  script: boardingScriptHex,
10336
11086
  address: baselineBoarding.address(this.network.hrp, serverPubKey).encode(),
@@ -10399,6 +11149,9 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10399
11149
  boardingPkScript: boardingTapscript.pkScript
10400
11150
  });
10401
11151
  }
11152
+ arkProvider;
11153
+ forfeitOutputScript;
11154
+ forfeitPubkey;
10402
11155
  static MIN_FEE_RATE = 1;
10403
11156
  // sats/vbyte
10404
11157
  identity;
@@ -10550,25 +11303,25 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10550
11303
  return this.getBoardingAddress();
10551
11304
  }
10552
11305
  const descriptor = await provider.getNextSigningDescriptor();
10553
- const pubKey = chunk32YKLQPS_cjs.deriveDescriptorLeafPubKey(descriptor);
10554
- const newBoarding = new chunk32YKLQPS_cjs.DefaultVtxo.Script({
11306
+ const pubKey = chunk4KXOCVXP_cjs.deriveDescriptorLeafPubKey(descriptor);
11307
+ const newBoarding = new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
10555
11308
  ...this._boardingTapscript.options,
10556
11309
  pubKey
10557
11310
  });
10558
- const csvTimelock = newBoarding.options.csvTimelock ?? chunk32YKLQPS_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
11311
+ const csvTimelock = newBoarding.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
10559
11312
  const manager = await this.getContractManager();
10560
11313
  await manager.createContract({
10561
11314
  type: "boarding",
10562
11315
  params: {
10563
11316
  pubKey: base.hex.encode(pubKey),
10564
11317
  serverPubKey: base.hex.encode(newBoarding.options.serverPubKey),
10565
- csvTimelock: chunkHXDZ2QTW_cjs.timelockToSequence(csvTimelock).toString()
11318
+ csvTimelock: chunkMQB5H4X5_cjs.timelockToSequence(csvTimelock).toString()
10566
11319
  },
10567
11320
  script: base.hex.encode(newBoarding.pkScript),
10568
11321
  address: newBoarding.address(this.network.hrp, this.arkServerPublicKey).encode(),
10569
11322
  state: "active",
10570
11323
  metadata: {
10571
- source: chunk32YKLQPS_cjs.WALLET_RECEIVE_SOURCE,
11324
+ source: chunk4KXOCVXP_cjs.WALLET_RECEIVE_SOURCE,
10572
11325
  signingDescriptor: descriptor
10573
11326
  }
10574
11327
  });
@@ -10607,7 +11360,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10607
11360
  const xonly = toXOnlyPubKey(newServerPubKey);
10608
11361
  let newServerUnrollScript;
10609
11362
  try {
10610
- newServerUnrollScript = chunkHXDZ2QTW_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
11363
+ newServerUnrollScript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
10611
11364
  } catch (e) {
10612
11365
  throw new Error("Invalid checkpointTapscript from server");
10613
11366
  }
@@ -10635,21 +11388,21 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10635
11388
  const [currentBoardingRow] = await manager.getContracts({
10636
11389
  script: currentBoardingScript
10637
11390
  });
10638
- const newOffchain = this.offchainTapscript instanceof chunk32YKLQPS_cjs.DelegateVtxo.Script ? new chunk32YKLQPS_cjs.DelegateVtxo.Script({
11391
+ const newOffchain = this.offchainTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script ? new chunk4KXOCVXP_cjs.DelegateVtxo.Script({
10639
11392
  ...this.offchainTapscript.options,
10640
11393
  serverPubKey: xonly
10641
- }) : new chunk32YKLQPS_cjs.DefaultVtxo.Script({
11394
+ }) : new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
10642
11395
  ...this.offchainTapscript.options,
10643
11396
  serverPubKey: xonly
10644
11397
  });
10645
- const newBoarding = new chunk32YKLQPS_cjs.DefaultVtxo.Script({
11398
+ const newBoarding = new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
10646
11399
  ...this._boardingTapscript.options,
10647
11400
  serverPubKey: xonly
10648
11401
  });
10649
- const offchainCsv = chunkHXDZ2QTW_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
11402
+ const offchainCsv = chunkMQB5H4X5_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
10650
11403
  const newOffchainScript = base.hex.encode(newOffchain.pkScript);
10651
11404
  const newOffchainAddress = newOffchain.address(this.network.hrp, xonly).encode();
10652
- if (newOffchain instanceof chunk32YKLQPS_cjs.DelegateVtxo.Script) {
11405
+ if (newOffchain instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script) {
10653
11406
  await manager.createContract({
10654
11407
  type: "delegate",
10655
11408
  params: {
@@ -10677,13 +11430,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10677
11430
  metadata: currentOffchainRow?.metadata
10678
11431
  });
10679
11432
  }
10680
- const boardingCsv = newBoarding.options.csvTimelock ?? chunk32YKLQPS_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
11433
+ const boardingCsv = newBoarding.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
10681
11434
  await manager.createContract({
10682
11435
  type: "boarding",
10683
11436
  params: {
10684
11437
  pubKey: base.hex.encode(newBoarding.options.pubKey),
10685
11438
  serverPubKey: base.hex.encode(xonly),
10686
- csvTimelock: chunkHXDZ2QTW_cjs.timelockToSequence(boardingCsv).toString()
11439
+ csvTimelock: chunkMQB5H4X5_cjs.timelockToSequence(boardingCsv).toString()
10687
11440
  },
10688
11441
  script: base.hex.encode(newBoarding.pkScript),
10689
11442
  address: newBoarding.address(this.network.hrp, xonly).encode(),
@@ -10778,7 +11531,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10778
11531
  const hd = provider instanceof HDDescriptorProvider;
10779
11532
  const staticDescriptor = hd ? void 0 : `tr(${base.hex.encode(await this.identity.xOnlyPublicKey())})`;
10780
11533
  const materialize = (index) => hd ? provider.materializeDescriptorAt(index) : staticDescriptor;
10781
- const delegatePubKey = this.offchainTapscript instanceof chunk32YKLQPS_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
11534
+ const delegatePubKey = this.offchainTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
10782
11535
  const arkInfo = await this.arkProvider.getInfo();
10783
11536
  const currentSignerPubKey = toXOnlyPubKey(base.hex.decode(arkInfo.signerPubkey));
10784
11537
  const deprecatedSignerPubKeys = arkInfo.deprecatedSigners.map(
@@ -10797,7 +11550,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10797
11550
  csvTimelocks: this.walletContractTimelocks,
10798
11551
  // Boarding-exit CSV so the boarding handler can build its
10799
11552
  // candidate script (distinct from the unilateral-exit matrix).
10800
- boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunk32YKLQPS_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
11553
+ boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
10801
11554
  delegatePubKey
10802
11555
  };
10803
11556
  const result = await manager.scanContracts({
@@ -10901,7 +11654,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10901
11654
  let serverUnrollScript;
10902
11655
  try {
10903
11656
  const raw = base.hex.decode(setup.info.checkpointTapscript);
10904
- serverUnrollScript = chunkHXDZ2QTW_cjs.CSVMultisigTapscript.decode(raw);
11657
+ serverUnrollScript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(raw);
10905
11658
  } catch (e) {
10906
11659
  throw new Error("Invalid checkpointTapscript from server");
10907
11660
  }
@@ -10932,6 +11685,14 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10932
11685
  boot?.rotator,
10933
11686
  boot?.provider
10934
11687
  );
11688
+ wallet._serverInfoSource = setup.serverInfoSource;
11689
+ if (setup.serverInfoSource === "live") {
11690
+ const now = Date.now();
11691
+ await saveValidatedArkInfoSnapshot(setup.walletRepository, setup.info, now);
11692
+ wallet._serverInfoLastOnlineAt = now;
11693
+ } else {
11694
+ wallet._serverInfoLastOnlineAt = setup.serverInfoLastOnlineAt;
11695
+ }
10935
11696
  wallet.refreshDeprecatedSigners(setup.info);
10936
11697
  {
10937
11698
  const ap = setup.arkProvider;
@@ -10953,6 +11714,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
10953
11714
  }
10954
11715
  wallet.intentRepository = config.storage?.intentRepository;
10955
11716
  wallet.virtualTxRepository = config.storage?.virtualTxRepository;
11717
+ wallet.exitDataCapture = config.storage?.exitDataCapture;
10956
11718
  await wallet.getVtxoManager();
10957
11719
  return wallet;
10958
11720
  }
@@ -11029,7 +11791,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11029
11791
  inputs: params.selectedVtxos,
11030
11792
  changeAmount: BigInt(changeAmount)
11031
11793
  };
11032
- const outputAddress = chunkHXDZ2QTW_cjs.ArkAddress.decode(params.address);
11794
+ const outputAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(params.address);
11033
11795
  const outputScript = BigInt(params.amount) < this.dustAmount ? outputAddress.subdustPkScript : outputAddress.pkScript;
11034
11796
  const outputs = [
11035
11797
  {
@@ -11082,13 +11844,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11082
11844
  }
11083
11845
  }
11084
11846
  const offchainAddress = await this.getAddress();
11085
- const offchainPkScript = chunkHXDZ2QTW_cjs.ArkAddress.decode(offchainAddress).pkScript;
11847
+ const offchainPkScript = chunkMQB5H4X5_cjs.ArkAddress.decode(offchainAddress).pkScript;
11086
11848
  const offchainOutputScript = base.hex.encode(offchainPkScript);
11087
11849
  if (!params) {
11088
11850
  const { fees, vtxoMaxAmount } = await this.arkProvider.getInfo();
11089
11851
  const estimator = new Estimator(fees.intentFee);
11090
11852
  let amount = 0;
11091
- const exitScript = chunkHXDZ2QTW_cjs.CSVMultisigTapscript.decode(
11853
+ const exitScript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(
11092
11854
  base.hex.decode(this.boardingTapscript.exitScript)
11093
11855
  );
11094
11856
  const boardingTimelock = exitScript.params.timelock;
@@ -11154,7 +11916,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11154
11916
  script: offchainOutputScript
11155
11917
  });
11156
11918
  output.amount -= BigInt(outputFee.satoshis);
11157
- if (output.amount <= this.dustAmount) {
11919
+ if (isSubdust(output.amount, this.dustAmount)) {
11158
11920
  throw new Error("Output amount is below dust limit");
11159
11921
  }
11160
11922
  params = {
@@ -11168,7 +11930,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11168
11930
  for (const [index, output] of params.outputs.entries()) {
11169
11931
  let script;
11170
11932
  try {
11171
- const addr = chunkHXDZ2QTW_cjs.ArkAddress.decode(output.address);
11933
+ const addr = chunkMQB5H4X5_cjs.ArkAddress.decode(output.address);
11172
11934
  script = addr.pkScript;
11173
11935
  hasOffchainOutputs = true;
11174
11936
  } catch {
@@ -11402,7 +12164,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11402
12164
  }
11403
12165
  continue;
11404
12166
  }
11405
- if (isRecoverable(input) || isSubdust(input, this.dustAmount)) {
12167
+ if (isRecoverable(input) || isSubdust({ value: input.value }, this.dustAmount)) {
11406
12168
  continue;
11407
12169
  }
11408
12170
  if (connectorsLeaves.length === 0) {
@@ -11430,7 +12192,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11430
12192
  index: input.vout,
11431
12193
  witnessUtxo: {
11432
12194
  amount: BigInt(input.value),
11433
- script: chunkHXDZ2QTW_cjs.VtxoScript.decode(input.tapTree).pkScript
12195
+ script: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript
11434
12196
  },
11435
12197
  sighashType: btcSigner.SigHash.DEFAULT,
11436
12198
  tapLeafScript: [input.forfeitTapLeafScript]
@@ -11449,7 +12211,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11449
12211
  forfeitTx = await this._signerRouter.sign(forfeitTx, [
11450
12212
  {
11451
12213
  index: 0,
11452
- lookupScript: chunkHXDZ2QTW_cjs.VtxoScript.decode(input.tapTree).pkScript
12214
+ lookupScript: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript
11453
12215
  }
11454
12216
  ]);
11455
12217
  signedForfeits.push(base.base64.encode(forfeitTx.toPSBT()));
@@ -11507,7 +12269,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11507
12269
  if (skip) {
11508
12270
  return { skip };
11509
12271
  }
11510
- const sweepTapscript = chunkHXDZ2QTW_cjs.CSVMultisigTapscript.encode({
12272
+ const sweepTapscript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.encode({
11511
12273
  timelock: {
11512
12274
  value: event.batchExpiry,
11513
12275
  type: event.batchExpiry >= 512n ? "seconds" : "blocks"
@@ -11613,9 +12375,9 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11613
12375
  ...existing ?? {},
11614
12376
  intentTxId,
11615
12377
  registerProof: intent.proof,
11616
- registerProofMessage: chunkUBYY2TPK_cjs.Intent.encodeMessage(intent.message),
12378
+ registerProofMessage: chunk7IYIFMF4_cjs.Intent.encodeMessage(intent.message),
11617
12379
  deleteProof: deleteIntent.proof,
11618
- deleteProofMessage: chunkUBYY2TPK_cjs.Intent.encodeMessage(deleteIntent.message),
12380
+ deleteProofMessage: chunk7IYIFMF4_cjs.Intent.encodeMessage(deleteIntent.message),
11619
12381
  intentVtxos: inputs.map((i) => ({
11620
12382
  txid: i.txid,
11621
12383
  vout: i.vout
@@ -11647,7 +12409,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11647
12409
  try {
11648
12410
  return await this.arkProvider.registerIntent(intent);
11649
12411
  } catch (error) {
11650
- if (error instanceof chunkUBYY2TPK_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
12412
+ if (error instanceof chunk7IYIFMF4_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
11651
12413
  const deleteIntent = await this.makeDeleteIntentSignature(inputs);
11652
12414
  await this.arkProvider.deleteIntent(deleteIntent);
11653
12415
  return this.arkProvider.registerIntent(intent);
@@ -11663,7 +12425,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11663
12425
  expire_at: 0,
11664
12426
  cosigners_public_keys: cosignerPubKeys
11665
12427
  };
11666
- const proof = chunkUBYY2TPK_cjs.Intent.create(message, coins, outputs);
12428
+ const proof = chunk7IYIFMF4_cjs.Intent.create(message, coins, outputs);
11667
12429
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
11668
12430
  return {
11669
12431
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -11675,7 +12437,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11675
12437
  type: "delete",
11676
12438
  expire_at: 0
11677
12439
  };
11678
- const proof = chunkUBYY2TPK_cjs.Intent.create(message, coins, []);
12440
+ const proof = chunk7IYIFMF4_cjs.Intent.create(message, coins, []);
11679
12441
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
11680
12442
  return {
11681
12443
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -11687,7 +12449,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
11687
12449
  type: "get-pending-tx",
11688
12450
  expire_at: 0
11689
12451
  };
11690
- const proof = chunkUBYY2TPK_cjs.Intent.create(message, coins, []);
12452
+ const proof = chunk7IYIFMF4_cjs.Intent.create(message, coins, []);
11691
12453
  const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
11692
12454
  return {
11693
12455
  proof: base.base64.encode(signedProof.toPSBT()),
@@ -12103,7 +12865,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
12103
12865
  );
12104
12866
  const arkTxJobs = inputs.map((input, index) => ({
12105
12867
  index,
12106
- lookupScript: chunkHXDZ2QTW_cjs.VtxoScript.decode(input.tapTree).pkScript
12868
+ lookupScript: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript
12107
12869
  }));
12108
12870
  const checkpointJobs = offchainTx.checkpoints.map(
12109
12871
  (c) => this.inputSigningJobsFromWitnessUtxos(c)
@@ -12336,7 +13098,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
12336
13098
  } else {
12337
13099
  let sourceAddress;
12338
13100
  try {
12339
- sourceAddress = chunkHXDZ2QTW_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
13101
+ sourceAddress = chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
12340
13102
  this.network
12341
13103
  );
12342
13104
  } catch {
@@ -12481,6 +13243,8 @@ var MessageBus = class {
12481
13243
  this.debug = debug;
12482
13244
  this.buildServicesFn = buildServices ?? this.buildServices.bind(this);
12483
13245
  }
13246
+ walletRepository;
13247
+ contractRepository;
12484
13248
  handlers;
12485
13249
  tickIntervalMs;
12486
13250
  messageTimeoutMs;
@@ -12645,7 +13409,7 @@ var MessageBus = class {
12645
13409
  this.initialized = true;
12646
13410
  }
12647
13411
  async buildServices(config) {
12648
- const arkProvider = new chunkUBYY2TPK_cjs.RestArkProvider(config.arkServer.url);
13412
+ const arkProvider = new chunk7IYIFMF4_cjs.RestArkProvider(config.arkServer.url);
12649
13413
  const storage = {
12650
13414
  walletRepository: this.walletRepository,
12651
13415
  contractRepository: this.contractRepository
@@ -12982,6 +13746,7 @@ var Ramps = class {
12982
13746
  constructor(wallet) {
12983
13747
  this.wallet = wallet;
12984
13748
  }
13749
+ wallet;
12985
13750
  /**
12986
13751
  * Onboard boarding inputs.
12987
13752
  *
@@ -13027,7 +13792,7 @@ var Ramps = class {
13027
13792
  }
13028
13793
  amount = amount ?? totalAmount;
13029
13794
  const offchainAddress = await this.wallet.getAddress();
13030
- const offchainAddr = chunkHXDZ2QTW_cjs.ArkAddress.decode(offchainAddress);
13795
+ const offchainAddr = chunkMQB5H4X5_cjs.ArkAddress.decode(offchainAddress);
13031
13796
  const offchainScript = base.hex.encode(offchainAddr.pkScript);
13032
13797
  const outputFee = estimator.evalOffchainOutput({
13033
13798
  amount,
@@ -13125,7 +13890,7 @@ var Ramps = class {
13125
13890
  let destinationScript;
13126
13891
  for (const networkName of networkNames) {
13127
13892
  try {
13128
- const network = chunkHXDZ2QTW_cjs.networks[networkName];
13893
+ const network = chunkMQB5H4X5_cjs.networks[networkName];
13129
13894
  const addr = btcSigner.Address(network).decode(destinationAddress);
13130
13895
  destinationScript = btcSigner.OutScript.encode(addr);
13131
13896
  break;
@@ -13470,10 +14235,18 @@ var WalletMessageHandler = class {
13470
14235
  type: "WALLET_STATUS",
13471
14236
  payload: {
13472
14237
  walletInitialized: true,
13473
- xOnlyPublicKey: pubKey
14238
+ xOnlyPublicKey: pubKey,
14239
+ providerConnectionState: this.readonlyWallet.getProviderConnectionState()
13474
14240
  }
13475
14241
  });
13476
14242
  }
14243
+ case "GET_CONTRACT_SYNC_STATE": {
14244
+ return this.tagged({
14245
+ id,
14246
+ type: "CONTRACT_SYNC_STATE",
14247
+ payload: { syncState: this.readonlyWallet.getContractSyncState() }
14248
+ });
14249
+ }
13477
14250
  case "CLEAR": {
13478
14251
  await this.clear();
13479
14252
  return this.tagged({
@@ -13802,7 +14575,7 @@ var WalletMessageHandler = class {
13802
14575
  // Wallet methods
13803
14576
  async handleInitWallet({ payload }) {
13804
14577
  const { arkServerUrl } = payload;
13805
- this.indexerProvider = new chunkUBYY2TPK_cjs.RestIndexerProvider(arkServerUrl);
14578
+ this.indexerProvider = new chunk7IYIFMF4_cjs.RestIndexerProvider(arkServerUrl);
13806
14579
  await this.onWalletInitialized();
13807
14580
  }
13808
14581
  async handleGetBalance() {
@@ -14236,6 +15009,7 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
14236
15009
  GET_BALANCE: 1e4,
14237
15010
  GET_BOARDING_ADDRESS: 1e4,
14238
15011
  GET_STATUS: 1e4,
15012
+ GET_CONTRACT_SYNC_STATE: 1e4,
14239
15013
  GET_DELEGATE_INFO: 1e4,
14240
15014
  IS_CONTRACT_MANAGER_WATCHING: 1e4,
14241
15015
  // Medium reads — may involve indexer queries
@@ -14319,6 +15093,8 @@ var ServiceWorkerReadonlyAssetManager = class {
14319
15093
  this.sendMessage = sendMessage;
14320
15094
  this.messageTag = messageTag;
14321
15095
  }
15096
+ sendMessage;
15097
+ messageTag;
14322
15098
  async getAssetDetails(assetId) {
14323
15099
  const message = {
14324
15100
  tag: this.messageTag,
@@ -14403,6 +15179,8 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
14403
15179
  messageTag
14404
15180
  );
14405
15181
  }
15182
+ serviceWorker;
15183
+ messageTag;
14406
15184
  walletRepository;
14407
15185
  contractRepository;
14408
15186
  identity;
@@ -14844,6 +15622,19 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
14844
15622
  throw new Error(`Failed to get status: ${error}`);
14845
15623
  }
14846
15624
  }
15625
+ /**
15626
+ * Wallet-level provider-connection freshness, delegated to the worker via
15627
+ * `GET_STATUS`. Async by necessity (the worker boundary is asynchronous); no
15628
+ * synchronous variant is offered because it would have the same transport
15629
+ * mismatch as the contract-manager proxy's cached `getSyncState()`.
15630
+ */
15631
+ async getProviderConnectionState() {
15632
+ const { providerConnectionState } = await this.getStatus();
15633
+ if (!providerConnectionState) {
15634
+ throw new Error("Worker did not report provider connection state");
15635
+ }
15636
+ return providerConnectionState;
15637
+ }
14847
15638
  async getActivityHistory() {
14848
15639
  return buildActivities(await this.getTransactionHistory(), this.activity.all());
14849
15640
  }
@@ -14898,6 +15689,32 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
14898
15689
  return wallet.sendMessage(message);
14899
15690
  };
14900
15691
  const messageTag = this.messageTag;
15692
+ const fetchSyncState = async () => {
15693
+ const message = {
15694
+ type: "GET_CONTRACT_SYNC_STATE",
15695
+ id: getRandomId(),
15696
+ tag: messageTag
15697
+ };
15698
+ const response = await sendContractMessage(message);
15699
+ return response.payload.syncState;
15700
+ };
15701
+ const UNKNOWN_STATE = {
15702
+ mode: "degraded",
15703
+ reason: "contract sync state unavailable from the worker"
15704
+ };
15705
+ let syncState = UNKNOWN_STATE;
15706
+ let everProbed = false;
15707
+ const refreshSyncState = async () => {
15708
+ try {
15709
+ syncState = await fetchSyncState();
15710
+ everProbed = true;
15711
+ } catch {
15712
+ if (!everProbed) {
15713
+ syncState = UNKNOWN_STATE;
15714
+ }
15715
+ }
15716
+ };
15717
+ await refreshSyncState();
14901
15718
  const manager = {
14902
15719
  async createContract(params) {
14903
15720
  const message = {
@@ -14908,6 +15725,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
14908
15725
  };
14909
15726
  try {
14910
15727
  const response = await sendContractMessage(message);
15728
+ await refreshSyncState();
14911
15729
  return response.payload.contract;
14912
15730
  } catch (e) {
14913
15731
  throw new Error("Failed to create contract");
@@ -14936,11 +15754,15 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
14936
15754
  };
14937
15755
  try {
14938
15756
  const response = await sendContractMessage(message);
15757
+ await refreshSyncState();
14939
15758
  return response.payload.contracts;
14940
15759
  } catch (e) {
14941
15760
  throw new Error("Failed to get contracts with vtxos");
14942
15761
  }
14943
15762
  },
15763
+ getSyncState() {
15764
+ return syncState;
15765
+ },
14944
15766
  async annotateVtxos(vtxos) {
14945
15767
  if (vtxos.length === 0) return [];
14946
15768
  const message = {
@@ -15049,7 +15871,11 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
15049
15871
  tag: messageTag,
15050
15872
  payload: opts
15051
15873
  };
15052
- await sendContractMessage(message);
15874
+ try {
15875
+ await sendContractMessage(message);
15876
+ } finally {
15877
+ await refreshSyncState();
15878
+ }
15053
15879
  },
15054
15880
  async refreshOutpoints(outpoints) {
15055
15881
  const message = {
@@ -15058,7 +15884,11 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
15058
15884
  tag: messageTag,
15059
15885
  payload: { outpoints }
15060
15886
  };
15061
- await sendContractMessage(message);
15887
+ try {
15888
+ await sendContractMessage(message);
15889
+ } finally {
15890
+ await refreshSyncState();
15891
+ }
15062
15892
  },
15063
15893
  scanContracts() {
15064
15894
  return Promise.reject(
@@ -15103,6 +15933,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
15103
15933
  );
15104
15934
  this.hasDelegate = hasDelegate;
15105
15935
  }
15936
+ serviceWorker;
15106
15937
  walletRepository;
15107
15938
  contractRepository;
15108
15939
  identity;
@@ -15484,6 +16315,7 @@ var OnchainWallet = class _OnchainWallet {
15484
16315
  this.onchainP2TR = onchainP2TR;
15485
16316
  this.provider = provider;
15486
16317
  }
16318
+ identity;
15487
16319
  static MIN_FEE_RATE = 1;
15488
16320
  // sat/vbyte
15489
16321
  onchainP2TR;
@@ -15498,12 +16330,12 @@ var OnchainWallet = class _OnchainWallet {
15498
16330
  * @returns Configured onchain wallet
15499
16331
  * @throws Error if the configured identity cannot produce a valid x-only public key
15500
16332
  */
15501
- static async create(identity, networkName = chunkHXDZ2QTW_cjs.DEFAULT_NETWORK_NAME, provider) {
16333
+ static async create(identity, networkName = chunkMQB5H4X5_cjs.DEFAULT_NETWORK_NAME, provider) {
15502
16334
  const pubkey = await identity.xOnlyPublicKey();
15503
16335
  if (!pubkey) {
15504
16336
  throw new Error("Invalid configured public key");
15505
16337
  }
15506
- const network = chunkHXDZ2QTW_cjs.getNetwork(networkName);
16338
+ const network = chunkMQB5H4X5_cjs.getNetwork(networkName);
15507
16339
  const onchainProvider = provider || new EsploraProvider(ESPLORA_URL[networkName]);
15508
16340
  const onchainP2TR = btcSigner.p2tr(pubkey, void 0, network);
15509
16341
  return new _OnchainWallet(identity, network, onchainP2TR, onchainProvider);
@@ -15609,7 +16441,7 @@ var OnchainWallet = class _OnchainWallet {
15609
16441
  if (!inputs) {
15610
16442
  throw new Error("Fee estimation failed");
15611
16443
  }
15612
- let tx = new chunkUBYY2TPK_cjs.Transaction();
16444
+ let tx = new chunk7IYIFMF4_cjs.Transaction();
15613
16445
  for (const input of inputs) {
15614
16446
  tx.addInput({
15615
16447
  txid: input.txid,
@@ -15667,7 +16499,7 @@ var OnchainWallet = class _OnchainWallet {
15667
16499
  * @throws If the parent has no anchor, or funding cannot be selected/signed
15668
16500
  */
15669
16501
  async bumpAnchor(parentHex, feeRate) {
15670
- const parent = chunkUBYY2TPK_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
16502
+ const parent = chunk7IYIFMF4_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
15671
16503
  const coins = (await this.getCoins()).filter((c) => c.status.confirmed);
15672
16504
  const child = await this.buildBumpPackage(parent, feeRate, coins);
15673
16505
  return [parent.hex, child.hex];
@@ -15785,6 +16617,8 @@ var WsElectrumChainSource = class {
15785
16617
  this.ws = ws;
15786
16618
  this.network = network;
15787
16619
  }
16620
+ ws;
16621
+ network;
15788
16622
  // Cached chain tip kept fresh by the headers subscription. Initialized
15789
16623
  // lazily on first call to subscribeHeaders().
15790
16624
  cachedTip = null;
@@ -16067,6 +16901,8 @@ var ElectrumOnchainProvider = class {
16067
16901
  this.network = network;
16068
16902
  this.chain = new WsElectrumChainSource(ws, network);
16069
16903
  }
16904
+ ws;
16905
+ network;
16070
16906
  chain;
16071
16907
  async getCoins(address) {
16072
16908
  const script = this.encodeAddress(address);
@@ -16428,7 +17264,7 @@ exports.BIP322 = void 0;
16428
17264
  async function sign2(message, identity, network) {
16429
17265
  const xOnlyPubKey = await identity.xOnlyPublicKey();
16430
17266
  const payment = btcSigner.p2tr(xOnlyPubKey, void 0, network);
16431
- const toSpend = chunkUBYY2TPK_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
17267
+ const toSpend = chunk7IYIFMF4_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
16432
17268
  const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
16433
17269
  const signed = await identity.sign(toSign, [0]);
16434
17270
  signed.finalizeIdx(0);
@@ -16486,7 +17322,7 @@ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
16486
17322
  if (sighashType !== btcSigner.SigHash.DEFAULT && sighashType !== btcSigner.SigHash.ALL) {
16487
17323
  return false;
16488
17324
  }
16489
- const toSpend = chunkUBYY2TPK_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
17325
+ const toSpend = chunk7IYIFMF4_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
16490
17326
  const toSign = craftBIP322ToSignP2TR(toSpend, pkScript, pubkey);
16491
17327
  const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
16492
17328
  const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
@@ -16507,7 +17343,7 @@ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
16507
17343
  }
16508
17344
  const sighashType = sigWithHash[sigWithHash.length - 1];
16509
17345
  const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
16510
- const toSpend = chunkUBYY2TPK_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
17346
+ const toSpend = chunk7IYIFMF4_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
16511
17347
  const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
16512
17348
  const scriptCode = btcSigner.OutScript.encode({ type: "pkh", hash: addressHash });
16513
17349
  const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
@@ -16560,7 +17396,7 @@ function encodeCompactSize(n) {
16560
17396
  return buf;
16561
17397
  }
16562
17398
  function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
16563
- const tx = new chunkUBYY2TPK_cjs.Transaction({ version: 0 });
17399
+ const tx = new chunk7IYIFMF4_cjs.Transaction({ version: 0 });
16564
17400
  tx.addInput({
16565
17401
  txid: toSpend.id,
16566
17402
  index: 0,
@@ -16574,12 +17410,12 @@ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
16574
17410
  });
16575
17411
  tx.addOutput({
16576
17412
  amount: 0n,
16577
- script: chunkUBYY2TPK_cjs.OP_RETURN_EMPTY_PKSCRIPT
17413
+ script: chunk7IYIFMF4_cjs.OP_RETURN_EMPTY_PKSCRIPT
16578
17414
  });
16579
17415
  return tx;
16580
17416
  }
16581
17417
  function craftBIP322ToSignSimple(toSpend, pkScript) {
16582
- const tx = new chunkUBYY2TPK_cjs.Transaction({ version: 0 });
17418
+ const tx = new chunk7IYIFMF4_cjs.Transaction({ version: 0 });
16583
17419
  tx.addInput({
16584
17420
  txid: toSpend.id,
16585
17421
  index: 0,
@@ -16591,12 +17427,12 @@ function craftBIP322ToSignSimple(toSpend, pkScript) {
16591
17427
  });
16592
17428
  tx.addOutput({
16593
17429
  amount: 0n,
16594
- script: chunkUBYY2TPK_cjs.OP_RETURN_EMPTY_PKSCRIPT
17430
+ script: chunk7IYIFMF4_cjs.OP_RETURN_EMPTY_PKSCRIPT
16595
17431
  });
16596
17432
  return tx;
16597
17433
  }
16598
17434
  function finalizeVirtualTx(type, psbtBase64) {
16599
- const tx = chunkUBYY2TPK_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
17435
+ const tx = chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
16600
17436
  if (type === "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */) {
16601
17437
  const input = tx.getInput(0);
16602
17438
  if (!input) {
@@ -16620,16 +17456,17 @@ var ExitPathError = class extends Error {
16620
17456
  this.reason = reason;
16621
17457
  this.name = "ExitPathError";
16622
17458
  }
17459
+ reason;
16623
17460
  };
16624
17461
  function delayWeight(sequence) {
16625
- const t = chunkHXDZ2QTW_cjs.sequenceToTimelock(sequence);
17462
+ const t = chunkMQB5H4X5_cjs.sequenceToTimelock(sequence);
16626
17463
  return t.type === "blocks" ? Number(t.value) : Number(t.value) / 600;
16627
17464
  }
16628
17465
  async function resolveUnilateralPath(params) {
16629
17466
  const { vtxo, scriptHex, contractRepository } = params;
16630
17467
  const contract = contractRepository ? (await contractRepository.getContracts({ script: scriptHex }))[0] : void 0;
16631
17468
  if (contract) {
16632
- const handler = chunk32YKLQPS_cjs.contractHandlers.get(contract.type);
17469
+ const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
16633
17470
  if (!handler) {
16634
17471
  throw new ExitPathError(
16635
17472
  "no-handler",
@@ -16652,12 +17489,12 @@ async function resolveUnilateralPath(params) {
16652
17489
  paths.sort((a, b) => delayWeight(a.sequence) - delayWeight(b.sequence));
16653
17490
  return { selection: paths[0], label: `${contract.type}:unilateral` };
16654
17491
  }
16655
- const decoded = chunkHXDZ2QTW_cjs.VtxoScript.decode(vtxo.tapTree);
17492
+ const decoded = chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree);
16656
17493
  let best;
16657
17494
  for (const exit of decoded.exitPaths()) {
16658
17495
  const leaf = decoded.findLeaf(base.hex.encode(exit.script));
16659
17496
  if (!leaf) continue;
16660
- const sequence = chunkHXDZ2QTW_cjs.timelockToSequence(exit.params.timelock);
17497
+ const sequence = chunkMQB5H4X5_cjs.timelockToSequence(exit.params.timelock);
16661
17498
  const weight = delayWeight(sequence);
16662
17499
  if (!best || weight < best.weight) {
16663
17500
  best = { selection: { leaf, sequence }, weight };
@@ -16673,7 +17510,7 @@ async function resolveUnilateralPath(params) {
16673
17510
  }
16674
17511
 
16675
17512
  // src/wallet/unroll.ts
16676
- function chainTxTypeToChainedExit(t) {
17513
+ function chainTxTypeToChainedExit2(t) {
16677
17514
  switch (t) {
16678
17515
  case "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */:
16679
17516
  return 1 /* Commitment */;
@@ -16703,6 +17540,11 @@ exports.Unroll = void 0;
16703
17540
  this.indexer = indexer;
16704
17541
  this.virtualTxRepository = virtualTxRepository;
16705
17542
  }
17543
+ toUnroll;
17544
+ bumper;
17545
+ explorer;
17546
+ indexer;
17547
+ virtualTxRepository;
16706
17548
  /** Create an unroll session by loading the virtual output chain from the indexer. */
16707
17549
  static async create(toUnroll, bumper, explorer, indexer, virtualTxRepository) {
16708
17550
  const { chain } = await indexer.getVtxoChain(toUnroll);
@@ -16736,7 +17578,7 @@ exports.Unroll = void 0;
16736
17578
  txid: next.txid,
16737
17579
  psbt,
16738
17580
  expiresAt: null,
16739
- type: chainTxTypeToChainedExit(next.type)
17581
+ type: chainTxTypeToChainedExit2(next.type)
16740
17582
  };
16741
17583
  try {
16742
17584
  await repo.upsertVirtualTxs([cached]);
@@ -16838,14 +17680,14 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
16838
17680
  }
16839
17681
  const resolved = await resolveUnilateralPath({
16840
17682
  vtxo,
16841
- scriptHex: base.hex.encode(chunkHXDZ2QTW_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
17683
+ scriptHex: base.hex.encode(chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
16842
17684
  contractRepository: wallet.contractRepository,
16843
17685
  walletPubKeyHex: base.hex.encode(await wallet.identity.xOnlyPublicKey()),
16844
17686
  currentTime: Date.now()
16845
17687
  });
16846
17688
  const spendingLeaf = resolved.selection.leaf;
16847
17689
  const sequence = resolved.selection.sequence;
16848
- const timelock = chunkHXDZ2QTW_cjs.sequenceToTimelock(sequence);
17690
+ const timelock = chunkMQB5H4X5_cjs.sequenceToTimelock(sequence);
16849
17691
  const elapsed = timelock.type === "blocks" ? chainTip.height >= txStatus.blockHeight + Number(timelock.value) : chainTip.time >= txStatus.blockTime + Number(timelock.value);
16850
17692
  if (!elapsed) {
16851
17693
  throw new Error(`no available exit path found for vtxo ${vtxo.txid}:${vtxo.vout}`);
@@ -16858,7 +17700,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
16858
17700
  sequence,
16859
17701
  witnessUtxo: {
16860
17702
  amount: BigInt(vtxo.value),
16861
- script: chunkHXDZ2QTW_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
17703
+ script: chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
16862
17704
  },
16863
17705
  sighashType: btcSigner.SigHash.DEFAULT
16864
17706
  });
@@ -16868,7 +17710,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
16868
17710
  btcSigner.TaprootControlBlock.encode(spendingLeaf[0]).length
16869
17711
  );
16870
17712
  }
16871
- const tx = new chunkUBYY2TPK_cjs.Transaction({ version: 2 });
17713
+ const tx = new chunk7IYIFMF4_cjs.Transaction({ version: 2 });
16872
17714
  for (const input of inputs) {
16873
17715
  tx.addInput(input);
16874
17716
  }
@@ -16914,99 +17756,6 @@ function doWait(onchainProvider, txid) {
16914
17756
  });
16915
17757
  };
16916
17758
  }
16917
-
16918
- // src/wallet/exit/chain.ts
16919
- var isCommitment = (t) => t === "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */ || t === "INDEXER_CHAINED_TX_TYPE_UNSPECIFIED" /* UNSPECIFIED */;
16920
- async function buildExitDag(params) {
16921
- const byTxid = /* @__PURE__ */ new Map();
16922
- for (const vtxo of params.vtxos) {
16923
- const outpoint = `${vtxo.txid}:${vtxo.vout}`;
16924
- let pageIndex = 0;
16925
- let hasMore = true;
16926
- while (hasMore) {
16927
- const { chain, page } = await params.indexer.getVtxoChain(
16928
- { txid: vtxo.txid, vout: vtxo.vout },
16929
- { pageIndex, pageSize: chunk32YKLQPS_cjs.DEFAULT_PAGE_SIZE }
16930
- );
16931
- for (const chainTx of chain) {
16932
- const existing = byTxid.get(chainTx.txid);
16933
- if (existing) {
16934
- existing.forVtxos.add(outpoint);
16935
- } else {
16936
- byTxid.set(chainTx.txid, { ...chainTx, forVtxos: /* @__PURE__ */ new Set([outpoint]) });
16937
- }
16938
- }
16939
- hasMore = page ? chain.length === chunk32YKLQPS_cjs.DEFAULT_PAGE_SIZE : false;
16940
- pageIndex++;
16941
- }
16942
- }
16943
- const pending = new Map(
16944
- [...byTxid.values()].filter((tx) => !isCommitment(tx.type)).map((tx) => [tx.txid, tx])
16945
- );
16946
- const inDegree = /* @__PURE__ */ new Map();
16947
- for (const tx of pending.values()) {
16948
- const parents = tx.spends.filter((p) => pending.has(p));
16949
- inDegree.set(tx.txid, parents.length);
16950
- }
16951
- const order = [];
16952
- const queue = [...pending.values()].filter((tx) => inDegree.get(tx.txid) === 0).sort((a, b) => a.txid.localeCompare(b.txid));
16953
- while (queue.length > 0) {
16954
- const tx = queue.shift();
16955
- order.push(tx);
16956
- const children = [...pending.values()].filter((c) => c.spends.includes(tx.txid)).sort((a, b) => a.txid.localeCompare(b.txid));
16957
- for (const child of children) {
16958
- const deg = inDegree.get(child.txid) - 1;
16959
- inDegree.set(child.txid, deg);
16960
- if (deg === 0) queue.push(child);
16961
- }
16962
- }
16963
- if (order.length !== pending.size) {
16964
- throw new Error("inconsistent vtxo chain from indexer (cycle detected)");
16965
- }
16966
- const nodes = [];
16967
- for (const tx of order) {
16968
- let confirmed = false;
16969
- try {
16970
- const status = await params.onchain.getTxStatus(tx.txid);
16971
- confirmed = status.confirmed;
16972
- } catch {
16973
- confirmed = false;
16974
- }
16975
- const expires = Number(tx.expiresAt);
16976
- nodes.push({
16977
- txid: tx.txid,
16978
- type: tx.type,
16979
- expiresAt: Number.isFinite(expires) && expires > 0 ? expires : void 0,
16980
- forVtxos: [...tx.forVtxos].sort(),
16981
- confirmed
16982
- });
16983
- }
16984
- return nodes;
16985
- }
16986
- function topoSortByDeps(items, idOf, depsOf) {
16987
- const produced = new Set(items.map(idOf));
16988
- const emitted = /* @__PURE__ */ new Set();
16989
- const ordered = [];
16990
- let remaining = items;
16991
- while (remaining.length > 0) {
16992
- const next = [];
16993
- let progress = false;
16994
- for (const item of remaining) {
16995
- if (depsOf(item).every((d) => !produced.has(d) || emitted.has(d))) {
16996
- ordered.push(item);
16997
- emitted.add(idOf(item));
16998
- progress = true;
16999
- } else {
17000
- next.push(item);
17001
- }
17002
- }
17003
- if (!progress) {
17004
- throw new Error("topological sort: cycle or unsatisfiable dependency");
17005
- }
17006
- remaining = next;
17007
- }
17008
- return ordered;
17009
- }
17010
17759
  function extraWitnessSize(path) {
17011
17760
  return (path.extraWitness ?? []).reduce((sum, item) => sum + 1 + item.length, 0);
17012
17761
  }
@@ -17028,7 +17777,7 @@ async function buildSignedSweep(params) {
17028
17777
  `uneconomic vtxo ${vtxo.txid}:${vtxo.vout}: value ${vtxo.value} - fee ${fee} < dust`
17029
17778
  );
17030
17779
  }
17031
- const tx = new chunkUBYY2TPK_cjs.Transaction({ version: 2 });
17780
+ const tx = new chunk7IYIFMF4_cjs.Transaction({ version: 2 });
17032
17781
  tx.addInput({
17033
17782
  txid: vtxo.txid,
17034
17783
  index: vtxo.vout,
@@ -17053,7 +17802,7 @@ async function buildSignedSweep(params) {
17053
17802
  finalScriptWitness: [
17054
17803
  tapScriptSig[0][1],
17055
17804
  ...path.extraWitness,
17056
- chunkHXDZ2QTW_cjs.scriptFromTapLeafScript(path.leaf),
17805
+ chunkMQB5H4X5_cjs.scriptFromTapLeafScript(path.leaf),
17057
17806
  btcSigner.TaprootControlBlock.encode(controlBlock)
17058
17807
  ]
17059
17808
  });
@@ -17098,7 +17847,7 @@ async function selectExitVtxos(opts) {
17098
17847
  `no contract registered for vtxo script ${vtxo.script} \u2014 register the contract before exiting`
17099
17848
  );
17100
17849
  }
17101
- const handler = chunk32YKLQPS_cjs.contractHandlers.get(contract.type);
17850
+ const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
17102
17851
  if (!handler) {
17103
17852
  throw new Error(`no contract handler registered for type '${contract.type}'`);
17104
17853
  }
@@ -17113,27 +17862,22 @@ async function computeExitLayout(opts, feeRate) {
17113
17862
  const { wallet, onchainWallet } = opts;
17114
17863
  const vtxos = await selectExitVtxos(opts);
17115
17864
  if (vtxos.length === 0) throw new Error("no vtxos to exit");
17865
+ const resolver = createExitChainResolver({
17866
+ indexer: wallet.indexerProvider,
17867
+ repository: wallet.virtualTxRepository,
17868
+ extraSources: wallet.exitDataCapture?.sources
17869
+ });
17116
17870
  const dag = await buildExitDag({
17117
17871
  vtxos,
17118
- indexer: wallet.indexerProvider,
17872
+ chain: resolver,
17119
17873
  onchain: wallet.onchainProvider
17120
17874
  });
17121
17875
  const pendingNodes = dag.filter((n) => !n.confirmed);
17122
17876
  const psbts = /* @__PURE__ */ new Map();
17123
17877
  if (pendingNodes.length > 0) {
17124
- const txids = pendingNodes.map((n) => n.txid);
17125
- let pageIndex = 0;
17126
- let hasMore = true;
17127
- while (hasMore) {
17128
- const { txs, page } = await wallet.indexerProvider.getVirtualTxs(txids, {
17129
- pageIndex,
17130
- pageSize: chunk32YKLQPS_cjs.DEFAULT_PAGE_SIZE
17131
- });
17132
- for (const psbt of txs) {
17133
- psbts.set(chunkUBYY2TPK_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
17134
- }
17135
- hasMore = page ? txs.length === chunk32YKLQPS_cjs.DEFAULT_PAGE_SIZE : false;
17136
- pageIndex++;
17878
+ const txs = await resolver.getVirtualTxs(pendingNodes.map((n) => n.txid));
17879
+ for (const psbt of txs) {
17880
+ psbts.set(chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
17137
17881
  }
17138
17882
  }
17139
17883
  const childVsize = Number(
@@ -17169,7 +17913,7 @@ async function computeExitLayout(opts, feeRate) {
17169
17913
  try {
17170
17914
  const resolved = await resolveUnilateralPath({
17171
17915
  vtxo,
17172
- scriptHex: base.hex.encode(chunkHXDZ2QTW_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
17916
+ scriptHex: base.hex.encode(chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
17173
17917
  contractRepository: wallet.contractRepository,
17174
17918
  walletPubKeyHex,
17175
17919
  currentTime: Date.now()
@@ -17188,7 +17932,7 @@ async function computeExitLayout(opts, feeRate) {
17188
17932
  });
17189
17933
  continue;
17190
17934
  }
17191
- const t = chunkHXDZ2QTW_cjs.sequenceToTimelock(resolved.selection.sequence);
17935
+ const t = chunkMQB5H4X5_cjs.sequenceToTimelock(resolved.selection.sequence);
17192
17936
  const delay = { type: t.type, value: Number(t.value) };
17193
17937
  infos.push({ outpoint, value: vtxo.value, sweepFee, path: resolved.label, delay });
17194
17938
  sweeps.push({ vtxo, resolved, sweepFee, delay });
@@ -17281,6 +18025,8 @@ var Executor = class {
17281
18025
  this.pollIntervalMs = opts?.pollIntervalMs ?? 5e3;
17282
18026
  this.feeWallet = opts?.feeWallet;
17283
18027
  }
18028
+ pkg;
18029
+ provider;
17284
18030
  pollIntervalMs;
17285
18031
  feeWallet;
17286
18032
  sleep() {
@@ -17493,7 +18239,7 @@ async function prepare(opts) {
17493
18239
  txid: sweep.vtxo.txid,
17494
18240
  vout: sweep.vtxo.vout,
17495
18241
  value: sweep.vtxo.value,
17496
- pkScript: chunkHXDZ2QTW_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
18242
+ pkScript: chunkMQB5H4X5_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
17497
18243
  },
17498
18244
  path: sweep.resolved.selection,
17499
18245
  outputAddress: opts.sweepAddress,
@@ -17578,7 +18324,7 @@ async function prepare(opts) {
17578
18324
  if (newFee <= splitterFee) break;
17579
18325
  splitterFee = newFee;
17580
18326
  }
17581
- const splitter = new chunkUBYY2TPK_cjs.Transaction({ version: 2 });
18327
+ const splitter = new chunk7IYIFMF4_cjs.Transaction({ version: 2 });
17582
18328
  for (const coin of selected.inputs) {
17583
18329
  splitter.addInput({
17584
18330
  txid: coin.txid,
@@ -17742,7 +18488,7 @@ function decodeArkContract(encoded) {
17742
18488
  }
17743
18489
  function contractFromArkContract(encoded, options = {}) {
17744
18490
  const parsed = decodeArkContract(encoded);
17745
- const handler = chunk32YKLQPS_cjs.contractHandlers.get(parsed.type);
18491
+ const handler = chunk4KXOCVXP_cjs.contractHandlers.get(parsed.type);
17746
18492
  if (!handler) {
17747
18493
  throw new Error(`No handler registered for contract type '${parsed.type}'`);
17748
18494
  }
@@ -17756,9 +18502,9 @@ function contractFromArkContract(encoded, options = {}) {
17756
18502
  metadata: options.metadata
17757
18503
  };
17758
18504
  }
17759
- function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunkHXDZ2QTW_cjs.DEFAULT_NETWORK.hrp, options = {}) {
18505
+ function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunkMQB5H4X5_cjs.DEFAULT_NETWORK.hrp, options = {}) {
17760
18506
  const parsed = decodeArkContract(encoded);
17761
- const handler = chunk32YKLQPS_cjs.contractHandlers.getOrThrow(parsed.type);
18507
+ const handler = chunk4KXOCVXP_cjs.contractHandlers.getOrThrow(parsed.type);
17762
18508
  const params = parsed.data;
17763
18509
  const vtxoScript = handler.createScript(params);
17764
18510
  return {
@@ -17851,6 +18597,7 @@ exports.combineTapscriptSigs = combineTapscriptSigs;
17851
18597
  exports.contractFromArkContract = contractFromArkContract;
17852
18598
  exports.contractFromArkContractWithAddress = contractFromArkContractWithAddress;
17853
18599
  exports.createDefaultActivityRegistry = createDefaultActivityRegistry;
18600
+ exports.createExitChainResolver = createExitChainResolver;
17854
18601
  exports.decodeArkContract = decodeArkContract;
17855
18602
  exports.deserializeAssets = deserializeAssets;
17856
18603
  exports.deserializeExitPackage = deserializeExitPackage;
@@ -17869,6 +18616,7 @@ exports.isCooperativelyMigratable = isCooperativelyMigratable;
17869
18616
  exports.isDiscoverable = isDiscoverable;
17870
18617
  exports.isExpired = isExpired;
17871
18618
  exports.isRecoverable = isRecoverable;
18619
+ exports.isRetryableProviderError = isRetryableProviderError;
17872
18620
  exports.isSpendable = isSpendable;
17873
18621
  exports.isSubdust = isSubdust;
17874
18622
  exports.isTerminalIntentState = isTerminalIntentState;
@@ -17894,5 +18642,5 @@ exports.validateVtxoTxGraph = validateVtxoTxGraph;
17894
18642
  exports.verifyTapscriptSignatures = verifyTapscriptSignatures;
17895
18643
  exports.waitForIncomingFunds = waitForIncomingFunds;
17896
18644
  exports.warnAndFilterVtxosForScript = warnAndFilterVtxosForScript;
17897
- //# sourceMappingURL=chunk-XIVCG6EP.cjs.map
17898
- //# sourceMappingURL=chunk-XIVCG6EP.cjs.map
18645
+ //# sourceMappingURL=chunk-D46YDM36.cjs.map
18646
+ //# sourceMappingURL=chunk-D46YDM36.cjs.map