@rhinestone/deposit-modal 0.5.0 → 0.6.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.
@@ -66,8 +66,9 @@ import {
66
66
  tokenFormatter,
67
67
  txRefsMatch,
68
68
  useLatestRef,
69
- useRpcUrls
70
- } from "./chunk-PS7HJ62M.mjs";
69
+ useRpcUrls,
70
+ useStableRpcUrls
71
+ } from "./chunk-GQDVHMOT.mjs";
71
72
  import {
72
73
  SAFE_ABI
73
74
  } from "./chunk-F7P4MV72.mjs";
@@ -1173,7 +1174,6 @@ function DepositNotification({
1173
1174
  solanaDepositAddress,
1174
1175
  targetChain,
1175
1176
  targetToken,
1176
- hasPostBridgeActions,
1177
1177
  service,
1178
1178
  onComplete,
1179
1179
  onFailed,
@@ -1207,8 +1207,7 @@ function DepositNotification({
1207
1207
  sourceToken: token,
1208
1208
  sourceDecimals,
1209
1209
  targetChain,
1210
- targetToken,
1211
- hasPostBridgeActions
1210
+ targetToken
1212
1211
  });
1213
1212
  const onCompleteRef = useLatestRef(onComplete);
1214
1213
  const onFailedRef = useLatestRef(onFailed);
@@ -1254,17 +1253,7 @@ function DepositNotification({
1254
1253
  if (!isMounted) return;
1255
1254
  const lastEvent = data.lastEvent;
1256
1255
  const eventForTx = isEventForTx(lastEvent, txHash) ? lastEvent : void 0;
1257
- const awaitingPostBridgeSwap = depositContextRef.current.hasPostBridgeActions;
1258
- if (eventForTx?.type === "post-bridge-swap-complete") {
1259
- const swapTxHash = eventForTx.data?.swap?.transactionHash;
1260
- handleComplete(swapTxHash);
1261
- return;
1262
- }
1263
- if (eventForTx?.type === "post-bridge-swap-failed") {
1264
- handleFailed(formatBridgeFailedMessage(eventForTx));
1265
- return;
1266
- }
1267
- if (eventForTx?.type === "bridge-complete" && !awaitingPostBridgeSwap) {
1256
+ if (eventForTx?.type === "bridge-complete") {
1268
1257
  const destTx = eventForTx.data?.destination?.transactionHash;
1269
1258
  handleComplete(destTx);
1270
1259
  return;
@@ -1529,7 +1518,6 @@ function DepositAddressStep({
1529
1518
  allowedRoutes,
1530
1519
  targetChain,
1531
1520
  targetToken,
1532
- hasPostBridgeActions,
1533
1521
  uiConfig,
1534
1522
  onDepositSubmitted,
1535
1523
  onDepositComplete,
@@ -2036,7 +2024,6 @@ function DepositAddressStep({
2036
2024
  solanaDepositAddress,
2037
2025
  targetChain,
2038
2026
  targetToken,
2039
- hasPostBridgeActions,
2040
2027
  service,
2041
2028
  onComplete: handleNotificationComplete,
2042
2029
  onFailed: handleNotificationFailed,
@@ -2052,6 +2039,20 @@ DepositAddressStep.displayName = "DepositAddressStep";
2052
2039
  // src/components/steps/FiatOnrampStep.tsx
2053
2040
  import { useCallback as useCallback3 } from "react";
2054
2041
 
2042
+ // src/core/swapped.ts
2043
+ var SWAPPED_ORIGINS = [
2044
+ "https://connect.swapped.com",
2045
+ "https://sandbox.swapped.com",
2046
+ "https://widget.swapped.com"
2047
+ ];
2048
+ var WIDGET_URL_EXPIRY_BUFFER_MS = 1e4;
2049
+ function isSwappedWidgetUrlFresh(res, now = Date.now()) {
2050
+ if (!res.expiresAt) return false;
2051
+ const expiry = Date.parse(res.expiresAt);
2052
+ if (!Number.isFinite(expiry)) return false;
2053
+ return expiry - now > WIDGET_URL_EXPIRY_BUFFER_MS;
2054
+ }
2055
+
2055
2056
  // src/components/steps/SwappedIframeStep.tsx
2056
2057
  import { useState as useState6, useEffect as useEffect6, useRef as useRef6, useMemo as useMemo4 } from "react";
2057
2058
 
@@ -2060,7 +2061,19 @@ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
2060
2061
  function FinalisingDepositStep() {
2061
2062
  return /* @__PURE__ */ jsxs7("div", { className: "rs-screen rs-finalising", children: [
2062
2063
  /* @__PURE__ */ jsxs7("div", { className: "rs-screen-body rs-finalising-body", children: [
2063
- /* @__PURE__ */ jsx7("span", { className: "rs-finalising-spinner", children: /* @__PURE__ */ jsx7(Spinner, {}) }),
2064
+ /* @__PURE__ */ jsxs7(
2065
+ "svg",
2066
+ {
2067
+ className: "rs-finalising-spinner",
2068
+ viewBox: "0 0 80 80",
2069
+ fill: "none",
2070
+ "aria-hidden": "true",
2071
+ children: [
2072
+ /* @__PURE__ */ jsx7("circle", { className: "rs-finalising-spinner-track", cx: "40", cy: "40", r: "34" }),
2073
+ /* @__PURE__ */ jsx7("circle", { className: "rs-finalising-spinner-head", cx: "40", cy: "40", r: "34" })
2074
+ ]
2075
+ }
2076
+ ),
2064
2077
  /* @__PURE__ */ jsxs7("div", { className: "rs-finalising-text", children: [
2065
2078
  /* @__PURE__ */ jsx7("h2", { className: "rs-finalising-title", children: "Finalising deposit" }),
2066
2079
  /* @__PURE__ */ jsx7("p", { className: "rs-finalising-subtitle", children: "We are depositing your funds to the application." })
@@ -2082,7 +2095,6 @@ var STEP_LABELS = [
2082
2095
  function SwappedOrderTracker({
2083
2096
  amount,
2084
2097
  currency = "USDC",
2085
- chainLabel = "Base",
2086
2098
  stepStates,
2087
2099
  terminal = null,
2088
2100
  onRetry
@@ -2091,7 +2103,7 @@ function SwappedOrderTracker({
2091
2103
  const title = terminal ? terminal.kind === "cancelled" ? "Order cancelled" : "Deposit failed" : formattedAmount ? `Depositing ${formattedAmount} ${currency}` : `Depositing ${currency}`;
2092
2104
  const labels = [
2093
2105
  STEP_LABELS[0],
2094
- `${currency} received on ${chainLabel}`,
2106
+ `${currency} received`,
2095
2107
  STEP_LABELS[2],
2096
2108
  STEP_LABELS[3]
2097
2109
  ];
@@ -2164,11 +2176,7 @@ var DEPOSIT_POLL_INTERVAL_MS = 2e3;
2164
2176
  var DEPOSIT_POLL_FAST_INITIAL_DELAY_MS = 1e3;
2165
2177
  var DEPOSIT_POLL_FAST_INTERVAL_MS = 500;
2166
2178
  var IFRAME_LOAD_TIMEOUT_MS = 15e3;
2167
- var SWAPPED_IFRAME_ORIGINS = /* @__PURE__ */ new Set([
2168
- "https://connect.swapped.com",
2169
- "https://sandbox.swapped.com",
2170
- "https://widget.swapped.com"
2171
- ]);
2179
+ var SWAPPED_IFRAME_ORIGINS = new Set(SWAPPED_ORIGINS);
2172
2180
  var SWAPPED_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
2173
2181
  "order_completed",
2174
2182
  "order_broadcasted"
@@ -2179,6 +2187,24 @@ var SWAPPED_STATUS_VALUES = /* @__PURE__ */ new Set([
2179
2187
  "order_broadcasted",
2180
2188
  "order_cancelled"
2181
2189
  ]);
2190
+ var SWAPPED_GO_BACK_KEY = "SWAPPED_GO_BACK";
2191
+ function parseMaybeJsonString(raw) {
2192
+ try {
2193
+ return JSON.parse(raw);
2194
+ } catch {
2195
+ return raw;
2196
+ }
2197
+ }
2198
+ function isSwappedGoBackMessage(raw) {
2199
+ let data = raw;
2200
+ if (typeof data === "string") {
2201
+ data = parseMaybeJsonString(data);
2202
+ }
2203
+ if (data === SWAPPED_GO_BACK_KEY) return true;
2204
+ if (!data || typeof data !== "object") return false;
2205
+ const obj = data;
2206
+ return obj.key === SWAPPED_GO_BACK_KEY || obj.type === SWAPPED_GO_BACK_KEY;
2207
+ }
2182
2208
  function parseSwappedIframeMessage(raw) {
2183
2209
  let data = raw;
2184
2210
  if (typeof data === "string") {
@@ -2199,6 +2225,7 @@ function parseSwappedIframeMessage(raw) {
2199
2225
  return {
2200
2226
  status: rawStatus,
2201
2227
  orderId: asString2(inner.order_id) ?? asString2(obj.orderId),
2228
+ externalCustomerId: asString2(inner.external_customer_id) ?? asString2(obj.external_customer_id) ?? asString2(inner.externalCustomerId) ?? asString2(obj.externalCustomerId),
2202
2229
  orderCrypto: asString2(inner.order_crypto) ?? asString2(obj.orderCrypto),
2203
2230
  orderCryptoAmount: asString2(inner.order_crypto_amount) ?? asString2(obj.orderCryptoAmount),
2204
2231
  transactionId: asString2(inner.transaction_id) ?? asString2(obj.transactionId)
@@ -2216,6 +2243,7 @@ function SwappedIframeStep({
2216
2243
  onSwappedComplete,
2217
2244
  onSwappedFailed,
2218
2245
  onClose,
2246
+ onGoBack,
2219
2247
  onError
2220
2248
  }) {
2221
2249
  const [widgetUrl, setWidgetUrl] = useState6(null);
@@ -2229,6 +2257,7 @@ function SwappedIframeStep({
2229
2257
  const completeFiredRef = useRef6(false);
2230
2258
  const failedFiredRef = useRef6(false);
2231
2259
  const expectedOrderUuidRef = useRef6(null);
2260
+ const expectedExternalCustomerIdRef = useRef6(null);
2232
2261
  const baselineDepositTxHashRef = useRef6(void 0);
2233
2262
  const currentDepositTxHashRef = useRef6(null);
2234
2263
  const fastDepositPollEnabledRef = useRef6(false);
@@ -2241,6 +2270,8 @@ function SwappedIframeStep({
2241
2270
  onSwappedFailedRef.current = onSwappedFailed;
2242
2271
  const onErrorRef = useRef6(onError);
2243
2272
  onErrorRef.current = onError;
2273
+ const onGoBackRef = useRef6(onGoBack);
2274
+ onGoBackRef.current = onGoBack;
2244
2275
  const loadUrlRef = useRef6(loadUrl);
2245
2276
  loadUrlRef.current = loadUrl;
2246
2277
  useEffect6(() => {
@@ -2252,6 +2283,7 @@ function SwappedIframeStep({
2252
2283
  setLatestEvent(null);
2253
2284
  setPhase("iframe");
2254
2285
  expectedOrderUuidRef.current = null;
2286
+ expectedExternalCustomerIdRef.current = null;
2255
2287
  completeFiredRef.current = false;
2256
2288
  failedFiredRef.current = false;
2257
2289
  baselineDepositTxHashRef.current = void 0;
@@ -2260,6 +2292,7 @@ function SwappedIframeStep({
2260
2292
  loadUrlRef.current().then((res) => {
2261
2293
  if (cancelled) return;
2262
2294
  setWidgetUrl(res.url);
2295
+ expectedExternalCustomerIdRef.current = res.externalCustomerId;
2263
2296
  const sep = res.externalCustomerId.indexOf(":");
2264
2297
  expectedOrderUuidRef.current = sep >= 0 ? res.externalCustomerId.slice(sep + 1) : null;
2265
2298
  }).catch((err) => {
@@ -2349,14 +2382,21 @@ function SwappedIframeStep({
2349
2382
  function onMessage(e) {
2350
2383
  if (!SWAPPED_IFRAME_ORIGINS.has(e.origin)) return;
2351
2384
  if (e.source !== iframeRef.current?.contentWindow) return;
2385
+ if (isSwappedGoBackMessage(e.data)) {
2386
+ onGoBackRef.current();
2387
+ return;
2388
+ }
2352
2389
  const parsed = parseSwappedIframeMessage(e.data);
2353
2390
  if (!parsed) return;
2354
- const orderId = parsed.orderId;
2355
- if (!orderId || orderId !== expectedOrderUuidRef.current) {
2391
+ const ext = parsed.externalCustomerId;
2392
+ const expected = expectedExternalCustomerIdRef.current;
2393
+ if (!ext || !expected || ext.toLowerCase() !== expected.toLowerCase()) {
2356
2394
  return;
2357
2395
  }
2358
2396
  setOrderState((prev) => ({
2359
- orderId,
2397
+ // Normalise to the uuid the backend poll also keys on, so orderState
2398
+ // is consistent regardless of which path set it.
2399
+ orderId: expectedOrderUuidRef.current ?? prev?.orderId ?? ext,
2360
2400
  status: parsed.status,
2361
2401
  orderCrypto: parsed.orderCrypto ?? prev?.orderCrypto ?? null,
2362
2402
  orderCryptoAmount: parsed.orderCryptoAmount ?? prev?.orderCryptoAmount ?? null,
@@ -2396,7 +2436,7 @@ function SwappedIframeStep({
2396
2436
  useEffect6(() => {
2397
2437
  if (completeFiredRef.current || failedFiredRef.current) return;
2398
2438
  const t = latestEvent?.type;
2399
- const isSuccess = t === "bridge-complete" || t === "post-bridge-swap-complete";
2439
+ const isSuccess = t === "bridge-complete";
2400
2440
  if (!isSuccess) return;
2401
2441
  const txHash = currentDepositTxHashRef.current;
2402
2442
  if (!txHash) return;
@@ -2479,7 +2519,7 @@ function deriveStepStates(swappedStatus, latestEvent) {
2479
2519
  }
2480
2520
  const step1Complete = swappedStatus === "order_completed" || swappedStatus === "order_broadcasted";
2481
2521
  const step2Complete = latestEvent !== null;
2482
- const step3Complete = latestEvent?.type === "bridge-complete" || latestEvent?.type === "post-bridge-swap-complete";
2522
+ const step3Complete = latestEvent?.type === "bridge-complete";
2483
2523
  if (step3Complete) {
2484
2524
  return ["complete", "complete", "complete", "pending"];
2485
2525
  }
@@ -2525,18 +2565,27 @@ function FiatOnrampStep({
2525
2565
  smartAccount,
2526
2566
  service,
2527
2567
  paymentMethod,
2568
+ consumePrefetchedUrl,
2528
2569
  onSwappedComplete,
2529
2570
  onSwappedFailed,
2530
2571
  onClose,
2572
+ onGoBack,
2531
2573
  onError
2532
2574
  }) {
2533
2575
  const loadUrl = useCallback3(async () => {
2534
- const res = await service.getSwappedWidgetUrl({
2576
+ const prefetched = consumePrefetchedUrl?.(smartAccount, paymentMethod);
2577
+ if (prefetched) {
2578
+ try {
2579
+ const cached = await prefetched;
2580
+ if (isSwappedWidgetUrlFresh(cached)) return cached;
2581
+ } catch {
2582
+ }
2583
+ }
2584
+ return service.getSwappedWidgetUrl({
2535
2585
  smartAccount,
2536
2586
  method: paymentMethod
2537
2587
  });
2538
- return res;
2539
- }, [service, smartAccount, paymentMethod]);
2588
+ }, [service, smartAccount, paymentMethod, consumePrefetchedUrl]);
2540
2589
  return /* @__PURE__ */ jsx10(
2541
2590
  SwappedIframeStep,
2542
2591
  {
@@ -2551,6 +2600,7 @@ function FiatOnrampStep({
2551
2600
  onSwappedComplete,
2552
2601
  onSwappedFailed,
2553
2602
  onClose,
2603
+ onGoBack,
2554
2604
  onError
2555
2605
  }
2556
2606
  );
@@ -2596,6 +2646,7 @@ function ExchangeConnectStep({
2596
2646
  onSwappedComplete,
2597
2647
  onSwappedFailed,
2598
2648
  onClose,
2649
+ onGoBack,
2599
2650
  onError
2600
2651
  }) {
2601
2652
  const loadUrl = useCallback4(async () => {
@@ -2619,6 +2670,7 @@ function ExchangeConnectStep({
2619
2670
  onSwappedComplete,
2620
2671
  onSwappedFailed,
2621
2672
  onClose,
2673
+ onGoBack,
2622
2674
  onError
2623
2675
  }
2624
2676
  );
@@ -4093,6 +4145,67 @@ function getEnabledProviders(config) {
4093
4145
  );
4094
4146
  }
4095
4147
 
4148
+ // src/store/state.ts
4149
+ function portfolioKey(network, address) {
4150
+ return network === "evm" ? `evm:${address.toLowerCase()}` : `solana:${address}`;
4151
+ }
4152
+ function createInitialState(overrides) {
4153
+ return {
4154
+ flow: {
4155
+ step: "connect",
4156
+ mode: null,
4157
+ isConnectSelectionConfirmed: false,
4158
+ hasNavigatedBack: false
4159
+ },
4160
+ wallet: {
4161
+ selectedWalletId: null
4162
+ },
4163
+ deposit: {
4164
+ targetChain: overrides.targetChain,
4165
+ targetToken: overrides.targetToken,
4166
+ sourceChain: null,
4167
+ sourceToken: null,
4168
+ sourceSymbol: null,
4169
+ sourceDecimals: null,
4170
+ selectedAsset: null,
4171
+ selectedSolanaToken: null,
4172
+ amount: null,
4173
+ targetAmount: null,
4174
+ targetTokenPriceUsd: null,
4175
+ balance: null,
4176
+ balanceUsd: null,
4177
+ inputAmountUsd: null,
4178
+ liquidityWarning: null
4179
+ },
4180
+ processing: {
4181
+ txHash: null,
4182
+ directTransfer: false,
4183
+ swappedContext: null
4184
+ },
4185
+ dappImport: {
4186
+ activeProviderId: null,
4187
+ availabilityOwner: null,
4188
+ availability: {},
4189
+ selectedAsset: null,
4190
+ bootError: false,
4191
+ attemptNonce: 0
4192
+ },
4193
+ setup: {
4194
+ byOwner: {}
4195
+ },
4196
+ portfolio: {
4197
+ byKey: {},
4198
+ nextRequestId: 0
4199
+ },
4200
+ fiat: {
4201
+ selectedMethod: null
4202
+ },
4203
+ exchange: {
4204
+ selectedConnection: null
4205
+ }
4206
+ };
4207
+ }
4208
+
4096
4209
  // src/store/selectors.ts
4097
4210
  var selectedWalletIdSelector = (state) => state.wallet.selectedWalletId;
4098
4211
  var IDLE_SETUP_ENTRY = {
@@ -4112,6 +4225,10 @@ function readSetupForOwner(setup, owner) {
4112
4225
  const entry = setup.byOwner[owner.toLowerCase()];
4113
4226
  return entry ?? { ...IDLE_SETUP_ENTRY, owner };
4114
4227
  }
4228
+ function readPortfolioEntry(portfolio, network, address) {
4229
+ if (!address) return void 0;
4230
+ return portfolio.byKey[portfolioKey(network, address)];
4231
+ }
4115
4232
 
4116
4233
  // src/core/dapp-imports/status.ts
4117
4234
  function computeDappImportStatus(providerId, inputs) {
@@ -4519,6 +4636,79 @@ function applyAction(state, action) {
4519
4636
  message: null,
4520
4637
  attemptNonce: entry.attemptNonce + 1
4521
4638
  }));
4639
+ case "portfolio/loading": {
4640
+ const key = portfolioKey(action.network, action.address);
4641
+ const requestId = state.portfolio.nextRequestId + 1;
4642
+ return {
4643
+ ...state,
4644
+ portfolio: {
4645
+ nextRequestId: requestId,
4646
+ byKey: {
4647
+ ...state.portfolio.byKey,
4648
+ [key]: { status: "loading", requestId, totalUsd: null }
4649
+ }
4650
+ }
4651
+ };
4652
+ }
4653
+ case "portfolio/reconciled": {
4654
+ const retainedKeys = new Set(
4655
+ action.wallets.map(
4656
+ ({ network, address }) => portfolioKey(network, address)
4657
+ )
4658
+ );
4659
+ const entries = Object.entries(state.portfolio.byKey);
4660
+ const retainedEntries = entries.filter(([key]) => retainedKeys.has(key));
4661
+ if (retainedEntries.length === entries.length) return state;
4662
+ return {
4663
+ ...state,
4664
+ portfolio: {
4665
+ ...state.portfolio,
4666
+ byKey: Object.fromEntries(retainedEntries)
4667
+ }
4668
+ };
4669
+ }
4670
+ case "portfolio/loaded": {
4671
+ const key = portfolioKey(action.network, action.address);
4672
+ const existing = state.portfolio.byKey[key];
4673
+ if (!existing || existing.status !== "loading" || existing.requestId !== action.requestId) {
4674
+ return state;
4675
+ }
4676
+ return {
4677
+ ...state,
4678
+ portfolio: {
4679
+ ...state.portfolio,
4680
+ byKey: {
4681
+ ...state.portfolio.byKey,
4682
+ [key]: {
4683
+ status: "ready",
4684
+ requestId: action.requestId,
4685
+ totalUsd: action.totalUsd
4686
+ }
4687
+ }
4688
+ }
4689
+ };
4690
+ }
4691
+ case "portfolio/failed": {
4692
+ const key = portfolioKey(action.network, action.address);
4693
+ const existing = state.portfolio.byKey[key];
4694
+ if (!existing || existing.status !== "loading" || existing.requestId !== action.requestId) {
4695
+ return state;
4696
+ }
4697
+ return {
4698
+ ...state,
4699
+ portfolio: {
4700
+ ...state.portfolio,
4701
+ byKey: {
4702
+ ...state.portfolio.byKey,
4703
+ [key]: {
4704
+ status: "error",
4705
+ requestId: action.requestId,
4706
+ totalUsd: existing.totalUsd
4707
+ }
4708
+ }
4709
+ }
4710
+ };
4711
+ }
4522
4712
  case "asset/selected":
4523
4713
  return {
4524
4714
  ...state,
@@ -4785,6 +4975,13 @@ function applyAction(state, action) {
4785
4975
  attemptNonce: 0
4786
4976
  },
4787
4977
  setup: { byOwner: preservedByOwner },
4978
+ // Ephemeral fetched balances — drop wholesale on close so a reopen
4979
+ // refetches rather than surfacing a stale balance (same hazard the
4980
+ // dappImport drop above guards against).
4981
+ portfolio: {
4982
+ byKey: {},
4983
+ nextRequestId: state.portfolio.nextRequestId
4984
+ },
4788
4985
  fiat: { selectedMethod: null },
4789
4986
  exchange: { selectedConnection: null }
4790
4987
  };
@@ -4819,60 +5016,6 @@ function applyAction(state, action) {
4819
5016
  }
4820
5017
  }
4821
5018
 
4822
- // src/store/state.ts
4823
- function createInitialState(overrides) {
4824
- return {
4825
- flow: {
4826
- step: "connect",
4827
- mode: null,
4828
- isConnectSelectionConfirmed: false,
4829
- hasNavigatedBack: false
4830
- },
4831
- wallet: {
4832
- selectedWalletId: null
4833
- },
4834
- deposit: {
4835
- targetChain: overrides.targetChain,
4836
- targetToken: overrides.targetToken,
4837
- sourceChain: null,
4838
- sourceToken: null,
4839
- sourceSymbol: null,
4840
- sourceDecimals: null,
4841
- selectedAsset: null,
4842
- selectedSolanaToken: null,
4843
- amount: null,
4844
- targetAmount: null,
4845
- targetTokenPriceUsd: null,
4846
- balance: null,
4847
- balanceUsd: null,
4848
- inputAmountUsd: null,
4849
- liquidityWarning: null
4850
- },
4851
- processing: {
4852
- txHash: null,
4853
- directTransfer: false,
4854
- swappedContext: null
4855
- },
4856
- dappImport: {
4857
- activeProviderId: null,
4858
- availabilityOwner: null,
4859
- availability: {},
4860
- selectedAsset: null,
4861
- bootError: false,
4862
- attemptNonce: 0
4863
- },
4864
- setup: {
4865
- byOwner: {}
4866
- },
4867
- fiat: {
4868
- selectedMethod: null
4869
- },
4870
- exchange: {
4871
- selectedConnection: null
4872
- }
4873
- };
4874
- }
4875
-
4876
5019
  // src/store/index.ts
4877
5020
  function createDepositStore(overrides) {
4878
5021
  const store = createStore(() => createInitialState(overrides));
@@ -4956,8 +5099,7 @@ function computeRequestKey(input, sessionOwnerAddress) {
4956
5099
  signerAddress: input.signerAddress.toLowerCase(),
4957
5100
  sessionChainIds: input.sessionChainIds ?? null,
4958
5101
  enableSolana: input.enableSolana ?? true,
4959
- forceRegister: input.forceRegister ?? false,
4960
- postBridgeActions: input.postBridgeActions ?? null
5102
+ forceRegister: input.forceRegister ?? false
4961
5103
  });
4962
5104
  }
4963
5105
  function computeCacheKey(input, sessionOwnerAddress) {
@@ -4975,7 +5117,7 @@ function computeCacheKey(input, sessionOwnerAddress) {
4975
5117
  });
4976
5118
  }
4977
5119
  function computeIsCacheable(input) {
4978
- return !input.forceRegister && !(input.postBridgeActions?.length ?? 0);
5120
+ return !input.forceRegister;
4979
5121
  }
4980
5122
  var SETUP_REQUEST_DEDUPE_TTL_MS = 3e4;
4981
5123
  var setupRequestDedupe = /* @__PURE__ */ new Map();
@@ -4996,7 +5138,6 @@ async function runAccountSetup(input, deps) {
4996
5138
  debugLog(debug, "account-setup", "setup:start", {
4997
5139
  owner: input.ownerAddress,
4998
5140
  sessionOwner: sessionOwner.address,
4999
- hasPostBridgeActions: Boolean(input.postBridgeActions?.length),
5000
5141
  forceRegister: input.forceRegister ?? false
5001
5142
  });
5002
5143
  const setup = await service.setupAccount({
@@ -5005,7 +5146,6 @@ async function runAccountSetup(input, deps) {
5005
5146
  targetChain: targetChainToCaip2(input.targetChain),
5006
5147
  targetToken: input.targetToken,
5007
5148
  recipient: input.recipient,
5008
- postBridgeActions: input.postBridgeActions,
5009
5149
  outputTokenRules: input.outputTokenRules,
5010
5150
  rejectUnmapped: input.rejectUnmapped,
5011
5151
  signerAddress: input.signerAddress,
@@ -5058,9 +5198,6 @@ async function runAccountSetup(input, deps) {
5058
5198
  chain: targetChainToCaip2(input.targetChain),
5059
5199
  token: input.targetToken,
5060
5200
  ...input.recipient && { recipient: input.recipient },
5061
- ...input.postBridgeActions?.length && {
5062
- postBridgeActions: input.postBridgeActions
5063
- },
5064
5201
  ...input.outputTokenRules?.length && {
5065
5202
  outputTokenRules: input.outputTokenRules
5066
5203
  },
@@ -5350,7 +5487,6 @@ function DepositFlow({
5350
5487
  amount: defaultAmount,
5351
5488
  recipient,
5352
5489
  appBalanceUsd,
5353
- postBridgeActions,
5354
5490
  outputTokenRules,
5355
5491
  rejectUnmapped,
5356
5492
  signerAddress = DEFAULT_SIGNER_ADDRESS,
@@ -5386,6 +5522,7 @@ function DepositFlow({
5386
5522
  const depositSlice = useDepositStore((s) => s.deposit);
5387
5523
  const processingSlice = useDepositStore((s) => s.processing);
5388
5524
  const setupSlice = useDepositStore((s) => s.setup);
5525
+ const portfolioSlice = useDepositStore((s) => s.portfolio);
5389
5526
  const fiatSlice = useDepositStore((s) => s.fiat);
5390
5527
  const exchangeSlice = useDepositStore((s) => s.exchange);
5391
5528
  const flowMode = flowSlice.mode;
@@ -5406,6 +5543,25 @@ function DepositFlow({
5406
5543
  },
5407
5544
  [debug]
5408
5545
  );
5546
+ const enableSwappedPreconnect = enableFiatOnramp || enableExchangeConnect;
5547
+ useEffect10(() => {
5548
+ if (!enableSwappedPreconnect) return;
5549
+ if (typeof document === "undefined") return;
5550
+ const links = [];
5551
+ for (const origin of SWAPPED_ORIGINS) {
5552
+ for (const rel of ["preconnect", "dns-prefetch"]) {
5553
+ const link = document.createElement("link");
5554
+ link.rel = rel;
5555
+ link.href = origin;
5556
+ link.dataset.rsSwappedPreconnect = "";
5557
+ document.head.appendChild(link);
5558
+ links.push(link);
5559
+ }
5560
+ }
5561
+ return () => {
5562
+ for (const link of links) link.remove();
5563
+ };
5564
+ }, [enableSwappedPreconnect]);
5409
5565
  const dappSwitchChain = useMemo7(() => {
5410
5566
  if (!dappWalletClient?.switchChain) return void 0;
5411
5567
  return async (chainId) => {
@@ -6114,6 +6270,46 @@ function DepositFlow({
6114
6270
  },
6115
6271
  [storeApi]
6116
6272
  );
6273
+ const swappedUrlPrefetchRef = useRef8(/* @__PURE__ */ new Map());
6274
+ const prefetchSwappedWidgetUrl = useCallback7(
6275
+ (smartAccount, method) => {
6276
+ const cache = swappedUrlPrefetchRef.current;
6277
+ const key = method ?? "";
6278
+ const owner = smartAccount.toLowerCase();
6279
+ const existing = cache.get(key);
6280
+ if (existing && existing.smartAccount === owner) return;
6281
+ const promise = service.getSwappedWidgetUrl({ smartAccount, method });
6282
+ promise.catch(() => {
6283
+ });
6284
+ cache.set(key, { smartAccount: owner, promise });
6285
+ logFlow("swapped:prefetch", { method: method ?? null });
6286
+ },
6287
+ [service, logFlow]
6288
+ );
6289
+ const consumeSwappedWidgetUrlPrefetch = useCallback7(
6290
+ (smartAccount, method) => {
6291
+ const cache = swappedUrlPrefetchRef.current;
6292
+ const key = method ?? "";
6293
+ const entry = cache.get(key);
6294
+ if (!entry) return null;
6295
+ cache.delete(key);
6296
+ if (entry.smartAccount !== smartAccount.toLowerCase()) return null;
6297
+ return entry.promise;
6298
+ },
6299
+ []
6300
+ );
6301
+ const handlePrefetchFiatMethod = useCallback7(
6302
+ (method) => {
6303
+ if (!enableFiatOnramp || !dappAddress) return;
6304
+ const entry = readSetupForOwner(setupSlice, dappAddress);
6305
+ if (entry.status !== "ready" || !entry.smartAccount) return;
6306
+ prefetchSwappedWidgetUrl(entry.smartAccount, method);
6307
+ },
6308
+ [enableFiatOnramp, dappAddress, setupSlice, prefetchSwappedWidgetUrl]
6309
+ );
6310
+ useEffect10(() => {
6311
+ swappedUrlPrefetchRef.current.clear();
6312
+ }, [dappAddress]);
6117
6313
  const handleNewDeposit = useCallback7(() => {
6118
6314
  onLifecycleRef.current?.({
6119
6315
  type: "smart-account-changed",
@@ -6123,6 +6319,7 @@ function DepositFlow({
6123
6319
  storeApi.dispatch({ type: "flow/reset" });
6124
6320
  stableWalletSignerRef.current = null;
6125
6321
  stableWalletSelectionKeyRef.current = null;
6322
+ swappedUrlPrefetchRef.current.clear();
6126
6323
  }, [onLifecycleRef, storeApi]);
6127
6324
  const setupInputBase = useMemo7(
6128
6325
  () => ({
@@ -6131,7 +6328,6 @@ function DepositFlow({
6131
6328
  signerAddress,
6132
6329
  sessionChainIds,
6133
6330
  recipient,
6134
- postBridgeActions,
6135
6331
  outputTokenRules,
6136
6332
  rejectUnmapped,
6137
6333
  forceRegister,
@@ -6143,7 +6339,6 @@ function DepositFlow({
6143
6339
  signerAddress,
6144
6340
  sessionChainIds,
6145
6341
  recipient,
6146
- postBridgeActions,
6147
6342
  outputTokenRules,
6148
6343
  rejectUnmapped,
6149
6344
  forceRegister,
@@ -6266,6 +6461,58 @@ function DepositFlow({
6266
6461
  storeApi,
6267
6462
  setupSlice.byOwner
6268
6463
  ]);
6464
+ const walletOptionsKey = useMemo7(
6465
+ () => walletOptions.map((option) => option.id).join(","),
6466
+ [walletOptions]
6467
+ );
6468
+ const desiredPortfolios = useMemo7(
6469
+ () => walletOptions.flatMap((option) => {
6470
+ const network = option.kind === "solana" ? "solana" : "evm";
6471
+ const address = option.kind === "solana" ? option.solanaAddress : option.address;
6472
+ return address ? [{ network, address }] : [];
6473
+ }),
6474
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- keyed on the stable id-join, not the walletOptions array identity
6475
+ [walletOptionsKey]
6476
+ );
6477
+ useEffect10(() => {
6478
+ storeApi.dispatch({
6479
+ type: "portfolio/reconciled",
6480
+ wallets: desiredPortfolios
6481
+ });
6482
+ desiredPortfolios.forEach(({ network, address }) => {
6483
+ if (readPortfolioEntry(storeApi.getState().portfolio, network, address)) {
6484
+ return;
6485
+ }
6486
+ storeApi.dispatch({ type: "portfolio/loading", network, address });
6487
+ const requestId = readPortfolioEntry(
6488
+ storeApi.getState().portfolio,
6489
+ network,
6490
+ address
6491
+ )?.requestId;
6492
+ if (requestId === void 0) return;
6493
+ void (async () => {
6494
+ try {
6495
+ const portfolio = network === "solana" ? await service.fetchSolanaPortfolio(address, {
6496
+ forceRefresh: true
6497
+ }) : await service.fetchPortfolio(address, { forceRefresh: true });
6498
+ storeApi.dispatch({
6499
+ type: "portfolio/loaded",
6500
+ network,
6501
+ address,
6502
+ requestId,
6503
+ totalUsd: portfolio.totalUsd
6504
+ });
6505
+ } catch {
6506
+ storeApi.dispatch({
6507
+ type: "portfolio/failed",
6508
+ network,
6509
+ address,
6510
+ requestId
6511
+ });
6512
+ }
6513
+ })();
6514
+ });
6515
+ }, [desiredPortfolios, service, storeApi, portfolioSlice.byKey]);
6269
6516
  const handleDepositAddressSubmitted = useCallback7(
6270
6517
  (data) => {
6271
6518
  logFlow("deposit-address:detected", {
@@ -6486,10 +6733,6 @@ function DepositFlow({
6486
6733
  const handleTotalBalanceComputed = useCallback7((total) => {
6487
6734
  setTotalBalanceUsd(total);
6488
6735
  }, []);
6489
- const walletOptionsKey = useMemo7(
6490
- () => walletOptions.map((option) => option.id).join(","),
6491
- [walletOptions]
6492
- );
6493
6736
  useEffect10(() => {
6494
6737
  if (storeApi.getState().flow.mode) {
6495
6738
  return;
@@ -6526,6 +6769,13 @@ function DepositFlow({
6526
6769
  const ownerForRow = option.kind === "solana" ? dappAddress : option.address ?? null;
6527
6770
  const entry = readSetupForOwner(setupSlice, ownerForRow ?? null);
6528
6771
  const state = entry.status === "ready" ? "ready" : entry.status === "error" ? "error" : "loading";
6772
+ const network = option.kind === "solana" ? "solana" : "evm";
6773
+ const balanceAddress = option.kind === "solana" ? option.solanaAddress : option.address;
6774
+ const portfolioEntry = readPortfolioEntry(
6775
+ portfolioSlice,
6776
+ network,
6777
+ balanceAddress
6778
+ );
6529
6779
  return {
6530
6780
  id: option.id,
6531
6781
  kind: option.kind,
@@ -6533,10 +6783,12 @@ function DepositFlow({
6533
6783
  icon: option.icon,
6534
6784
  address: option.address ?? option.solanaAddress ?? option.id,
6535
6785
  state,
6536
- errorReason: entry.message ?? void 0
6786
+ errorReason: entry.message ?? void 0,
6787
+ balanceStatus: portfolioEntry?.status ?? "loading",
6788
+ balanceUsd: portfolioEntry?.status === "ready" ? portfolioEntry.totalUsd : null
6537
6789
  };
6538
6790
  });
6539
- }, [walletOptions, setupSlice, dappAddress]);
6791
+ }, [walletOptions, setupSlice, dappAddress, portfolioSlice]);
6540
6792
  const transferCryptoEntry = useMemo7(
6541
6793
  () => readSetupForOwner(setupSlice, dappAddress),
6542
6794
  [setupSlice, dappAddress]
@@ -6564,6 +6816,7 @@ function DepositFlow({
6564
6816
  } : void 0,
6565
6817
  fiatPaymentMethods: enableFiatOnramp && dappAddress ? fiatOnrampMethods && fiatOnrampMethods.length > 0 ? fiatOnrampMethods : DEFAULT_FIAT_ONRAMP_METHODS : void 0,
6566
6818
  onSelectFiatMethod: enableFiatOnramp && dappAddress ? (method) => handleSelectFiatMethod(method) : void 0,
6819
+ onPrefetchFiatMethod: enableFiatOnramp && dappAddress ? handlePrefetchFiatMethod : void 0,
6567
6820
  onSelectFundFromExchange: enableExchangeConnect && dappAddress ? () => handleSelectExchange() : void 0,
6568
6821
  onRequestConnect,
6569
6822
  onConnect,
@@ -6628,7 +6881,6 @@ function DepositFlow({
6628
6881
  allowedRoutes,
6629
6882
  targetChain,
6630
6883
  targetToken,
6631
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
6632
6884
  uiConfig,
6633
6885
  onDepositSubmitted: handleDepositAddressSubmitted,
6634
6886
  onDepositComplete: handleDepositComplete,
@@ -6672,10 +6924,12 @@ function DepositFlow({
6672
6924
  smartAccount: step.smartAccount,
6673
6925
  service,
6674
6926
  paymentMethod: step.paymentMethod,
6927
+ consumePrefetchedUrl: consumeSwappedWidgetUrlPrefetch,
6675
6928
  onSwappedComplete: handleSwappedComplete,
6676
6929
  onSwappedFailed: handleDepositFailed,
6677
6930
  onClose: onClose ?? (() => {
6678
6931
  }),
6932
+ onGoBack: handleBack,
6679
6933
  onError: handleError
6680
6934
  }
6681
6935
  ),
@@ -6694,7 +6948,6 @@ function DepositFlow({
6694
6948
  sourceDecimals: step.sourceDecimals,
6695
6949
  amountUsd: step.inputAmountUsd,
6696
6950
  swappedContext: step.swappedContext,
6697
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
6698
6951
  service,
6699
6952
  directTransfer: step.directTransfer,
6700
6953
  isSwappedOrder: true,
@@ -6744,6 +6997,7 @@ function DepositFlow({
6744
6997
  onSwappedFailed: handleDepositFailed,
6745
6998
  onClose: onClose ?? (() => {
6746
6999
  }),
7000
+ onGoBack: handleBack,
6747
7001
  onError: handleError
6748
7002
  }
6749
7003
  ),
@@ -6762,7 +7016,6 @@ function DepositFlow({
6762
7016
  sourceDecimals: step.sourceDecimals,
6763
7017
  amountUsd: step.inputAmountUsd,
6764
7018
  swappedContext: step.swappedContext,
6765
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
6766
7019
  service,
6767
7020
  directTransfer: step.directTransfer,
6768
7021
  isSwappedOrder: true,
@@ -6892,7 +7145,6 @@ function DepositFlow({
6892
7145
  sourceSymbol: effectiveStep.sourceSymbol,
6893
7146
  sourceDecimals: effectiveStep.sourceDecimals,
6894
7147
  amountUsd: effectiveStep.inputAmountUsd,
6895
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
6896
7148
  service,
6897
7149
  directTransfer: effectiveStep.directTransfer,
6898
7150
  onClose,
@@ -7054,7 +7306,6 @@ function DepositFlow({
7054
7306
  sourceSymbol: effectiveStep.sourceSymbol,
7055
7307
  sourceDecimals: effectiveStep.sourceDecimals,
7056
7308
  amountUsd: effectiveStep.inputAmountUsd,
7057
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
7058
7309
  service,
7059
7310
  directTransfer: effectiveStep.directTransfer,
7060
7311
  uiConfig,
@@ -7357,7 +7608,7 @@ DepositHistoryPanel.displayName = "DepositHistoryPanel";
7357
7608
  // src/DepositModal.tsx
7358
7609
  import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
7359
7610
  var ReownDepositInner = lazy2(
7360
- () => import("./DepositModalReown-6AO4QURQ.mjs").then((m) => ({ default: m.DepositModalReown }))
7611
+ () => import("./DepositModalReown-YD7TLEAA.mjs").then((m) => ({ default: m.DepositModalReown }))
7361
7612
  );
7362
7613
  function sortByCreatedAtDesc(items) {
7363
7614
  return [...items].sort((a, b) => {
@@ -7407,7 +7658,7 @@ function DepositModalInner({
7407
7658
  recipient,
7408
7659
  appBalanceUsd,
7409
7660
  backendUrl = DEFAULT_BACKEND_URL,
7410
- rpcUrls,
7661
+ rpcUrls: rpcUrlsProp,
7411
7662
  signerAddress = DEFAULT_SIGNER_ADDRESS,
7412
7663
  sessionChainIds,
7413
7664
  forceRegister = false,
@@ -7418,7 +7669,6 @@ function DepositModalInner({
7418
7669
  enableQrTransfer = true,
7419
7670
  fiatOnrampMethods,
7420
7671
  enableExchangeConnect = false,
7421
- postBridgeActions,
7422
7672
  outputTokenRules,
7423
7673
  rejectUnmapped,
7424
7674
  reownWallet,
@@ -7454,6 +7704,7 @@ function DepositModalInner({
7454
7704
  const historyLoadedRef = useRef9(false);
7455
7705
  const targetChain = targetChainProp === "solana" ? "solana" : getChainId(targetChainProp);
7456
7706
  const sourceChain = sourceChainProp ? getChainId(sourceChainProp) : void 0;
7707
+ const rpcUrls = useStableRpcUrls(rpcUrlsProp);
7457
7708
  const [recipientIsContract, setRecipientIsContract] = useState13(false);
7458
7709
  const onErrorRef = useLatestRef(onError);
7459
7710
  useEffect11(() => {
@@ -7667,7 +7918,6 @@ function DepositModalInner({
7667
7918
  amount: defaultAmount,
7668
7919
  recipient,
7669
7920
  appBalanceUsd,
7670
- postBridgeActions,
7671
7921
  outputTokenRules,
7672
7922
  rejectUnmapped,
7673
7923
  signerAddress,