@rhinestone/deposit-modal 0.8.0 → 0.8.2

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.
Files changed (30) hide show
  1. package/dist/{DepositModalReown-J5YFZKFS.cjs → DepositModalReown-A2W6R27Q.cjs} +9 -9
  2. package/dist/{DepositModalReown-RZ6VSMKP.mjs → DepositModalReown-IB5WUXVT.mjs} +6 -6
  3. package/dist/{WithdrawModalReown-4YUV2WWV.mjs → WithdrawModalReown-A4S4BJHG.mjs} +5 -5
  4. package/dist/{WithdrawModalReown-B6BGY52S.cjs → WithdrawModalReown-KUWNNA2X.cjs} +8 -8
  5. package/dist/{chunk-SX52FXKH.mjs → chunk-2O2FJYRY.mjs} +8 -1
  6. package/dist/{chunk-JRFPKFL6.cjs → chunk-3WIHTUQ6.cjs} +105 -98
  7. package/dist/{chunk-XLXJW44N.cjs → chunk-46BRQZ2P.cjs} +500 -458
  8. package/dist/{chunk-LXTAAHPC.mjs → chunk-4BLOPOVO.mjs} +2 -2
  9. package/dist/{chunk-VURI4G2Z.cjs → chunk-5E67UM3V.cjs} +7 -7
  10. package/dist/{chunk-IRI34U6N.cjs → chunk-DSXMWQYB.cjs} +262 -139
  11. package/dist/{chunk-5S5BQ2GM.mjs → chunk-KGZU3BL2.mjs} +59 -17
  12. package/dist/{chunk-4IOQIWDY.cjs → chunk-ORKEBFMR.cjs} +4 -4
  13. package/dist/{chunk-PUMTR35E.cjs → chunk-P5T4XSN2.cjs} +9 -2
  14. package/dist/{chunk-YLIPI3NU.mjs → chunk-RARNNVZO.mjs} +1 -1
  15. package/dist/{chunk-TYB6AA6D.mjs → chunk-RH6XQHMA.mjs} +1 -1
  16. package/dist/{chunk-RXWJ267K.mjs → chunk-TUSEN26M.mjs} +172 -49
  17. package/dist/{chunk-WL7AXYQ4.cjs → chunk-UNVVUULP.cjs} +3 -3
  18. package/dist/{chunk-7JJ4EFDY.mjs → chunk-XK5RH4FZ.mjs} +12 -5
  19. package/dist/constants.cjs +2 -2
  20. package/dist/constants.mjs +1 -1
  21. package/dist/deposit.cjs +6 -6
  22. package/dist/deposit.mjs +5 -5
  23. package/dist/index.cjs +7 -7
  24. package/dist/index.mjs +6 -6
  25. package/dist/polymarket.cjs +6 -6
  26. package/dist/polymarket.mjs +3 -3
  27. package/dist/styles.css +147 -1
  28. package/dist/withdraw.cjs +5 -5
  29. package/dist/withdraw.mjs +4 -4
  30. package/package.json +1 -1
