@owney/sdk 0.7.26-beta.4 → 0.7.26-beta.5

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.js CHANGED
@@ -2298,7 +2298,8 @@ function createSwapApi(baseUrl, apiKey) {
2298
2298
  // Omitted, the routing API searches every supported chain — which is
2299
2299
  // what a picker wants, since its rows already span all three.
2300
2300
  ...params.chainId === void 0 ? {} : { chainId: String(params.chainId) },
2301
- ...params.limit === void 0 ? {} : { limit: String(params.limit) }
2301
+ ...params.limit === void 0 ? {} : { limit: String(params.limit) },
2302
+ ...params.direction === void 0 ? {} : { direction: params.direction }
2302
2303
  }).toString()}`
2303
2304
  ),
2304
2305
  /**
@@ -2384,12 +2385,41 @@ function createSwapApi(baseUrl, apiKey) {
2384
2385
  // src/lib/swap/swap.rpc.ts
2385
2386
  import { fallback, http as http2 } from "viem";
2386
2387
  var DEFAULT_RPC_URLS = {
2387
- 1: ["https://cloudflare-eth.com", "https://ethereum-rpc.publicnode.com"],
2388
+ // NOT cloudflare-eth.com, which used to lead this list. It answers
2389
+ // eth_chainId happily, errors on eth_blockNumber, and — the part that
2390
+ // actually broke things — returns `result: null` for the receipt of a
2391
+ // transaction that is demonstrably mined. Null is a VALID answer meaning
2392
+ // "not found", so viem's fallback has no reason to try the next endpoint:
2393
+ // waitForTransactionReceipt simply polls until it times out, which on this
2394
+ // chain is ten minutes of a spinner (ROUT-242). An endpoint that ERRORS is
2395
+ // safe; an endpoint that lies quietly is not.
2396
+ 1: ["https://ethereum-rpc.publicnode.com", "https://eth.drpc.org"],
2388
2397
  8453: ["https://mainnet.base.org", "https://base-rpc.publicnode.com"],
2389
2398
  42161: [
2390
2399
  "https://arb1.arbitrum.io/rpc",
2391
2400
  "https://arbitrum-one-rpc.publicnode.com"
2392
- ]
2401
+ ],
2402
+ // Added with the wider swap chain set (ROUT-242, comment 15982). Every one
2403
+ // of these answered with `access-control-allow-origin: *` on 2026-09-29;
2404
+ // a chain without two verified endpoints does not belong in the list.
2405
+ 10: ["https://mainnet.optimism.io", "https://optimism-rpc.publicnode.com"],
2406
+ // polygon-rpc.com led this list until it started answering every call with
2407
+ // "API key disabled, reason: tenant disabled". It errors rather than lying,
2408
+ // so the fallback did cover it — at the cost of a failed request in front of
2409
+ // every Polygon read.
2410
+ 137: ["https://polygon-bor-rpc.publicnode.com", "https://polygon.drpc.org"],
2411
+ 56: ["https://bsc-dataseed.bnbchain.org", "https://bsc-rpc.publicnode.com"],
2412
+ 43114: [
2413
+ "https://api.avax.network/ext/bc/C/rpc",
2414
+ "https://avalanche-c-chain-rpc.publicnode.com"
2415
+ ],
2416
+ 143: ["https://rpc.monad.xyz", "https://rpc1.monad.xyz"],
2417
+ // ONE endpoint, not two: of the six the public chain registry lists for Arc,
2418
+ // this is the only one that answers a browser at all. viem ships none. It
2419
+ // was checked with a real eth_chainId call (0x13b2), not just a CORS header,
2420
+ // but a single provider is a single point of failure - add a second when one
2421
+ // exists.
2422
+ 5042: ["https://rpc.beamrpc.com"]
2393
2423
  };
2394
2424
  function swapReadTransport(chainId, overrides) {
2395
2425
  const override = overrides?.[chainId];
@@ -2402,6 +2432,167 @@ function receiptTimeoutMs(chainId) {
2402
2432
  return chainId === 1 ? 6e5 : 18e4;
2403
2433
  }
2404
2434
 
2435
+ // src/lib/swap/swap.wrap.ts
2436
+ var WRAP_SELECTOR = "0xd0e30db0";
2437
+ var FALLBACK_WRAP_GAS = 50000n;
2438
+ var APPROVE_GAS = 60000n;
2439
+ var GAS_SAFETY = 2n;
2440
+ var MIN_WALLET_GAS_PRICE = 3000000000n;
2441
+ async function wrapNative(deps, options) {
2442
+ const { chainId, wrapper, nativeSymbol, requested } = options;
2443
+ const balance = await deps.readNativeBalance();
2444
+ let wrapGas;
2445
+ try {
2446
+ wrapGas = await deps.estimateWrapGas(wrapper, requested);
2447
+ } catch (error) {
2448
+ wrapGas = FALLBACK_WRAP_GAS;
2449
+ debugLog("owney-sdk", "wrap: gas estimate failed, using the fallback", {
2450
+ fallback: FALLBACK_WRAP_GAS.toString(),
2451
+ message: error instanceof Error ? error.message : String(error)
2452
+ });
2453
+ }
2454
+ const measured = await deps.getMaxFeePerGas();
2455
+ const gasPrice = measured > MIN_WALLET_GAS_PRICE ? measured : MIN_WALLET_GAS_PRICE;
2456
+ const reserve = (wrapGas + APPROVE_GAS) * gasPrice * GAS_SAFETY;
2457
+ const spendable = balance > reserve ? balance - reserve : 0n;
2458
+ const wrapped = requested < spendable ? requested : spendable;
2459
+ debugLog("owney-sdk", "wrap: sizing", {
2460
+ balance: balance.toString(),
2461
+ requested: requested.toString(),
2462
+ measuredGasPrice: measured.toString(),
2463
+ reservedAtGasPrice: gasPrice.toString(),
2464
+ reserve: reserve.toString(),
2465
+ wrapped: wrapped.toString()
2466
+ });
2467
+ if (wrapped <= 0n) {
2468
+ throw new OwneyError(
2469
+ "SWAP_INSUFFICIENT_GAS",
2470
+ `Not enough ${nativeSymbol} to cover both the swap and its network fees. Leave a little ${nativeSymbol} for gas, or swap a smaller amount.`,
2471
+ {
2472
+ chainId,
2473
+ // Named in the details as well as the message so the app's own copy
2474
+ // can say "leave a little POL" rather than re-deriving it.
2475
+ symbol: nativeSymbol,
2476
+ balance: balance.toString(),
2477
+ requested: requested.toString(),
2478
+ reserve: reserve.toString()
2479
+ }
2480
+ );
2481
+ }
2482
+ await deps.ensureChain(chainId);
2483
+ debugLog("owney-sdk", "wrap: sending deposit()", {
2484
+ wrapper,
2485
+ value: wrapped.toString()
2486
+ });
2487
+ const txHash = await deps.sendTransaction(
2488
+ { to: wrapper, data: WRAP_SELECTOR, value: wrapped.toString() },
2489
+ options.onSubmitted
2490
+ );
2491
+ return { wrapped, txHash };
2492
+ }
2493
+ function requireWrapper(quote) {
2494
+ const wrapper = quote.wrappedNative;
2495
+ if (!wrapper?.address) {
2496
+ throw new OwneyError(
2497
+ "SWAP_NATIVE_UNSUPPORTED",
2498
+ `Swapping ${quote.src.symbol} from this chain to another isn't supported yet. Swap a token instead, or move to the destination chain first.`,
2499
+ { chainId: quote.src.chainId, symbol: quote.src.symbol }
2500
+ );
2501
+ }
2502
+ return { symbol: wrapper.symbol, address: wrapper.address };
2503
+ }
2504
+
2505
+ // src/lib/swap/swap.chains.ts
2506
+ import {
2507
+ arbitrum as arbitrum2,
2508
+ arc,
2509
+ avalanche,
2510
+ base as base2,
2511
+ bsc,
2512
+ mainnet as mainnet2,
2513
+ monad,
2514
+ optimism,
2515
+ polygon
2516
+ } from "viem/chains";
2517
+ var CHAINS = {
2518
+ 8453: base2,
2519
+ 42161: arbitrum2,
2520
+ 1: mainnet2,
2521
+ 10: optimism,
2522
+ 137: polygon,
2523
+ 56: bsc,
2524
+ 43114: avalanche,
2525
+ 143: monad,
2526
+ 5042: arc
2527
+ };
2528
+ var SWAP_CHAIN_IDS = Object.keys(CHAINS).map(Number);
2529
+ function swapChain(chainId) {
2530
+ return CHAINS[chainId];
2531
+ }
2532
+
2533
+ // src/lib/swap/swap.arrival.ts
2534
+ var DEFAULT_TIMEOUT_MS = 18e4;
2535
+ var DEFAULT_POLL_MS = 4e3;
2536
+ var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
2537
+ async function awaitWithdrawalArrival(options) {
2538
+ const { arrived, lastReadError } = await awaitBalanceIncrease(options);
2539
+ if (arrived !== null) return arrived;
2540
+ throw new OwneyError(
2541
+ "WITHDRAW_ARRIVAL_TIMEOUT",
2542
+ "The withdrawal was accepted but the funds had not arrived in time to swap them. They are on their way to your wallet in the original asset.",
2543
+ {
2544
+ baseline: options.baseline.toString(),
2545
+ waitedMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
2546
+ ...lastReadError ? { lastReadError } : {}
2547
+ }
2548
+ );
2549
+ }
2550
+ async function awaitBalanceIncrease(options) {
2551
+ const {
2552
+ readBalance,
2553
+ baseline,
2554
+ timeoutMs = DEFAULT_TIMEOUT_MS,
2555
+ pollMs = DEFAULT_POLL_MS
2556
+ } = options;
2557
+ const deadline = Date.now() + timeoutMs;
2558
+ debugLog("owney-sdk", "arrival: waiting for funds to land", {
2559
+ baseline: baseline.toString(),
2560
+ timeoutMs
2561
+ });
2562
+ let lastError;
2563
+ for (; ; ) {
2564
+ try {
2565
+ const balance = await readBalance();
2566
+ if (balance > baseline) {
2567
+ const arrived = balance - baseline;
2568
+ debugLog("owney-sdk", "arrival: funds landed", {
2569
+ arrived: arrived.toString()
2570
+ });
2571
+ return { arrived };
2572
+ }
2573
+ } catch (error) {
2574
+ lastError = error;
2575
+ debugLog("owney-sdk", "arrival: balance read failed, retrying", {
2576
+ message: error instanceof Error ? error.message : String(error)
2577
+ });
2578
+ }
2579
+ if (Date.now() >= deadline) {
2580
+ debugLog("owney-sdk", "arrival: nothing landed before the deadline", {
2581
+ baseline: baseline.toString(),
2582
+ waitedMs: timeoutMs,
2583
+ ...lastError ? {
2584
+ lastReadError: lastError instanceof Error ? lastError.message : String(lastError)
2585
+ } : {}
2586
+ });
2587
+ return lastError ? {
2588
+ arrived: null,
2589
+ lastReadError: lastError instanceof Error ? lastError.message : String(lastError)
2590
+ } : { arrived: null };
2591
+ }
2592
+ await sleep(pollMs);
2593
+ }
2594
+ }
2595
+
2405
2596
  // src/lib/permit2.ts
