@arkade-os/swap 0.0.4 → 0.0.6

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.
package/dist/index.cjs CHANGED
@@ -53,6 +53,7 @@ __export(index_exports, {
53
53
  ONCHAIN_RECEIVE_PAIR: () => ONCHAIN_RECEIVE_PAIR,
54
54
  ONCHAIN_SECONDS_PER_BLOCK: () => ONCHAIN_SECONDS_PER_BLOCK,
55
55
  ONCHAIN_SEND_PAIR: () => ONCHAIN_SEND_PAIR,
56
+ PreimageNotRecoverableError: () => PreimageNotRecoverableError,
56
57
  QUOTE_OPTIONS: () => QUOTE_OPTIONS,
57
58
  REFUND_MTP_LAG_SECONDS: () => REFUND_MTP_LAG_SECONDS,
58
59
  RFQ_RESOLVED_STATES: () => RFQ_RESOLVED_STATES,
@@ -60,6 +61,7 @@ __export(index_exports, {
60
61
  RFQ_TERMINAL_STATES: () => RFQ_TERMINAL_STATES,
61
62
  RefundNotLocallyPossibleError: () => RefundNotLocallyPossibleError,
62
63
  RfqSwapManager: () => RfqSwapManager,
64
+ SOLO_REFUND_HEADROOM_SECONDS: () => SOLO_REFUND_HEADROOM_SECONDS,
63
65
  SWAP_LOCKUP_CONTRACT_KIND: () => SWAP_LOCKUP_CONTRACT_KIND,
64
66
  SWAP_LOCKUP_CONTRACT_LABEL: () => SWAP_LOCKUP_CONTRACT_LABEL,
65
67
  SWAP_LOCKUP_CONTRACT_TYPE: () => SWAP_LOCKUP_CONTRACT_TYPE,
@@ -107,6 +109,7 @@ __export(index_exports, {
107
109
  onchainReceiveRequest: () => onchainReceiveRequest,
108
110
  onchainSendRequest: () => onchainSendRequest,
109
111
  paymentHashOf: () => paymentHashOf,
112
+ preimageForSwapRecord: () => preimageForSwapRecord,
110
113
  pushClaim: () => pushClaim,
111
114
  pushRefundWithoutReceiver: () => pushRefundWithoutReceiver,
112
115
  readLockupFate: () => readLockupFate,
@@ -125,6 +128,7 @@ __export(index_exports, {
125
128
  senderIdentityForSwapRecord: () => senderIdentityForSwapRecord,
126
129
  spendTxidsOf: () => spendTxidsOf,
127
130
  spendUpdate: () => spendUpdate,
131
+ swapActivityResolver: () => swapActivityResolver,
128
132
  swapPrograms: () => swapPrograms,
129
133
  swapSecretsToRecord: () => swapSecretsToRecord,
130
134
  unilateralClaimDelay: () => unilateralClaimDelay,
@@ -142,7 +146,7 @@ module.exports = __toCommonJS(index_exports);
142
146
  // src/offer.ts
143
147
  var import_base2 = require("@scure/base");
144
148
  var import_utils = require("@scure/btc-signer/utils.js");
145
- var import_sdk = require("@arkade-os/sdk");
149
+ var import_sdk2 = require("@arkade-os/sdk");
146
150
 
147
151
  // src/swap-want-asset.program.json
148
152
  var swap_want_asset_program_default = {
@@ -273,6 +277,8 @@ async function retireSettledOfferContracts(manager, swaps) {
273
277
 
274
278
  // src/store.ts
275
279
  var import_base = require("@scure/base");
280
+ var import_sha2 = require("@noble/hashes/sha2.js");
281
+ var import_sdk = require("@arkade-os/sdk");
276
282
  var BTC_ASSET_ID = "btc";
277
283
  var byNewest = (a, b) => b.createdAt - a.createdAt;
278
284
  var getAssetSwapsOrThrow = async (repository) => {
@@ -327,13 +333,66 @@ var updateAssetSwapBestEffort = async (repository, id, changes) => {
327
333
  };
328
334
  var swapSecretsToRecord = (secrets) => ({
329
335
  signingDescriptor: secrets.descriptor,
330
- ..."mustPersistPreimage" in secrets && secrets.mustPersistPreimage ? { preimageHex: import_base.hex.encode(secrets.preimage) } : {}
336
+ ..."mustPersistPreimage" in secrets && secrets.mustPersistPreimage ? { preimageHex: import_base.hex.encode(secrets.preimage) } : {},
337
+ ..."preimageSalt" in secrets && secrets.preimageSalt ? { preimageSaltHex: import_base.hex.encode(secrets.preimageSalt) } : {}
331
338
  });
339
+ var decodeHex32 = (value, field) => {
340
+ const bytes = import_base.hex.decode(value);
341
+ if (bytes.length !== 32) {
342
+ throw new Error(`${field} must be 32 bytes, got ${bytes.length}`);
343
+ }
344
+ return bytes;
345
+ };
346
+ var PreimageNotRecoverableError = class extends Error {
347
+ constructor(reason, message, options) {
348
+ super(message, options);
349
+ this.reason = reason;
350
+ }
351
+ reason;
352
+ name = "PreimageNotRecoverableError";
353
+ };
354
+ var preimageForSwapRecord = async (wallet, record) => {
355
+ if (!record.signingDescriptor) {
356
+ throw new PreimageNotRecoverableError(
357
+ "no-secrets",
358
+ "this swap record carries no signing descriptor"
359
+ );
360
+ }
361
+ let stored;
362
+ let salt;
363
+ try {
364
+ stored = record.preimageHex ? decodeHex32(record.preimageHex, "preimageHex") : void 0;
365
+ salt = record.preimageSaltHex ? decodeHex32(record.preimageSaltHex, "preimageSaltHex") : void 0;
366
+ } catch (cause) {
367
+ throw new PreimageNotRecoverableError(
368
+ "malformed-record",
369
+ `this swap record's secrets projection is unreadable: ${String(cause)}`,
370
+ { cause }
371
+ );
372
+ }
373
+ let preimage;
374
+ try {
375
+ preimage = await (0, import_sdk.contractPreimage)(wallet, record.signingDescriptor, { stored, salt });
376
+ } catch (cause) {
377
+ throw new PreimageNotRecoverableError(
378
+ "not-derivable",
379
+ `this wallet cannot produce the preimage for ${record.signingDescriptor}`,
380
+ { cause }
381
+ );
382
+ }
383
+ if (record.paymentHash && import_base.hex.encode((0, import_sha2.sha256)(preimage)) !== record.paymentHash.toLowerCase()) {
384
+ throw new PreimageNotRecoverableError(
385
+ "hash-mismatch",
386
+ "the derived preimage does not match this swap's payment hash: wrong wallet, or a tampered salt"
387
+ );
388
+ }
389
+ return preimage;
390
+ };
332
391
 
333
392
  // src/offer.ts
334
393
  var swapPrograms = {
335
- wantAsset: import_sdk.arkade.parseArtifact(swap_want_asset_program_default),
336
- wantBtc: import_sdk.arkade.parseArtifact(swap_want_btc_program_default)
394
+ wantAsset: import_sdk2.arkade.parseArtifact(swap_want_asset_program_default),
395
+ wantBtc: import_sdk2.arkade.parseArtifact(swap_want_btc_program_default)
337
396
  };
338
397
  function swapProgramBinding(offer, serverPubkey) {
339
398
  if (offer.makerPkScript.length !== FIELDS.makerPkScript.width) {
@@ -361,7 +420,7 @@ function swapProgramBinding(offer, serverPubkey) {
361
420
  }
362
421
  function offerVtxoScript(offer, serverPubkey) {
363
422
  const { program, args, keys } = swapProgramBinding(offer, serverPubkey);
364
- return new import_sdk.arkade.ArkadeProgramScript(program, args, keys);
423
+ return new import_sdk2.arkade.ArkadeProgramScript(program, args, keys);
365
424
  }
366
425
  var OFFER_PACKET_TYPE = 3;
367
426
  var FIELDS = {
@@ -443,8 +502,8 @@ function decodeOffer(data) {
443
502
  return {
444
503
  swapPkScript: need("swapPkScript"),
445
504
  wantAmount: new DataView(amount.buffer, amount.byteOffset).getBigUint64(0, false),
446
- ...fields.wantAsset && { wantAsset: import_sdk.asset.AssetId.fromBytes(fields.wantAsset) },
447
- ...fields.offerAsset && { offerAsset: import_sdk.asset.AssetId.fromBytes(fields.offerAsset) },
505
+ ...fields.wantAsset && { wantAsset: import_sdk2.asset.AssetId.fromBytes(fields.wantAsset) },
506
+ ...fields.offerAsset && { offerAsset: import_sdk2.asset.AssetId.fromBytes(fields.offerAsset) },
448
507
  makerPkScript: need("makerPkScript"),
449
508
  makerPublicKey: need("makerPublicKey"),
450
509
  emulatorPubkey: need("emulatorPubkey")
@@ -455,17 +514,17 @@ var OFFER_CONTRACT_KIND = "asset-swap-offer";
455
514
  async function registerOfferContract(wallet, arkServerUrl, network, binding, serverPubkey, expectedPkScript) {
456
515
  const { program, args, keys } = swapProgramBinding(binding, serverPubkey);
457
516
  const contractManager = await wallet.getContractManager();
458
- const client = await import_sdk.arkade.Arkade.connect({
459
- arkade: new import_sdk.RestArkProvider(arkServerUrl),
460
- indexer: new import_sdk.RestIndexerProvider(arkServerUrl),
517
+ const client = await import_sdk2.arkade.Arkade.connect({
518
+ arkade: new import_sdk2.RestArkProvider(arkServerUrl),
519
+ indexer: new import_sdk2.RestIndexerProvider(arkServerUrl),
461
520
  identity: wallet.identity,
462
521
  // without this the row's `address` would be derived against the SDK's
463
522
  // default network while its script is right — a row that disagrees with
464
523
  // the address the user is about to fund
465
- network: (0, import_sdk.getNetwork)(network),
524
+ network: (0, import_sdk2.getNetwork)(network),
466
525
  contractManager
467
526
  });
468
- const contract = new import_sdk.arkade.ArkadeContract(client, program, args, keys);
527
+ const contract = new import_sdk2.arkade.ArkadeContract(client, program, args, keys);
469
528
  if (import_base2.hex.encode(contract.pkScript) !== import_base2.hex.encode(expectedPkScript)) {
470
529
  throw new Error("derived covenant does not match the offer's swapPkScript");
471
530
  }
@@ -480,20 +539,20 @@ async function createOffer(wallet, arkServerUrl, params) {
480
539
  throw new Error("set exactly one of wantAsset (BTC->asset) or offerAsset (asset->BTC)");
481
540
  }
482
541
  const [info, makerAddress, makerPublicKey] = await Promise.all([
483
- new import_sdk.RestArkProvider(arkServerUrl).getInfo(),
542
+ new import_sdk2.RestArkProvider(arkServerUrl).getInfo(),
484
543
  wallet.getAddress(),
485
544
  wallet.identity.xOnlyPublicKey()
486
545
  ]);
487
- const serverPubKey = import_base2.hex.decode((0, import_sdk.toXOnlySignerHex)(info.signerPubkey));
488
- const network = (0, import_sdk.getNetwork)(info.network);
546
+ const serverPubKey = import_base2.hex.decode((0, import_sdk2.toXOnlySignerHex)(info.signerPubkey));
547
+ const network = (0, import_sdk2.getNetwork)(info.network);
489
548
  const emuKey = import_base2.hex.decode(
490
- (0, import_sdk.toXOnlySignerHex)((0, import_sdk.resolveEmulatorPubkey)(network, params.emulatorPubkey))
549
+ (0, import_sdk2.toXOnlySignerHex)((0, import_sdk2.resolveEmulatorPubkey)(network, params.emulatorPubkey))
491
550
  );
492
551
  const binding = {
493
552
  wantAmount: params.wantAmount,
494
553
  wantAsset: params.wantAsset,
495
554
  offerAsset: params.offerAsset,
496
- makerPkScript: import_sdk.ArkAddress.decode(makerAddress).pkScript,
555
+ makerPkScript: import_sdk2.ArkAddress.decode(makerAddress).pkScript,
497
556
  makerPublicKey,
498
557
  emulatorPubkey: emuKey
499
558
  };
@@ -521,9 +580,9 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
521
580
  const { repository, fundingTxid, swapAddress } = opts;
522
581
  const offer = decodeOffer(import_base2.hex.decode(offerHex));
523
582
  const contractManager = await wallet.getContractManager();
524
- const client = await import_sdk.arkade.Arkade.connect({
525
- arkade: new import_sdk.RestArkProvider(arkServerUrl),
526
- indexer: new import_sdk.RestIndexerProvider(arkServerUrl),
583
+ const client = await import_sdk2.arkade.Arkade.connect({
584
+ arkade: new import_sdk2.RestArkProvider(arkServerUrl),
585
+ indexer: new import_sdk2.RestIndexerProvider(arkServerUrl),
527
586
  identity: wallet.identity,
528
587
  // registered offers resolve their VTXOs from the contract repository
529
588
  // instead of a direct indexer query; the indexer above stays as the
@@ -533,15 +592,15 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
533
592
  // script and the payout script comes from wallet.getAddress(), so the
534
593
  // client's network (which only shapes address derivation) is unused here
535
594
  });
536
- const serverKey = swapAddress ? import_sdk.ArkAddress.decode(swapAddress).serverPubKey : client.serverKey;
595
+ const serverKey = swapAddress ? import_sdk2.ArkAddress.decode(swapAddress).serverPubKey : client.serverKey;
537
596
  const { program, args, keys } = swapProgramBinding(offer, serverKey);
538
- const rebuilt = new import_sdk.arkade.ArkadeProgramScript(program, args, keys);
597
+ const rebuilt = new import_sdk2.arkade.ArkadeProgramScript(program, args, keys);
539
598
  if (import_base2.hex.encode(rebuilt.pkScript) !== import_base2.hex.encode(offer.swapPkScript)) {
540
599
  throw new Error(
541
600
  "rebuilt covenant does not match the offer's swapPkScript \u2014 the server signing key has likely rotated since funding; pass swapAddress (the funded address) to pin the original key"
542
601
  );
543
602
  }
544
- const contract = new import_sdk.arkade.ArkadeContract(client, program, args, keys);
603
+ const contract = new import_sdk2.arkade.ArkadeContract(client, program, args, keys);
545
604
  const [vtxos, makerAddress] = await Promise.all([contract.getUtxos(), wallet.getAddress()]);
546
605
  if (!fundingTxid && vtxos.length > 1) {
547
606
  throw new Error(
@@ -550,7 +609,7 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
550
609
  }
551
610
  const vtxo = fundingTxid ? vtxos.find((v) => v.txid === fundingTxid) : vtxos[0];
552
611
  if (!vtxo) throw new Error("no spendable VTXO at the swap address");
553
- const makerPkScript = import_sdk.ArkAddress.decode(makerAddress).pkScript;
612
+ const makerPkScript = import_sdk2.ArkAddress.decode(makerAddress).pkScript;
554
613
  const cancel = contract.functions.cancel().from({ txid: vtxo.txid, vout: vtxo.vout, value: vtxo.value }).to(makerPkScript, BigInt(vtxo.value));
555
614
  for (const a of vtxo.assets ?? []) {
556
615
  cancel.withAsset({
@@ -577,7 +636,7 @@ async function cancelOffer(wallet, arkServerUrl, offerHex, opts) {
577
636
 
578
637
  // src/markets.ts
579
638
  var import_solver_discovery = require("@arkade-os/solver-discovery");
580
- var import_sdk2 = require("@arkade-os/sdk");
639
+ var import_sdk3 = require("@arkade-os/sdk");
581
640
  var QUOTE_OPTIONS = { safetyBps: 0 };
582
641
  var makeCachedFeedFetch = (ttlMs = 3e4, fetchImpl = fetch) => {
583
642
  const cache = /* @__PURE__ */ new Map();
@@ -694,7 +753,7 @@ var validatePlan = (plan, giveBalance, dust) => {
694
753
  const receiveIsBtc = plan.receive.asset.id === BTC_ASSET_ID;
695
754
  if (depositIsBtc || receiveIsBtc) {
696
755
  const btcSide = depositIsBtc ? plan.deposit.atomic : plan.receive.atomic;
697
- if ((0, import_sdk2.isSubdust)(btcSide, dust)) return "below-dust";
756
+ if ((0, import_sdk3.isSubdust)(btcSide, dust)) return "below-dust";
698
757
  }
699
758
  return void 0;
700
759
  };
@@ -702,7 +761,7 @@ var validatePlan = (plan, giveBalance, dust) => {
702
761
  // src/repository.ts
703
762
  var marketsCacheKey = (network, registry) => `arkade-intents-markets-${network}-${registry}`;
704
763
  var InMemoryAssetSwapRepository = class {
705
- version = 1;
764
+ version = 2;
706
765
  swaps = /* @__PURE__ */ new Map();
707
766
  scanned = /* @__PURE__ */ new Set();
708
767
  markets = /* @__PURE__ */ new Map();
@@ -734,7 +793,7 @@ var InMemoryAssetSwapRepository = class {
734
793
  };
735
794
 
736
795
  // src/indexedDbRepository.ts
737
- var import_sdk3 = require("@arkade-os/sdk");
796
+ var import_sdk4 = require("@arkade-os/sdk");
738
797
  var DEFAULT_DB_NAME = "arkade-intents";
739
798
  var DB_VERSION = 1;
740
799
  var STORE_SWAPS = "swaps";
@@ -764,7 +823,7 @@ var IndexedDbAssetSwapRepository = class {
764
823
  this.dbName = dbName;
765
824
  }
766
825
  dbName;
767
- version = 1;
826
+ version = 2;
768
827
  // the promise, not the resolved database: openDatabase bumps a refcount on
769
828
  // every call including cache hits, while dispose closes once, so two
770
829
  // concurrent first calls would strand the refcount above zero and leak the
@@ -772,7 +831,7 @@ var IndexedDbAssetSwapRepository = class {
772
831
  // can be retried rather than cached forever.
773
832
  dbPromise = null;
774
833
  ensureDb() {
775
- return this.dbPromise ??= (0, import_sdk3.openDatabase)(this.dbName, DB_VERSION, initDatabase).catch(
834
+ return this.dbPromise ??= (0, import_sdk4.openDatabase)(this.dbName, DB_VERSION, initDatabase).catch(
776
835
  (err) => {
777
836
  this.dbPromise = null;
778
837
  throw err;
@@ -829,14 +888,14 @@ var IndexedDbAssetSwapRepository = class {
829
888
  }
830
889
  async [Symbol.asyncDispose]() {
831
890
  if (!this.dbPromise) return;
832
- await (0, import_sdk3.closeDatabase)(this.dbName);
891
+ await (0, import_sdk4.closeDatabase)(this.dbName);
833
892
  this.dbPromise = null;
834
893
  }
835
894
  };
836
895
 
837
896
  // src/restore.ts
838
897
  var import_base3 = require("@scure/base");
839
- var import_sdk4 = require("@arkade-os/sdk");
898
+ var import_sdk5 = require("@arkade-os/sdk");
840
899
  var TXS_PER_REQUEST = 50;
841
900
  async function fetchParsedTxs(indexer, txids) {
842
901
  const parsedByTxid = /* @__PURE__ */ new Map();
@@ -852,7 +911,7 @@ async function fetchParsedTxs(indexer, txids) {
852
911
  if (result.status !== "fulfilled") continue;
853
912
  for (const psbt of result.value) {
854
913
  try {
855
- const parsed = import_sdk4.Transaction.fromPSBT(import_base3.base64.decode(psbt));
914
+ const parsed = import_sdk5.Transaction.fromPSBT(import_base3.base64.decode(psbt));
856
915
  parsedByTxid.set(parsed.id, parsed);
857
916
  } catch {
858
917
  }
@@ -880,7 +939,7 @@ function classifySpend(offer, serverPubkey, spendTx, deposit) {
880
939
  if (!input.txid || input.index !== deposit.vout) continue;
881
940
  if (import_base3.hex.encode(input.txid) !== deposit.txid) continue;
882
941
  for (const leaf of input.tapLeafScript ?? []) {
883
- const spent = import_base3.hex.encode((0, import_sdk4.scriptFromTapLeafScript)(leaf));
942
+ const spent = import_base3.hex.encode((0, import_sdk5.scriptFromTapLeafScript)(leaf));
884
943
  if (leaves.cancel && spent === import_base3.hex.encode(leaves.cancel)) return "cancelled";
885
944
  if (leaves.fulfill && spent === import_base3.hex.encode(leaves.fulfill)) return "fulfilled";
886
945
  }
@@ -911,7 +970,7 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
911
970
  if (!fundingTx) continue;
912
971
  fetchedTxids.push(txid);
913
972
  try {
914
- const packet = import_sdk4.Extension.fromTx(parsed).getPacketByType(OFFER_PACKET_TYPE);
973
+ const packet = import_sdk5.Extension.fromTx(parsed).getPacketByType(OFFER_PACKET_TYPE);
915
974
  if (!packet) continue;
916
975
  const payload = packet.serialize();
917
976
  found.push({
@@ -1002,7 +1061,7 @@ async function restoreAssetSwaps(indexer, txs, existingIds, opts) {
1002
1061
 
1003
1062
  // src/watch.ts
1004
1063
  var import_base4 = require("@scure/base");
1005
- var import_sdk5 = require("@arkade-os/sdk");
1064
+ var import_sdk6 = require("@arkade-os/sdk");
1006
1065
  var TERMINAL = ["fulfilled", "cancelled", "recoverable"];
1007
1066
  function spendUpdate(swap, spend) {
1008
1067
  if (TERMINAL.includes(swap.status)) return void 0;
@@ -1022,8 +1081,8 @@ async function watchOfferSwaps({
1022
1081
  onUpdate
1023
1082
  }) {
1024
1083
  const manager = await wallet.getContractManager();
1025
- const serverPubkey = import_sdk5.ArkAddress.decode(await wallet.getAddress()).serverPubKey;
1026
- const indexer = new import_sdk5.RestIndexerProvider(arkServerUrl);
1084
+ const serverPubkey = import_sdk6.ArkAddress.decode(await wallet.getAddress()).serverPubKey;
1085
+ const indexer = new import_sdk6.RestIndexerProvider(arkServerUrl);
1027
1086
  let queue = Promise.resolve();
1028
1087
  const enqueue = (task) => {
1029
1088
  queue = queue.then(task).catch(() => {
@@ -1038,7 +1097,7 @@ async function watchOfferSwaps({
1038
1097
  return classifyDepositSpend(
1039
1098
  decodeOffer(import_base4.hex.decode(swap.offerHex)),
1040
1099
  serverPubkey,
1041
- txs.map((psbt) => import_sdk5.Transaction.fromPSBT(import_base4.base64.decode(psbt))),
1100
+ txs.map((psbt) => import_sdk6.Transaction.fromPSBT(import_base4.base64.decode(psbt))),
1042
1101
  { txid: vtxo.txid, vout: vtxo.vout }
1043
1102
  );
1044
1103
  } catch {
@@ -1082,11 +1141,11 @@ async function watchOfferSwaps({
1082
1141
  // src/rfq.ts
1083
1142
  var import_base8 = require("@scure/base");
1084
1143
  var import_legacy2 = require("@noble/hashes/legacy.js");
1085
- var import_sdk7 = require("@arkade-os/sdk");
1144
+ var import_sdk8 = require("@arkade-os/sdk");
1086
1145
 
1087
1146
  // src/onchainHtlc.ts
1088
1147
  var import_base5 = require("@scure/base");
1089
- var import_sha2 = require("@noble/hashes/sha2.js");
1148
+ var import_sha22 = require("@noble/hashes/sha2.js");
1090
1149
  var import_legacy = require("@noble/hashes/legacy.js");
1091
1150
  var btc = __toESM(require("@scure/btc-signer"), 1);
1092
1151
  var ONCHAIN_ORDER_MARGIN_SECONDS = 2 * 60 * 60;
@@ -1095,7 +1154,7 @@ var MAX_MIN_CONFIRMATIONS = 6;
1095
1154
  var ONCHAIN_SECONDS_PER_BLOCK = 600;
1096
1155
  var ONCHAIN_DUST_SATS = BigInt(330);
1097
1156
  var newPreimage = () => crypto.getRandomValues(new Uint8Array(32));
1098
- var paymentHashOf = (preimage) => import_base5.hex.encode((0, import_sha2.sha256)(preimage));
1157
+ var paymentHashOf = (preimage) => import_base5.hex.encode((0, import_sha22.sha256)(preimage));
1099
1158
  var h160FromPaymentHash = (paymentHash) => (0, import_legacy.ripemd160)(import_base5.hex.decode(paymentHash));
1100
1159
  var L1_NETWORKS = {
1101
1160
  bitcoin: btc.NETWORK,
@@ -1236,7 +1295,7 @@ function extractPreimage(txHex, paymentHash) {
1236
1295
  }
1237
1296
  for (const stack of raw.witnesses ?? []) {
1238
1297
  for (const item of stack) {
1239
- if (item.length === 32 && import_base5.hex.encode((0, import_sha2.sha256)(item)) === paymentHash) return item;
1298
+ if (item.length === 32 && import_base5.hex.encode((0, import_sha22.sha256)(item)) === paymentHash) return item;
1240
1299
  }
1241
1300
  }
1242
1301
  return null;
@@ -1291,13 +1350,13 @@ async function classifyOnchainHtlc(chain, input) {
1291
1350
  }
1292
1351
 
1293
1352
  // src/rfq.ts
1294
- var import_sdk8 = require("@arkade-os/sdk");
1353
+ var import_sdk9 = require("@arkade-os/sdk");
1295
1354
 
1296
1355
  // src/claimPacket.ts
1297
1356
  var import_base6 = require("@scure/base");
1298
1357
  var import_secp256k1 = require("@noble/curves/secp256k1.js");
1299
1358
  var import_hkdf = require("@noble/hashes/hkdf.js");
1300
- var import_sha22 = require("@noble/hashes/sha2.js");
1359
+ var import_sha23 = require("@noble/hashes/sha2.js");
1301
1360
  var HKDF_INFO = new TextEncoder().encode("covclaimd/preimage/v1");
1302
1361
  async function sealClaimPacket(input) {
1303
1362
  return sealWithEntropy(
@@ -1313,7 +1372,7 @@ async function sealWithEntropy(input, ephemeralKey, nonce) {
1313
1372
  }
1314
1373
  const ephemeralPub = import_secp256k1.secp256k1.getPublicKey(ephemeralKey, true);
1315
1374
  const sharedX = import_secp256k1.secp256k1.getSharedSecret(ephemeralKey, input.covclaimdPubkey, true).subarray(1);
1316
- const key = (0, import_hkdf.hkdf)(import_sha22.sha256, sharedX, ephemeralPub, HKDF_INFO, 32);
1375
+ const key = (0, import_hkdf.hkdf)(import_sha23.sha256, sharedX, ephemeralPub, HKDF_INFO, 32);
1317
1376
  if (nonce.length !== 12) throw new Error("nonce must be 12 bytes");
1318
1377
  const aesKey = await crypto.subtle.importKey("raw", key, "AES-GCM", false, [
1319
1378
  "encrypt"
@@ -1338,7 +1397,7 @@ async function sealWithEntropy(input, ephemeralKey, nonce) {
1338
1397
 
1339
1398
  // src/lockupContract.ts
1340
1399
  var import_base7 = require("@scure/base");
1341
- var import_sdk6 = require("@arkade-os/sdk");
1400
+ var import_sdk7 = require("@arkade-os/sdk");
1342
1401
  var SWAP_LOCKUP_CONTRACT_TYPE = "vhtlc-v2";
1343
1402
  var SWAP_LOCKUP_CONTRACT_LABEL = "Arkade RFQ swap lockup";
1344
1403
  var SWAP_LOCKUP_CONTRACT_KIND = "rfq-swap-lockup";
@@ -1360,7 +1419,7 @@ async function registerLockupContract(contracts, script, address) {
1360
1419
  try {
1361
1420
  await contracts.createContract({
1362
1421
  type: SWAP_LOCKUP_CONTRACT_TYPE,
1363
- params: import_sdk6.VHTLCV2ContractHandler.serializeParams(script.options),
1422
+ params: import_sdk7.VHTLCV2ContractHandler.serializeParams(script.options),
1364
1423
  script: import_base7.hex.encode(script.pkScript),
1365
1424
  address,
1366
1425
  label: SWAP_LOCKUP_CONTRACT_LABEL,
@@ -1622,27 +1681,28 @@ var relayTransport = (relayUrl, options) => {
1622
1681
  };
1623
1682
  };
1624
1683
  var SEQUENCE_GRANULARITY_SECONDS = 512;
1684
+ var SOLO_REFUND_HEADROOM_SECONDS = 8 * SEQUENCE_GRANULARITY_SECONDS;
1625
1685
  var unilateralClaimDelay = (serverExitDelaySeconds) => {
1626
1686
  if (!Number.isFinite(serverExitDelaySeconds) || serverExitDelaySeconds < SEQUENCE_GRANULARITY_SECONDS) {
1627
1687
  throw new Error(
1628
1688
  `server exit delay must be at least ${SEQUENCE_GRANULARITY_SECONDS}s of seconds, got ${serverExitDelaySeconds}`
1629
1689
  );
1630
1690
  }
1631
- if (serverExitDelaySeconds > (65535 - 2) * SEQUENCE_GRANULARITY_SECONDS) {
1691
+ if (serverExitDelaySeconds > 65535 * SEQUENCE_GRANULARITY_SECONDS - SOLO_REFUND_HEADROOM_SECONDS) {
1632
1692
  throw new Error(
1633
- `server exit delay ${serverExitDelaySeconds}s exceeds what BIP68 can encode once the two refund tiers are stacked above it`
1693
+ `server exit delay ${serverExitDelaySeconds}s exceeds what BIP68 can encode once the solo refund's headroom is stacked above it`
1634
1694
  );
1635
1695
  }
1636
1696
  return Math.ceil(serverExitDelaySeconds / SEQUENCE_GRANULARITY_SECONDS) * SEQUENCE_GRANULARITY_SECONDS;
1637
1697
  };
1638
- var unilateralRefundDelay = (claimDelay) => claimDelay + SEQUENCE_GRANULARITY_SECONDS;
1639
- var unilateralRefundWithoutReceiverDelay = (claimDelay) => claimDelay + 2 * SEQUENCE_GRANULARITY_SECONDS;
1698
+ var unilateralRefundDelay = (claimDelay) => claimDelay;
1699
+ var unilateralRefundWithoutReceiverDelay = (claimDelay) => claimDelay + SOLO_REFUND_HEADROOM_SECONDS;
1640
1700
  function lightningSendVtxoScript(params) {
1641
1701
  const seconds = (value) => ({
1642
1702
  type: "seconds",
1643
1703
  value: BigInt(value)
1644
1704
  });
1645
- return new import_sdk7.VHTLC.ScriptV2({
1705
+ return new import_sdk8.VHTLC.ScriptV2({
1646
1706
  sender: params.senderPubkey,
1647
1707
  receiver: params.solverPubkey,
1648
1708
  server: params.serverPubkey,
@@ -1665,10 +1725,10 @@ function lightningSendVtxoScript(params) {
1665
1725
  }
1666
1726
  async function requestLightningSend(wallet, arkServerUrl, transport, params) {
1667
1727
  const rfqId = params.rfqId ?? newRfqId();
1668
- const secrets = await (0, import_sdk8.provisionRefundKey)(wallet);
1728
+ const secrets = await (0, import_sdk9.provisionRefundKey)(wallet);
1669
1729
  const senderPubkey = secrets.pubkey;
1670
1730
  const [info, refundAddress] = await Promise.all([
1671
- new import_sdk7.RestArkProvider(arkServerUrl).getInfo(),
1731
+ new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
1672
1732
  wallet.getAddress()
1673
1733
  ]);
1674
1734
  const quote = await transport.requestQuote(
@@ -1692,7 +1752,7 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
1692
1752
  );
1693
1753
  }
1694
1754
  const serverPubkey = xOnly(import_base8.hex.decode(info.signerPubkey), "ark signer key");
1695
- const network = (0, import_sdk7.getNetwork)(info.network);
1755
+ const network = (0, import_sdk8.getNetwork)(info.network);
1696
1756
  const script = lightningSendVtxoScript({
1697
1757
  solverPubkey: xOnly(import_base8.hex.decode(quote.solver_pubkey), "solver key"),
1698
1758
  refundLocktime: quote.refund_locktime,
@@ -1700,12 +1760,12 @@ async function requestLightningSend(wallet, arkServerUrl, transport, params) {
1700
1760
  paymentHash: params.invoice.paymentHash,
1701
1761
  claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
1702
1762
  emulatorPubkey: xOnly(
1703
- import_base8.hex.decode((0, import_sdk7.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
1763
+ import_base8.hex.decode((0, import_sdk8.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
1704
1764
  "emulator signer key"
1705
1765
  ),
1706
1766
  senderPubkey,
1707
1767
  receiverPkScript: solverHex(receiverPkScriptHex, "profile.receiver_pk_script"),
1708
- refundPkScript: import_sdk7.ArkAddress.decode(refundAddress).pkScript
1768
+ refundPkScript: import_sdk8.ArkAddress.decode(refundAddress).pkScript
1709
1769
  });
1710
1770
  const address = script.address(network.hrp, serverPubkey).encode();
1711
1771
  verifyLockupAddress(quote, address);
@@ -1800,7 +1860,7 @@ function deriveOnchainSend(input) {
1800
1860
  emulatorPubkey: input.emulatorPubkey,
1801
1861
  senderPubkey: input.senderPubkey,
1802
1862
  receiverPkScript: solverHex(receiverPkScriptHex, "profile.receiver_pk_script"),
1803
- refundPkScript: import_sdk7.ArkAddress.decode(input.refundAddress).pkScript
1863
+ refundPkScript: import_sdk8.ArkAddress.decode(input.refundAddress).pkScript
1804
1864
  });
1805
1865
  const address = script.address(input.hrp, input.serverPubkey).encode();
1806
1866
  verifyLockupAddress(quote, address);
@@ -1826,7 +1886,7 @@ function deriveOnchainSend(input) {
1826
1886
  }
1827
1887
  async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
1828
1888
  const rfqId = params.rfqId ?? newRfqId();
1829
- const secrets = await (0, import_sdk8.provisionClaimSecret)(wallet, { preimage: params.preimage });
1889
+ const secrets = await (0, import_sdk9.provisionClaimSecret)(wallet, { preimage: params.preimage });
1830
1890
  if (secrets.mustPersistPreimage) {
1831
1891
  console.warn(
1832
1892
  "[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before funding"
@@ -1835,7 +1895,7 @@ async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
1835
1895
  const paymentHash = import_base8.hex.encode(secrets.paymentHash);
1836
1896
  const senderPubkey = secrets.pubkey;
1837
1897
  const [info, refundAddress] = await Promise.all([
1838
- new import_sdk7.RestArkProvider(arkServerUrl).getInfo(),
1898
+ new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
1839
1899
  wallet.getAddress()
1840
1900
  ]);
1841
1901
  const quote = await transport.requestQuote(
@@ -1849,14 +1909,14 @@ async function requestOnchainSend(wallet, arkServerUrl, transport, params) {
1849
1909
  amountSide: params.amountSide
1850
1910
  })
1851
1911
  );
1852
- const network = (0, import_sdk7.getNetwork)(info.network);
1912
+ const network = (0, import_sdk8.getNetwork)(info.network);
1853
1913
  const derived = deriveOnchainSend({
1854
1914
  quote,
1855
1915
  paymentHash,
1856
1916
  payoutPubkey: params.payoutPubkey,
1857
1917
  serverPubkey: xOnly(import_base8.hex.decode(info.signerPubkey), "ark signer key"),
1858
1918
  emulatorPubkey: xOnly(
1859
- import_base8.hex.decode((0, import_sdk7.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
1919
+ import_base8.hex.decode((0, import_sdk8.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
1860
1920
  "emulator signer key"
1861
1921
  ),
1862
1922
  claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
@@ -1964,7 +2024,7 @@ function receiveVtxoScript(params) {
1964
2024
  type: "seconds",
1965
2025
  value: BigInt(value)
1966
2026
  });
1967
- return new import_sdk7.VHTLC.ScriptV2({
2027
+ return new import_sdk8.VHTLC.ScriptV2({
1968
2028
  sender: params.solverPubkey,
1969
2029
  receiver: params.payoutPubkey,
1970
2030
  server: params.serverPubkey,
@@ -2003,7 +2063,7 @@ function deriveLightningReceive(input) {
2003
2063
  emulatorPubkey: input.emulatorPubkey,
2004
2064
  solverRefundPkScript: solverHex(solverRefundPkScriptHex, "profile.solver_refund_pk_script"),
2005
2065
  payoutPubkey: input.payoutPubkey,
2006
- payoutPkScript: import_sdk7.ArkAddress.decode(input.payoutAddress).pkScript
2066
+ payoutPkScript: import_sdk8.ArkAddress.decode(input.payoutAddress).pkScript
2007
2067
  });
2008
2068
  const address = script.address(input.hrp, input.serverPubkey).encode();
2009
2069
  verifyLockupAddress(quote, address);
@@ -2011,7 +2071,7 @@ function deriveLightningReceive(input) {
2011
2071
  }
2012
2072
  async function requestLightningReceive(wallet, arkServerUrl, transport, params) {
2013
2073
  const rfqId = params.rfqId ?? newRfqId();
2014
- const secrets = await (0, import_sdk8.provisionClaimSecret)(wallet);
2074
+ const secrets = await (0, import_sdk9.provisionClaimSecret)(wallet);
2015
2075
  if (secrets.mustPersistPreimage) {
2016
2076
  console.warn(
2017
2077
  "[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before paying"
@@ -2021,7 +2081,7 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
2021
2081
  const paymentHash = import_base8.hex.encode(secrets.paymentHash);
2022
2082
  const payoutPubkey = secrets.pubkey;
2023
2083
  const [info, payoutAddress] = await Promise.all([
2024
- new import_sdk7.RestArkProvider(arkServerUrl).getInfo(),
2084
+ new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
2025
2085
  wallet.getAddress()
2026
2086
  ]);
2027
2087
  const claimPacket = await sealClaimPacket({
@@ -2040,7 +2100,7 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
2040
2100
  })
2041
2101
  );
2042
2102
  assertQuotedAmount(quote, params.amountSide, params.amount);
2043
- const network = (0, import_sdk7.getNetwork)(info.network);
2103
+ const network = (0, import_sdk8.getNetwork)(info.network);
2044
2104
  const derived = deriveLightningReceive({
2045
2105
  quote,
2046
2106
  paymentHash,
@@ -2048,7 +2108,7 @@ async function requestLightningReceive(wallet, arkServerUrl, transport, params)
2048
2108
  payoutAddress,
2049
2109
  serverPubkey: xOnly(import_base8.hex.decode(info.signerPubkey), "ark signer key"),
2050
2110
  emulatorPubkey: xOnly(
2051
- import_base8.hex.decode((0, import_sdk7.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
2111
+ import_base8.hex.decode((0, import_sdk8.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
2052
2112
  "emulator signer key"
2053
2113
  ),
2054
2114
  claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
@@ -2103,7 +2163,7 @@ function deriveOnchainReceive(input) {
2103
2163
  emulatorPubkey: input.emulatorPubkey,
2104
2164
  solverRefundPkScript: solverHex(solverRefundPkScriptHex, "profile.solver_refund_pk_script"),
2105
2165
  payoutPubkey: input.payoutPubkey,
2106
- payoutPkScript: import_sdk7.ArkAddress.decode(input.payoutAddress).pkScript
2166
+ payoutPkScript: import_sdk8.ArkAddress.decode(input.payoutAddress).pkScript
2107
2167
  });
2108
2168
  const address = script.address(input.hrp, input.serverPubkey).encode();
2109
2169
  verifyLockupAddress(quote, address);
@@ -2129,7 +2189,7 @@ function deriveOnchainReceive(input) {
2129
2189
  }
2130
2190
  async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
2131
2191
  const rfqId = params.rfqId ?? newRfqId();
2132
- const secrets = await (0, import_sdk8.provisionClaimSecret)(wallet);
2192
+ const secrets = await (0, import_sdk9.provisionClaimSecret)(wallet);
2133
2193
  if (secrets.mustPersistPreimage) {
2134
2194
  console.warn(
2135
2195
  "[swap] this swap's preimage cannot be re-derived from the seed and MUST be persisted with the record before funding"
@@ -2139,7 +2199,7 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
2139
2199
  const paymentHash = import_base8.hex.encode(secrets.paymentHash);
2140
2200
  const payoutPubkey = secrets.pubkey;
2141
2201
  const [info, payoutAddress] = await Promise.all([
2142
- new import_sdk7.RestArkProvider(arkServerUrl).getInfo(),
2202
+ new import_sdk8.RestArkProvider(arkServerUrl).getInfo(),
2143
2203
  wallet.getAddress()
2144
2204
  ]);
2145
2205
  const claimPacket = await sealClaimPacket({
@@ -2159,7 +2219,7 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
2159
2219
  })
2160
2220
  );
2161
2221
  assertQuotedAmount(quote, params.amountSide, params.amount);
2162
- const network = (0, import_sdk7.getNetwork)(info.network);
2222
+ const network = (0, import_sdk8.getNetwork)(info.network);
2163
2223
  const derived = deriveOnchainReceive({
2164
2224
  quote,
2165
2225
  paymentHash,
@@ -2168,7 +2228,7 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
2168
2228
  refundPubkey: params.refundPubkey,
2169
2229
  serverPubkey: xOnly(import_base8.hex.decode(info.signerPubkey), "ark signer key"),
2170
2230
  emulatorPubkey: xOnly(
2171
- import_base8.hex.decode((0, import_sdk7.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
2231
+ import_base8.hex.decode((0, import_sdk8.resolveEmulatorPubkey)(network, params.emulatorPubkey)),
2172
2232
  "emulator signer key"
2173
2233
  ),
2174
2234
  claimDelay: unilateralClaimDelay(Number(info.unilateralExitDelay)),
@@ -2207,13 +2267,13 @@ async function requestOnchainReceive(wallet, arkServerUrl, transport, params) {
2207
2267
  // src/claim.ts
2208
2268
  var import_base10 = require("@scure/base");
2209
2269
  var import_legacy3 = require("@noble/hashes/legacy.js");
2210
- var import_sha24 = require("@noble/hashes/sha2.js");
2211
- var import_sdk10 = require("@arkade-os/sdk");
2270
+ var import_sha25 = require("@noble/hashes/sha2.js");
2271
+ var import_sdk11 = require("@arkade-os/sdk");
2212
2272
 
2213
2273
  // src/refund.ts
2214
2274
  var import_base9 = require("@scure/base");
2215
- var import_sha23 = require("@noble/hashes/sha2.js");
2216
- var import_sdk9 = require("@arkade-os/sdk");
2275
+ var import_sha24 = require("@noble/hashes/sha2.js");
2276
+ var import_sdk10 = require("@arkade-os/sdk");
2217
2277
  var sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2218
2278
  var isRfqTerminal = (state) => RFQ_TERMINAL_STATES.includes(state);
2219
2279
  var RFQ_RESOLVED_STATES = ["settled", "refunded"];
@@ -2285,9 +2345,9 @@ async function findLockupVtxos(indexer, swapPkScript) {
2285
2345
  }
2286
2346
  return out;
2287
2347
  }
2288
- var hashesTo = (candidate, paymentHash) => import_base9.hex.encode((0, import_sha23.sha256)(candidate)) === paymentHash;
2348
+ var hashesTo = (candidate, paymentHash) => import_base9.hex.encode((0, import_sha24.sha256)(candidate)) === paymentHash;
2289
2349
  var candidateWitnessItems = (tx, inputIndex) => [
2290
- ...(0, import_sdk9.getArkPsbtFields)(tx, inputIndex, import_sdk9.ConditionWitness).flat(),
2350
+ ...(0, import_sdk10.getArkPsbtFields)(tx, inputIndex, import_sdk10.ConditionWitness).flat(),
2291
2351
  ...tx.getInput(inputIndex).finalScriptWitness ?? []
2292
2352
  ];
2293
2353
  async function readLockupFate(indexer, input) {
@@ -2306,7 +2366,7 @@ async function readLockupFate(indexer, input) {
2306
2366
  for (const raw of txs) {
2307
2367
  let tx;
2308
2368
  try {
2309
- tx = import_sdk9.Transaction.fromPSBT(import_base9.base64.decode(raw));
2369
+ tx = import_sdk10.Transaction.fromPSBT(import_base9.base64.decode(raw));
2310
2370
  } catch {
2311
2371
  continue;
2312
2372
  }
@@ -2343,14 +2403,14 @@ async function pushRefundWithoutReceiver(ark, input) {
2343
2403
  const info = await ark.getInfo();
2344
2404
  let serverUnrollScript;
2345
2405
  try {
2346
- serverUnrollScript = import_sdk9.CSVMultisigTapscript.decode(import_base9.hex.decode(info.checkpointTapscript));
2406
+ serverUnrollScript = import_sdk10.CSVMultisigTapscript.decode(import_base9.hex.decode(info.checkpointTapscript));
2347
2407
  } catch {
2348
2408
  throw new Error("invalid checkpointTapscript from the Arkade server");
2349
2409
  }
2350
2410
  const leaf = input.script.refundWithoutReceiver();
2351
2411
  const tapTree = input.script.encode();
2352
2412
  const amount = input.vtxos.reduce((sum, vtxo) => sum + vtxo.value, 0);
2353
- const { arkTx, checkpoints } = (0, import_sdk9.buildOffchainTx)(
2413
+ const { arkTx, checkpoints } = (0, import_sdk10.buildOffchainTx)(
2354
2414
  input.vtxos.map((vtxo) => ({
2355
2415
  txid: vtxo.txid,
2356
2416
  vout: vtxo.vout,
@@ -2366,8 +2426,8 @@ async function pushRefundWithoutReceiver(ark, input) {
2366
2426
  import_base9.base64.encode(signedArkTx.toPSBT()),
2367
2427
  checkpoints.map((c) => import_base9.base64.encode(c.toPSBT()))
2368
2428
  );
2369
- (0, import_sdk9.assertSubmittedArkTxid)(submitted, signedArkTx, "refundWithoutReceiver");
2370
- const matched = (0, import_sdk9.matchServerCheckpoints)(
2429
+ (0, import_sdk10.assertSubmittedArkTxid)(submitted, signedArkTx, "refundWithoutReceiver");
2430
+ const matched = (0, import_sdk10.matchServerCheckpoints)(
2371
2431
  submitted.signedCheckpointTxs,
2372
2432
  checkpoints,
2373
2433
  "refundWithoutReceiver"
@@ -2454,20 +2514,20 @@ async function pushClaim(ark, input) {
2454
2514
  }
2455
2515
  }
2456
2516
  const committed = input.script.options.preimageHash;
2457
- if (import_base10.hex.encode((0, import_legacy3.ripemd160)((0, import_sha24.sha256)(input.preimage))) !== import_base10.hex.encode(committed)) {
2517
+ if (import_base10.hex.encode((0, import_legacy3.ripemd160)((0, import_sha25.sha256)(input.preimage))) !== import_base10.hex.encode(committed)) {
2458
2518
  throw new Error("preimage does not match the covenant's payment hash");
2459
2519
  }
2460
2520
  const info = await ark.getInfo();
2461
2521
  let serverUnrollScript;
2462
2522
  try {
2463
- serverUnrollScript = import_sdk10.CSVMultisigTapscript.decode(import_base10.hex.decode(info.checkpointTapscript));
2523
+ serverUnrollScript = import_sdk11.CSVMultisigTapscript.decode(import_base10.hex.decode(info.checkpointTapscript));
2464
2524
  } catch {
2465
2525
  throw new Error("invalid checkpointTapscript from the Arkade server");
2466
2526
  }
2467
2527
  const leaf = input.script.claim();
2468
2528
  const tapTree = input.script.encode();
2469
- const arkTxid = await (0, import_sdk10.signAndSubmitOffchainTx)({
2470
- identity: (0, import_sdk10.claimWithPreimageIdentity)(input.receiver, input.preimage),
2529
+ const arkTxid = await (0, import_sdk11.signAndSubmitOffchainTx)({
2530
+ identity: (0, import_sdk11.claimWithPreimageIdentity)(input.receiver, input.preimage),
2471
2531
  provider: ark,
2472
2532
  inputs: input.vtxos.map((vtxo) => ({
2473
2533
  txid: vtxo.txid,
@@ -2514,7 +2574,7 @@ async function claimReceiveLockup(indexer, ark, input) {
2514
2574
  }
2515
2575
 
2516
2576
  // src/refundBlocked.ts
2517
- var import_sdk11 = require("@arkade-os/sdk");
2577
+ var import_sdk12 = require("@arkade-os/sdk");
2518
2578
  var RefundNotLocallyPossibleError = class extends Error {
2519
2579
  constructor(reason, message, options) {
2520
2580
  super(message, options);
@@ -2531,16 +2591,16 @@ async function senderIdentityForSwapRecord(wallet, record) {
2531
2591
  );
2532
2592
  }
2533
2593
  try {
2534
- return await (0, import_sdk11.contractSigner)(wallet, record.signingDescriptor);
2594
+ return await (0, import_sdk12.contractSigner)(wallet, record.signingDescriptor);
2535
2595
  } catch (cause) {
2536
- if (cause instanceof import_sdk11.WalletCannotSignError) {
2596
+ if (cause instanceof import_sdk12.WalletCannotSignError) {
2537
2597
  throw new RefundNotLocallyPossibleError(
2538
2598
  "unsignable-wallet",
2539
2599
  `this wallet holds ${record.signingDescriptor} but cannot sign with it; attach its signer`,
2540
2600
  { cause }
2541
2601
  );
2542
2602
  }
2543
- if (cause instanceof import_sdk11.ForeignDescriptorError) {
2603
+ if (cause instanceof import_sdk12.ForeignDescriptorError) {
2544
2604
  throw new RefundNotLocallyPossibleError(
2545
2605
  "foreign-descriptor",
2546
2606
  `this wallet cannot derive ${record.signingDescriptor}; the swap was created on another wallet`,
@@ -3317,6 +3377,60 @@ var outcomeOf = (swap) => {
3317
3377
  };
3318
3378
  var errorMessage = (error) => error instanceof Error ? error.message : String(error);
3319
3379
  var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
3380
+
3381
+ // src/activity.ts
3382
+ var LABELS = {
3383
+ lightning_send: "Lightning send",
3384
+ lightning_receive: "Lightning receive",
3385
+ onchain_send: "Onchain send"
3386
+ };
3387
+ var OUTCOME = {
3388
+ pending: "pending",
3389
+ // `claimable` and `claimed` are both in-progress states with no
3390
+ // user-visible phase distinct from "pending". `needs_counterparty` is
3391
+ // different in kind — the swap is BLOCKED, not merely in flight, since no
3392
+ // unilateral trader move exists (see `RfqSwapState`). Collapsing it into
3393
+ // `pending` here is a deliberate choice the opaque-token design permits —
3394
+ // apps map tokens themselves — but a future reader weighing a `"blocked"`
3395
+ // or `"stuck"` token should know this was already considered.
3396
+ claimable: "pending",
3397
+ claimed: "pending",
3398
+ needs_counterparty: "pending",
3399
+ settled: "settled",
3400
+ refunded: "refunded",
3401
+ failed: "failed"
3402
+ };
3403
+ function swapActivityResolver(deps) {
3404
+ let byTxid = /* @__PURE__ */ new Map();
3405
+ return {
3406
+ id: "arkade:swap",
3407
+ async prepare() {
3408
+ const swaps = await deps.listSwaps();
3409
+ const index = /* @__PURE__ */ new Map();
3410
+ for (const swap of swaps) {
3411
+ for (const txid of swap.txids) {
3412
+ if (txid) index.set(txid, swap);
3413
+ }
3414
+ }
3415
+ byTxid = index;
3416
+ },
3417
+ resolve(tx) {
3418
+ const key = tx.key.arkTxid || tx.key.commitmentTxid || tx.key.boardingTxid;
3419
+ const swap = key ? byTxid.get(key) : void 0;
3420
+ if (!swap) return void 0;
3421
+ const lostReceive = swap.kind === "lightning_receive" && swap.state === "refunded";
3422
+ return [
3423
+ {
3424
+ groupId: `swap:${swap.rfqId}`,
3425
+ label: LABELS[swap.kind],
3426
+ kind: "swap",
3427
+ outcome: lostReceive ? "lost" : OUTCOME[swap.state],
3428
+ metadata: { rfqId: swap.rfqId, swapKind: swap.kind }
3429
+ }
3430
+ ];
3431
+ }
3432
+ };
3433
+ }
3320
3434
  // Annotate the CommonJS export names for ESM import in node:
3321
3435
  0 && (module.exports = {
3322
3436
  ARKADE_ASSET,
@@ -3342,6 +3456,7 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
3342
3456
  ONCHAIN_RECEIVE_PAIR,
3343
3457
  ONCHAIN_SECONDS_PER_BLOCK,
3344
3458
  ONCHAIN_SEND_PAIR,
3459
+ PreimageNotRecoverableError,
3345
3460
  QUOTE_OPTIONS,
3346
3461
  REFUND_MTP_LAG_SECONDS,
3347
3462
  RFQ_RESOLVED_STATES,
@@ -3349,6 +3464,7 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
3349
3464
  RFQ_TERMINAL_STATES,
3350
3465
  RefundNotLocallyPossibleError,
3351
3466
  RfqSwapManager,
3467
+ SOLO_REFUND_HEADROOM_SECONDS,
3352
3468
  SWAP_LOCKUP_CONTRACT_KIND,
3353
3469
  SWAP_LOCKUP_CONTRACT_LABEL,
3354
3470
  SWAP_LOCKUP_CONTRACT_TYPE,
@@ -3396,6 +3512,7 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
3396
3512
  onchainReceiveRequest,
3397
3513
  onchainSendRequest,
3398
3514
  paymentHashOf,
3515
+ preimageForSwapRecord,
3399
3516
  pushClaim,
3400
3517
  pushRefundWithoutReceiver,
3401
3518
  readLockupFate,
@@ -3414,6 +3531,7 @@ var outpointKey = (vtxo) => `${vtxo.txid}:${vtxo.vout}`;
3414
3531
  senderIdentityForSwapRecord,
3415
3532
  spendTxidsOf,
3416
3533
  spendUpdate,
3534
+ swapActivityResolver,
3417
3535
  swapPrograms,
3418
3536
  swapSecretsToRecord,
3419
3537
  unilateralClaimDelay,