@satora/swap 1.6.1 → 1.7.0

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
@@ -1733,6 +1733,11 @@ var SwapWorker = class {
1733
1733
  #executing = /* @__PURE__ */ new Set();
1734
1734
  /** Swaps with a scheduled auto-claim retry (backoff timer + attempt count). */
1735
1735
  #retries = /* @__PURE__ */ new Map();
1736
+ /**
1737
+ * Swaps whose claim needs the user's wallet (RIF Relay): handed to
1738
+ * `onActionRequired` once and not auto-run while the claim is recommended.
1739
+ */
1740
+ #needsUser = /* @__PURE__ */ new Set();
1736
1741
  #unsubs = [];
1737
1742
  #started = false;
1738
1743
  constructor(options) {
@@ -1775,6 +1780,7 @@ var SwapWorker = class {
1775
1780
  this.#hintSource.stop();
1776
1781
  for (const { timer } of this.#retries.values()) clearTimeout(timer);
1777
1782
  this.#retries.clear();
1783
+ this.#needsUser.clear();
1778
1784
  this.#executing.clear();
1779
1785
  }
1780
1786
  /** Chain-reconcile every tracked swap (the post-outage catch-up sweep). */
@@ -1797,9 +1803,11 @@ var SwapWorker = class {
1797
1803
  }
1798
1804
  this.#hintSource.subscribe([swapId]);
1799
1805
  if (recommended && AUTO_EXECUTABLE.has(recommended) && this.#execute) {
1806
+ if (this.#needsUser.has(swapId)) return;
1800
1807
  this.#autoExecute(swapId, actions);
1801
1808
  return;
1802
1809
  }
1810
+ this.#needsUser.delete(swapId);
1803
1811
  this.#cancelRetry(swapId);
1804
1812
  if (!recommended) return;
1805
1813
  const automation = actions.actions.find(
@@ -1816,6 +1824,12 @@ var SwapWorker = class {
1816
1824
  if (!actionId) return;
1817
1825
  this.#executing.add(swapId);
1818
1826
  void execute(swapId, actionId).then(() => this.#cancelRetry(swapId)).catch((error) => {
1827
+ if (needsWallet(error)) {
1828
+ this.#cancelRetry(swapId);
1829
+ this.#needsUser.add(swapId);
1830
+ this.#onActionRequired?.(swapId, actions);
1831
+ return;
1832
+ }
1819
1833
  console.warn(`SwapWorker: ${actionId}(${swapId}) failed:`, error);
1820
1834
  this.#scheduleRetry(swapId, actions);
1821
1835
  }).finally(() => this.#executing.delete(swapId));
@@ -1863,6 +1877,9 @@ var SwapWorker = class {
1863
1877
  if (existing) clearTimeout(existing.timer);
1864
1878
  }
1865
1879
  };
1880
+ function needsWallet(error) {
1881
+ return error instanceof Error && error.name === "WalletClaimRequiredError";
1882
+ }
1866
1883
 
1867
1884
  // src/hints/ws-status-source.ts
1868
1885
  var MAX_ARGS_PER_FRAME = 64;
@@ -2108,6 +2125,12 @@ function buildArkadeVhtlcRef(input) {
2108
2125
 
2109
2126
  // src/tracker/from-swap.ts
2110
2127
  var ms = (seconds2) => seconds2 * 1e3;
2128
+ var ONCHAIN_CLAIM_MARGIN_SECONDS = 30 * 60;
2129
+ function onchainClaimDeadline(refundLocktime, network) {
2130
+ const net = network?.toLowerCase();
2131
+ const mainnet = net === "bitcoin" || net === "mainnet";
2132
+ return ms(refundLocktime - (mainnet ? ONCHAIN_CLAIM_MARGIN_SECONDS : 0));
2133
+ }
2111
2134
  var MAINNET_LOCKED_TOKEN = {
2112
2135
  1: "0x18084fba666a33d37592fa2633fd49a74dd93a88",
2113
2136
  // tBTC
@@ -2382,6 +2405,37 @@ function swapToTracked(stored) {
2382
2405
  serverRefundLocktime: 0
2383
2406
  // no on-chain server leg
2384
2407
  };
2408
+ // The user's payment is held off-chain; the server funds the BTC HTLC
2409
+ // the client claims.
2410
+ case "lightning_to_bitcoin":
2411
+ return {
2412
+ swapId: r.id,
2413
+ serverHtlc: bitcoinLeg(
2414
+ r.btc_htlc_address,
2415
+ r.hash_lock,
2416
+ Number(r.target_amount)
2417
+ ),
2418
+ clientRefundLocktime: 0,
2419
+ // no on-chain client leg
2420
+ serverRefundLocktime: onchainClaimDeadline(
2421
+ r.btc_refund_locktime,
2422
+ r.network
2423
+ )
2424
+ };
2425
+ // Client funds the BTC HTLC; the server pays the invoice and sweeps it.
2426
+ case "bitcoin_to_lightning":
2427
+ return {
2428
+ swapId: r.id,
2429
+ clientHtlc: bitcoinLeg(
2430
+ r.btc_htlc_address,
2431
+ r.hash_lock,
2432
+ Number(r.source_amount),
2433
+ CLIENT_FUNDING_MIN_CONFIRMATIONS
2434
+ ),
2435
+ clientRefundLocktime: ms(r.btc_refund_locktime),
2436
+ serverRefundLocktime: 0
2437
+ // no on-chain server leg
2438
+ };
2385
2439
  default:
2386
2440
  return void 0;
2387
2441
  }
@@ -2877,6 +2931,10 @@ var Client = class {
2877
2931
  return this.#legacy.getChainConfig(...args);
2878
2932
  }
2879
2933
  /** Delegated to the legacy client (migration checkpoint). */
2934
+ getRifRelay(...args) {
2935
+ return this.#legacy.getRifRelay(...args);
2936
+ }
2937
+ /** Delegated to the legacy client (migration checkpoint). */
2880
2938
  getReferralFee(...args) {
2881
2939
  return this.#legacy.getReferralFee(...args);
2882
2940
  }
@@ -3013,6 +3071,18 @@ var Client = class {
3013
3071
  );
3014
3072
  }
3015
3073
  /** Delegated to the legacy client (migration checkpoint). */
3074
+ createLightningToBitcoinSwap(...args) {
3075
+ return this.#trackAfterCreate(
3076
+ this.#legacy.createLightningToBitcoinSwap(...args)
3077
+ );
3078
+ }
3079
+ /** Delegated to the legacy client (migration checkpoint). */
3080
+ createBitcoinToLightningSwap(...args) {
3081
+ return this.#trackAfterCreate(
3082
+ this.#legacy.createBitcoinToLightningSwap(...args)
3083
+ );
3084
+ }
3085
+ /** Delegated to the legacy client (migration checkpoint). */
3016
3086
  createEvmToLightningSwap(...args) {
3017
3087
  return this.#trackAfterCreate(
3018
3088
  this.#legacy.createEvmToLightningSwap(...args)
@@ -3041,10 +3111,22 @@ var Client = class {
3041
3111
  return this.#legacy.fundSwap(...args);
3042
3112
  }
3043
3113
  /** Delegated to the legacy client (migration checkpoint). */
3114
+ fundSwapFromSolana(...args) {
3115
+ return this.#legacy.fundSwapFromSolana(...args);
3116
+ }
3117
+ /** Delegated to the legacy client (migration checkpoint). */
3118
+ getSolanaUsdcBalance(...args) {
3119
+ return this.#legacy.getSolanaUsdcBalance(...args);
3120
+ }
3121
+ /** Delegated to the legacy client (migration checkpoint). */
3044
3122
  refundEvmWithSigner(...args) {
3045
3123
  return this.#legacy.refundEvmWithSigner(...args);
3046
3124
  }
3047
3125
  /** Delegated to the legacy client (migration checkpoint). */
3126
+ refundEvmSponsored(...args) {
3127
+ return this.#legacy.refundEvmSponsored(...args);
3128
+ }
3129
+ /** Delegated to the legacy client (migration checkpoint). */
3048
3130
  collabRefundEvmWithSigner(...args) {
3049
3131
  return this.#legacy.collabRefundEvmWithSigner(...args);
3050
3132
  }
@@ -3069,6 +3151,10 @@ var Client = class {
3069
3151
  return this.#trackAfterRetry(this.#legacy.continueRefundedEvmSwap(...args));
3070
3152
  }
3071
3153
  /** Delegated to the legacy client (migration checkpoint). */
3154
+ recoverCctpInboundSwap(...args) {
3155
+ return this.#legacy.recoverCctpInboundSwap(...args);
3156
+ }
3157
+ /** Delegated to the legacy client (migration checkpoint). */
3072
3158
  recoverGaslessFunds(...args) {
3073
3159
  return this.#legacy.recoverGaslessFunds(...args);
3074
3160
  }
@@ -3497,6 +3583,10 @@ var ClientBuilder = class {
3497
3583
  this.#inner.withAa(...args);
3498
3584
  return this;
3499
3585
  }
3586
+ withSolanaRpcUrl(...args) {
3587
+ this.#inner.withSolanaRpcUrl(...args);
3588
+ return this;
3589
+ }
3500
3590
  withLogger(...args) {
3501
3591
  this.#inner.withLogger(...args);
3502
3592
  return this;