@rhinestone/deposit-modal 0.5.1 → 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.
@@ -68,7 +68,7 @@ import {
68
68
  useLatestRef,
69
69
  useRpcUrls,
70
70
  useStableRpcUrls
71
- } from "./chunk-4YLVKTSU.mjs";
71
+ } from "./chunk-GQDVHMOT.mjs";
72
72
  import {
73
73
  SAFE_ABI
74
74
  } from "./chunk-F7P4MV72.mjs";
@@ -1174,7 +1174,6 @@ function DepositNotification({
1174
1174
  solanaDepositAddress,
1175
1175
  targetChain,
1176
1176
  targetToken,
1177
- hasPostBridgeActions,
1178
1177
  service,
1179
1178
  onComplete,
1180
1179
  onFailed,
@@ -1208,8 +1207,7 @@ function DepositNotification({
1208
1207
  sourceToken: token,
1209
1208
  sourceDecimals,
1210
1209
  targetChain,
1211
- targetToken,
1212
- hasPostBridgeActions
1210
+ targetToken
1213
1211
  });
1214
1212
  const onCompleteRef = useLatestRef(onComplete);
1215
1213
  const onFailedRef = useLatestRef(onFailed);
@@ -1255,17 +1253,7 @@ function DepositNotification({
1255
1253
  if (!isMounted) return;
1256
1254
  const lastEvent = data.lastEvent;
1257
1255
  const eventForTx = isEventForTx(lastEvent, txHash) ? lastEvent : void 0;
1258
- const awaitingPostBridgeSwap = depositContextRef.current.hasPostBridgeActions;
1259
- if (eventForTx?.type === "post-bridge-swap-complete") {
1260
- const swapTxHash = eventForTx.data?.swap?.transactionHash;
1261
- handleComplete(swapTxHash);
1262
- return;
1263
- }
1264
- if (eventForTx?.type === "post-bridge-swap-failed") {
1265
- handleFailed(formatBridgeFailedMessage(eventForTx));
1266
- return;
1267
- }
1268
- if (eventForTx?.type === "bridge-complete" && !awaitingPostBridgeSwap) {
1256
+ if (eventForTx?.type === "bridge-complete") {
1269
1257
  const destTx = eventForTx.data?.destination?.transactionHash;
1270
1258
  handleComplete(destTx);
1271
1259
  return;
@@ -1530,7 +1518,6 @@ function DepositAddressStep({
1530
1518
  allowedRoutes,
1531
1519
  targetChain,
1532
1520
  targetToken,
1533
- hasPostBridgeActions,
1534
1521
  uiConfig,
1535
1522
  onDepositSubmitted,
1536
1523
  onDepositComplete,
@@ -2037,7 +2024,6 @@ function DepositAddressStep({
2037
2024
  solanaDepositAddress,
2038
2025
  targetChain,
2039
2026
  targetToken,
2040
- hasPostBridgeActions,
2041
2027
  service,
2042
2028
  onComplete: handleNotificationComplete,
2043
2029
  onFailed: handleNotificationFailed,
@@ -2053,6 +2039,20 @@ DepositAddressStep.displayName = "DepositAddressStep";
2053
2039
  // src/components/steps/FiatOnrampStep.tsx
2054
2040
  import { useCallback as useCallback3 } from "react";
2055
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
+
2056
2056
  // src/components/steps/SwappedIframeStep.tsx
2057
2057
  import { useState as useState6, useEffect as useEffect6, useRef as useRef6, useMemo as useMemo4 } from "react";
2058
2058
 
@@ -2176,11 +2176,7 @@ var DEPOSIT_POLL_INTERVAL_MS = 2e3;
2176
2176
  var DEPOSIT_POLL_FAST_INITIAL_DELAY_MS = 1e3;
2177
2177
  var DEPOSIT_POLL_FAST_INTERVAL_MS = 500;
2178
2178
  var IFRAME_LOAD_TIMEOUT_MS = 15e3;
2179
- var SWAPPED_IFRAME_ORIGINS = /* @__PURE__ */ new Set([
2180
- "https://connect.swapped.com",
2181
- "https://sandbox.swapped.com",
2182
- "https://widget.swapped.com"
2183
- ]);
2179
+ var SWAPPED_IFRAME_ORIGINS = new Set(SWAPPED_ORIGINS);
2184
2180
  var SWAPPED_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
2185
2181
  "order_completed",
2186
2182
  "order_broadcasted"
@@ -2191,6 +2187,24 @@ var SWAPPED_STATUS_VALUES = /* @__PURE__ */ new Set([
2191
2187
  "order_broadcasted",
2192
2188
  "order_cancelled"
2193
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
+ }
2194
2208
  function parseSwappedIframeMessage(raw) {
2195
2209
  let data = raw;
2196
2210
  if (typeof data === "string") {
@@ -2211,6 +2225,7 @@ function parseSwappedIframeMessage(raw) {
2211
2225
  return {
2212
2226
  status: rawStatus,
2213
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),
2214
2229
  orderCrypto: asString2(inner.order_crypto) ?? asString2(obj.orderCrypto),
2215
2230
  orderCryptoAmount: asString2(inner.order_crypto_amount) ?? asString2(obj.orderCryptoAmount),
2216
2231
  transactionId: asString2(inner.transaction_id) ?? asString2(obj.transactionId)
@@ -2228,6 +2243,7 @@ function SwappedIframeStep({
2228
2243
  onSwappedComplete,
2229
2244
  onSwappedFailed,
2230
2245
  onClose,
2246
+ onGoBack,
2231
2247
  onError
2232
2248
  }) {
2233
2249
  const [widgetUrl, setWidgetUrl] = useState6(null);
@@ -2241,6 +2257,7 @@ function SwappedIframeStep({
2241
2257
  const completeFiredRef = useRef6(false);
2242
2258
  const failedFiredRef = useRef6(false);
2243
2259
  const expectedOrderUuidRef = useRef6(null);
2260
+ const expectedExternalCustomerIdRef = useRef6(null);
2244
2261
  const baselineDepositTxHashRef = useRef6(void 0);
2245
2262
  const currentDepositTxHashRef = useRef6(null);
2246
2263
  const fastDepositPollEnabledRef = useRef6(false);
@@ -2253,6 +2270,8 @@ function SwappedIframeStep({
2253
2270
  onSwappedFailedRef.current = onSwappedFailed;
2254
2271
  const onErrorRef = useRef6(onError);
2255
2272
  onErrorRef.current = onError;
2273
+ const onGoBackRef = useRef6(onGoBack);
2274
+ onGoBackRef.current = onGoBack;
2256
2275
  const loadUrlRef = useRef6(loadUrl);
2257
2276
  loadUrlRef.current = loadUrl;
2258
2277
  useEffect6(() => {
@@ -2264,6 +2283,7 @@ function SwappedIframeStep({
2264
2283
  setLatestEvent(null);
2265
2284
  setPhase("iframe");
2266
2285
  expectedOrderUuidRef.current = null;
2286
+ expectedExternalCustomerIdRef.current = null;
2267
2287
  completeFiredRef.current = false;
2268
2288
  failedFiredRef.current = false;
2269
2289
  baselineDepositTxHashRef.current = void 0;
@@ -2272,6 +2292,7 @@ function SwappedIframeStep({
2272
2292
  loadUrlRef.current().then((res) => {
2273
2293
  if (cancelled) return;
2274
2294
  setWidgetUrl(res.url);
2295
+ expectedExternalCustomerIdRef.current = res.externalCustomerId;
2275
2296
  const sep = res.externalCustomerId.indexOf(":");
2276
2297
  expectedOrderUuidRef.current = sep >= 0 ? res.externalCustomerId.slice(sep + 1) : null;
2277
2298
  }).catch((err) => {
@@ -2361,14 +2382,21 @@ function SwappedIframeStep({
2361
2382
  function onMessage(e) {
2362
2383
  if (!SWAPPED_IFRAME_ORIGINS.has(e.origin)) return;
2363
2384
  if (e.source !== iframeRef.current?.contentWindow) return;
2385
+ if (isSwappedGoBackMessage(e.data)) {
2386
+ onGoBackRef.current();
2387
+ return;
2388
+ }
2364
2389
  const parsed = parseSwappedIframeMessage(e.data);
2365
2390
  if (!parsed) return;
2366
- const orderId = parsed.orderId;
2367
- if (!orderId || orderId !== expectedOrderUuidRef.current) {
2391
+ const ext = parsed.externalCustomerId;
2392
+ const expected = expectedExternalCustomerIdRef.current;
2393
+ if (!ext || !expected || ext.toLowerCase() !== expected.toLowerCase()) {
2368
2394
  return;
2369
2395
  }
2370
2396
  setOrderState((prev) => ({
2371
- 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,
2372
2400
  status: parsed.status,
2373
2401
  orderCrypto: parsed.orderCrypto ?? prev?.orderCrypto ?? null,
2374
2402
  orderCryptoAmount: parsed.orderCryptoAmount ?? prev?.orderCryptoAmount ?? null,
@@ -2408,7 +2436,7 @@ function SwappedIframeStep({
2408
2436
  useEffect6(() => {
2409
2437
  if (completeFiredRef.current || failedFiredRef.current) return;
2410
2438
  const t = latestEvent?.type;
2411
- const isSuccess = t === "bridge-complete" || t === "post-bridge-swap-complete";
2439
+ const isSuccess = t === "bridge-complete";
2412
2440
  if (!isSuccess) return;
2413
2441
  const txHash = currentDepositTxHashRef.current;
2414
2442
  if (!txHash) return;
@@ -2491,7 +2519,7 @@ function deriveStepStates(swappedStatus, latestEvent) {
2491
2519
  }
2492
2520
  const step1Complete = swappedStatus === "order_completed" || swappedStatus === "order_broadcasted";
2493
2521
  const step2Complete = latestEvent !== null;
2494
- const step3Complete = latestEvent?.type === "bridge-complete" || latestEvent?.type === "post-bridge-swap-complete";
2522
+ const step3Complete = latestEvent?.type === "bridge-complete";
2495
2523
  if (step3Complete) {
2496
2524
  return ["complete", "complete", "complete", "pending"];
2497
2525
  }
@@ -2537,18 +2565,27 @@ function FiatOnrampStep({
2537
2565
  smartAccount,
2538
2566
  service,
2539
2567
  paymentMethod,
2568
+ consumePrefetchedUrl,
2540
2569
  onSwappedComplete,
2541
2570
  onSwappedFailed,
2542
2571
  onClose,
2572
+ onGoBack,
2543
2573
  onError
2544
2574
  }) {
2545
2575
  const loadUrl = useCallback3(async () => {
2546
- 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({
2547
2585
  smartAccount,
2548
2586
  method: paymentMethod
2549
2587
  });
2550
- return res;
2551
- }, [service, smartAccount, paymentMethod]);
2588
+ }, [service, smartAccount, paymentMethod, consumePrefetchedUrl]);
2552
2589
  return /* @__PURE__ */ jsx10(
2553
2590
  SwappedIframeStep,
2554
2591
  {
@@ -2563,6 +2600,7 @@ function FiatOnrampStep({
2563
2600
  onSwappedComplete,
2564
2601
  onSwappedFailed,
2565
2602
  onClose,
2603
+ onGoBack,
2566
2604
  onError
2567
2605
  }
2568
2606
  );
@@ -2608,6 +2646,7 @@ function ExchangeConnectStep({
2608
2646
  onSwappedComplete,
2609
2647
  onSwappedFailed,
2610
2648
  onClose,
2649
+ onGoBack,
2611
2650
  onError
2612
2651
  }) {
2613
2652
  const loadUrl = useCallback4(async () => {
@@ -2631,6 +2670,7 @@ function ExchangeConnectStep({
2631
2670
  onSwappedComplete,
2632
2671
  onSwappedFailed,
2633
2672
  onClose,
2673
+ onGoBack,
2634
2674
  onError
2635
2675
  }
2636
2676
  );
@@ -4105,6 +4145,67 @@ function getEnabledProviders(config) {
4105
4145
  );
4106
4146
  }
4107
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
+
4108
4209
  // src/store/selectors.ts
4109
4210
  var selectedWalletIdSelector = (state) => state.wallet.selectedWalletId;
4110
4211
  var IDLE_SETUP_ENTRY = {
@@ -4124,6 +4225,10 @@ function readSetupForOwner(setup, owner) {
4124
4225
  const entry = setup.byOwner[owner.toLowerCase()];
4125
4226
  return entry ?? { ...IDLE_SETUP_ENTRY, owner };
4126
4227
  }
4228
+ function readPortfolioEntry(portfolio, network, address) {
4229
+ if (!address) return void 0;
4230
+ return portfolio.byKey[portfolioKey(network, address)];
4231
+ }
4127
4232
 
4128
4233
  // src/core/dapp-imports/status.ts
4129
4234
  function computeDappImportStatus(providerId, inputs) {
@@ -4531,6 +4636,79 @@ function applyAction(state, action) {
4531
4636
  message: null,
4532
4637
  attemptNonce: entry.attemptNonce + 1
4533
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
+ }
4534
4712
  case "asset/selected":
4535
4713
  return {
4536
4714
  ...state,
@@ -4797,6 +4975,13 @@ function applyAction(state, action) {
4797
4975
  attemptNonce: 0
4798
4976
  },
4799
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
+ },
4800
4985
  fiat: { selectedMethod: null },
4801
4986
  exchange: { selectedConnection: null }
4802
4987
  };
@@ -4831,60 +5016,6 @@ function applyAction(state, action) {
4831
5016
  }
4832
5017
  }
4833
5018
 
4834
- // src/store/state.ts
4835
- function createInitialState(overrides) {
4836
- return {
4837
- flow: {
4838
- step: "connect",
4839
- mode: null,
4840
- isConnectSelectionConfirmed: false,
4841
- hasNavigatedBack: false
4842
- },
4843
- wallet: {
4844
- selectedWalletId: null
4845
- },
4846
- deposit: {
4847
- targetChain: overrides.targetChain,
4848
- targetToken: overrides.targetToken,
4849
- sourceChain: null,
4850
- sourceToken: null,
4851
- sourceSymbol: null,
4852
- sourceDecimals: null,
4853
- selectedAsset: null,
4854
- selectedSolanaToken: null,
4855
- amount: null,
4856
- targetAmount: null,
4857
- targetTokenPriceUsd: null,
4858
- balance: null,
4859
- balanceUsd: null,
4860
- inputAmountUsd: null,
4861
- liquidityWarning: null
4862
- },
4863
- processing: {
4864
- txHash: null,
4865
- directTransfer: false,
4866
- swappedContext: null
4867
- },
4868
- dappImport: {
4869
- activeProviderId: null,
4870
- availabilityOwner: null,
4871
- availability: {},
4872
- selectedAsset: null,
4873
- bootError: false,
4874
- attemptNonce: 0
4875
- },
4876
- setup: {
4877
- byOwner: {}
4878
- },
4879
- fiat: {
4880
- selectedMethod: null
4881
- },
4882
- exchange: {
4883
- selectedConnection: null
4884
- }
4885
- };
4886
- }
4887
-
4888
5019
  // src/store/index.ts
4889
5020
  function createDepositStore(overrides) {
4890
5021
  const store = createStore(() => createInitialState(overrides));
@@ -4968,8 +5099,7 @@ function computeRequestKey(input, sessionOwnerAddress) {
4968
5099
  signerAddress: input.signerAddress.toLowerCase(),
4969
5100
  sessionChainIds: input.sessionChainIds ?? null,
4970
5101
  enableSolana: input.enableSolana ?? true,
4971
- forceRegister: input.forceRegister ?? false,
4972
- postBridgeActions: input.postBridgeActions ?? null
5102
+ forceRegister: input.forceRegister ?? false
4973
5103
  });
4974
5104
  }
4975
5105
  function computeCacheKey(input, sessionOwnerAddress) {
@@ -4987,7 +5117,7 @@ function computeCacheKey(input, sessionOwnerAddress) {
4987
5117
  });
4988
5118
  }
4989
5119
  function computeIsCacheable(input) {
4990
- return !input.forceRegister && !(input.postBridgeActions?.length ?? 0);
5120
+ return !input.forceRegister;
4991
5121
  }
4992
5122
  var SETUP_REQUEST_DEDUPE_TTL_MS = 3e4;
4993
5123
  var setupRequestDedupe = /* @__PURE__ */ new Map();
@@ -5008,7 +5138,6 @@ async function runAccountSetup(input, deps) {
5008
5138
  debugLog(debug, "account-setup", "setup:start", {
5009
5139
  owner: input.ownerAddress,
5010
5140
  sessionOwner: sessionOwner.address,
5011
- hasPostBridgeActions: Boolean(input.postBridgeActions?.length),
5012
5141
  forceRegister: input.forceRegister ?? false
5013
5142
  });
5014
5143
  const setup = await service.setupAccount({
@@ -5017,7 +5146,6 @@ async function runAccountSetup(input, deps) {
5017
5146
  targetChain: targetChainToCaip2(input.targetChain),
5018
5147
  targetToken: input.targetToken,
5019
5148
  recipient: input.recipient,
5020
- postBridgeActions: input.postBridgeActions,
5021
5149
  outputTokenRules: input.outputTokenRules,
5022
5150
  rejectUnmapped: input.rejectUnmapped,
5023
5151
  signerAddress: input.signerAddress,
@@ -5070,9 +5198,6 @@ async function runAccountSetup(input, deps) {
5070
5198
  chain: targetChainToCaip2(input.targetChain),
5071
5199
  token: input.targetToken,
5072
5200
  ...input.recipient && { recipient: input.recipient },
5073
- ...input.postBridgeActions?.length && {
5074
- postBridgeActions: input.postBridgeActions
5075
- },
5076
5201
  ...input.outputTokenRules?.length && {
5077
5202
  outputTokenRules: input.outputTokenRules
5078
5203
  },
@@ -5362,7 +5487,6 @@ function DepositFlow({
5362
5487
  amount: defaultAmount,
5363
5488
  recipient,
5364
5489
  appBalanceUsd,
5365
- postBridgeActions,
5366
5490
  outputTokenRules,
5367
5491
  rejectUnmapped,
5368
5492
  signerAddress = DEFAULT_SIGNER_ADDRESS,
@@ -5398,6 +5522,7 @@ function DepositFlow({
5398
5522
  const depositSlice = useDepositStore((s) => s.deposit);
5399
5523
  const processingSlice = useDepositStore((s) => s.processing);
5400
5524
  const setupSlice = useDepositStore((s) => s.setup);
5525
+ const portfolioSlice = useDepositStore((s) => s.portfolio);
5401
5526
  const fiatSlice = useDepositStore((s) => s.fiat);
5402
5527
  const exchangeSlice = useDepositStore((s) => s.exchange);
5403
5528
  const flowMode = flowSlice.mode;
@@ -5418,6 +5543,25 @@ function DepositFlow({
5418
5543
  },
5419
5544
  [debug]
5420
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]);
5421
5565
  const dappSwitchChain = useMemo7(() => {
5422
5566
  if (!dappWalletClient?.switchChain) return void 0;
5423
5567
  return async (chainId) => {
@@ -6126,6 +6270,46 @@ function DepositFlow({
6126
6270
  },
6127
6271
  [storeApi]
6128
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]);
6129
6313
  const handleNewDeposit = useCallback7(() => {
6130
6314
  onLifecycleRef.current?.({
6131
6315
  type: "smart-account-changed",
@@ -6135,6 +6319,7 @@ function DepositFlow({
6135
6319
  storeApi.dispatch({ type: "flow/reset" });
6136
6320
  stableWalletSignerRef.current = null;
6137
6321
  stableWalletSelectionKeyRef.current = null;
6322
+ swappedUrlPrefetchRef.current.clear();
6138
6323
  }, [onLifecycleRef, storeApi]);
6139
6324
  const setupInputBase = useMemo7(
6140
6325
  () => ({
@@ -6143,7 +6328,6 @@ function DepositFlow({
6143
6328
  signerAddress,
6144
6329
  sessionChainIds,
6145
6330
  recipient,
6146
- postBridgeActions,
6147
6331
  outputTokenRules,
6148
6332
  rejectUnmapped,
6149
6333
  forceRegister,
@@ -6155,7 +6339,6 @@ function DepositFlow({
6155
6339
  signerAddress,
6156
6340
  sessionChainIds,
6157
6341
  recipient,
6158
- postBridgeActions,
6159
6342
  outputTokenRules,
6160
6343
  rejectUnmapped,
6161
6344
  forceRegister,
@@ -6278,6 +6461,58 @@ function DepositFlow({
6278
6461
  storeApi,
6279
6462
  setupSlice.byOwner
6280
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]);
6281
6516
  const handleDepositAddressSubmitted = useCallback7(
6282
6517
  (data) => {
6283
6518
  logFlow("deposit-address:detected", {
@@ -6498,10 +6733,6 @@ function DepositFlow({
6498
6733
  const handleTotalBalanceComputed = useCallback7((total) => {
6499
6734
  setTotalBalanceUsd(total);
6500
6735
  }, []);
6501
- const walletOptionsKey = useMemo7(
6502
- () => walletOptions.map((option) => option.id).join(","),
6503
- [walletOptions]
6504
- );
6505
6736
  useEffect10(() => {
6506
6737
  if (storeApi.getState().flow.mode) {
6507
6738
  return;
@@ -6538,6 +6769,13 @@ function DepositFlow({
6538
6769
  const ownerForRow = option.kind === "solana" ? dappAddress : option.address ?? null;
6539
6770
  const entry = readSetupForOwner(setupSlice, ownerForRow ?? null);
6540
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
+ );
6541
6779
  return {
6542
6780
  id: option.id,
6543
6781
  kind: option.kind,
@@ -6545,10 +6783,12 @@ function DepositFlow({
6545
6783
  icon: option.icon,
6546
6784
  address: option.address ?? option.solanaAddress ?? option.id,
6547
6785
  state,
6548
- errorReason: entry.message ?? void 0
6786
+ errorReason: entry.message ?? void 0,
6787
+ balanceStatus: portfolioEntry?.status ?? "loading",
6788
+ balanceUsd: portfolioEntry?.status === "ready" ? portfolioEntry.totalUsd : null
6549
6789
  };
6550
6790
  });
6551
- }, [walletOptions, setupSlice, dappAddress]);
6791
+ }, [walletOptions, setupSlice, dappAddress, portfolioSlice]);
6552
6792
  const transferCryptoEntry = useMemo7(
6553
6793
  () => readSetupForOwner(setupSlice, dappAddress),
6554
6794
  [setupSlice, dappAddress]
@@ -6576,6 +6816,7 @@ function DepositFlow({
6576
6816
  } : void 0,
6577
6817
  fiatPaymentMethods: enableFiatOnramp && dappAddress ? fiatOnrampMethods && fiatOnrampMethods.length > 0 ? fiatOnrampMethods : DEFAULT_FIAT_ONRAMP_METHODS : void 0,
6578
6818
  onSelectFiatMethod: enableFiatOnramp && dappAddress ? (method) => handleSelectFiatMethod(method) : void 0,
6819
+ onPrefetchFiatMethod: enableFiatOnramp && dappAddress ? handlePrefetchFiatMethod : void 0,
6579
6820
  onSelectFundFromExchange: enableExchangeConnect && dappAddress ? () => handleSelectExchange() : void 0,
6580
6821
  onRequestConnect,
6581
6822
  onConnect,
@@ -6640,7 +6881,6 @@ function DepositFlow({
6640
6881
  allowedRoutes,
6641
6882
  targetChain,
6642
6883
  targetToken,
6643
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
6644
6884
  uiConfig,
6645
6885
  onDepositSubmitted: handleDepositAddressSubmitted,
6646
6886
  onDepositComplete: handleDepositComplete,
@@ -6684,10 +6924,12 @@ function DepositFlow({
6684
6924
  smartAccount: step.smartAccount,
6685
6925
  service,
6686
6926
  paymentMethod: step.paymentMethod,
6927
+ consumePrefetchedUrl: consumeSwappedWidgetUrlPrefetch,
6687
6928
  onSwappedComplete: handleSwappedComplete,
6688
6929
  onSwappedFailed: handleDepositFailed,
6689
6930
  onClose: onClose ?? (() => {
6690
6931
  }),
6932
+ onGoBack: handleBack,
6691
6933
  onError: handleError
6692
6934
  }
6693
6935
  ),
@@ -6706,7 +6948,6 @@ function DepositFlow({
6706
6948
  sourceDecimals: step.sourceDecimals,
6707
6949
  amountUsd: step.inputAmountUsd,
6708
6950
  swappedContext: step.swappedContext,
6709
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
6710
6951
  service,
6711
6952
  directTransfer: step.directTransfer,
6712
6953
  isSwappedOrder: true,
@@ -6756,6 +6997,7 @@ function DepositFlow({
6756
6997
  onSwappedFailed: handleDepositFailed,
6757
6998
  onClose: onClose ?? (() => {
6758
6999
  }),
7000
+ onGoBack: handleBack,
6759
7001
  onError: handleError
6760
7002
  }
6761
7003
  ),
@@ -6774,7 +7016,6 @@ function DepositFlow({
6774
7016
  sourceDecimals: step.sourceDecimals,
6775
7017
  amountUsd: step.inputAmountUsd,
6776
7018
  swappedContext: step.swappedContext,
6777
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
6778
7019
  service,
6779
7020
  directTransfer: step.directTransfer,
6780
7021
  isSwappedOrder: true,
@@ -6904,7 +7145,6 @@ function DepositFlow({
6904
7145
  sourceSymbol: effectiveStep.sourceSymbol,
6905
7146
  sourceDecimals: effectiveStep.sourceDecimals,
6906
7147
  amountUsd: effectiveStep.inputAmountUsd,
6907
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
6908
7148
  service,
6909
7149
  directTransfer: effectiveStep.directTransfer,
6910
7150
  onClose,
@@ -7066,7 +7306,6 @@ function DepositFlow({
7066
7306
  sourceSymbol: effectiveStep.sourceSymbol,
7067
7307
  sourceDecimals: effectiveStep.sourceDecimals,
7068
7308
  amountUsd: effectiveStep.inputAmountUsd,
7069
- hasPostBridgeActions: Boolean(postBridgeActions?.length),
7070
7309
  service,
7071
7310
  directTransfer: effectiveStep.directTransfer,
7072
7311
  uiConfig,
@@ -7369,7 +7608,7 @@ DepositHistoryPanel.displayName = "DepositHistoryPanel";
7369
7608
  // src/DepositModal.tsx
7370
7609
  import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
7371
7610
  var ReownDepositInner = lazy2(
7372
- () => import("./DepositModalReown-YJBDBCRA.mjs").then((m) => ({ default: m.DepositModalReown }))
7611
+ () => import("./DepositModalReown-YD7TLEAA.mjs").then((m) => ({ default: m.DepositModalReown }))
7373
7612
  );
7374
7613
  function sortByCreatedAtDesc(items) {
7375
7614
  return [...items].sort((a, b) => {
@@ -7430,7 +7669,6 @@ function DepositModalInner({
7430
7669
  enableQrTransfer = true,
7431
7670
  fiatOnrampMethods,
7432
7671
  enableExchangeConnect = false,
7433
- postBridgeActions,
7434
7672
  outputTokenRules,
7435
7673
  rejectUnmapped,
7436
7674
  reownWallet,
@@ -7680,7 +7918,6 @@ function DepositModalInner({
7680
7918
  amount: defaultAmount,
7681
7919
  recipient,
7682
7920
  appBalanceUsd,
7683
- postBridgeActions,
7684
7921
  outputTokenRules,
7685
7922
  rejectUnmapped,
7686
7923
  signerAddress,