2406
2597
  import { bytesToHex } from "viem";
2407
2598
  var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
@@ -2525,17 +2716,17 @@ var SWAP_TERMINAL_STATUSES = [
2525
2716
  var isSwapTerminal = (status) => SWAP_TERMINAL_STATUSES.includes(status);
2526
2717
 
2527
2718
  // src/lib/swap/swap.order-runner.ts
2528
- var DEFAULT_POLL_MS = 5e3;
2719
+ var DEFAULT_POLL_MS2 = 5e3;
2529
2720
  var MAX_BACKOFF_MS = 3e4;
2530
- var backoffFor = (failures, base3) => Math.min(base3 * 2 ** Math.min(failures, 5), MAX_BACKOFF_MS);
2531
- var DEFAULT_TIMEOUT_MS = 15 * 60 * 1e3;
2721
+ var backoffFor = (failures, base4) => Math.min(base4 * 2 ** Math.min(failures, 5), MAX_BACKOFF_MS);
2722
+ var DEFAULT_TIMEOUT_MS2 = 15 * 60 * 1e3;
2532
2723
  async function runFusionOrder(deps, options) {
2533
2724
  const {
2534
2725
  orderHash,
2535
2726
  secrets,
2536
2727
  onStage,
2537
- pollIntervalMs = DEFAULT_POLL_MS,
2538
- timeoutMs = DEFAULT_TIMEOUT_MS
2728
+ pollIntervalMs = DEFAULT_POLL_MS2,
2729
+ timeoutMs = DEFAULT_TIMEOUT_MS2
2539
2730
  } = options;
2540
2731
  const deadline = deps.now() + timeoutMs;
2541
2732
  let failures = 0;
@@ -2546,7 +2737,11 @@ async function runFusionOrder(deps, options) {
2546
2737
  throw new OwneyError(
2547
2738
  "SWAP_REQUEST_FAILED",
2548
2739
  "Timed out waiting for the swap to settle. It may still complete \u2014 check the order status before retrying.",
2549
- { orderHash }
2740
+ // Marks the one failure that means "we stopped watching a live order",
2741
+ // as opposed to a verdict or a prompt nobody answered. The executor
2742
+ // checks the wallet before believing it: resolvers do not stop filling
2743
+ // because we stopped looking (ROUT-242, comment 15980).
2744
+ { orderHash, settlementUnconfirmed: true }
2550
2745
  );
2551
2746
  }
2552
2747
  let ready;
@@ -2599,10 +2794,10 @@ async function runFusionOrder(deps, options) {
2599
2794
  }
2600
2795
 
2601
2796
  // src/lib/swap/swap.same-chain-runner.ts
2602
- var DEFAULT_POLL_MS2 = 5e3;
2797
+ var DEFAULT_POLL_MS3 = 5e3;
2603
2798
  var MAX_BACKOFF_MS2 = 3e4;
2604
- var backoffFor2 = (failures, base3) => Math.min(base3 * 2 ** Math.min(failures, 5), MAX_BACKOFF_MS2);
2605
- var DEFAULT_TIMEOUT_MS2 = 3 * 60 * 1e3;
2799
+ var backoffFor2 = (failures, base4) => Math.min(base4 * 2 ** Math.min(failures, 5), MAX_BACKOFF_MS2);
2800
+ var DEFAULT_TIMEOUT_MS3 = 3 * 60 * 1e3;
2606
2801
  function explain(status) {
2607
2802
  switch (status) {
2608
2803
  case "expired":
@@ -2625,8 +2820,8 @@ async function runSameChainOrder(deps, options) {
2625
2820
  const {
2626
2821
  orderHash,
2627
2822
  onStage,
2628
- pollIntervalMs = DEFAULT_POLL_MS2,
2629
- timeoutMs = DEFAULT_TIMEOUT_MS2
2823
+ pollIntervalMs = DEFAULT_POLL_MS3,
2824
+ timeoutMs = DEFAULT_TIMEOUT_MS3
2630
2825
  } = options;
2631
2826
  const deadline = deps.now() + timeoutMs;
2632
2827
  let failures = 0;
@@ -2724,6 +2919,35 @@ function listOrders(now = Date.now()) {
2724
2919
  }
2725
2920
 
2726
2921
  // src/lib/swap/swap.executor.ts
2922
+ var WALLET_PROMPT_TIMEOUT_MS = 3 * 60 * 1e3;
2923
+ async function awaitWalletPrompt(prompt, what) {
2924
+ let timer;
2925
+ try {
2926
+ return await Promise.race([
2927
+ prompt(),
2928
+ new Promise((_, reject) => {
2929
+ timer = setTimeout(() => {
2930
+ reject(
2931
+ new OwneyError(
2932
+ "SWAP_WALLET_PROMPT_TIMEOUT",
2933
+ // Naming the stale request matters: the wallet is still holding
2934
+ // it, which is why the next connection attempt is refused too
2935
+ // ("Connection can be declined if a previous request is still
2936
+ // active"). Dismissing it is what actually unblocks them.
2937
+ `Your wallet didn't answer the request to ${what}. Open your wallet, dismiss any request still waiting there, and try again.`,
2938
+ { prompt: what, timeoutMs: WALLET_PROMPT_TIMEOUT_MS }
2939
+ )
2940
+ );
2941
+ }, WALLET_PROMPT_TIMEOUT_MS);
2942
+ })
2943
+ ]);
2944
+ } finally {
2945
+ if (timer) clearTimeout(timer);
2946
+ }
2947
+ }
2948
+ function stoppedWatching(error) {
2949
+ return error instanceof OwneyError && error.details?.settlementUnconfirmed === true;
2950
+ }
2727
2951
  var DEFAULT_SLIPPAGE = 1;
2728
2952
  async function affordableAmount(deps, quoted) {
2729
2953
  const balance = await deps.readSourceBalance();
@@ -2746,21 +2970,39 @@ async function executeSwap(deps, options) {
2746
2970
  });
2747
2971
  const before = await deps.readTargetBalance();
2748
2972
  debugLog("owney-sdk", "swap: target balance before", before.toString());
2749
- const result = quote.rail === "classic" ? await runClassic(deps, options) : quote.rail === "fusion" ? await runSameChainFusion(deps, options, walletAddress) : await runFusion(deps, options, walletAddress);
2750
- const after = await deps.readTargetBalance();
2751
- const received = after - before;
2752
- debugLog("owney-sdk", "swap: target balance after", {
2753
- after: after.toString(),
2754
- received: received.toString()
2973
+ let result;
2974
+ let railError;
2975
+ try {
2976
+ result = quote.rail === "classic" ? await runClassic(deps, options) : quote.rail === "fusion" ? await runSameChainFusion(deps, options, walletAddress) : await runFusion(deps, options, walletAddress);
2977
+ } catch (error) {
2978
+ if (!stoppedWatching(error)) throw error;
2979
+ railError = error;
2980
+ debugLog("owney-sdk", "swap: rail failed, checking whether funds landed", {
2981
+ message: error instanceof Error ? error.message : String(error)
2982
+ });
2983
+ }
2984
+ const { arrived } = await awaitBalanceIncrease({
2985
+ readBalance: () => deps.readTargetBalance(),
2986
+ baseline: before,
2987
+ ...options.arrivalTimeoutMs === void 0 ? {} : { timeoutMs: options.arrivalTimeoutMs },
2988
+ ...options.arrivalPollMs === void 0 ? {} : { pollMs: options.arrivalPollMs }
2755
2989
  });
2756
- if (received <= 0n) {
2990
+ if (arrived === null) {
2991
+ if (railError) throw railError;
2757
2992
  throw new OwneyError(
2758
2993
  "SWAP_REQUEST_FAILED",
2759
2994
  "The swap completed but no funds arrived in the wallet. Check the transaction before retrying.",
2760
- { rail: quote.rail, ...result }
2995
+ { rail: quote.rail, ...result ?? {} }
2761
2996
  );
2762
2997
  }
2763
- return { received: received.toString(), ...result };
2998
+ if (railError) {
2999
+ debugLog("owney-sdk", "swap: rail gave up but the funds are here", {
3000
+ received: arrived.toString()
3001
+ });
3002
+ const orderHash = railError.details?.orderHash;
3003
+ if (orderHash) clearOrder(orderHash);
3004
+ }
3005
+ return { received: arrived.toString(), ...result ?? {} };
2764
3006
  }
2765
3007
  async function runClassic(deps, options) {
2766
3008
  const {
@@ -2840,7 +3082,10 @@ async function runSameChainFusion(deps, options, walletAddress) {
2840
3082
  });
2841
3083
  onStage?.("signing");
2842
3084
  await deps.ensureChain(quote.src.chainId);
2843
- const signature = await deps.signTypedData(built.typedData);
3085
+ const signature = await awaitWalletPrompt(
3086
+ () => deps.signTypedData(built.typedData),
3087
+ "sign the swap"
3088
+ );
2844
3089
  debugLog("owney-sdk", "swap: signed, submitting same-chain order");
2845
3090
  await deps.api.submitOrder({
2846
3091
  // Without this the routing API hands the order to the Fusion+ relayer,
@@ -2870,7 +3115,10 @@ async function authoriseSpend(deps, options, amount, isNativeSource) {
2870
3115
  if (current >= amount) return void 0;
2871
3116
  onStage?.("approving");
2872
3117
  await deps.ensureChain(quote.src.chainId);
2873
- const permit = quote.permitSupported ? await deps.buildPermit?.(quote.spender, MAX_UINT256) ?? void 0 : void 0;
3118
+ const permit = quote.permitSupported ? await awaitWalletPrompt(
3119
+ async () => deps.buildPermit?.(quote.spender, MAX_UINT256),
3120
+ `approve ${quote.src.symbol}`
3121
+ ) ?? void 0 : void 0;
2874
3122
  if (permit) {
2875
3123
  debugLog("owney-sdk", "swap: permitting limit order protocol", {
2876
3124
  bytes: (permit.length - 2) / 2
@@ -2884,8 +3132,15 @@ async function authoriseSpend(deps, options, amount, isNativeSource) {
2884
3132
  async function runFusion(deps, options, walletAddress) {
2885
3133
  const { quote, direction, onStage } = options;
2886
3134
  const isNativeSource = quote.src.address.toLowerCase().startsWith("0xeeee");
2887
- const amount = isNativeSource ? BigInt(quote.src.amount) : await affordableAmount(deps, BigInt(quote.src.amount));
2888
- const permit = await authoriseSpend(deps, options, amount, isNativeSource);
3135
+ if (isNativeSource) {
3136
+ throw new OwneyError(
3137
+ "SWAP_NATIVE_UNSUPPORTED",
3138
+ `${quote.src.symbol} has to be wrapped before it can be swapped to another chain. Nothing has left your wallet.`,
3139
+ { chainId: quote.src.chainId, symbol: quote.src.symbol }
3140
+ );
3141
+ }
3142
+ const amount = await affordableAmount(deps, BigInt(quote.src.amount));
3143
+ const permit = await authoriseSpend(deps, options, amount, false);
2889
3144
  const { secrets, secretHashes } = mintSecrets(quote.secretsCount ?? 1);
2890
3145
  onStage?.("quoting");
2891
3146
  debugLog("owney-sdk", "swap: building fusion order", {
@@ -2920,7 +3175,10 @@ async function runFusion(deps, options, walletAddress) {
2920
3175
  debugLog("owney-sdk", "swap: awaiting signature in wallet", {
2921
3176
  signingOnChain: quote.src.chainId
2922
3177
  });
2923
- const signature = await deps.signTypedData(built.typedData);
3178
+ const signature = await awaitWalletPrompt(
3179
+ () => deps.signTypedData(built.typedData),
3180
+ "sign the swap"
3181
+ );
2924
3182
  debugLog("owney-sdk", "swap: signed, submitting to relayer");
2925
3183
  await deps.api.submitOrder({
2926
3184
  srcChainId: quote.src.chainId,
@@ -3056,54 +3314,64 @@ async function buildErc2612Permit(reads, input) {
3056
3314
  );
3057
3315
  }
3058
3316
 
3059
- // src/lib/swap/swap.arrival.ts
3060
- var DEFAULT_TIMEOUT_MS3 = 18e4;
3061
- var DEFAULT_POLL_MS3 = 4e3;
3062
- var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
3063
- async function awaitWithdrawalArrival(options) {
3064
- const {
3065
- readBalance,
3066
- baseline,
3067
- timeoutMs = DEFAULT_TIMEOUT_MS3,
3068
- pollMs = DEFAULT_POLL_MS3
3069
- } = options;
3070
- const deadline = Date.now() + timeoutMs;
3071
- debugLog("owney-sdk", "withdraw: waiting for funds to land", {
3072
- baseline: baseline.toString(),
3073
- timeoutMs
3074
- });
3075
- let lastError;
3076
- for (; ; ) {
3077
- try {
3078
- const balance = await readBalance();
3079
- if (balance > baseline) {
3080
- const arrived = balance - baseline;
3081
- debugLog("owney-sdk", "withdraw: funds landed", {
3082
- arrived: arrived.toString()
3083
- });
3084
- return arrived;
3085
- }
3086
- } catch (error) {
3087
- lastError = error;
3088
- debugLog("owney-sdk", "withdraw: balance read failed, retrying", {
3089
- message: error instanceof Error ? error.message : String(error)
3090
- });
3317
+ // src/lib/swap/swap.pending-deposit.ts
3318
+ var KEY_PREFIX3 = "owney.swap.pending-deposit";
3319
+ var MAX_AGE_MS2 = 24 * 60 * 60 * 1e3;
3320
+ var storage3 = () => {
3321
+ if (typeof window === "undefined") return null;
3322
+ try {
3323
+ return window.localStorage;
3324
+ } catch {
3325
+ return null;
3326
+ }
3327
+ };
3328
+ var keyFor2 = (id) => `${KEY_PREFIX3}.${id}`;
3329
+ function savePendingDeposit(entry) {
3330
+ const store = storage3();
3331
+ if (!store) return;
3332
+ try {
3333
+ store.setItem(keyFor2(entry.id), JSON.stringify(entry));
3334
+ } catch {
3335
+ return;
3336
+ }
3337
+ }
3338
+ function clearPendingDeposit(id) {
3339
+ const store = storage3();
3340
+ if (!store) return;
3341
+ try {
3342
+ store.removeItem(keyFor2(id));
3343
+ } catch {
3344
+ return;
3345
+ }
3346
+ }
3347
+ function listPendingDeposits(now = Date.now()) {
3348
+ const store = storage3();
3349
+ if (!store) return [];
3350
+ const out = [];
3351
+ try {
3352
+ const keys = [];
3353
+ for (let i = 0; i < store.length; i++) {
3354
+ const key2 = store.key(i);
3355
+ if (key2?.startsWith(`${KEY_PREFIX3}.`)) keys.push(key2);
3091
3356
  }
3092
- if (Date.now() >= deadline) {
3093
- throw new OwneyError(
3094
- "WITHDRAW_ARRIVAL_TIMEOUT",
3095
- "The withdrawal was accepted but the funds had not arrived in time to swap them. They are on their way to your wallet in the original asset.",
3096
- {
3097
- baseline: baseline.toString(),
3098
- waitedMs: timeoutMs,
3099
- ...lastError ? {
3100
- lastReadError: lastError instanceof Error ? lastError.message : String(lastError)
3101
- } : {}
3357
+ for (const key2 of keys) {
3358
+ const raw = store.getItem(key2);
3359
+ if (!raw) continue;
3360
+ try {
3361
+ const parsed = JSON.parse(raw);
3362
+ if (now - parsed.createdAt > MAX_AGE_MS2) {
3363
+ store.removeItem(key2);
3364
+ continue;
3102
3365
  }
3103
- );
3366
+ out.push(parsed);
3367
+ } catch {
3368
+ store.removeItem(key2);
3369
+ }
3104
3370
  }
3105
- await sleep(pollMs);
3371
+ } catch {
3372
+ return out;
3106
3373
  }
3374
+ return out.sort((a, b) => b.createdAt - a.createdAt);
3107
3375
  }
3108
3376
 
3109
3377
  // src/lib/health-report.ts
@@ -3303,7 +3571,7 @@ import {
3303
3571
  custom,
3304
3572
  erc20Abi as erc20Abi2
3305
3573
  } from "viem";
3306
- import { base as base2, arbitrum as arbitrum2, mainnet as mainnet2 } from "viem/chains";
3574
+ import { base as base3, arbitrum as arbitrum3, mainnet as mainnet3 } from "viem/chains";
3307
3575
 
3308
3576
  // src/lib/transfer-auth.ts
3309
3577
  import { bytesToHex as bytesToHex2 } from "viem";
@@ -3344,10 +3612,10 @@ function randomAuthNonce() {
3344
3612
  // src/lib/sponsor-client.ts
3345
3613
  var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
3346
3614
  async function postSponsorTransferAuth(input) {
3347
- const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3615
+ const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3348
3616
  let res;
3349
3617
  try {
3350
- res = await fetch(`${base3}/api/v1/sponsor/erc20-transfer-auth`, {
3618
+ res = await fetch(`${base4}/api/v1/sponsor/erc20-transfer-auth`, {
3351
3619
  method: "POST",
3352
3620
  headers: {
3353
3621
  "content-type": "application/json",
@@ -3384,10 +3652,10 @@ async function postSponsorTransferAuth(input) {
3384
3652
  return parsed.data;
3385
3653
  }
3386
3654
  async function postSponsorPermit2Transfer(input) {
3387
- const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3655
+ const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3388
3656
  let res;
3389
3657
  try {
3390
- res = await fetch(`${base3}/api/v1/sponsor/permit2-transfer`, {
3658
+ res = await fetch(`${base4}/api/v1/sponsor/permit2-transfer`, {
3391
3659
  method: "POST",
3392
3660
  headers: {
3393
3661
  "content-type": "application/json",
@@ -3422,11 +3690,11 @@ async function postSponsorPermit2Transfer(input) {
3422
3690
  return parsed.data;
3423
3691
  }
3424
3692
  async function getSponsorRelayerAddress(input) {
3425
- const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3693
+ const base4 = input.baseUrl ?? ROUTING_API_BASE_URL3;
3426
3694
  let res;
3427
3695
  try {
3428
3696
  res = await fetch(
3429
- `${base3}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
3697
+ `${base4}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
3430
3698
  {
3431
3699
  headers: { "x-owney-api-key": input.apiKey }
3432
3700
  }
@@ -3711,6 +3979,7 @@ function makeSponsoredCallsCallback(deps) {
3711
3979
  }
3712
3980
 
3713
3981
  // src/client.ts
3982
+ var WALLET_CATCHUP_TIMEOUT_MS = 3e4;
3714
3983
  function encodeMultiAgentCursor(map) {
3715
3984
  return Buffer.from(JSON.stringify(map), "utf8").toString("base64");
3716
3985
  }
@@ -3737,9 +4006,9 @@ var SPONSORED_USDC_BY_CHAIN = {
3737
4006
  1: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
3738
4007
  };
3739
4008
  var VIEM_CHAIN2 = {
3740
- 8453: base2,
3741
- 42161: arbitrum2,
3742
- 1: mainnet2
4009
+ 8453: base3,
4010
+ 42161: arbitrum3,
4011
+ 1: mainnet3
3743
4012
  };
3744
4013
  var SPONSORED_WETH_BY_CHAIN = {
3745
4014
  8453: "0x4200000000000000000000000000000000000006",
@@ -4528,7 +4797,7 @@ var OwneySDK = class {
4528
4797
  async ensureSwapChain(chainId) {
4529
4798
  const provider = this.requireConnectedProvider();
4530
4799
  const state = this.requireState();
4531
- const chain = VIEM_CHAIN2[chainId];
4800
+ const chain = swapChain(chainId);
4532
4801
  if (!chain) {
4533
4802
  throw new OwneyError(
4534
4803
  "CHAIN_UNSUPPORTED",
@@ -4546,6 +4815,111 @@ var OwneySDK = class {
4546
4815
  chainId
4547
4816
  );
4548
4817
  }
4818
+ /**
4819
+ * Turn a native-source cross-chain quote into an ERC-20 one.
4820
+ *
4821
+ * Fusion+ cannot escrow native value, so the quote arrives with
4822
+ * `requiresOnchainOrder` set and the relayer would refuse the order after
4823
+ * the user signed it (ROUT-242). Wrapping first costs one transaction and
4824
+ * puts the swap back on the ERC-20 rail that already works, rather than
4825
+ * adding a second order type that would need its own escrow handling.
4826
+ *
4827
+ * Re-quoted afterwards rather than patched: the amount wrapped may be less
4828
+ * than the amount quoted (gas has to come out of the same balance), and
4829
+ * every executor dep — allowance, permit, balances — is derived from the
4830
+ * quote's source token. A quote naming ETH would have all of them reading
4831
+ * the wrong asset.
4832
+ */
4833
+ async wrapNativeSource(quote, walletAddress, onStage, direction) {
4834
+ const wrapper = requireWrapper(quote);
4835
+ const chainId = quote.src.chainId;
4836
+ const chain = swapChain(chainId);
4837
+ const provider = this.requireConnectedProvider();
4838
+ const publicClient = createPublicClient2({
4839
+ chain,
4840
+ transport: swapReadTransport(chainId, this.zyfaiRpcUrls)
4841
+ });
4842
+ const wallet = createWalletClient({
4843
+ account: walletAddress,
4844
+ chain,
4845
+ transport: custom(provider)
4846
+ });
4847
+ onStage?.("wrapping");
4848
+ const { wrapped } = await wrapNative(
4849
+ {
4850
+ readNativeBalance: () => publicClient.getBalance({
4851
+ address: walletAddress
4852
+ }),
4853
+ estimateWrapGas: (to, value) => publicClient.estimateGas({
4854
+ account: walletAddress,
4855
+ to,
4856
+ data: WRAP_SELECTOR,
4857
+ value
4858
+ }),
4859
+ // The 1559 ceiling, not the spot price: a wallet bills against the
4860
+ // former and the two differ wildly on a quiet chain.
4861
+ getMaxFeePerGas: async () => {
4862
+ const fees = await publicClient.estimateFeesPerGas();
4863
+ return fees.maxFeePerGas ?? publicClient.getGasPrice();
4864
+ },
4865
+ sendTransaction: async (tx, onSubmitted) => {
4866
+ const hash = await wallet.sendTransaction({
4867
+ to: tx.to,
4868
+ data: tx.data,
4869
+ value: BigInt(tx.value),
4870
+ account: walletAddress,
4871
+ chain
4872
+ });
4873
+ onSubmitted?.(hash);
4874
+ const receipt = await publicClient.waitForTransactionReceipt({
4875
+ hash,
4876
+ confirmations: 1,
4877
+ timeout: receiptTimeoutMs(chainId)
4878
+ });
4879
+ if (receipt.status !== "success") {
4880
+ throw new OwneyError(
4881
+ "SWAP_REQUEST_FAILED",
4882
+ `Wrapping your ${quote.src.symbol} failed (tx ${hash}). Nothing was swapped.`,
4883
+ { hash }
4884
+ );
4885
+ }
4886
+ return hash;
4887
+ },
4888
+ ensureChain: (id) => this.ensureSwapChain(id)
4889
+ },
4890
+ {
4891
+ chainId,
4892
+ wrapper: wrapper.address,
4893
+ nativeSymbol: quote.src.symbol,
4894
+ requested: BigInt(quote.src.amount),
4895
+ onSubmitted: () => onStage?.("wrapped")
4896
+ }
4897
+ );
4898
+ debugLog("owney-sdk", "swap: wrapped native source", {
4899
+ symbol: wrapper.symbol,
4900
+ amount: wrapped.toString()
4901
+ });
4902
+ try {
4903
+ return await this.swapApi().quote({
4904
+ from: { chainId, symbol: wrapper.symbol, amount: wrapped.toString() },
4905
+ to: { chainId: quote.dst.chainId, symbol: quote.dst.symbol },
4906
+ walletAddress,
4907
+ ...direction ? { direction } : {}
4908
+ });
4909
+ } catch (error) {
4910
+ throw new OwneyError(
4911
+ "SWAP_REQUEST_FAILED",
4912
+ `Your ${quote.src.symbol} was wrapped to ${wrapper.symbol}, but the swap couldn't be priced. The funds are in your wallet as ${wrapper.symbol} \u2014 swap that instead, no need to wrap again.`,
4913
+ {
4914
+ wrappedSymbol: wrapper.symbol,
4915
+ wrappedAmount: wrapped.toString(),
4916
+ chainId,
4917
+ cause: error instanceof Error ? error.message : String(error),
4918
+ ...error instanceof OwneyError ? { causeCode: error.code } : {}
4919
+ }
4920
+ );
4921
+ }
4922
+ }
4549
4923
  /**
4550
4924
  * Binds the executor's abstract deps to this client's wallet.
4551
4925
  *
@@ -4555,8 +4929,8 @@ var OwneySDK = class {
4555
4929
  buildSwapDeps(quote) {
4556
4930
  const state = this.requireState();
4557
4931
  const provider = this.requireConnectedProvider();
4558
- const srcChain = VIEM_CHAIN2[quote.src.chainId];
4559
- const dstChain = VIEM_CHAIN2[quote.dst.chainId];
4932
+ const srcChain = swapChain(quote.src.chainId);
4933
+ const dstChain = swapChain(quote.dst.chainId);
4560
4934
  const wallet = createWalletClient({
4561
4935
  account: state.walletAddress,
4562
4936
  chain: srcChain,
@@ -4686,13 +5060,59 @@ var OwneySDK = class {
4686
5060
  sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
4687
5061
  now: () => Date.now()
4688
5062
  },
4689
- runner: {
4690
- readyForSecrets: (h) => this.swapApi().readyForSecrets(h),
4691
- submitSecret: (h, secret) => this.swapApi().submitSecret(h, secret),
4692
- orderStatus: (h) => this.swapApi().orderStatus(h),
4693
- sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
4694
- now: () => Date.now()
4695
- }
5063
+ runner: this.swapRunnerDeps()
5064
+ };
5065
+ }
5066
+ /**
5067
+ * Waits until the WALLET'S OWN node reports at least `amount` of `token`.
5068
+ *
5069
+ * Separate from the swap's arrival measurement on purpose: that one runs on
5070
+ * a pinned HTTP RPC, and what matters here is the view the deposit will
5071
+ * actually use. Returns whether it got there — a courtesy, not a gate, since
5072
+ * the deposit's own check is the authority and refusing to even attempt
5073
+ * would strand funds we might have been able to move.
5074
+ */
5075
+ async walletSeesBalance(chainId, token, amount) {
5076
+ const provider = this.requireConnectedProvider();
5077
+ const state = this.requireState();
5078
+ const pub = createPublicClient2({
5079
+ chain: swapChain(chainId),
5080
+ transport: custom(provider)
5081
+ });
5082
+ const { arrived } = await awaitBalanceIncrease({
5083
+ readBalance: () => pub.readContract({
5084
+ address: token,
5085
+ abi: ERC20_ALLOWANCE_ABI,
5086
+ functionName: "balanceOf",
5087
+ args: [state.walletAddress]
5088
+ }),
5089
+ // `awaitBalanceIncrease` resolves on the first read STRICTLY above the
5090
+ // baseline, so one below the target means "at least the target".
5091
+ baseline: amount - 1n,
5092
+ timeoutMs: WALLET_CATCHUP_TIMEOUT_MS
5093
+ });
5094
+ return arrived !== null;
5095
+ }
5096
+ /**
5097
+ * Runs a quoted swap. A named seam rather than an inline `executeSwap` call
5098
+ * so the deposit half of `swapAndDeposit` can be exercised on its own.
5099
+ */
5100
+ runSwap(quote, options) {
5101
+ return executeSwap(this.buildSwapDeps(quote), { quote, ...options });
5102
+ }
5103
+ /**
5104
+ * The half of the swap deps that only ever talks to the routing API.
5105
+ *
5106
+ * Split out because resuming an order needs exactly this and nothing else —
5107
+ * no provider, no wallet client, no chain. See `resumePendingSwaps`.
5108
+ */
5109
+ swapRunnerDeps() {
5110
+ return {
5111
+ readyForSecrets: (h) => this.swapApi().readyForSecrets(h),
5112
+ submitSecret: (h, secret) => this.swapApi().submitSecret(h, secret),
5113
+ orderStatus: (h) => this.swapApi().orderStatus(h),
5114
+ sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
5115
+ now: () => Date.now()
4696
5116
  };
4697
5117
  }
4698
5118
  /**
@@ -4704,6 +5124,93 @@ var OwneySDK = class {
4704
5124
  async getSwapTokens() {
4705
5125
  return this.swapApi().listTokens();
4706
5126
  }
5127
+ /**
5128
+ * Swaps that landed but were never deposited, newest first.
5129
+ *
5130
+ * The money is already in the wallet in the right asset — what is missing is
5131
+ * an ordinary deposit, which is why this needs no order and no signature to
5132
+ * describe. See `completePendingDeposit`.
5133
+ */
5134
+ listPendingDeposits() {
5135
+ return listPendingDeposits();
5136
+ }
5137
+ /**
5138
+ * Deposit a swap that already landed.
5139
+ *
5140
+ * Nothing is swapped again: the funds are in the wallet, so this is the
5141
+ * second half of `swapAndDeposit` on its own. Cleared only once the deposit
5142
+ * has actually gone through — a failure here leaves the record in place so it
5143
+ * can be offered again rather than silently dropped.
5144
+ */
5145
+ async completePendingDeposit(id) {
5146
+ const entry = listPendingDeposits().find((p) => p.id === id);
5147
+ if (!entry) {
5148
+ throw new OwneyError(
5149
+ "SWAP_REQUEST_FAILED",
5150
+ "That swap is no longer waiting to be added.",
5151
+ { id }
5152
+ );
5153
+ }
5154
+ await this.ensureSwapChain(entry.chainId);
5155
+ const deposit = await this.deposit({
5156
+ amount: entry.received,
5157
+ asset: entry.symbol,
5158
+ ...entry.agentId ? { agentId: entry.agentId } : {}
5159
+ });
5160
+ clearPendingDeposit(entry.id);
5161
+ return deposit;
5162
+ }
5163
+ /**
5164
+ * Pick up cross-chain swaps a previous session left in flight.
5165
+ *
5166
+ * A Fusion+ order is only finished when the client publishes a secret for
5167
+ * each fill, once the escrows exist — so a user who closed the tab mid-swap
5168
+ * leaves an order nobody will ever complete, and it expires and refunds
5169
+ * instead of arriving. The preimages are stored for exactly this (24h sweep,
5170
+ * see the secret store); this is the other half.
5171
+ *
5172
+ * Needs NO wallet, deliberately. The signature already happened and the funds
5173
+ * are already escrowed, so finishing is pure API work — demanding a reconnect
5174
+ * first would strand the people it exists for.
5175
+ *
5176
+ * Every order is attempted even if an earlier one throws: they are unrelated
5177
+ * escrows, and one ending badly must not abandon the next one's secrets.
5178
+ * `unfinished` is not a verdict — the order may still settle, so unless the
5179
+ * chain has said refunded or cancelled its preimages are kept.
5180
+ */
5181
+ async resumePendingSwaps(options = {}) {
5182
+ const pending = listOrders();
5183
+ if (pending.length === 0) return [];
5184
+ const runner = this.swapRunnerDeps();
5185
+ const results = [];
5186
+ for (const order of pending) {
5187
+ try {
5188
+ await runFusionOrder(runner, {
5189
+ orderHash: order.orderHash,
5190
+ secrets: order.secrets,
5191
+ ...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs },
5192
+ ...options.onStage ? {
5193
+ onStage: (stage) => options.onStage(order.orderHash, stage)
5194
+ } : {}
5195
+ });
5196
+ clearOrder(order.orderHash);
5197
+ results.push({
5198
+ orderHash: order.orderHash,
5199
+ status: "completed"
5200
+ });
5201
+ } catch (error) {
5202
+ if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED")) {
5203
+ clearOrder(order.orderHash);
5204
+ }
5205
+ results.push({
5206
+ orderHash: order.orderHash,
5207
+ status: "unfinished",
5208
+ ...error instanceof OwneyError ? { error } : {}
5209
+ });
5210
+ }
5211
+ }
5212
+ return results;
5213
+ }
4707
5214
  /**
4708
5215
  * What the wallet actually holds, across every supported chain, restricted
4709
5216
  * to tokens a swap could use.
@@ -4758,7 +5265,8 @@ var OwneySDK = class {
4758
5265
  return this.swapApi().searchTokens({
4759
5266
  query,
4760
5267
  ...params.chainId === void 0 ? {} : { chainId: params.chainId },
4761
- ...params.limit === void 0 ? {} : { limit: params.limit }
5268
+ ...params.limit === void 0 ? {} : { limit: params.limit },
5269
+ ...params.direction === void 0 ? {} : { direction: params.direction }
4762
5270
  });
4763
5271
  }
4764
5272
  /**
@@ -4797,26 +5305,56 @@ var OwneySDK = class {
4797
5305
  async swapAndDeposit(options) {
4798
5306
  const state = this.requireState();
4799
5307
  const api = this.swapApi();
4800
- const quote = await api.quote({
5308
+ const quoted = await api.quote({
4801
5309
  from: options.from,
4802
5310
  to: options.to,
4803
5311
  walletAddress: state.walletAddress
4804
5312
  });
5313
+ const quote = quoted.requiresOnchainOrder ? await this.wrapNativeSource(
5314
+ quoted,
5315
+ state.walletAddress,
5316
+ options.onSwapProgress
5317
+ ) : quoted;
4805
5318
  await this.ensureSwapChain(quote.src.chainId);
4806
- const swap = await executeSwap(this.buildSwapDeps(quote), {
4807
- quote,
5319
+ const swap = await this.runSwap(quote, {
4808
5320
  walletAddress: state.walletAddress,
4809
5321
  ...options.slippage === void 0 ? {} : { slippage: options.slippage },
4810
5322
  ...options.onSwapProgress ? { onStage: options.onSwapProgress } : {}
4811
5323
  });
4812
5324
  options.onSwapProgress?.("depositing");
4813
- await this.ensureSwapChain(quote.dst.chainId);
4814
- const deposit = await this.deposit({
4815
- amount: swap.received,
4816
- asset: options.to.symbol,
4817
- ...options.agentId ? { agentId: options.agentId } : {}
4818
- });
4819
- return { swap, deposit };
5325
+ try {
5326
+ await this.ensureSwapChain(quote.dst.chainId);
5327
+ await this.walletSeesBalance(
5328
+ quote.dst.chainId,
5329
+ quote.dst.address,
5330
+ BigInt(swap.received)
5331
+ );
5332
+ const deposit = await this.deposit({
5333
+ amount: swap.received,
5334
+ asset: options.to.symbol,
5335
+ ...options.agentId ? { agentId: options.agentId } : {}
5336
+ });
5337
+ return { swap, deposit };
5338
+ } catch (error) {
5339
+ const pending = {
5340
+ id: `${quote.dst.chainId}-${options.to.symbol}-${Date.now()}`,
5341
+ received: swap.received,
5342
+ symbol: options.to.symbol,
5343
+ chainId: quote.dst.chainId,
5344
+ ...options.agentId ? { agentId: options.agentId } : {},
5345
+ createdAt: Date.now()
5346
+ };
5347
+ savePendingDeposit(pending);
5348
+ throw new OwneyError(
5349
+ "SWAP_DEPOSIT_PENDING",
5350
+ `The swap went through and your ${options.to.symbol} is in your wallet, but adding it to the agent didn't complete. Nothing needs swapping again.`,
5351
+ {
5352
+ ...pending,
5353
+ cause: error instanceof Error ? error.message : String(error),
5354
+ ...error instanceof OwneyError ? { causeCode: error.code } : {}
5355
+ }
5356
+ );
5357
+ }
4820
5358
  }
4821
5359
  /**
4822
5360
  * Withdraw from an agent and swap the proceeds into whatever the user wants
@@ -5664,8 +6202,8 @@ import { SiweMessage } from "siwe";
5664
6202
  import { ZyfaiSDK as ZyfaiSDK2 } from "@zyfai/sdk";
5665
6203
 
5666
6204
  // src/agents/zyfai/zyfai.siwx-cache.ts
5667
- var KEY_PREFIX3 = "owney.siwx.session";
5668
- var storage3 = () => {
6205
+ var KEY_PREFIX4 = "owney.siwx.session";
6206
+ var storage4 = () => {
5669
6207
  if (typeof window === "undefined") return null;
5670
6208
  try {
5671
6209
  return window.localStorage;
@@ -5673,8 +6211,8 @@ var storage3 = () => {
5673
6211
  return null;
5674
6212
  }
5675
6213
  };
5676
- var buildKey2 = (address) => `${KEY_PREFIX3}:${address.toLowerCase()}`;
5677
- var legacyKeyPrefix2 = (address) => `${KEY_PREFIX3}:${address.toLowerCase()}:`;
6214
+ var buildKey2 = (address) => `${KEY_PREFIX4}:${address.toLowerCase()}`;
6215
+ var legacyKeyPrefix2 = (address) => `${KEY_PREFIX4}:${address.toLowerCase()}:`;
5678
6216
  var memorySiwxSessions = /* @__PURE__ */ new Map();
5679
6217
  var readLegacySiwxSession = (store, address) => {
5680
6218
  if (!store) return null;
@@ -5706,7 +6244,7 @@ var readLegacySiwxSession = (store, address) => {
5706
6244
  var readSiwxSession = (address, chainId) => {
5707
6245
  if (typeof window === "undefined") return null;
5708
6246
  const key2 = buildKey2(address);
5709
- const store = storage3();
6247
+ const store = storage4();
5710
6248
  let raw = null;
5711
6249
  try {
5712
6250
  raw = store?.getItem(key2) ?? null;
@@ -5736,7 +6274,7 @@ var writeSiwxSession = (address, _chainId, session) => {
5736
6274
  if (typeof window === "undefined") return;
5737
6275
  const key2 = buildKey2(address);
5738
6276
  memorySiwxSessions.set(key2, session);
5739
- const store = storage3();
6277
+ const store = storage4();
5740
6278
  try {
5741
6279
  store?.setItem(key2, JSON.stringify(session));
5742
6280
  } catch {
@@ -5745,7 +6283,7 @@ var writeSiwxSession = (address, _chainId, session) => {
5745
6283
  var clearSiwxSession = (address, _chainId) => {
5746
6284
  const key2 = buildKey2(address);
5747
6285
  memorySiwxSessions.delete(key2);
5748
- const store = storage3();
6286
+ const store = storage4();
5749
6287
  try {
5750
6288
  store?.removeItem(key2);
5751
6289
  } catch {
@@ -5878,6 +6416,7 @@ export {
5878
6416
  OwneyError,
5879
6417
  OwneySDK,
5880
6418
  createOwneySIWX,
6419
+ listPendingDeposits,
5881
6420
  listOrders as listPendingSwaps,
5882
6421
  setOwneyDebug
5883
6422
  };