@xswap-link/sdk 0.14.1 → 0.15.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.
- package/CHANGELOG.md +6 -0
- package/dist/index.global.js +92 -92
- package/dist/index.js +1799 -1725
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1752 -1681
- package/dist/index.mjs.map +1 -1
- package/localTheme.ts +1 -1
- package/package.json +1 -1
- package/src/assets/icons/ChainlinkMarkIcon.tsx +4 -5
- package/src/assets/icons/CheckCircleThinIcon.tsx +22 -0
- package/src/assets/icons/ChevronDownThinIcon.tsx +39 -0
- package/src/assets/icons/ChevronDownWideThinIcon.tsx +18 -0
- package/src/assets/icons/ChevronsUpDownThinIcon.tsx +21 -0
- package/src/assets/icons/CloseIcon.tsx +3 -2
- package/src/assets/icons/ErrorCircleThinIcon.tsx +22 -0
- package/src/assets/icons/LinkExternalThinIcon.tsx +19 -0
- package/src/assets/icons/LoadingRingIcon.tsx +22 -0
- package/src/assets/icons/ProgressRingThinIcon.tsx +29 -0
- package/src/assets/icons/SearchThinIcon.tsx +15 -0
- package/src/assets/icons/SignThinIcon.tsx +15 -0
- package/src/assets/icons/WalletCheckThinIcon.tsx +24 -0
- package/src/assets/icons/index.ts +11 -0
- package/src/components/PoweredBy/index.tsx +1 -1
- package/src/components/Swap/Header/index.tsx +2 -4
- package/src/components/Swap/HistoryView/ActivityCard/index.tsx +110 -115
- package/src/components/Swap/HistoryView/index.tsx +10 -7
- package/src/components/Swap/ReorderButton/ReorderButton.tsx +4 -4
- package/src/components/Swap/SettingsView/Delivery/index.tsx +19 -17
- package/src/components/Swap/SettingsView/InfiniteApproval/index.tsx +19 -17
- package/src/components/Swap/SettingsView/Slippage/index.tsx +55 -49
- package/src/components/Swap/SwapView/ConfirmationView/TokenTiles/index.tsx +69 -0
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/Header/index.tsx +13 -25
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/Steps/index.tsx +65 -113
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/index.tsx +19 -23
- package/src/components/Swap/SwapView/ConfirmationView/TxResult/index.tsx +51 -74
- package/src/components/Swap/SwapView/FeesPanel/index.tsx +4 -4
- package/src/components/Swap/SwapView/SwapButton/index.tsx +0 -29
- package/src/components/Swap/SwapView/SwapPanel/AmountPanel/index.tsx +2 -2
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/ChainPicker/index.tsx +3 -3
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/NetworkFilter/index.tsx +17 -16
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/TokenPicker/index.tsx +91 -40
- package/src/components/Swap/SwapView/SwapPanel/TokenPanel/index.tsx +4 -4
- package/src/components/Swap/SwapView/SwapPanel/UsdValue/index.tsx +2 -2
- package/src/components/Swap/SwapView/SwapPanel/WalletPanel/index.tsx +10 -16
- package/src/components/Swap/SwapView/SwapPanel/index.tsx +3 -3
- package/src/components/Swap/SwapView/WalletPicker/index.tsx +131 -139
- package/src/components/Swap/SwapView/index.tsx +11 -7
- package/src/components/Swap/WalletPickerView/index.tsx +65 -0
- package/src/components/Swap/index.tsx +23 -6
- package/src/components/ToggleButton/index.tsx +5 -7
- package/src/components/TokenLogo/index.tsx +1 -1
- package/src/components/TxModal/index.tsx +14 -4
- package/src/components/global.css +18 -1
- package/src/constants/index.ts +4 -0
- package/src/context/SwapProvider.tsx +106 -19
- package/src/utils/validation.ts +9 -4
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/ArrowIcon.tsx +0 -13
- package/src/components/Swap/SwapView/ConfirmationView/TxOverview/SwapPanel/index.tsx +0 -72
- package/src/components/Swap/SwapView/ConfirmationView/TxResult/TokenItem/index.tsx +0 -25
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { TxConfigFormPayload } from "@src/components";
|
|
2
2
|
import {
|
|
3
|
+
DEFAULT_BRIDGE_DESTINATION_CHAIN_ID,
|
|
4
|
+
DEFAULT_BRIDGE_SOURCE_CHAIN_ID,
|
|
3
5
|
DEFAULT_DESTINATION_CHAIN_ID,
|
|
4
6
|
DEFAULT_REQUEST_ABORT_MSG,
|
|
5
7
|
DEFAULT_SOURCE_CHAIN_ID,
|
|
@@ -291,6 +293,19 @@ export const SwapProvider = ({
|
|
|
291
293
|
const routeAbortController = useRef<AbortController | null>(null);
|
|
292
294
|
const refreshSelectedTokenBalanceNonce = useRef(crypto.randomUUID());
|
|
293
295
|
const prevWalletAddresses = useRef<string | undefined>(undefined);
|
|
296
|
+
// last wallet chain id seen by the follow-the-wallet effect below
|
|
297
|
+
const prevFollowedWalletChainId = useRef<string | undefined>(undefined);
|
|
298
|
+
// True between the bridgeUI-change reset and the re-init that follows it.
|
|
299
|
+
// Effects in the reset's commit still close over the pre-reset state (with
|
|
300
|
+
// the new bridgeUI), so acting on that mix would remap the old mode's route
|
|
301
|
+
// as the new mode's — this ref lets them bail out synchronously.
|
|
302
|
+
const initPending = useRef(false);
|
|
303
|
+
// True while a bridgeUI-change re-init is pending. The web-component
|
|
304
|
+
// wrapper delivers attribute updates one by one, so at re-init time the
|
|
305
|
+
// route config may still hold the previous mode's values (there is no way
|
|
306
|
+
// to tell them apart from intentional ones) — the re-init therefore
|
|
307
|
+
// ignores route config entirely and starts from the new mode's defaults.
|
|
308
|
+
const modeSwitchReinit = useRef(false);
|
|
294
309
|
|
|
295
310
|
// =============================================================================
|
|
296
311
|
// Memoized Values
|
|
@@ -691,6 +706,12 @@ export const SwapProvider = ({
|
|
|
691
706
|
!srcToken ||
|
|
692
707
|
!srcToken?.address
|
|
693
708
|
) {
|
|
709
|
+
// Nothing to read a balance for — drop the previous selection's
|
|
710
|
+
// balance (and invalidate any in-flight read) so the MAX button
|
|
711
|
+
// never acts on a stale value.
|
|
712
|
+
refreshSelectedTokenBalanceNonce.current = crypto.randomUUID();
|
|
713
|
+
setSrcTokenBalanceWei("");
|
|
714
|
+
setIsFetchingBalance(false);
|
|
694
715
|
return;
|
|
695
716
|
}
|
|
696
717
|
|
|
@@ -1077,9 +1098,23 @@ export const SwapProvider = ({
|
|
|
1077
1098
|
// useEffects responsible for state updates and validations
|
|
1078
1099
|
// =============================================================================
|
|
1079
1100
|
|
|
1080
|
-
//
|
|
1101
|
+
// Follows a real in-session wallet network switch with the source chain.
|
|
1102
|
+
// Only a defined -> defined change counts: the chain id first appearing
|
|
1103
|
+
// during reconnect is ignored, since wagmi restores a persisted (possibly
|
|
1104
|
+
// stale) chain id before the connector reports the actual one. Bridge keeps
|
|
1105
|
+
// its fixed default route instead of following the wallet chain.
|
|
1081
1106
|
useEffect(() => {
|
|
1082
|
-
|
|
1107
|
+
const prevWalletChainId = prevFollowedWalletChainId.current;
|
|
1108
|
+
prevFollowedWalletChainId.current = walletChainId;
|
|
1109
|
+
|
|
1110
|
+
if (
|
|
1111
|
+
!walletChainId ||
|
|
1112
|
+
!prevWalletChainId ||
|
|
1113
|
+
prevWalletChainId === walletChainId ||
|
|
1114
|
+
!isInitialStateSet ||
|
|
1115
|
+
integrationConfig?.srcChainId ||
|
|
1116
|
+
bridgeUI
|
|
1117
|
+
) {
|
|
1083
1118
|
return;
|
|
1084
1119
|
}
|
|
1085
1120
|
const initSrcChain = supportedChains.find(
|
|
@@ -1093,19 +1128,29 @@ export const SwapProvider = ({
|
|
|
1093
1128
|
isInitialStateSet,
|
|
1094
1129
|
supportedChains,
|
|
1095
1130
|
integrationConfig?.srcChainId,
|
|
1131
|
+
bridgeUI,
|
|
1096
1132
|
]);
|
|
1097
1133
|
|
|
1098
|
-
// resets
|
|
1134
|
+
// resets the widget state when bridgeUI changes at runtime: back to the
|
|
1135
|
+
// main view (leaving Settings/History), cleared selection and amount, and
|
|
1136
|
+
// re-arms the init effect below so the new mode gets its default route
|
|
1137
|
+
// (config -> wallet chain -> mode defaults) applied again.
|
|
1099
1138
|
useEffect(() => {
|
|
1100
1139
|
if (!isInitialStateSet) {
|
|
1101
1140
|
return;
|
|
1102
1141
|
}
|
|
1103
1142
|
|
|
1143
|
+
initPending.current = true;
|
|
1144
|
+
modeSwitchReinit.current = true;
|
|
1145
|
+
setTab(init.tab);
|
|
1104
1146
|
setActivePicker(null);
|
|
1147
|
+
setError(init.error);
|
|
1148
|
+
setSrcValue(init.srcValue);
|
|
1105
1149
|
setSrcToken(undefined);
|
|
1106
1150
|
setDstToken(undefined);
|
|
1107
1151
|
setSrcChain(undefined);
|
|
1108
1152
|
setDstChain(undefined);
|
|
1153
|
+
setIsInitialStateSet(false);
|
|
1109
1154
|
|
|
1110
1155
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1111
1156
|
}, [bridgeUI]);
|
|
@@ -1121,21 +1166,51 @@ export const SwapProvider = ({
|
|
|
1121
1166
|
return;
|
|
1122
1167
|
}
|
|
1123
1168
|
|
|
1169
|
+
// During a bridgeUI-change re-init the route config may still hold the
|
|
1170
|
+
// previous mode's values (web-component attribute updates arrive one by
|
|
1171
|
+
// one), so it is ignored — the new mode starts from its own defaults.
|
|
1172
|
+
// Route config still seeds the very first init (deep links, integrator
|
|
1173
|
+
// presets).
|
|
1174
|
+
const ignoreRouteConfig = modeSwitchReinit.current;
|
|
1175
|
+
const cfgSrcChainId = ignoreRouteConfig
|
|
1176
|
+
? undefined
|
|
1177
|
+
: integrationConfig?.srcChainId;
|
|
1178
|
+
const cfgDstChainId = ignoreRouteConfig
|
|
1179
|
+
? undefined
|
|
1180
|
+
: integrationConfig?.dstChainId;
|
|
1181
|
+
const cfgSrcTokenAddr = ignoreRouteConfig
|
|
1182
|
+
? undefined
|
|
1183
|
+
: integrationConfig?.srcTokenAddr;
|
|
1184
|
+
const cfgDstTokenAddr = ignoreRouteConfig
|
|
1185
|
+
? undefined
|
|
1186
|
+
: integrationConfig?.dstTokenAddr;
|
|
1187
|
+
|
|
1124
1188
|
// find chains
|
|
1189
|
+
// Default routes are fixed (swap: ETH -> ETH, bridge: ETH -> Base) and do
|
|
1190
|
+
// not follow the wallet's chain — on load wagmi can still report a stale,
|
|
1191
|
+
// persisted chain id, so it can't be trusted here. Integrator config
|
|
1192
|
+
// still takes precedence, and a real in-session network switch is
|
|
1193
|
+
// followed by the effect below.
|
|
1125
1194
|
const searchedSrcChainId =
|
|
1126
|
-
srcChain ||
|
|
1127
|
-
|
|
1128
|
-
(
|
|
1129
|
-
(bridgeUI ? undefined : DEFAULT_SOURCE_CHAIN_ID);
|
|
1195
|
+
srcChain?.chainId ||
|
|
1196
|
+
cfgSrcChainId ||
|
|
1197
|
+
(bridgeUI ? DEFAULT_BRIDGE_SOURCE_CHAIN_ID : DEFAULT_SOURCE_CHAIN_ID);
|
|
1130
1198
|
|
|
1131
1199
|
const initSrcChain = supportedChains.find(
|
|
1132
1200
|
({ chainId }) => chainId === searchedSrcChainId,
|
|
1133
1201
|
);
|
|
1134
1202
|
|
|
1203
|
+
// Bridge can't route within one chain, so when the source already sits on
|
|
1204
|
+
// the default bridge destination, fall back to the reversed default route.
|
|
1205
|
+
const bridgeDefaultDstChainId =
|
|
1206
|
+
initSrcChain?.chainId === DEFAULT_BRIDGE_DESTINATION_CHAIN_ID
|
|
1207
|
+
? DEFAULT_BRIDGE_SOURCE_CHAIN_ID
|
|
1208
|
+
: DEFAULT_BRIDGE_DESTINATION_CHAIN_ID;
|
|
1209
|
+
|
|
1135
1210
|
const searchedDstChainId =
|
|
1136
|
-
dstChain ||
|
|
1137
|
-
|
|
1138
|
-
(bridgeUI ?
|
|
1211
|
+
dstChain?.chainId ||
|
|
1212
|
+
cfgDstChainId ||
|
|
1213
|
+
(bridgeUI ? bridgeDefaultDstChainId : DEFAULT_DESTINATION_CHAIN_ID);
|
|
1139
1214
|
|
|
1140
1215
|
const initDstChain = supportedChains.find(
|
|
1141
1216
|
({ chainId }) => chainId === searchedDstChainId,
|
|
@@ -1146,13 +1221,13 @@ export const SwapProvider = ({
|
|
|
1146
1221
|
let initSrcToken: Token | undefined;
|
|
1147
1222
|
|
|
1148
1223
|
const srcTokenAddress = resolveTokenAddress(
|
|
1149
|
-
|
|
1150
|
-
|
|
1224
|
+
cfgSrcTokenAddr,
|
|
1225
|
+
cfgSrcChainId,
|
|
1151
1226
|
supportedChains,
|
|
1152
1227
|
);
|
|
1153
1228
|
const dstTokenAddress = resolveTokenAddress(
|
|
1154
|
-
|
|
1155
|
-
|
|
1229
|
+
cfgDstTokenAddr,
|
|
1230
|
+
cfgDstChainId,
|
|
1156
1231
|
supportedChains,
|
|
1157
1232
|
);
|
|
1158
1233
|
|
|
@@ -1182,6 +1257,8 @@ export const SwapProvider = ({
|
|
|
1182
1257
|
setSrcToken(source.token);
|
|
1183
1258
|
setDstToken(target.token);
|
|
1184
1259
|
// Mark initial state as set
|
|
1260
|
+
modeSwitchReinit.current = false;
|
|
1261
|
+
initPending.current = false;
|
|
1185
1262
|
setIsInitialStateSet(true);
|
|
1186
1263
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1187
1264
|
}, [
|
|
@@ -1200,7 +1277,11 @@ export const SwapProvider = ({
|
|
|
1200
1277
|
if (
|
|
1201
1278
|
!bridgeTokensDictionary ||
|
|
1202
1279
|
supportedChains.length === 0 ||
|
|
1203
|
-
!isInitialStateSet
|
|
1280
|
+
!isInitialStateSet ||
|
|
1281
|
+
// A bridgeUI-change reset is in flight: this closure still holds the
|
|
1282
|
+
// previous mode's route, so mapping it against the new mode would
|
|
1283
|
+
// resurrect it. The re-init applies the new mode's defaults instead.
|
|
1284
|
+
initPending.current
|
|
1204
1285
|
) {
|
|
1205
1286
|
return;
|
|
1206
1287
|
}
|
|
@@ -1241,9 +1322,15 @@ export const SwapProvider = ({
|
|
|
1241
1322
|
bridgeTokensDictionary,
|
|
1242
1323
|
isInitialStateSet,
|
|
1243
1324
|
]);
|
|
1325
|
+
// Notify effects below also re-run whenever the integrator recreates the
|
|
1326
|
+
// callback props (inline arrows give them a new identity every render).
|
|
1327
|
+
// During a bridgeUI-change reset their closures still hold the previous
|
|
1328
|
+
// mode's route, and re-emitting it would feed it back to the integrator as
|
|
1329
|
+
// config — the initPending guard keeps them quiet until the re-init lands.
|
|
1330
|
+
|
|
1244
1331
|
// notifies integration or global callback when the destination chain changes.
|
|
1245
1332
|
useEffect(() => {
|
|
1246
|
-
if (!isInitialStateSet) {
|
|
1333
|
+
if (!isInitialStateSet || initPending.current) {
|
|
1247
1334
|
return;
|
|
1248
1335
|
}
|
|
1249
1336
|
if (integrationConfig.onDstChainChange) {
|
|
@@ -1255,7 +1342,7 @@ export const SwapProvider = ({
|
|
|
1255
1342
|
}, [integrationConfig.onDstChainChange, dstChain]);
|
|
1256
1343
|
// notifies integration or global callback when the destination token changes.
|
|
1257
1344
|
useEffect(() => {
|
|
1258
|
-
if (!isInitialStateSet) {
|
|
1345
|
+
if (!isInitialStateSet || initPending.current) {
|
|
1259
1346
|
return;
|
|
1260
1347
|
}
|
|
1261
1348
|
const token = dstToken
|
|
@@ -1271,7 +1358,7 @@ export const SwapProvider = ({
|
|
|
1271
1358
|
}, [integrationConfig.onDstTokenChange, dstToken]);
|
|
1272
1359
|
// notifies integration or global callback when the source chain changes.
|
|
1273
1360
|
useEffect(() => {
|
|
1274
|
-
if (!isInitialStateSet) {
|
|
1361
|
+
if (!isInitialStateSet || initPending.current) {
|
|
1275
1362
|
return;
|
|
1276
1363
|
}
|
|
1277
1364
|
if (integrationConfig.onSrcChainChange) {
|
|
@@ -1283,7 +1370,7 @@ export const SwapProvider = ({
|
|
|
1283
1370
|
}, [integrationConfig.onSrcChainChange, srcChain]);
|
|
1284
1371
|
// notifies integration or global callback when the source token changes.
|
|
1285
1372
|
useEffect(() => {
|
|
1286
|
-
if (!isInitialStateSet) {
|
|
1373
|
+
if (!isInitialStateSet || initPending.current) {
|
|
1287
1374
|
return;
|
|
1288
1375
|
}
|
|
1289
1376
|
const token = srcToken
|
package/src/utils/validation.ts
CHANGED
|
@@ -379,11 +379,16 @@ const mapToValidPathBridge = ({
|
|
|
379
379
|
chain: newSourceChain,
|
|
380
380
|
bridgeTokensDictionary,
|
|
381
381
|
});
|
|
382
|
-
if (defaultToken && newSourceChain
|
|
383
|
-
const
|
|
384
|
-
|
|
382
|
+
if (defaultToken && newSourceChain) {
|
|
383
|
+
const bridgeTargets =
|
|
384
|
+
bridgeTokensDictionary[newSourceChain.chainId]?.[
|
|
385
385
|
defaultToken.address.toLowerCase()
|
|
386
|
-
]
|
|
386
|
+
] || {};
|
|
387
|
+
// With no target chain picked yet the default still applies, as long as
|
|
388
|
+
// the token is bridgeable somewhere.
|
|
389
|
+
const isDefaultTokenBridgeable = newTargetChain
|
|
390
|
+
? !!bridgeTargets[newTargetChain.chainId]
|
|
391
|
+
: Object.keys(bridgeTargets).length > 0;
|
|
387
392
|
|
|
388
393
|
if (isDefaultTokenBridgeable) {
|
|
389
394
|
newSourceToken = defaultToken;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { ArrowDownLongIcon } from "@src/assets/icons";
|
|
2
|
-
|
|
3
|
-
export const ArrowIcon = () => {
|
|
4
|
-
return (
|
|
5
|
-
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 p-1 border border-solid border-t_text_primary border-opacity-10 rounded-xl bg-t_bg_secondary">
|
|
6
|
-
<div className="relative bg-gradient-to-r from-t_main_accent_light to-t_main_accent_dark w-8 h-8 rounded-xl">
|
|
7
|
-
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 fill-white">
|
|
8
|
-
<ArrowDownLongIcon />
|
|
9
|
-
</div>
|
|
10
|
-
</div>
|
|
11
|
-
</div>
|
|
12
|
-
);
|
|
13
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { TokenLogo } from "@src/components";
|
|
2
|
-
import { useSwapContext } from "@src/context";
|
|
3
|
-
import { SwapPanelType } from "../../../index";
|
|
4
|
-
import { useMemo } from "react";
|
|
5
|
-
import { Ecosystem } from "@src/models";
|
|
6
|
-
|
|
7
|
-
type Props = {
|
|
8
|
-
type: SwapPanelType;
|
|
9
|
-
};
|
|
10
|
-
export const SwapPanel = ({ type }: Props) => {
|
|
11
|
-
const {
|
|
12
|
-
srcToken,
|
|
13
|
-
srcChain,
|
|
14
|
-
dstToken,
|
|
15
|
-
dstChain,
|
|
16
|
-
srcValue,
|
|
17
|
-
srcValueUsd,
|
|
18
|
-
dstValue,
|
|
19
|
-
dstValueUsd,
|
|
20
|
-
bridgeUI,
|
|
21
|
-
} = useSwapContext();
|
|
22
|
-
|
|
23
|
-
const token = useMemo(
|
|
24
|
-
() => (type === "source" ? srcToken : dstToken),
|
|
25
|
-
[dstToken, srcToken, type],
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
const chain = useMemo(
|
|
29
|
-
() => (type === "source" ? srcChain : dstChain),
|
|
30
|
-
[dstChain, srcChain, type],
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
const value = useMemo(() => {
|
|
34
|
-
if (
|
|
35
|
-
type === "destination" &&
|
|
36
|
-
bridgeUI &&
|
|
37
|
-
srcChain?.ecosystem === Ecosystem.SOLANA
|
|
38
|
-
) {
|
|
39
|
-
return srcValue;
|
|
40
|
-
}
|
|
41
|
-
return type === "source" ? srcValue : dstValue;
|
|
42
|
-
}, [type, bridgeUI, srcChain?.ecosystem, srcValue, dstValue]);
|
|
43
|
-
|
|
44
|
-
const valueUsd = useMemo(() => {
|
|
45
|
-
return type === "source" ? srcValueUsd : dstValueUsd;
|
|
46
|
-
}, [dstValueUsd, srcValueUsd, type]);
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<div className="flex justify-between bg-gradient-to-r from-t_main_accent_light/20 to-t_main_accent_dark/20 p-5 rounded-xl">
|
|
50
|
-
<div className="flex flex-col">
|
|
51
|
-
<div className="opacity-60 text-sm mb-2">{`You ${
|
|
52
|
-
type === "source" ? "pay" : "receive"
|
|
53
|
-
}`}</div>
|
|
54
|
-
<div className={`${type === "destination" && "text-t_text_secondary"}`}>
|
|
55
|
-
{value}
|
|
56
|
-
</div>
|
|
57
|
-
{valueUsd && <div className="opacity-60">${valueUsd}</div>}
|
|
58
|
-
</div>
|
|
59
|
-
<div className="flex items-center gap-3">
|
|
60
|
-
<div className="flex flex-col text-right">
|
|
61
|
-
<div>{token?.symbol}</div>
|
|
62
|
-
<div className="opacity-60">{chain?.displayName}</div>
|
|
63
|
-
</div>
|
|
64
|
-
<TokenLogo
|
|
65
|
-
token={token}
|
|
66
|
-
className="w-9 h-9"
|
|
67
|
-
generatedLogoClassName="w-9 h-9"
|
|
68
|
-
/>
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
71
|
-
);
|
|
72
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { TokenLogoWithChain } from "@src/components";
|
|
2
|
-
import { Chain, Token } from "@src/models";
|
|
3
|
-
|
|
4
|
-
type Props = {
|
|
5
|
-
chain: Chain | undefined;
|
|
6
|
-
token: Token | undefined;
|
|
7
|
-
value: string;
|
|
8
|
-
};
|
|
9
|
-
export const TokenItem = ({ chain, token, value }: Props) => {
|
|
10
|
-
return (
|
|
11
|
-
<div className="flex items-center gap-2">
|
|
12
|
-
<TokenLogoWithChain
|
|
13
|
-
chain={chain}
|
|
14
|
-
token={token}
|
|
15
|
-
chainLogoClassName="w-5"
|
|
16
|
-
tokenLogoClassName="w-9 h-9"
|
|
17
|
-
generatedLogoClassName="w-9 h-9 text-[16px]"
|
|
18
|
-
/>
|
|
19
|
-
<div className="flex flex-col w-min sm:w-auto">
|
|
20
|
-
<div>{`${value} ${token?.symbol}`}</div>
|
|
21
|
-
<div className="opacity-60">{chain?.displayName}</div>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
);
|
|
25
|
-
};
|