@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.
- package/dist/{DepositModalReown-J5YFZKFS.cjs → DepositModalReown-A2W6R27Q.cjs} +9 -9
- package/dist/{DepositModalReown-RZ6VSMKP.mjs → DepositModalReown-IB5WUXVT.mjs} +6 -6
- package/dist/{WithdrawModalReown-4YUV2WWV.mjs → WithdrawModalReown-A4S4BJHG.mjs} +5 -5
- package/dist/{WithdrawModalReown-B6BGY52S.cjs → WithdrawModalReown-KUWNNA2X.cjs} +8 -8
- package/dist/{chunk-SX52FXKH.mjs → chunk-2O2FJYRY.mjs} +8 -1
- package/dist/{chunk-JRFPKFL6.cjs → chunk-3WIHTUQ6.cjs} +105 -98
- package/dist/{chunk-XLXJW44N.cjs → chunk-46BRQZ2P.cjs} +500 -458
- package/dist/{chunk-LXTAAHPC.mjs → chunk-4BLOPOVO.mjs} +2 -2
- package/dist/{chunk-VURI4G2Z.cjs → chunk-5E67UM3V.cjs} +7 -7
- package/dist/{chunk-IRI34U6N.cjs → chunk-DSXMWQYB.cjs} +262 -139
- package/dist/{chunk-5S5BQ2GM.mjs → chunk-KGZU3BL2.mjs} +59 -17
- package/dist/{chunk-4IOQIWDY.cjs → chunk-ORKEBFMR.cjs} +4 -4
- package/dist/{chunk-PUMTR35E.cjs → chunk-P5T4XSN2.cjs} +9 -2
- package/dist/{chunk-YLIPI3NU.mjs → chunk-RARNNVZO.mjs} +1 -1
- package/dist/{chunk-TYB6AA6D.mjs → chunk-RH6XQHMA.mjs} +1 -1
- package/dist/{chunk-RXWJ267K.mjs → chunk-TUSEN26M.mjs} +172 -49
- package/dist/{chunk-WL7AXYQ4.cjs → chunk-UNVVUULP.cjs} +3 -3
- package/dist/{chunk-7JJ4EFDY.mjs → chunk-XK5RH4FZ.mjs} +12 -5
- package/dist/constants.cjs +2 -2
- package/dist/constants.mjs +1 -1
- package/dist/deposit.cjs +6 -6
- package/dist/deposit.mjs +5 -5
- package/dist/index.cjs +7 -7
- package/dist/index.mjs +6 -6
- package/dist/polymarket.cjs +6 -6
- package/dist/polymarket.mjs +3 -3
- package/dist/styles.css +147 -1
- package/dist/withdraw.cjs +5 -5
- package/dist/withdraw.mjs +4 -4
- package/package.json +1 -1
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
executePolymarketSafeTransfer,
|
|
8
8
|
fetchPolymarketProxyWallet,
|
|
9
9
|
readPolymarketBalances
|
|
10
|
-
} from "./chunk-
|
|
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-
|
|
75
|
+
} from "./chunk-TUSEN26M.mjs";
|
|
73
76
|
import {
|
|
74
77
|
SAFE_ABI
|
|
75
|
-
} from "./chunk-
|
|
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-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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: () =>
|
|
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
|
-
|
|
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
|
|
5837
|
+
fetchTokenPriceUsd(service, {
|
|
5838
|
+
chainId: targetChain,
|
|
5839
|
+
address: targetToken,
|
|
5840
|
+
symbol: targetSymbol
|
|
5841
|
+
}).then((price) => {
|
|
5801
5842
|
if (cancelled) return;
|
|
5802
|
-
|
|
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-
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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;
|
|
@@ -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-
|
|
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:
|
|
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 [
|
|
2765
|
-
|
|
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
|
-
|
|
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
|
|
2943
|
+
useState as useState4,
|
|
2828
2944
|
useRef as useRef3,
|
|
2829
|
-
useEffect as
|
|
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] =
|
|
2836
|
-
const [position, setPosition] =
|
|
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
|
-
|
|
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
|
|
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] =
|
|
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
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
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 {
|
|
3258
|
-
|
|
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
|
-
|
|
4014
|
-
|
|
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,
|