@@ -7,7 +7,7 @@ import {
7
7
  executePolymarketSafeTransfer,
8
8
  fetchPolymarketProxyWallet,
9
9
  readPolymarketBalances
10
- } from "./chunk-YLIPI3NU.mjs";
10
+ } from "./chunk-RARNNVZO.mjs";
11
11
  import {
12
12
  AlertTriangleIcon,
13
13
  ArrowUpRightIcon,
@@ -47,6 +47,7 @@ import {
47
47
  debugError,
48
48
  debugLog,
49
49
  failureMessageForEvent,
50
+ fetchTokenPriceUsd,
50
51
  formatQuotedReceive,
51
52
  formatReceiveEstimate,
52
53
  formatTokenAmount,
@@ -58,8 +59,10 @@ import {
58
59
  getHyperEvmReadClient,
59
60
  getPublicClient,
60
61
  isDepositEvent,
62
+ isDisplayStablecoinSymbol,
61
63
  isFailedEvent,
62
64
  isNativeAsset,
65
+ isRecognizedToken,
63
66
  loadSessionOwnerFromStorage,
64
67
  portfolioToAssets,
65
68
  rpcUrlFor,
@@ -69,10 +72,10 @@ import {
69
72
  useLatestRef,
70
73
  useRpcUrls,
71
74
  useStableRpcUrls
72
- } from "./chunk-RXWJ267K.mjs";
75
+ } from "./chunk-TUSEN26M.mjs";
73
76
  import {
74
77
  SAFE_ABI
75
- } from "./chunk-TYB6AA6D.mjs";
78
+ } from "./chunk-RH6XQHMA.mjs";
76
79
  import {
77
80
  DEFAULT_BACKEND_URL,
78
81
  DEFAULT_SIGNER_ADDRESS,
@@ -104,7 +107,7 @@ import {
104
107
  isVirtualDestination,
105
108
  parseEvmChainId,
106
109
  targetChainToCaip2
107
- } from "./chunk-SX52FXKH.mjs";
110
+ } from "./chunk-2O2FJYRY.mjs";
108
111
 
109
112
  // src/DepositModal.tsx
110
113
  import {
@@ -906,7 +909,11 @@ function ConfirmStep({
906
909
  sourceSymbol: asset.symbol,
907
910
  targetSymbol,
908
911
  sourceAmountUsd,
909
- prices: targetTokenPriceUsd !== null && targetTokenPriceUsd > 0 ? { [targetSymbol.toUpperCase()]: targetTokenPriceUsd } : {}
912
+ sourceTrusted: isRecognizedToken(asset.token, asset.chainId),
913
+ // The target is the curated deposit destination, so a stablecoin target
914
+ // estimates at $1 when unquoted (DepositFlow skips fetching stablecoin
915
+ // target prices). Not applied to the source — that can be a held token.
916
+ prices: targetTokenPriceUsd !== null && targetTokenPriceUsd > 0 ? { [targetSymbol.toUpperCase()]: targetTokenPriceUsd } : isDisplayStablecoinSymbol(targetSymbol) ? { [targetSymbol.toUpperCase()]: 1 } : {}
910
917
  });
911
918
  if (estimate !== void 0) return estimate;
912
919
  return targetSymbol;
@@ -2305,6 +2312,7 @@ function SwappedIframeStep({
2305
2312
  onImmersiveChange
2306
2313
  }) {
2307
2314
  const [widgetUrl, setWidgetUrl] = useState6(null);
2315
+ const [iframeSrc, setIframeSrc] = useState6(null);
2308
2316
  const [loadError, setLoadError] = useState6(null);
2309
2317
  const [iframeLoaded, setIframeLoaded] = useState6(false);
2310
2318
  const [retryToken, setRetryToken] = useState6(0);
@@ -2340,6 +2348,7 @@ function SwappedIframeStep({
2340
2348
  setLoadError(null);
2341
2349
  setIframeLoaded(false);
2342
2350
  setWidgetUrl(null);
2351
+ setIframeSrc(null);
2343
2352
  setOrderState(null);
2344
2353
  setLatestEvent(null);
2345
2354
  setPhase("iframe");
@@ -2381,6 +2390,9 @@ function SwappedIframeStep({
2381
2390
  }, IFRAME_LOAD_TIMEOUT_MS);
2382
2391
  return () => clearTimeout(timer);
2383
2392
  }, [widgetUrl, iframeLoaded, loadError]);
2393
+ useEffect6(() => {
2394
+ setIframeSrc(widgetUrl && !loadError ? widgetUrl : null);
2395
+ }, [widgetUrl, loadError, retryToken]);
2384
2396
  useEffect6(() => {
2385
2397
  let cancelled = false;
2386
2398
  let timeoutId;
@@ -2543,6 +2555,13 @@ function SwappedIframeStep({
2543
2555
  onImmersiveChangeRef.current?.(immersive);
2544
2556
  }, [immersive]);
2545
2557
  useEffect6(() => () => onImmersiveChangeRef.current?.(false), []);
2558
+ const handleRetry = () => {
2559
+ setIframeSrc(null);
2560
+ setWidgetUrl(null);
2561
+ setIframeLoaded(false);
2562
+ setLoadError(null);
2563
+ setRetryToken((n) => n + 1);
2564
+ };
2546
2565
  if (phase === "tracker") {
2547
2566
  const paymentReceived = stepStates[0] === "complete";
2548
2567
  if (variant === "connect" && !terminalState && paymentReceived) {
@@ -2555,7 +2574,7 @@ function SwappedIframeStep({
2555
2574
  currency: orderState?.orderCrypto ?? "USDC",
2556
2575
  stepStates,
2557
2576
  terminal: terminalState,
2558
- onRetry: () => setRetryToken((n) => n + 1),
2577
+ onRetry: handleRetry,
2559
2578
  onClose
2560
2579
  }
2561
2580
  );
@@ -2569,7 +2588,7 @@ function SwappedIframeStep({
2569
2588
  {
2570
2589
  type: "button",
2571
2590
  className: "rs-fiat-onramp-retry",
2572
- onClick: () => setRetryToken((n) => n + 1),
2591
+ onClick: handleRetry,
2573
2592
  children: "Retry"
2574
2593
  }
2575
2594
  )
@@ -2579,12 +2598,20 @@ function SwappedIframeStep({
2579
2598
  "iframe",
2580
2599
  {
2581
2600
  ref: iframeRef,
2582
- src: widgetUrl,
2601
+ src: iframeSrc ?? void 0,
2583
2602
  title: iframeTitle,
2584
2603
  className: "rs-fiat-onramp-iframe",
2585
2604
  sandbox: "allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation",
2586
2605
  allow: "payment; camera; microphone; clipboard-write; geolocation",
2587
- onLoad: () => setIframeLoaded(true)
2606
+ onLoad: () => {
2607
+ try {
2608
+ if (iframeRef.current?.contentWindow?.location?.href === "about:blank") {
2609
+ return;
2610
+ }
2611
+ } catch {
2612
+ }
2613
+ setIframeLoaded(true);
2614
+ }
2588
2615
  },
2589
2616
  retryToken
2590
2617
  )
@@ -3631,7 +3658,10 @@ function SolanaConfirmStep({
3631
3658
  sourceSymbol: token.symbol,
3632
3659
  targetSymbol,
3633
3660
  sourceAmountUsd,
3634
- prices: targetTokenPriceUsd !== null && targetTokenPriceUsd > 0 ? { [targetSymbol.toUpperCase()]: targetTokenPriceUsd } : {}
3661
+ sourceTrusted: isRecognizedToken(token.mint, "solana"),
3662
+ // Curated stablecoin target estimates at $1 when unquoted; never applied
3663
+ // to the source (a held token). See ConfirmStep for the rationale.
3664
+ prices: targetTokenPriceUsd !== null && targetTokenPriceUsd > 0 ? { [targetSymbol.toUpperCase()]: targetTokenPriceUsd } : isDisplayStablecoinSymbol(targetSymbol) ? { [targetSymbol.toUpperCase()]: 1 } : {}
3635
3665
  });
3636
3666
  if (estimate !== void 0) return estimate;
3637
3667
  return targetSymbol;
@@ -4246,7 +4276,8 @@ function createInitialState(overrides) {
4246
4276
  step: "connect",
4247
4277
  mode: null,
4248
4278
  isConnectSelectionConfirmed: false,
4249
- hasNavigatedBack: false
4279
+ hasNavigatedBack: false,
4280
+ methodTab: "crypto"
4250
4281
  },
4251
4282
  wallet: {
4252
4283
  selectedWalletId: null
@@ -4623,6 +4654,11 @@ function applyAction(state, action) {
4623
4654
  step: "deposit-address"
4624
4655
  }
4625
4656
  };
4657
+ case "connect/method-tab-changed":
4658
+ return {
4659
+ ...state,
4660
+ flow: { ...state.flow, methodTab: action.tab }
4661
+ };
4626
4662
  case "connect/fiat-onramp-selected":
4627
4663
  return {
4628
4664
  ...state,
@@ -5056,7 +5092,8 @@ function applyAction(state, action) {
5056
5092
  step: "connect",
5057
5093
  mode: null,
5058
5094
  isConnectSelectionConfirmed: false,
5059
- hasNavigatedBack: false
5095
+ hasNavigatedBack: false,
5096
+ methodTab: "crypto"
5060
5097
  },
5061
5098
  wallet: {
5062
5099
  selectedWalletId: null
@@ -5797,15 +5834,18 @@ function DepositFlow({
5797
5834
  return;
5798
5835
  }
5799
5836
  let cancelled = false;
5800
- service.fetchPrices([targetSymbol]).then((prices) => {
5837
+ fetchTokenPriceUsd(service, {
5838
+ chainId: targetChain,
5839
+ address: targetToken,
5840
+ symbol: targetSymbol
5841
+ }).then((price) => {
5801
5842
  if (cancelled) return;
5802
- const price = prices[targetSymbol.toUpperCase()];
5803
- targetMarketPriceRef.current = typeof price === "number" && price > 0 ? price : null;
5843
+ targetMarketPriceRef.current = price;
5804
5844
  });
5805
5845
  return () => {
5806
5846
  cancelled = true;
5807
5847
  };
5808
- }, [service, targetSymbol, isTargetStablecoin]);
5848
+ }, [service, targetSymbol, isTargetStablecoin, targetChain, targetToken]);
5809
5849
  const walletSignerContext = useMemo7(() => {
5810
5850
  if (flowMode === "deposit-address") {
5811
5851
  return null;
@@ -6967,6 +7007,8 @@ function DepositFlow({
6967
7007
  ConnectStep,
6968
7008
  {
6969
7009
  walletRows,
7010
+ defaultMethodTab: flowSlice.methodTab,
7011
+ onMethodTabChange: (tab) => storeApi.dispatch({ type: "connect/method-tab-changed", tab }),
6970
7012
  transferCryptoState: dappAddress ? transferCryptoState : void 0,
6971
7013
  transferCryptoErrorReason: dappAddress ? transferCryptoEntry.message ?? void 0 : void 0,
6972
7014
  onSelectTransferCrypto: enableQrTransfer && dappAddress ? () => {
@@ -7782,7 +7824,7 @@ DepositHistoryPanel.displayName = "DepositHistoryPanel";
7782
7824
  // src/DepositModal.tsx
7783
7825
  import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
7784
7826
  var ReownDepositInner = lazy2(
7785
- () => import("./DepositModalReown-RZ6VSMKP.mjs").then((m) => ({ default: m.DepositModalReown }))
7827
+ () => import("./DepositModalReown-IB5WUXVT.mjs").then((m) => ({ default: m.DepositModalReown }))
7786
7828
  );
7787
7829
  function sortByCreatedAtDesc(items) {
7788
7830
  return [...items].sort((a, b) => {
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkWL7AXYQ4cjs = require('./chunk-WL7AXYQ4.cjs');
3
+ var _chunkUNVVUULPcjs = require('./chunk-UNVVUULP.cjs');
4
4
 
5
5
  // src/core/dapp-imports/polymarket/constants.ts
6
6
  var POLYMARKET_POLYGON_CHAIN_ID = 137;
@@ -100,7 +100,7 @@ async function executePolymarketSafeTransfer(params) {
100
100
  }
101
101
  const isOwner = await publicClient.readContract({
102
102
  address: safeAddress,
103
- abi: _chunkWL7AXYQ4cjs.SAFE_ABI,
103
+ abi: _chunkUNVVUULPcjs.SAFE_ABI,
104
104
  functionName: "isOwner",
105
105
  args: [account.address]
106
106
  });
@@ -117,7 +117,7 @@ async function executePolymarketSafeTransfer(params) {
117
117
  account,
118
118
  chain,
119
119
  address: safeAddress,
120
- abi: _chunkWL7AXYQ4cjs.SAFE_ABI,
120
+ abi: _chunkUNVVUULPcjs.SAFE_ABI,
121
121
  functionName: "execTransaction",
122
122
  args: [
123
123
  safeTx.to,
@@ -136,7 +136,7 @@ async function executePolymarketSafeTransfer(params) {
136
136
  hash: txHash
137
137
  });
138
138
  const parsed = _viem.parseEventLogs.call(void 0, {
139
- abi: _chunkWL7AXYQ4cjs.SAFE_ABI,
139
+ abi: _chunkUNVVUULPcjs.SAFE_ABI,
140
140
  logs: receipt.logs.filter(
141
141
  (log) => log.address.toLowerCase() === safeAddress.toLowerCase()
142
142
  ),
@@ -117,7 +117,7 @@ var ICON_SLUG_ALIASES = {
117
117
  xdai: "dai"
118
118
  };
119
119
  function tokenIconUrl(symbol) {
120
- const key = symbol.toLowerCase();
120
+ const key = symbol.toLowerCase().replace(/₮/g, "t");
121
121
  const slug = _nullishCoalesce(ICON_SLUG_ALIASES[key], () => ( key));
122
122
  return `https://s3.rhinestone.dev/tokens/${slug}.svg`;
123
123
  }
@@ -634,6 +634,12 @@ function findChainIdForToken(address) {
634
634
  }
635
635
  return void 0;
636
636
  }
637
+ function isRegistryTokenOnChain(token, chainId) {
638
+ const normalized = token.toLowerCase();
639
+ if (normalized === NATIVE_TOKEN_ADDRESS) return true;
640
+ const chainEntry = chainRegistry[String(chainId)];
641
+ return chainEntry ? chainEntry.tokens.some((t) => t.address.toLowerCase() === normalized) : false;
642
+ }
637
643
  var NATIVE_SYMBOL_BY_CHAIN = {
638
644
  [_chains.bsc.id]: "BNB",
639
645
  [_chains.plasma.id]: "XPL",
@@ -790,4 +796,5 @@ function getExplorerName(chainId) {
790
796
 
791
797
 
792
798
 
793
- exports.toEvmCaip2 = toEvmCaip2; exports.targetChainToCaip2 = targetChainToCaip2; exports.parseEvmChainId = parseEvmChainId; exports.isSolanaCaip2 = isSolanaCaip2; exports.isHyperCoreCaip2 = isHyperCoreCaip2; exports.HYPERCORE_CHAIN_ID = HYPERCORE_CHAIN_ID; exports.HYPERCORE_MAINNET_CAIP2 = HYPERCORE_MAINNET_CAIP2; exports.HYPERCORE_USDC_ADDRESS = HYPERCORE_USDC_ADDRESS; exports.HYPERCORE_USDT0_ADDRESS = HYPERCORE_USDT0_ADDRESS; exports.HYPERCORE_SOURCE_TOKENS = HYPERCORE_SOURCE_TOKENS; exports.HYPERCORE_MIN_DEPOSIT_USD = HYPERCORE_MIN_DEPOSIT_USD; exports.isVirtualDestination = isVirtualDestination; exports.isContractBytecode = isContractBytecode; exports.SOLANA_TOKENS = SOLANA_TOKENS; exports.getSolanaTokenBySymbol = getSolanaTokenBySymbol; exports.getSolanaTokenByMint = getSolanaTokenByMint; exports.isNativeSol = isNativeSol; exports.getChainIcon = getChainIcon; exports.tokenIconUrl = tokenIconUrl; exports.getTokenIcon = getTokenIcon; exports.DEFAULT_BACKEND_URL = DEFAULT_BACKEND_URL; exports.DEFAULT_SIGNER_ADDRESS = DEFAULT_SIGNER_ADDRESS; exports.NATIVE_TOKEN_ADDRESS = NATIVE_TOKEN_ADDRESS; exports.CHAIN_BY_ID = CHAIN_BY_ID; exports.SOURCE_CHAINS = SOURCE_CHAINS; exports.SUPPORTED_CHAINS = SUPPORTED_CHAINS; exports.chainRegistry = chainRegistry; exports.getChainId = getChainId; exports.getChainObject = getChainObject; exports.getUsdcAddress = getUsdcAddress; exports.getUsdcDecimals = getUsdcDecimals; exports.getTokenAddress = getTokenAddress; exports.getTokenDecimals = getTokenDecimals; exports.getTargetTokenSymbolsForChain = getTargetTokenSymbolsForChain; exports.getSupportedTokenSymbolsForChain = getSupportedTokenSymbolsForChain; exports.getSupportedChainIds = getSupportedChainIds; exports.isSupportedTokenAddressForChain = isSupportedTokenAddressForChain; exports.getSupportedTargetTokens = getSupportedTargetTokens; exports.findTokenDecimals = findTokenDecimals; exports.getTokenDecimalsByAddress = getTokenDecimalsByAddress; exports.findChainIdForToken = findChainIdForToken; exports.getNativeSymbol = getNativeSymbol; exports.getTokenSymbol = getTokenSymbol; exports.getTargetTokenSymbol = getTargetTokenSymbol; exports.isStablecoinSymbol = isStablecoinSymbol; exports.getChainName = getChainName; exports.getChainBadge = getChainBadge; exports.getExplorerUrl = getExplorerUrl; exports.getExplorerTxUrl = getExplorerTxUrl; exports.getExplorerName = getExplorerName;
799
+
800
+ exports.toEvmCaip2 = toEvmCaip2; exports.targetChainToCaip2 = targetChainToCaip2; exports.parseEvmChainId = parseEvmChainId; exports.isSolanaCaip2 = isSolanaCaip2; exports.isHyperCoreCaip2 = isHyperCoreCaip2; exports.HYPERCORE_CHAIN_ID = HYPERCORE_CHAIN_ID; exports.HYPERCORE_MAINNET_CAIP2 = HYPERCORE_MAINNET_CAIP2; exports.HYPERCORE_USDC_ADDRESS = HYPERCORE_USDC_ADDRESS; exports.HYPERCORE_USDT0_ADDRESS = HYPERCORE_USDT0_ADDRESS; exports.HYPERCORE_SOURCE_TOKENS = HYPERCORE_SOURCE_TOKENS; exports.HYPERCORE_MIN_DEPOSIT_USD = HYPERCORE_MIN_DEPOSIT_USD; exports.isVirtualDestination = isVirtualDestination; exports.isContractBytecode = isContractBytecode; exports.SOLANA_TOKENS = SOLANA_TOKENS; exports.getSolanaTokenBySymbol = getSolanaTokenBySymbol; exports.getSolanaTokenByMint = getSolanaTokenByMint; exports.isNativeSol = isNativeSol; exports.getChainIcon = getChainIcon; exports.tokenIconUrl = tokenIconUrl; exports.getTokenIcon = getTokenIcon; exports.DEFAULT_BACKEND_URL = DEFAULT_BACKEND_URL; exports.DEFAULT_SIGNER_ADDRESS = DEFAULT_SIGNER_ADDRESS; exports.NATIVE_TOKEN_ADDRESS = NATIVE_TOKEN_ADDRESS; exports.CHAIN_BY_ID = CHAIN_BY_ID; exports.SOURCE_CHAINS = SOURCE_CHAINS; exports.SUPPORTED_CHAINS = SUPPORTED_CHAINS; exports.chainRegistry = chainRegistry; exports.getChainId = getChainId; exports.getChainObject = getChainObject; exports.getUsdcAddress = getUsdcAddress; exports.getUsdcDecimals = getUsdcDecimals; exports.getTokenAddress = getTokenAddress; exports.getTokenDecimals = getTokenDecimals; exports.getTargetTokenSymbolsForChain = getTargetTokenSymbolsForChain; exports.getSupportedTokenSymbolsForChain = getSupportedTokenSymbolsForChain; exports.getSupportedChainIds = getSupportedChainIds; exports.isSupportedTokenAddressForChain = isSupportedTokenAddressForChain; exports.getSupportedTargetTokens = getSupportedTargetTokens; exports.findTokenDecimals = findTokenDecimals; exports.getTokenDecimalsByAddress = getTokenDecimalsByAddress; exports.findChainIdForToken = findChainIdForToken; exports.isRegistryTokenOnChain = isRegistryTokenOnChain; exports.getNativeSymbol = getNativeSymbol; exports.getTokenSymbol = getTokenSymbol; exports.getTargetTokenSymbol = getTargetTokenSymbol; exports.isStablecoinSymbol = isStablecoinSymbol; exports.getChainName = getChainName; exports.getChainBadge = getChainBadge; exports.getExplorerUrl = getExplorerUrl; exports.getExplorerTxUrl = getExplorerTxUrl; exports.getExplorerName = getExplorerName;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SAFE_ABI
3
- } from "./chunk-TYB6AA6D.mjs";
3
+ } from "./chunk-RH6XQHMA.mjs";
4
4
 
5
5
  // src/core/dapp-imports/polymarket/constants.ts
6
6
  var POLYMARKET_POLYGON_CHAIN_ID = 137;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getChainName
3
- } from "./chunk-SX52FXKH.mjs";
3
+ } from "./chunk-2O2FJYRY.mjs";
4
4
 
5
5
  // src/core/safe.ts
6
6
  import {
@@ -14,10 +14,12 @@ import {
14
14
  getTokenDecimalsByAddress,
15
15
  getTokenSymbol,
16
16
  isHyperCoreCaip2,
17
+ isRegistryTokenOnChain,
17
18
  isSolanaCaip2,
18
19
  parseEvmChainId,
20
+ toEvmCaip2,
19
21
  tokenIconUrl
20
- } from "./chunk-SX52FXKH.mjs";
22
+ } from "./chunk-2O2FJYRY.mjs";
21
23
 
22
24
  // src/components/ui/Modal.tsx
23
25
  import {
@@ -1074,6 +1076,31 @@ function createDepositService(baseUrl, options) {
1074
1076
  return {};
1075
1077
  }
1076
1078
  },
1079
+ async fetchPricesByAddress(caip2Ids) {
1080
+ const list = caip2Ids.filter((id) => id.length > 0);
1081
+ if (list.length === 0) return {};
1082
+ const url = apiUrl(
1083
+ `/prices?${new URLSearchParams({ addresses: list.join(",") }).toString()}`
1084
+ );
1085
+ try {
1086
+ const response = await fetch(url, {
1087
+ method: "GET",
1088
+ headers: { "Content-Type": "application/json" },
1089
+ cache: "no-store"
1090
+ });
1091
+ if (!response.ok) {
1092
+ debugError(debug, scope, "fetchPricesByAddress:failed", {
1093
+ status: response.status
1094
+ });
1095
+ return {};
1096
+ }
1097
+ const data = await response.json();
1098
+ return data.prices ?? {};
1099
+ } catch (err) {
1100
+ debugError(debug, scope, "fetchPricesByAddress:error", err);
1101
+ return {};
1102
+ }
1103
+ },
1077
1104
  async getSwappedWidgetUrl(params) {
1078
1105
  const url = apiUrl("/onramp/swapped/widget-url");
1079
1106
  debugLog(debug, scope, "getSwappedWidgetUrl:request", {
@@ -2497,7 +2524,8 @@ function ConnectStep({
2497
2524
  onSelectDappImport,
2498
2525
  title = "Deposit",
2499
2526
  subtitle,
2500
- defaultMethodTab = "crypto"
2527
+ defaultMethodTab = "crypto",
2528
+ onMethodTabChange
2501
2529
  }) {
2502
2530
  const rows = walletRows ?? [];
2503
2531
  const handleConnect = onConnect ?? onRequestConnect;
@@ -2709,6 +2737,10 @@ function ConnectStep({
2709
2737
  const hasCash = cashRows.length > 0;
2710
2738
  const showToggle = hasCrypto && hasCash;
2711
2739
  const [tab, setTab] = useState(defaultMethodTab);
2740
+ const handleTabChange = (next) => {
2741
+ setTab(next);
2742
+ onMethodTabChange?.(next);
2743
+ };
2712
2744
  const activeTab = showToggle ? tab : hasCash && !hasCrypto ? "cash" : "crypto";
2713
2745
  const activeRows = activeTab === "cash" ? cashRows : cryptoRows;
2714
2746
  useEffect3(() => {
@@ -2732,7 +2764,7 @@ function ConnectStep({
2732
2764
  {
2733
2765
  ariaLabel: "Deposit method type",
2734
2766
  value: activeTab,
2735
- onChange: setTab,
2767
+ onChange: handleTabChange,
2736
2768
  options: [
2737
2769
  { value: "crypto", label: "Crypto" },
2738
2770
  { value: "cash", label: "Cash" }
@@ -2760,25 +2792,109 @@ ConnectStep.displayName = "ConnectStep";
2760
2792
  // src/components/ui/TokenIcon.tsx
2761
2793
  import { useState as useState2 } from "react";
2762
2794
  import { Fragment as Fragment3, jsx as jsx19 } from "react/jsx-runtime";
2795
+ function preconnectIconCdn() {
2796
+ if (typeof document === "undefined") return;
2797
+ if (document.getElementById("rs-icon-cdn-preconnect")) return;
2798
+ const link = document.createElement("link");
2799
+ link.id = "rs-icon-cdn-preconnect";
2800
+ link.rel = "preconnect";
2801
+ link.href = "https://s3.rhinestone.dev";
2802
+ link.crossOrigin = "anonymous";
2803
+ document.head.appendChild(link);
2804
+ }
2805
+ preconnectIconCdn();
2763
2806
  function TokenIcon({ symbol, className, fallback }) {
2764
- const [failedSymbol, setFailedSymbol] = useState2(null);
2765
- if (failedSymbol === symbol) {
2807
+ const [loadedSymbol, setLoadedSymbol] = useState2(null);
2808
+ const [erroredSymbol, setErroredSymbol] = useState2(null);
2809
+ if (erroredSymbol === symbol) {
2766
2810
  return /* @__PURE__ */ jsx19(Fragment3, { children: fallback });
2767
2811
  }
2812
+ const loading = loadedSymbol !== symbol;
2768
2813
  return /* @__PURE__ */ jsx19(
2769
2814
  "img",
2770
2815
  {
2771
2816
  src: tokenIconUrl(symbol),
2772
2817
  alt: "",
2773
- className,
2774
- loading: "lazy",
2818
+ className: `rs-token-icon ${className ?? ""}`.trimEnd(),
2775
2819
  decoding: "async",
2776
- onError: () => setFailedSymbol(symbol)
2777
- }
2820
+ "data-loading": loading ? "" : void 0,
2821
+ onLoad: () => setLoadedSymbol(symbol),
2822
+ onError: () => setErroredSymbol(symbol)
2823
+ },
2824
+ symbol
2778
2825
  );
2779
2826
  }
2780
2827
  TokenIcon.displayName = "TokenIcon";
2781
2828
 
2829
+ // src/core/useTokenPrices.ts
2830
+ import { useEffect as useEffect4, useState as useState3 } from "react";
2831
+ function isErc20(token) {
2832
+ return typeof token.chainId === "number" && !!token.address && token.address.toLowerCase() !== NATIVE_TOKEN_ADDRESS.toLowerCase();
2833
+ }
2834
+ function caip2For(token) {
2835
+ return `${toEvmCaip2(token.chainId)}:${token.address.toLowerCase()}`;
2836
+ }
2837
+ async function fetchTokenPriceUsd(service, token) {
2838
+ if (isErc20(token)) {
2839
+ const caip2 = caip2For(token);
2840
+ const prices2 = await service.fetchPricesByAddress([caip2]);
2841
+ const price2 = prices2[caip2];
2842
+ return typeof price2 === "number" && price2 > 0 ? price2 : null;
2843
+ }
2844
+ const symbol = token.symbol.toUpperCase();
2845
+ const prices = await service.fetchPrices([symbol]);
2846
+ const price = prices[symbol];
2847
+ return typeof price === "number" && price > 0 ? price : null;
2848
+ }
2849
+ function useTokenPrices(service, tokens) {
2850
+ const [prices, setPrices] = useState3({});
2851
+ const defined = tokens.filter((t) => Boolean(t?.symbol));
2852
+ const entries = [
2853
+ ...new Map(
2854
+ defined.map((token) => {
2855
+ const erc20 = isErc20(token);
2856
+ const caip2 = erc20 ? caip2For(token) : null;
2857
+ const symbol = token.symbol.toUpperCase();
2858
+ return [caip2 ?? `sym:${symbol}`, { symbol, caip2 }];
2859
+ })
2860
+ ).values()
2861
+ ].sort(
2862
+ (a, b) => (a.caip2 ?? a.symbol).localeCompare(b.caip2 ?? b.symbol)
2863
+ );
2864
+ const key = JSON.stringify(entries);
2865
+ useEffect4(() => {
2866
+ if (key === "[]") return;
2867
+ let cancelled = false;
2868
+ const parsed = JSON.parse(key);
2869
+ const symbols = [
2870
+ ...new Set(parsed.filter((e) => !e.caip2).map((e) => e.symbol))
2871
+ ];
2872
+ const caip2Ids = [
2873
+ ...new Set(
2874
+ parsed.filter((e) => e.caip2).map((e) => e.caip2)
2875
+ )
2876
+ ];
2877
+ Promise.all([
2878
+ symbols.length > 0 ? service.fetchPrices(symbols) : Promise.resolve({}),
2879
+ caip2Ids.length > 0 ? service.fetchPricesByAddress(caip2Ids) : Promise.resolve({})
2880
+ ]).then(([bySymbol, byAddress]) => {
2881
+ if (cancelled) return;
2882
+ const merged = { ...bySymbol };
2883
+ for (const entry of parsed) {
2884
+ if (!entry.caip2) continue;
2885
+ const price = byAddress[entry.caip2];
2886
+ if (typeof price === "number") merged[entry.symbol] = price;
2887
+ }
2888
+ setPrices(merged);
2889
+ }).catch(() => {
2890
+ });
2891
+ return () => {
2892
+ cancelled = true;
2893
+ };
2894
+ }, [service, key]);
2895
+ return prices;
2896
+ }
2897
+
2782
2898
  // src/components/steps/ProcessingStep.tsx
2783
2899
  import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef4, useState as useState6 } from "react";
2784
2900
 
@@ -2824,16 +2940,16 @@ Button.displayName = "Button";
2824
2940
 
2825
2941
  // src/components/ui/Tooltip.tsx
2826
2942
  import {
2827
- useState as useState3,
2943
+ useState as useState4,
2828
2944
  useRef as useRef3,
2829
- useEffect as useEffect4,
2945
+ useEffect as useEffect5,
2830
2946
  useCallback as useCallback2
2831
2947
  } from "react";
2832
2948
  import { createPortal as createPortal2 } from "react-dom";
2833
2949
  import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
2834
2950
  function Tooltip({ content, children, className }) {
2835
- const [open, setOpen] = useState3(false);
2836
- const [position, setPosition] = useState3(null);
2951
+ const [open, setOpen] = useState4(false);
2952
+ const [position, setPosition] = useState4(null);
2837
2953
  const triggerRef = useRef3(null);
2838
2954
  const bubbleRef = useRef3(null);
2839
2955
  const updatePosition = useCallback2(() => {
@@ -2845,7 +2961,7 @@ function Tooltip({ content, children, className }) {
2845
2961
  left: rect.left + rect.width / 2
2846
2962
  });
2847
2963
  }, []);
2848
- useEffect4(() => {
2964
+ useEffect5(() => {
2849
2965
  if (!open) return;
2850
2966
  updatePosition();
2851
2967
  function handleOutside(event) {
@@ -2920,10 +3036,10 @@ function Tooltip({ content, children, className }) {
2920
3036
  Tooltip.displayName = "Tooltip";
2921
3037
 
2922
3038
  // src/components/ui/FeesAccordion.tsx
2923
- import { useState as useState4 } from "react";
3039
+ import { useState as useState5 } from "react";
2924
3040
  import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
2925
3041
  function FeesAccordion({ total, rows, tooltip }) {
2926
- const [open, setOpen] = useState4(false);
3042
+ const [open, setOpen] = useState5(false);
2927
3043
  const expandable = rows.length > 0;
2928
3044
  return /* @__PURE__ */ jsxs19("div", { className: "rs-fees-accordion", children: [
2929
3045
  /* @__PURE__ */ jsxs19("div", { className: "rs-fees-accordion-summary", children: [
@@ -3246,18 +3362,38 @@ function formatRawTokenAmount(rawAmount, token) {
3246
3362
  if (value === void 0) return void 0;
3247
3363
  return formatTokenAmount(value, token.symbol);
3248
3364
  }
3365
+ function isDisplayStablecoinSymbol(symbol) {
3366
+ return symbol !== void 0 && STABLECOIN_SYMBOLS.has(symbol.toUpperCase());
3367
+ }
3249
3368
  function priceUsdFor(symbol, prices) {
3250
3369
  if (!symbol) return void 0;
3251
- const upper = symbol.toUpperCase();
3252
- const quoted = prices[upper];
3253
- if (typeof quoted === "number" && quoted > 0) return quoted;
3254
- return STABLECOIN_SYMBOLS.has(upper) ? 1 : void 0;
3370
+ const quoted = prices[symbol.toUpperCase()];
3371
+ return typeof quoted === "number" && quoted > 0 ? quoted : void 0;
3372
+ }
3373
+ function isRecognizedToken(address, chain) {
3374
+ if (address === void 0 || chain === void 0) return false;
3375
+ if (chain === "solana") return getSolanaTokenByMint(address) !== void 0;
3376
+ if (chain === "hypercore") {
3377
+ return HYPERCORE_SOURCE_TOKENS.some(
3378
+ (t) => t.address.toLowerCase() === address.toLowerCase()
3379
+ );
3380
+ }
3381
+ return EVM_ADDRESS_RE.test(address) && isRegistryTokenOnChain(address, chain);
3255
3382
  }
3256
3383
  function estimateReceiveAmount(params) {
3257
- const { sourceAmount, sourceSymbol, targetSymbol, sourceAmountUsd, prices } = params;
3258
- if (sourceSymbol !== void 0 && sourceSymbol.toUpperCase() === targetSymbol.toUpperCase()) {
3384
+ const {
3385
+ sourceAmount,
3386
+ sourceSymbol,
3387
+ targetSymbol,
3388
+ sourceAmountUsd,
3389
+ prices,
3390
+ sourceTrusted
3391
+ } = params;
3392
+ const trusted = sourceTrusted !== false;
3393
+ if (trusted && sourceSymbol !== void 0 && sourceSymbol.toUpperCase() === targetSymbol.toUpperCase()) {
3259
3394
  return sourceAmount;
3260
3395
  }
3396
+ if (!trusted) return void 0;
3261
3397
  const usdValue = sourceAmountUsd !== void 0 && Number.isFinite(sourceAmountUsd) ? sourceAmountUsd : sourceAmount !== void 0 ? (() => {
3262
3398
  const sourcePrice = priceUsdFor(sourceSymbol, prices);
3263
3399
  return sourcePrice !== void 0 ? sourceAmount * sourcePrice : void 0;
@@ -3293,31 +3429,6 @@ function formatReceiveEstimate(params) {
3293
3429
  return sameSymbol ? `${formatted} ${params.targetSymbol}` : `~${formatted} ${params.targetSymbol}`;
3294
3430
  }
3295
3431
 
3296
- // src/core/useTokenPrices.ts
3297
- import { useEffect as useEffect5, useState as useState5 } from "react";
3298
- function useTokenPrices(service, symbols) {
3299
- const [prices, setPrices] = useState5({});
3300
- const symbolsKey = [
3301
- ...new Set(
3302
- symbols.filter((symbol) => Boolean(symbol)).map((symbol) => symbol.toUpperCase())
3303
- )
3304
- ].sort().join(",");
3305
- useEffect5(() => {
3306
- if (!symbolsKey) return;
3307
- let cancelled = false;
3308
- service.fetchPrices(symbolsKey.split(",")).then((result) => {
3309
- if (!cancelled && result && Object.keys(result).length > 0) {
3310
- setPrices(result);
3311
- }
3312
- }).catch(() => {
3313
- });
3314
- return () => {
3315
- cancelled = true;
3316
- };
3317
- }, [service, symbolsKey]);
3318
- return prices;
3319
- }
3320
-
3321
3432
  // src/components/steps/ProcessingStep.tsx
3322
3433
  import { Fragment as Fragment5, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
3323
3434
  function SuccessBadge() {
@@ -4010,8 +4121,16 @@ function ProcessingStep({
4010
4121
  const formattedDestinationAmount = eventDestination.amount !== void 0 ? formatRawTokenAmount(eventDestination.amount, targetDisplay) : void 0;
4011
4122
  const amountUsdNumber = amountUsd !== void 0 && Number(amountUsd) > 0 ? Number(amountUsd) : void 0;
4012
4123
  const prices = useTokenPrices(service, [
4013
- sourceDisplay.symbol,
4014
- targetDisplay.symbol
4124
+ {
4125
+ chainId: displaySourceChain,
4126
+ address: displaySourceToken,
4127
+ symbol: sourceDisplay.symbol
4128
+ },
4129
+ {
4130
+ chainId: eventDestination.chainId ?? targetChain,
4131
+ address: eventDestination.token ?? targetToken,
4132
+ symbol: targetDisplay.symbol
4133
+ }
4015
4134
  ]);
4016
4135
  const estimatedReceiveAmount = (() => {
4017
4136
  const estimate = estimateReceiveAmount({
@@ -4019,6 +4138,7 @@ function ProcessingStep({
4019
4138
  sourceSymbol: sourceDisplay.symbol,
4020
4139
  targetSymbol: targetDisplay.symbol,
4021
4140
  sourceAmountUsd: amountUsdNumber,
4141
+ sourceTrusted: isRecognizedToken(displaySourceToken, displaySourceChain),
4022
4142
  prices
4023
4143
  });
4024
4144
  return estimate !== void 0 ? formatTokenAmount(estimate, targetDisplay.symbol) : void 0;
@@ -4395,6 +4515,8 @@ export {
4395
4515
  formatUserError,
4396
4516
  Tooltip,
4397
4517
  formatTokenAmount,
4518
+ isDisplayStablecoinSymbol,
4519
+ isRecognizedToken,
4398
4520
  formatQuotedReceive,
4399
4521
  formatReceiveEstimate,
4400
4522
  getEventTxHash,
@@ -4403,6 +4525,7 @@ export {
4403
4525
  isFailedEvent,
4404
4526
  txRefsMatch,
4405
4527
  failureMessageForEvent,
4528
+ fetchTokenPriceUsd,
4406
4529
  useTokenPrices,
4407
4530
  ProcessingStep,
4408
4531
  rpcUrlFor,