@lifi/widget 4.8.0 → 4.10.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/README.md +26 -3
- package/dist/esm/components/AmountInputCard/AmountInputCardPair.js +5 -2
- package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -1
- package/dist/esm/components/SelectChainAndToken.js +5 -2
- package/dist/esm/components/SelectChainAndToken.js.map +1 -1
- package/dist/esm/components/SendToWallet/SendToWalletButton.js +5 -4
- package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
- package/dist/esm/components/TokenList/TokenDetailsSheet.js +5 -8
- package/dist/esm/components/TokenList/TokenDetailsSheet.js.map +1 -1
- package/dist/esm/components/TokenList/TokenDetailsSheetContent.js +30 -2
- package/dist/esm/components/TokenList/TokenDetailsSheetContent.js.map +1 -1
- package/dist/esm/components/TokenList/TokenListItem.js +36 -47
- package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
- package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts.map +1 -1
- package/dist/esm/components/TokenList/VirtualizedTokenList.js +2 -2
- package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
- package/dist/esm/components/TokenList/tokenVerificationIcons.js +29 -0
- package/dist/esm/components/TokenList/tokenVerificationIcons.js.map +1 -0
- package/dist/esm/components/TokenList/useTokenSelect.d.ts.map +1 -1
- package/dist/esm/components/TokenList/useTokenSelect.js +10 -0
- package/dist/esm/components/TokenList/useTokenSelect.js.map +1 -1
- package/dist/esm/config/constants.js.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/config/version.js.map +1 -1
- package/dist/esm/hooks/useAccountsBalancesData.js +5 -2
- package/dist/esm/hooks/useAccountsBalancesData.js.map +1 -1
- package/dist/esm/hooks/useAddressValidation.d.ts +3 -2
- package/dist/esm/hooks/useAddressValidation.d.ts.map +1 -1
- package/dist/esm/hooks/useAddressValidation.js +48 -21
- package/dist/esm/hooks/useAddressValidation.js.map +1 -1
- package/dist/esm/hooks/useGasRefuel.js +4 -1
- package/dist/esm/hooks/useGasRefuel.js.map +1 -1
- package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
- package/dist/esm/hooks/useRoutes.js +11 -6
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useToAddressAutoPopulate.js +6 -8
- package/dist/esm/hooks/useToAddressAutoPopulate.js.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.d.ts +3 -2
- package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.js +8 -7
- package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
- package/dist/esm/hooks/useToAddressReset.js +6 -3
- package/dist/esm/hooks/useToAddressReset.js.map +1 -1
- package/dist/esm/hooks/useTokenBalance.js +2 -1
- package/dist/esm/hooks/useTokenBalance.js.map +1 -1
- package/dist/esm/hooks/useTokens.js +1 -1
- package/dist/esm/i18n/bn.json +7 -2
- package/dist/esm/i18n/de.json +7 -2
- package/dist/esm/i18n/en.json +7 -2
- package/dist/esm/i18n/es.json +7 -2
- package/dist/esm/i18n/fr.json +7 -2
- package/dist/esm/i18n/hi.json +7 -2
- package/dist/esm/i18n/id.json +7 -2
- package/dist/esm/i18n/it.json +7 -2
- package/dist/esm/i18n/ja.json +7 -2
- package/dist/esm/i18n/ko.json +7 -2
- package/dist/esm/i18n/pl.json +7 -2
- package/dist/esm/i18n/pt.json +7 -2
- package/dist/esm/i18n/th.json +7 -2
- package/dist/esm/i18n/tr.json +7 -2
- package/dist/esm/i18n/uk.json +7 -2
- package/dist/esm/i18n/vi.json +7 -2
- package/dist/esm/i18n/zh.json +7 -2
- package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js +7 -4
- package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js.map +1 -1
- package/dist/esm/pages/SendToWallet/BookmarksPage.js +35 -31
- package/dist/esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js +4 -3
- package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/RecentWalletsPage.js +43 -39
- package/dist/esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js +32 -26
- package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/SendToWalletPage.js +5 -10
- package/dist/esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
- package/dist/esm/providers/WalletProvider/WalletProvider.d.ts.map +1 -1
- package/dist/esm/providers/WalletProvider/WalletProvider.js +14 -2
- package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js +10 -14
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
- package/dist/esm/stores/bookmarks/types.d.ts +3 -0
- package/dist/esm/stores/bookmarks/types.d.ts.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.d.ts.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.js +4 -1
- package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
- package/dist/esm/stores/form/FormStore.js +3 -2
- package/dist/esm/stores/form/FormStore.js.map +1 -1
- package/dist/esm/stores/form/URLSearchParamsBuilder.js +7 -3
- package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
- package/dist/esm/stores/form/getDefaultValuesFromQueryString.js +4 -1
- package/dist/esm/stores/form/getDefaultValuesFromQueryString.js.map +1 -1
- package/dist/esm/utils/chainType.js +32 -1
- package/dist/esm/utils/chainType.js.map +1 -1
- package/dist/esm/utils/customReceiver.js +6 -1
- package/dist/esm/utils/customReceiver.js.map +1 -1
- package/dist/esm/utils/token.js +13 -1
- package/dist/esm/utils/token.js.map +1 -1
- package/package.json +7 -7
- package/src/components/AmountInputCard/AmountInputCardPair.tsx +6 -2
- package/src/components/SelectChainAndToken.tsx +5 -1
- package/src/components/SendToWallet/SendToWalletButton.tsx +13 -8
- package/src/components/TokenList/TokenDetailsSheet.tsx +5 -9
- package/src/components/TokenList/TokenDetailsSheetContent.tsx +46 -4
- package/src/components/TokenList/TokenListItem.tsx +44 -68
- package/src/components/TokenList/VirtualizedTokenList.tsx +3 -6
- package/src/components/TokenList/tokenVerificationIcons.ts +15 -0
- package/src/components/TokenList/types.ts +3 -11
- package/src/components/TokenList/useTokenSelect.ts +15 -0
- package/src/config/constants.ts +3 -0
- package/src/config/version.ts +1 -1
- package/src/hooks/useAccountsBalancesData.ts +6 -2
- package/src/hooks/useAddressValidation.ts +87 -32
- package/src/hooks/useGasRefuel.ts +11 -1
- package/src/hooks/useRoutes.ts +23 -18
- package/src/hooks/useToAddressAutoPopulate.ts +13 -17
- package/src/hooks/useToAddressRequirements.ts +19 -4
- package/src/hooks/useToAddressReset.ts +13 -4
- package/src/hooks/useTokenBalance.ts +6 -1
- package/src/pages/SendToWallet/BookmarkAddressSheet.tsx +5 -1
- package/src/pages/SendToWallet/BookmarksPage.tsx +42 -52
- package/src/pages/SendToWallet/ConnectedWalletsPage.tsx +4 -14
- package/src/pages/SendToWallet/RecentWalletsPage.tsx +59 -66
- package/src/pages/SendToWallet/SendToConfiguredWalletPage.tsx +45 -50
- package/src/pages/SendToWallet/SendToWalletPage.tsx +4 -16
- package/src/providers/WalletProvider/WalletProvider.tsx +28 -3
- package/src/providers/WidgetProvider/WidgetProvider.tsx +20 -19
- package/src/stores/bookmarks/types.ts +3 -0
- package/src/stores/chains/ChainOrderStore.tsx +4 -1
- package/src/stores/form/FormStore.tsx +2 -0
- package/src/stores/form/URLSearchParamsBuilder.tsx +4 -2
- package/src/stores/form/getDefaultValuesFromQueryString.ts +19 -0
- package/src/utils/chainType.ts +73 -1
- package/src/utils/customReceiver.ts +36 -0
- package/src/utils/token.ts +48 -0
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
[**LI.FI Widget**](https://docs.li.fi/widget/overview) features include:
|
|
18
18
|
|
|
19
|
-
- **Provider-based architecture** - Modular blockchain support with separate packages for Ethereum, Bitcoin, Solana, Sui, Tron, and Stellar
|
|
19
|
+
- **Provider-based architecture** - Modular blockchain support with separate packages for Ethereum, Bitcoin, Solana, Sui, Tron, and Stellar, plus Zcash as a destination
|
|
20
20
|
- All ecosystems, chains, bridges, exchanges, and solvers that [LI.FI](https://docs.li.fi/introduction/chains) supports
|
|
21
21
|
- Embeddable variants - compact, wide, and drawer
|
|
22
22
|
- Options to allow or deny certain chains, tokens, bridges, and exchanges
|
|
@@ -179,6 +179,26 @@ npm install @lifi/widget-provider-stellar
|
|
|
179
179
|
yarn add @lifi/widget-provider-stellar
|
|
180
180
|
```
|
|
181
181
|
|
|
182
|
+
**Zcash (destination only):**
|
|
183
|
+
|
|
184
|
+
**pnpm:**
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
pnpm add @lifi/widget-provider-zcash
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**npm:**
|
|
191
|
+
|
|
192
|
+
```sh
|
|
193
|
+
npm install @lifi/widget-provider-zcash
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**yarn:**
|
|
197
|
+
|
|
198
|
+
```sh
|
|
199
|
+
yarn add @lifi/widget-provider-zcash
|
|
200
|
+
```
|
|
201
|
+
|
|
182
202
|
**Note:** You only need to install the provider packages for the blockchains you want to support. Each provider package includes its required peer dependencies.
|
|
183
203
|
|
|
184
204
|
### LI.FI Wallet Management
|
|
@@ -225,7 +245,7 @@ npm install @lifi/widget-light
|
|
|
225
245
|
yarn add @lifi/widget-light
|
|
226
246
|
```
|
|
227
247
|
|
|
228
|
-
Ecosystem handlers are available as subpath imports (`@lifi/widget-light/ethereum`, `@lifi/widget-light/solana`, `@lifi/widget-light/bitcoin`, `@lifi/widget-light/sui`, `@lifi/widget-light/tron`) — install the corresponding peer dependencies only for the chains you need. See the [widget-light integration guide](/packages/widget-embedded/README.md) for full setup instructions.
|
|
248
|
+
Ecosystem handlers are available as subpath imports (`@lifi/widget-light/ethereum`, `@lifi/widget-light/solana`, `@lifi/widget-light/bitcoin`, `@lifi/widget-light/sui`, `@lifi/widget-light/tron`) — install the corresponding peer dependencies only for the chains you need. Zcash is not available in widget-light yet. See the [widget-light integration guide](/packages/widget-embedded/README.md) for full setup instructions.
|
|
229
249
|
|
|
230
250
|
## Architecture
|
|
231
251
|
|
|
@@ -239,6 +259,7 @@ The LI.FI Widget uses a **provider-based architecture** that allows you to selec
|
|
|
239
259
|
- **`@lifi/widget-provider-sui`** - Sui support (requires [@mysten/dapp-kit-react](https://sdk.mystenlabs.com/dapp-kit))
|
|
240
260
|
- **`@lifi/widget-provider-tron`** - Tron support (requires [@tronweb3/tronwallet-adapter-react-hooks](https://github.com/tronweb3/tronwallet-adapter))
|
|
241
261
|
- **`@lifi/widget-provider-stellar`** - Stellar support (bundles [Stellar Wallets Kit](https://github.com/Creit-Tech/Stellar-Wallets-Kit); no extra install)
|
|
262
|
+
- **`@lifi/widget-provider-zcash`** - Zcash as a destination chain: validates transparent (`t1`/`t3`) receivers and unified (`u1`) receivers that carry an Orchard receiver; no wallet connection and no extra install. Without it the widget offers no ZEC
|
|
242
263
|
- **`@lifi/wallet-management`** - Wallet management UI components
|
|
243
264
|
- **`@lifi/widget-light`** - Lightweight iframe-based integration ([docs](https://docs.li.fi/widget/widget-light-overview))
|
|
244
265
|
|
|
@@ -275,7 +296,7 @@ export const WidgetPage = () => {
|
|
|
275
296
|
};
|
|
276
297
|
```
|
|
277
298
|
|
|
278
|
-
**Multi-chain example** (Ethereum, Solana, Bitcoin, Sui, Tron, and Stellar):
|
|
299
|
+
**Multi-chain example** (Ethereum, Solana, Bitcoin, Sui, Tron, and Stellar, plus Zcash as a destination):
|
|
279
300
|
|
|
280
301
|
```tsx
|
|
281
302
|
import { LiFiWidget, WidgetConfig } from '@lifi/widget';
|
|
@@ -285,12 +306,14 @@ import { SolanaProvider } from '@lifi/widget-provider-solana';
|
|
|
285
306
|
import { StellarProvider } from '@lifi/widget-provider-stellar';
|
|
286
307
|
import { SuiProvider } from '@lifi/widget-provider-sui';
|
|
287
308
|
import { TronProvider } from '@lifi/widget-provider-tron';
|
|
309
|
+
import { ZcashProvider } from '@lifi/widget-provider-zcash';
|
|
288
310
|
|
|
289
311
|
const widgetConfig: WidgetConfig = {
|
|
290
312
|
providers: [
|
|
291
313
|
EthereumProvider(),
|
|
292
314
|
SolanaProvider(),
|
|
293
315
|
BitcoinProvider(),
|
|
316
|
+
ZcashProvider(),
|
|
294
317
|
SuiProvider(),
|
|
295
318
|
TronProvider(),
|
|
296
319
|
StellarProvider(),
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { isDestinationAllowedAsSource } from "../../utils/chainType.js";
|
|
1
2
|
import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
|
|
3
|
+
import { useFieldValues } from "../../stores/form/useFieldValues.js";
|
|
2
4
|
import { CardContainer } from "./AmountInputCard.style.js";
|
|
3
5
|
import { LimitPriceCard } from "../LimitPriceCard/LimitPriceCard.js";
|
|
4
6
|
import { SwapButton } from "../SwapButton/SwapButton.js";
|
|
@@ -7,8 +9,9 @@ import { SendAmountCard } from "./SendAmountCard.js";
|
|
|
7
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
10
|
//#region src/components/AmountInputCard/AmountInputCardPair.tsx
|
|
9
11
|
const AmountInputCardPair = (props) => {
|
|
10
|
-
const { mode } = useWidgetConfig();
|
|
11
|
-
const
|
|
12
|
+
const { mode, chains } = useWidgetConfig();
|
|
13
|
+
const [toChainId] = useFieldValues("toChain");
|
|
14
|
+
const showSwapButton = mode !== "refuel" && isDestinationAllowedAsSource(toChainId, chains);
|
|
12
15
|
return /* @__PURE__ */ jsxs(CardContainer, {
|
|
13
16
|
...props,
|
|
14
17
|
children: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AmountInputCardPair.js","names":[],"sources":["../../../../src/components/AmountInputCard/AmountInputCardPair.tsx"],"sourcesContent":["import type { BoxProps } from '@mui/material'\nimport type React from 'react'\nimport type { JSX } from 'react'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { LimitPriceCard } from '../LimitPriceCard/LimitPriceCard.js'\nimport { SwapButton } from '../SwapButton/SwapButton.js'\nimport { CardContainer } from './AmountInputCard.style.js'\nimport { ReceiveAmountCard } from './ReceiveAmountCard.js'\nimport { SendAmountCard } from './SendAmountCard.js'\n\nexport const AmountInputCardPair: React.FC<BoxProps> = (props): JSX.Element => {\n // Refuel's destination is fixed to native gas, so reversing from/to is\n // meaningless — hide the swap button (and the notch mask it sits in).\n const { mode } = useWidgetConfig()\n const
|
|
1
|
+
{"version":3,"file":"AmountInputCardPair.js","names":[],"sources":["../../../../src/components/AmountInputCard/AmountInputCardPair.tsx"],"sourcesContent":["import type { BoxProps } from '@mui/material'\nimport type React from 'react'\nimport type { JSX } from 'react'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport { isDestinationAllowedAsSource } from '../../utils/chainType.js'\nimport { LimitPriceCard } from '../LimitPriceCard/LimitPriceCard.js'\nimport { SwapButton } from '../SwapButton/SwapButton.js'\nimport { CardContainer } from './AmountInputCard.style.js'\nimport { ReceiveAmountCard } from './ReceiveAmountCard.js'\nimport { SendAmountCard } from './SendAmountCard.js'\n\nexport const AmountInputCardPair: React.FC<BoxProps> = (props): JSX.Element => {\n // Refuel's destination is fixed to native gas, so reversing from/to is\n // meaningless — hide the swap button (and the notch mask it sits in).\n const { mode, chains } = useWidgetConfig()\n const [toChainId] = useFieldValues('toChain')\n const showSwapButton =\n mode !== 'refuel' && isDestinationAllowedAsSource(toChainId, chains)\n\n return (\n <CardContainer {...props}>\n {mode === 'limit' ? <LimitPriceCard sx={{ marginBottom: 1 }} /> : null}\n <SendAmountCard mask={showSwapButton} />\n <SwapButton sx={{ visibility: showSwapButton ? 'visible' : 'hidden' }} />\n <ReceiveAmountCard mask={showSwapButton} />\n </CardContainer>\n )\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAa,uBAA2C,UAAuB;CAG7E,MAAM,EAAE,MAAM,WAAW,gBAAgB;CACzC,MAAM,CAAC,aAAa,eAAe,SAAS;CAC5C,MAAM,iBACJ,SAAS,YAAY,6BAA6B,WAAW,MAAM;CAErE,OACE,qBAAC,eAAD;EAAe,GAAI;EAAnB,UAAA;GACG,SAAS,UAAU,oBAAC,gBAAD,EAAgB,IAAI,EAAE,cAAc,EAAE,EAAI,CAAA,IAAI;GAClE,oBAAC,gBAAD,EAAgB,MAAM,eAAiB,CAAA;GACvC,oBAAC,YAAD,EAAY,IAAI,EAAE,YAAY,iBAAiB,YAAY,SAAS,EAAI,CAAA;GACxE,oBAAC,mBAAD,EAAmB,MAAM,eAAiB,CAAA;EAC7B;;AAEnB"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { isDestinationAllowedAsSource } from "../utils/chainType.js";
|
|
1
2
|
import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
|
|
3
|
+
import { useFieldValues } from "../stores/form/useFieldValues.js";
|
|
2
4
|
import { ReverseTokensButtonEmpty } from "./ReverseTokensButton/ReverseTokensButton.style.js";
|
|
3
5
|
import { ReverseTokensButton } from "./ReverseTokensButton/ReverseTokensButton.js";
|
|
4
6
|
import { SelectTokenButton } from "./SelectTokenButton/SelectTokenButton.js";
|
|
@@ -6,8 +8,9 @@ import { Box } from "@mui/material";
|
|
|
6
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
9
|
//#region src/components/SelectChainAndToken.tsx
|
|
8
10
|
const SelectChainAndToken = (props) => {
|
|
9
|
-
const { disabledUI, hiddenUI, mode } = useWidgetConfig();
|
|
10
|
-
const
|
|
11
|
+
const { disabledUI, hiddenUI, mode, chains } = useWidgetConfig();
|
|
12
|
+
const [toChainId] = useFieldValues("toChain");
|
|
13
|
+
const hiddenReverse = mode === "refuel" || !isDestinationAllowedAsSource(toChainId, chains) || disabledUI?.fromToken || disabledUI?.toToken || hiddenUI?.fromToken || hiddenUI?.toToken || hiddenUI?.reverseTokensButton;
|
|
11
14
|
const hiddenFromToken = hiddenUI?.fromToken;
|
|
12
15
|
const hiddenToToken = mode === "custom" || hiddenUI?.toToken;
|
|
13
16
|
const showReverseButton = !hiddenToToken && !hiddenFromToken;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectChainAndToken.js","names":[],"sources":["../../../src/components/SelectChainAndToken.tsx"],"sourcesContent":["import type { BoxProps } from '@mui/material'\nimport { Box } from '@mui/material'\nimport { ReverseTokensButton } from '../components/ReverseTokensButton/ReverseTokensButton.js'\nimport { SelectTokenButton } from '../components/SelectTokenButton/SelectTokenButton.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { ReverseTokensButtonEmpty } from './ReverseTokensButton/ReverseTokensButton.style.js'\n\nexport const SelectChainAndToken: React.FC<BoxProps> = (props) => {\n const { disabledUI, hiddenUI, mode } = useWidgetConfig()\n\n const hiddenReverse =\n mode === 'refuel' ||\n disabledUI?.fromToken ||\n disabledUI?.toToken ||\n hiddenUI?.fromToken ||\n hiddenUI?.toToken ||\n hiddenUI?.reverseTokensButton\n\n const hiddenFromToken = hiddenUI?.fromToken\n const hiddenToToken = mode === 'custom' || hiddenUI?.toToken\n\n const showReverseButton = !hiddenToToken && !hiddenFromToken\n\n return (\n <Box {...props} sx={{ display: 'flex', ...props.sx }}>\n {!hiddenFromToken ? (\n <SelectTokenButton formType=\"from\" hiddenReverse={hiddenReverse} />\n ) : null}\n {showReverseButton ? (\n !hiddenReverse ? (\n <ReverseTokensButton />\n ) : (\n <ReverseTokensButtonEmpty />\n )\n ) : null}\n {!hiddenToToken ? (\n <SelectTokenButton formType=\"to\" hiddenReverse={hiddenReverse} />\n ) : null}\n </Box>\n )\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"SelectChainAndToken.js","names":[],"sources":["../../../src/components/SelectChainAndToken.tsx"],"sourcesContent":["import type { BoxProps } from '@mui/material'\nimport { Box } from '@mui/material'\nimport { ReverseTokensButton } from '../components/ReverseTokensButton/ReverseTokensButton.js'\nimport { SelectTokenButton } from '../components/SelectTokenButton/SelectTokenButton.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { isDestinationAllowedAsSource } from '../utils/chainType.js'\nimport { ReverseTokensButtonEmpty } from './ReverseTokensButton/ReverseTokensButton.style.js'\n\nexport const SelectChainAndToken: React.FC<BoxProps> = (props) => {\n const { disabledUI, hiddenUI, mode, chains } = useWidgetConfig()\n const [toChainId] = useFieldValues('toChain')\n\n const hiddenReverse =\n mode === 'refuel' ||\n !isDestinationAllowedAsSource(toChainId, chains) ||\n disabledUI?.fromToken ||\n disabledUI?.toToken ||\n hiddenUI?.fromToken ||\n hiddenUI?.toToken ||\n hiddenUI?.reverseTokensButton\n\n const hiddenFromToken = hiddenUI?.fromToken\n const hiddenToToken = mode === 'custom' || hiddenUI?.toToken\n\n const showReverseButton = !hiddenToToken && !hiddenFromToken\n\n return (\n <Box {...props} sx={{ display: 'flex', ...props.sx }}>\n {!hiddenFromToken ? (\n <SelectTokenButton formType=\"from\" hiddenReverse={hiddenReverse} />\n ) : null}\n {showReverseButton ? (\n !hiddenReverse ? (\n <ReverseTokensButton />\n ) : (\n <ReverseTokensButtonEmpty />\n )\n ) : null}\n {!hiddenToToken ? (\n <SelectTokenButton formType=\"to\" hiddenReverse={hiddenReverse} />\n ) : null}\n </Box>\n )\n}\n"],"mappings":";;;;;;;;;AASA,MAAa,uBAA2C,UAAU;CAChE,MAAM,EAAE,YAAY,UAAU,MAAM,WAAW,gBAAgB;CAC/D,MAAM,CAAC,aAAa,eAAe,SAAS;CAE5C,MAAM,gBACJ,SAAS,YACT,CAAC,6BAA6B,WAAW,MAAM,KAC/C,YAAY,aACZ,YAAY,WACZ,UAAU,aACV,UAAU,WACV,UAAU;CAEZ,MAAM,kBAAkB,UAAU;CAClC,MAAM,gBAAgB,SAAS,YAAY,UAAU;CAErD,MAAM,oBAAoB,CAAC,iBAAiB,CAAC;CAE7C,OACE,qBAAC,KAAD;EAAK,GAAI;EAAO,IAAI;GAAE,SAAS;GAAQ,GAAG,MAAM;EAAG;EAAnD,UAAA;GACG,CAAC,kBACA,oBAAC,mBAAD;IAAmB,UAAS;IAAsB;GAAgB,CAAA,IAChE;GACH,oBACC,CAAC,gBACC,oBAAC,qBAAD,CAAsB,CAAA,IAEtB,oBAAC,0BAAD,CAA2B,CAAA,IAE3B;GACH,CAAC,gBACA,oBAAC,mBAAD;IAAmB,UAAS;IAAoB;GAAgB,CAAA,IAC9D;EACD;;AAET"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { defaultChainIdsByType } from "../../utils/chainType.js";
|
|
1
2
|
import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
|
|
2
3
|
import { navigationRoutes } from "../../utils/navigationRoutes.js";
|
|
3
4
|
import { useBookmarkActions } from "../../stores/bookmarks/useBookmarkActions.js";
|
|
@@ -5,7 +6,6 @@ import { useBookmarks } from "../../stores/bookmarks/useBookmarks.js";
|
|
|
5
6
|
import { useFieldActions } from "../../stores/form/useFieldActions.js";
|
|
6
7
|
import { useFieldValues } from "../../stores/form/useFieldValues.js";
|
|
7
8
|
import { Card as Card$1 } from "../Card/Card.js";
|
|
8
|
-
import { defaultChainIdsByType } from "../../utils/chainType.js";
|
|
9
9
|
import { useToAddressRequirements } from "../../hooks/useToAddressRequirements.js";
|
|
10
10
|
import { CardIconButton } from "../Card/CardIconButton.js";
|
|
11
11
|
import { shortenAddress } from "../../utils/wallet.js";
|
|
@@ -31,14 +31,15 @@ const SendToWalletButton = ({ onEditAddress, onClearAddress, requireAddress, ...
|
|
|
31
31
|
const { selectedBookmark } = useBookmarks();
|
|
32
32
|
const { setSelectedBookmark } = useBookmarkActions();
|
|
33
33
|
const { accounts } = useAccount();
|
|
34
|
-
const {
|
|
34
|
+
const { getChainFromAddress } = useChainTypeFromAddress();
|
|
35
35
|
const { requiredToAddress } = useToAddressRequirements();
|
|
36
36
|
const disabledToAddress = disabledUI?.toAddress;
|
|
37
37
|
const hiddenToAddress = hiddenUI?.toAddress;
|
|
38
38
|
const address = toAddressFieldValue ? shortenAddress(toAddressFieldValue) : t("sendToWallet.enterAddress", { context: "short" });
|
|
39
39
|
const matchingConnectedAccount = accounts.find((account) => account.address === toAddressFieldValue);
|
|
40
|
-
const
|
|
41
|
-
const
|
|
40
|
+
const detectedChain = !matchingConnectedAccount && selectedBookmark?.chainId === void 0 && toAddressFieldValue ? getChainFromAddress(toAddressFieldValue) : void 0;
|
|
41
|
+
const chainType = !matchingConnectedAccount ? selectedBookmark?.chainType || detectedChain?.chainType : void 0;
|
|
42
|
+
const chainId = toChainId && toTokenAddress ? toChainId : matchingConnectedAccount ? matchingConnectedAccount.chainId : selectedBookmark?.chainId ?? detectedChain?.chainId ?? (chainType ? defaultChainIdsByType[chainType] : void 0);
|
|
42
43
|
const isConnectedAccount = selectedBookmark?.isConnectedAccount && matchingConnectedAccount?.isConnected;
|
|
43
44
|
const connectedAccountName = matchingConnectedAccount?.connector?.name;
|
|
44
45
|
const bookmarkName = selectedBookmark?.name;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SendToWalletButton.js","names":["Card"],"sources":["../../../../src/components/SendToWallet/SendToWalletButton.tsx"],"sourcesContent":["import { useAccount } from '@lifi/wallet-management'\nimport { useChainTypeFromAddress } from '@lifi/widget-provider'\nimport CloseRounded from '@mui/icons-material/CloseRounded'\nimport WarningRounded from '@mui/icons-material/WarningRounded'\nimport { Box, Collapse } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport { type MouseEventHandler, useEffect, useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useBookmarkActions } from '../../stores/bookmarks/useBookmarkActions.js'\nimport { useBookmarks } from '../../stores/bookmarks/useBookmarks.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport { defaultChainIdsByType } from '../../utils/chainType.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { shortenAddress } from '../../utils/wallet.js'\nimport { AccountAvatar } from '../Avatar/AccountAvatar.js'\nimport type { CardProps } from '../Card/Card.js'\nimport { Card } from '../Card/Card.js'\nimport { CardIconButton } from '../Card/CardIconButton.js'\nimport { CardTitle } from '../Card/CardTitle.js'\nimport {\n SendToWalletCardHeader,\n SendToWalletCardTitleRow,\n SendToWalletRequiredLabel,\n SendToWalletRequiredLabelText,\n} from './SendToWalletButton.style.js'\n\nexport const SendToWalletButton: React.FC<\n CardProps & {\n onEditAddress?: (() => void) | null\n onClearAddress?: () => void\n // Keep the card visible (and flag it required when empty) even when the\n // widget's own toAddress requirement is off, e.g. a user-settable checkout\n // recipient that must be filled before continuing.\n requireAddress?: boolean\n }\n> = ({ onEditAddress, onClearAddress, requireAddress, ...props }) => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const { disabledUI, hiddenUI, toAddress, toAddresses, mode, modeOptions } =\n useWidgetConfig()\n const [toAddressFieldValue, toChainId, toTokenAddress] = useFieldValues(\n 'toAddress',\n 'toChain',\n 'toToken'\n )\n const { setFieldValue } = useFieldActions()\n const { selectedBookmark } = useBookmarks()\n const { setSelectedBookmark } = useBookmarkActions()\n const { accounts } = useAccount()\n const { getChainTypeFromAddress } = useChainTypeFromAddress()\n const { requiredToAddress } = useToAddressRequirements()\n const disabledToAddress = disabledUI?.toAddress\n const hiddenToAddress = hiddenUI?.toAddress\n\n const address = toAddressFieldValue\n ? shortenAddress(toAddressFieldValue)\n : t('sendToWallet.enterAddress', {\n context: 'short',\n })\n\n const matchingConnectedAccount = accounts.find(\n (account) => account.address === toAddressFieldValue\n )\n\n const chainType = !matchingConnectedAccount\n ? selectedBookmark?.chainType ||\n (toAddressFieldValue\n ? getChainTypeFromAddress(toAddressFieldValue)\n : undefined)\n : undefined\n\n const chainId =\n toChainId && toTokenAddress\n ? toChainId\n : matchingConnectedAccount\n ? matchingConnectedAccount.chainId\n : chainType\n ? defaultChainIdsByType[chainType]\n : undefined\n\n const isConnectedAccount =\n selectedBookmark?.isConnectedAccount &&\n matchingConnectedAccount?.isConnected\n const connectedAccountName = matchingConnectedAccount?.connector?.name\n const bookmarkName = selectedBookmark?.name\n\n const headerTitle = isConnectedAccount\n ? connectedAccountName || address\n : bookmarkName || connectedAccountName || address\n\n const headerSubheader =\n isConnectedAccount || bookmarkName || connectedAccountName ? address : null\n\n const disabledForChanges = Boolean(toAddressFieldValue) && disabledToAddress\n\n // `onEditAddress === null` renders the card read-only (consumer-controlled,\n // e.g. a fixed checkout recipient); a function overrides the default route nav.\n const readOnly = onEditAddress === null || disabledForChanges\n\n const handleOnClick = () => {\n if (onEditAddress !== undefined) {\n onEditAddress?.()\n return\n }\n navigate({\n to: toAddresses?.length\n ? navigationRoutes.configuredWallets\n : navigationRoutes.sendToWallet,\n })\n }\n\n const clearSelectedBookmark: MouseEventHandler<HTMLButtonElement> = (e) => {\n e.stopPropagation()\n if (onClearAddress) {\n onClearAddress()\n return\n }\n setFieldValue('toAddress', '', { isTouched: true })\n setSelectedBookmark()\n }\n\n // The collapse opens instantly on first page load/component mount when there is an address to display\n // After which it needs an animated transition for open and closing.\n // collapseTransitionTime is used specify the transition time for opening and closing\n const collapseTransitionTime = useRef(0)\n\n // Timeout is needed here to push the collapseTransitionTime update to the back of the event loop so that it doesn't fired too quickly\n useEffect(() => {\n const timeout = setTimeout(() => {\n collapseTransitionTime.current = 225\n }, 0)\n return () => clearTimeout(timeout)\n }, [])\n\n const addressRequired = requireAddress || requiredToAddress\n const isOpenCollapse =\n !hiddenToAddress && (addressRequired || !!toAddressFieldValue)\n\n const title =\n mode === 'custom' && modeOptions?.custom?.type === 'deposit'\n ? t('header.depositTo')\n : t('header.sendToWallet')\n\n return (\n <Collapse\n timeout={collapseTransitionTime.current as number}\n in={isOpenCollapse}\n mountOnEnter\n unmountOnExit\n >\n <Card\n role=\"button\"\n onClick={readOnly ? undefined : handleOnClick}\n sx={{ width: '100%', ...props.sx }}\n >\n <SendToWalletCardTitleRow>\n <CardTitle sx={{ p: 0 }}>{title}</CardTitle>\n {addressRequired && !toAddressFieldValue ? (\n <SendToWalletRequiredLabel variant=\"warning\">\n <WarningRounded sx={{ fontSize: 14 }} />\n <SendToWalletRequiredLabelText type=\"icon\">\n {t('sendToWallet.required')}\n </SendToWalletRequiredLabelText>\n </SendToWalletRequiredLabel>\n ) : null}\n </SendToWalletCardTitleRow>\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <SendToWalletCardHeader\n avatar={\n <AccountAvatar\n chainId={chainId}\n account={matchingConnectedAccount}\n toAddress={toAddress}\n empty={!toAddressFieldValue}\n />\n }\n title={headerTitle}\n subheader={headerSubheader}\n selected={!!toAddressFieldValue || disabledToAddress}\n action={\n toAddressFieldValue && !readOnly ? (\n <CardIconButton onClick={clearSelectedBookmark} size=\"small\">\n <CloseRounded fontSize=\"inherit\" />\n </CardIconButton>\n ) : null\n }\n />\n </Box>\n </Card>\n </Collapse>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SendToWalletButton.js","names":["Card"],"sources":["../../../../src/components/SendToWallet/SendToWalletButton.tsx"],"sourcesContent":["import { useAccount } from '@lifi/wallet-management'\nimport { useChainTypeFromAddress } from '@lifi/widget-provider'\nimport CloseRounded from '@mui/icons-material/CloseRounded'\nimport WarningRounded from '@mui/icons-material/WarningRounded'\nimport { Box, Collapse } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport { type MouseEventHandler, useEffect, useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useBookmarkActions } from '../../stores/bookmarks/useBookmarkActions.js'\nimport { useBookmarks } from '../../stores/bookmarks/useBookmarks.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport { defaultChainIdsByType } from '../../utils/chainType.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { shortenAddress } from '../../utils/wallet.js'\nimport { AccountAvatar } from '../Avatar/AccountAvatar.js'\nimport type { CardProps } from '../Card/Card.js'\nimport { Card } from '../Card/Card.js'\nimport { CardIconButton } from '../Card/CardIconButton.js'\nimport { CardTitle } from '../Card/CardTitle.js'\nimport {\n SendToWalletCardHeader,\n SendToWalletCardTitleRow,\n SendToWalletRequiredLabel,\n SendToWalletRequiredLabelText,\n} from './SendToWalletButton.style.js'\n\nexport const SendToWalletButton: React.FC<\n CardProps & {\n onEditAddress?: (() => void) | null\n onClearAddress?: () => void\n // Keep the card visible (and flag it required when empty) even when the\n // widget's own toAddress requirement is off, e.g. a user-settable checkout\n // recipient that must be filled before continuing.\n requireAddress?: boolean\n }\n> = ({ onEditAddress, onClearAddress, requireAddress, ...props }) => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const { disabledUI, hiddenUI, toAddress, toAddresses, mode, modeOptions } =\n useWidgetConfig()\n const [toAddressFieldValue, toChainId, toTokenAddress] = useFieldValues(\n 'toAddress',\n 'toChain',\n 'toToken'\n )\n const { setFieldValue } = useFieldActions()\n const { selectedBookmark } = useBookmarks()\n const { setSelectedBookmark } = useBookmarkActions()\n const { accounts } = useAccount()\n const { getChainFromAddress } = useChainTypeFromAddress()\n const { requiredToAddress } = useToAddressRequirements()\n const disabledToAddress = disabledUI?.toAddress\n const hiddenToAddress = hiddenUI?.toAddress\n\n const address = toAddressFieldValue\n ? shortenAddress(toAddressFieldValue)\n : t('sendToWallet.enterAddress', {\n context: 'short',\n })\n\n const matchingConnectedAccount = accounts.find(\n (account) => account.address === toAddressFieldValue\n )\n\n // A bookmark from the config or the URL may carry no chainId.\n const detectedChain =\n !matchingConnectedAccount &&\n selectedBookmark?.chainId === undefined &&\n toAddressFieldValue\n ? getChainFromAddress(toAddressFieldValue)\n : undefined\n\n const chainType = !matchingConnectedAccount\n ? selectedBookmark?.chainType || detectedChain?.chainType\n : undefined\n\n const chainId =\n toChainId && toTokenAddress\n ? toChainId\n : matchingConnectedAccount\n ? matchingConnectedAccount.chainId\n : (selectedBookmark?.chainId ??\n detectedChain?.chainId ??\n (chainType ? defaultChainIdsByType[chainType] : undefined))\n\n const isConnectedAccount =\n selectedBookmark?.isConnectedAccount &&\n matchingConnectedAccount?.isConnected\n const connectedAccountName = matchingConnectedAccount?.connector?.name\n const bookmarkName = selectedBookmark?.name\n\n const headerTitle = isConnectedAccount\n ? connectedAccountName || address\n : bookmarkName || connectedAccountName || address\n\n const headerSubheader =\n isConnectedAccount || bookmarkName || connectedAccountName ? address : null\n\n const disabledForChanges = Boolean(toAddressFieldValue) && disabledToAddress\n\n // `onEditAddress === null` renders the card read-only (consumer-controlled,\n // e.g. a fixed checkout recipient); a function overrides the default route nav.\n const readOnly = onEditAddress === null || disabledForChanges\n\n const handleOnClick = () => {\n if (onEditAddress !== undefined) {\n onEditAddress?.()\n return\n }\n navigate({\n to: toAddresses?.length\n ? navigationRoutes.configuredWallets\n : navigationRoutes.sendToWallet,\n })\n }\n\n const clearSelectedBookmark: MouseEventHandler<HTMLButtonElement> = (e) => {\n e.stopPropagation()\n if (onClearAddress) {\n onClearAddress()\n return\n }\n setFieldValue('toAddress', '', { isTouched: true })\n setSelectedBookmark()\n }\n\n // The collapse opens instantly on first page load/component mount when there is an address to display\n // After which it needs an animated transition for open and closing.\n // collapseTransitionTime is used specify the transition time for opening and closing\n const collapseTransitionTime = useRef(0)\n\n // Timeout is needed here to push the collapseTransitionTime update to the back of the event loop so that it doesn't fired too quickly\n useEffect(() => {\n const timeout = setTimeout(() => {\n collapseTransitionTime.current = 225\n }, 0)\n return () => clearTimeout(timeout)\n }, [])\n\n const addressRequired = requireAddress || requiredToAddress\n const isOpenCollapse =\n !hiddenToAddress && (addressRequired || !!toAddressFieldValue)\n\n const title =\n mode === 'custom' && modeOptions?.custom?.type === 'deposit'\n ? t('header.depositTo')\n : t('header.sendToWallet')\n\n return (\n <Collapse\n timeout={collapseTransitionTime.current as number}\n in={isOpenCollapse}\n mountOnEnter\n unmountOnExit\n >\n <Card\n role=\"button\"\n onClick={readOnly ? undefined : handleOnClick}\n sx={{ width: '100%', ...props.sx }}\n >\n <SendToWalletCardTitleRow>\n <CardTitle sx={{ p: 0 }}>{title}</CardTitle>\n {addressRequired && !toAddressFieldValue ? (\n <SendToWalletRequiredLabel variant=\"warning\">\n <WarningRounded sx={{ fontSize: 14 }} />\n <SendToWalletRequiredLabelText type=\"icon\">\n {t('sendToWallet.required')}\n </SendToWalletRequiredLabelText>\n </SendToWalletRequiredLabel>\n ) : null}\n </SendToWalletCardTitleRow>\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n }}\n >\n <SendToWalletCardHeader\n avatar={\n <AccountAvatar\n chainId={chainId}\n account={matchingConnectedAccount}\n toAddress={toAddress}\n empty={!toAddressFieldValue}\n />\n }\n title={headerTitle}\n subheader={headerSubheader}\n selected={!!toAddressFieldValue || disabledToAddress}\n action={\n toAddressFieldValue && !readOnly ? (\n <CardIconButton onClick={clearSelectedBookmark} size=\"small\">\n <CloseRounded fontSize=\"inherit\" />\n </CardIconButton>\n ) : null\n }\n />\n </Box>\n </Card>\n </Collapse>\n )\n}\n"],"mappings":"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"}
|
|
@@ -5,15 +5,13 @@ import { jsx } from "react/jsx-runtime";
|
|
|
5
5
|
//#region src/components/TokenList/TokenDetailsSheet.tsx
|
|
6
6
|
const TokenDetailsSheet = ({ ref }) => {
|
|
7
7
|
const bottomSheetRef = useRef(null);
|
|
8
|
-
const [
|
|
9
|
-
const [chainId, setChainId] = useState(void 0);
|
|
8
|
+
const [listToken, setListToken] = useState(void 0);
|
|
10
9
|
const [withoutContractAddress, setWithoutContractAddress] = useState(false);
|
|
11
10
|
useImperativeHandle(ref, () => ({
|
|
12
11
|
isOpen: () => bottomSheetRef.current?.isOpen(),
|
|
13
|
-
open: (
|
|
14
|
-
|
|
12
|
+
open: (token, noContractAddress) => {
|
|
13
|
+
setListToken(token);
|
|
15
14
|
setWithoutContractAddress(noContractAddress);
|
|
16
|
-
setChainId(chainId);
|
|
17
15
|
bottomSheetRef.current?.open();
|
|
18
16
|
},
|
|
19
17
|
close: () => {
|
|
@@ -25,9 +23,8 @@ const TokenDetailsSheet = ({ ref }) => {
|
|
|
25
23
|
keepMounted: true,
|
|
26
24
|
children: /* @__PURE__ */ jsx(TokenDetailsSheetContent, {
|
|
27
25
|
onClose: () => bottomSheetRef.current?.close(),
|
|
28
|
-
|
|
29
|
-
withoutContractAddress
|
|
30
|
-
chainId
|
|
26
|
+
listToken,
|
|
27
|
+
withoutContractAddress
|
|
31
28
|
})
|
|
32
29
|
});
|
|
33
30
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenDetailsSheet.js","names":[],"sources":["../../../../src/components/TokenList/TokenDetailsSheet.tsx"],"sourcesContent":["import type { JSX, Ref } from 'react'\nimport { useImperativeHandle, useRef, useState } from 'react'\nimport { BottomSheet } from '../BottomSheet/BottomSheet.js'\nimport type { BottomSheetBase } from '../BottomSheet/types.js'\nimport { TokenDetailsSheetContent } from './TokenDetailsSheetContent.js'\nimport type { TokenDetailsSheetBase } from './types.js'\n\nexport const TokenDetailsSheet = ({\n ref,\n}: {\n ref?: Ref<TokenDetailsSheetBase>\n}): JSX.Element => {\n const bottomSheetRef = useRef<BottomSheetBase>(null)\n const [
|
|
1
|
+
{"version":3,"file":"TokenDetailsSheet.js","names":[],"sources":["../../../../src/components/TokenList/TokenDetailsSheet.tsx"],"sourcesContent":["import type { JSX, Ref } from 'react'\nimport { useImperativeHandle, useRef, useState } from 'react'\nimport type { TokenAmount } from '../../types/token.js'\nimport { BottomSheet } from '../BottomSheet/BottomSheet.js'\nimport type { BottomSheetBase } from '../BottomSheet/types.js'\nimport { TokenDetailsSheetContent } from './TokenDetailsSheetContent.js'\nimport type { TokenDetailsSheetBase } from './types.js'\n\nexport const TokenDetailsSheet = ({\n ref,\n}: {\n ref?: Ref<TokenDetailsSheetBase>\n}): JSX.Element => {\n const bottomSheetRef = useRef<BottomSheetBase>(null)\n const [listToken, setListToken] = useState<TokenAmount | undefined>(undefined)\n const [withoutContractAddress, setWithoutContractAddress] = useState(false)\n\n useImperativeHandle(\n ref,\n () => ({\n isOpen: () => bottomSheetRef.current?.isOpen(),\n open: (token: TokenAmount, noContractAddress: boolean) => {\n setListToken(token)\n setWithoutContractAddress(noContractAddress)\n bottomSheetRef.current?.open()\n },\n close: () => {\n bottomSheetRef.current?.close()\n },\n }),\n []\n )\n\n return (\n <BottomSheet ref={bottomSheetRef} keepMounted>\n <TokenDetailsSheetContent\n onClose={() => bottomSheetRef.current?.close()}\n listToken={listToken}\n withoutContractAddress={withoutContractAddress}\n />\n </BottomSheet>\n )\n}\n"],"mappings":";;;;;AAQA,MAAa,qBAAqB,EAChC,UAGiB;CACjB,MAAM,iBAAiB,OAAwB,IAAI;CACnD,MAAM,CAAC,WAAW,gBAAgB,SAAkC,KAAA,CAAS;CAC7E,MAAM,CAAC,wBAAwB,6BAA6B,SAAS,KAAK;CAE1E,oBACE,YACO;EACL,cAAc,eAAe,SAAS,OAAO;EAC7C,OAAO,OAAoB,sBAA+B;GACxD,aAAa,KAAK;GAClB,0BAA0B,iBAAiB;GAC3C,eAAe,SAAS,KAAK;EAC/B;EACA,aAAa;GACX,eAAe,SAAS,MAAM;EAChC;CACF,IACA,CAAC,CACH;CAEA,OACE,oBAAC,aAAD;EAAa,KAAK;EAAgB,aAAA;EAChC,UAAA,oBAAC,0BAAD;GACE,eAAe,eAAe,SAAS,MAAM;GAClC;GACa;EACzB,CAAA;CACU,CAAA;AAEjB"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useAvailableChains } from "../../hooks/useAvailableChains.js";
|
|
2
|
+
import { getTokenStatusTextKey, getTokenVerificationBadge } from "../../utils/token.js";
|
|
2
3
|
import { useToken } from "../../hooks/useToken.js";
|
|
3
4
|
import { CardIconButton } from "../Card/CardIconButton.js";
|
|
4
5
|
import { TokenAvatar } from "../Avatar/TokenAvatar.js";
|
|
5
6
|
import { shortenAddress } from "../../utils/wallet.js";
|
|
6
7
|
import { useExplorer } from "../../hooks/useExplorer.js";
|
|
7
8
|
import { Label, MetricContainer, TokenDetailsSheetContainer, TokenDetailsSheetHeader } from "./TokenDetailsSheetContent.style.js";
|
|
9
|
+
import { tokenVerificationIcons } from "./tokenVerificationIcons.js";
|
|
8
10
|
import { useMemo } from "react";
|
|
9
11
|
import { Box, IconButton, Link, Skeleton, Typography } from "@mui/material";
|
|
10
12
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -14,12 +16,17 @@ import OpenInNewRounded from "@mui/icons-material/OpenInNewRounded";
|
|
|
14
16
|
import Close from "@mui/icons-material/Close";
|
|
15
17
|
//#region src/components/TokenList/TokenDetailsSheetContent.tsx
|
|
16
18
|
const noDataLabel = "-";
|
|
17
|
-
const TokenDetailsSheetContent = ({
|
|
19
|
+
const TokenDetailsSheetContent = ({ listToken, withoutContractAddress, onClose }) => {
|
|
18
20
|
const { t } = useTranslation();
|
|
19
21
|
const { getAddressLink } = useExplorer();
|
|
20
22
|
const { getChainById } = useAvailableChains();
|
|
23
|
+
const tokenAddress = listToken?.address;
|
|
24
|
+
const chainId = listToken?.chainId;
|
|
21
25
|
const { token, isLoading } = useToken(chainId, tokenAddress, true);
|
|
22
26
|
const chain = useMemo(() => getChainById(chainId), [chainId, getChainById]);
|
|
27
|
+
const statusBadge = listToken ? getTokenVerificationBadge(listToken) : void 0;
|
|
28
|
+
const statusIcon = statusBadge ? tokenVerificationIcons[statusBadge] : void 0;
|
|
29
|
+
const statusText = listToken ? t(getTokenStatusTextKey(listToken)) : noDataLabel;
|
|
23
30
|
const copyContractAddress = async (e) => {
|
|
24
31
|
e.stopPropagation();
|
|
25
32
|
try {
|
|
@@ -161,7 +168,28 @@ const TokenDetailsSheetContent = ({ tokenAddress, chainId, withoutContractAddres
|
|
|
161
168
|
maximumFractionDigits: 2
|
|
162
169
|
}) : noDataLabel
|
|
163
170
|
})
|
|
164
|
-
})
|
|
171
|
+
}),
|
|
172
|
+
/* @__PURE__ */ jsxs(MetricContainer, { children: [/* @__PURE__ */ jsx(Label, { children: t("tokenMetric.status") }), /* @__PURE__ */ jsxs(Box, {
|
|
173
|
+
sx: {
|
|
174
|
+
display: "flex",
|
|
175
|
+
alignItems: "flex-start",
|
|
176
|
+
gap: 1
|
|
177
|
+
},
|
|
178
|
+
children: [statusIcon ? /* @__PURE__ */ jsx(statusIcon.Icon, { sx: {
|
|
179
|
+
flexShrink: 0,
|
|
180
|
+
fontSize: 20,
|
|
181
|
+
color: statusIcon.color
|
|
182
|
+
} }) : null, /* @__PURE__ */ jsx(Typography, {
|
|
183
|
+
sx: {
|
|
184
|
+
minWidth: 0,
|
|
185
|
+
fontWeight: 500,
|
|
186
|
+
fontSize: "14px",
|
|
187
|
+
lineHeight: "20px",
|
|
188
|
+
color: "text.primary"
|
|
189
|
+
},
|
|
190
|
+
children: statusText
|
|
191
|
+
})]
|
|
192
|
+
})] })
|
|
165
193
|
] });
|
|
166
194
|
};
|
|
167
195
|
const MetricWithSkeleton = ({ label, width, height, isLoading, children }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TokenDetailsSheetContent.js","names":[],"sources":["../../../../src/components/TokenList/TokenDetailsSheetContent.tsx"],"sourcesContent":["import Close from '@mui/icons-material/Close'\nimport ContentCopyRounded from '@mui/icons-material/ContentCopyRounded'\nimport OpenInNewRounded from '@mui/icons-material/OpenInNewRounded'\nimport { Box, IconButton, Link, Skeleton, Typography } from '@mui/material'\nimport type React from 'react'\nimport { type JSX, type PropsWithChildren, useMemo } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useExplorer } from '../../hooks/useExplorer.js'\nimport { useToken } from '../../hooks/useToken.js'\nimport { shortenAddress } from '../../utils/wallet.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport { CardIconButton } from '../Card/CardIconButton.js'\nimport {\n Label,\n MetricContainer,\n TokenDetailsSheetContainer,\n TokenDetailsSheetHeader,\n} from './TokenDetailsSheetContent.style.js'\n\ninterface TokenDetailsSheetContentProps {\n tokenAddress: string | undefined\n chainId: number | undefined\n withoutContractAddress: boolean\n onClose: () => void\n}\n\nconst noDataLabel = '-'\n\nexport const TokenDetailsSheetContent = ({\n tokenAddress,\n chainId,\n withoutContractAddress,\n onClose,\n}: TokenDetailsSheetContentProps): JSX.Element => {\n const { t } = useTranslation()\n const { getAddressLink } = useExplorer()\n const { getChainById } = useAvailableChains()\n\n const { token, isLoading } = useToken(chainId, tokenAddress, true)\n const chain = useMemo(() => getChainById(chainId), [chainId, getChainById])\n\n const copyContractAddress = async (e: React.MouseEvent) => {\n e.stopPropagation()\n try {\n // Clipboard API may throw if access is denied (e.g., in insecure contexts or older browsers)\n await navigator.clipboard.writeText(tokenAddress || '')\n } catch {\n // Silently fail to avoid crashing the UI if clipboard write fails\n }\n }\n\n return (\n <TokenDetailsSheetContainer>\n <TokenDetailsSheetHeader>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n gap: 3,\n }}\n >\n <TokenAvatar\n token={token}\n chain={chain}\n tokenAvatarSize={72}\n chainAvatarSize={28}\n isLoading={isLoading}\n />\n <MetricContainer>\n {isLoading ? (\n <>\n <Skeleton variant=\"rounded\" width={80} height={24} />\n <Skeleton variant=\"rounded\" width={80} height={16} />\n </>\n ) : (\n <>\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '24px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.symbol || noDataLabel}\n </Typography>\n <Label>{token?.name || noDataLabel}</Label>\n </>\n )}\n </MetricContainer>\n </Box>\n <IconButton\n onClick={(e) => {\n e.stopPropagation()\n onClose()\n }}\n sx={{ mt: '-8px', mr: '-8px' }}\n >\n <Close />\n </IconButton>\n </TokenDetailsSheetHeader>\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.currentPrice')}\n width={200}\n height={40}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '32px',\n lineHeight: '40px',\n color: 'text.primary',\n }}\n >\n {token?.priceUSD\n ? t('format.currency', {\n value: token.priceUSD,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n {!withoutContractAddress && (\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.contractAddress')}\n width={200}\n height={24}\n >\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n gap: 1,\n }}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {shortenAddress(tokenAddress)}\n </Typography>\n {tokenAddress && (\n <CardIconButton size=\"small\" onClick={copyContractAddress}>\n <ContentCopyRounded fontSize=\"inherit\" />\n </CardIconButton>\n )}\n {tokenAddress && (\n <CardIconButton\n size=\"small\"\n LinkComponent={Link}\n href={getAddressLink(tokenAddress, chainId)}\n target=\"_blank\"\n rel=\"nofollow noreferrer\"\n onClick={(e) => e.stopPropagation()}\n >\n <OpenInNewRounded fontSize=\"inherit\" />\n </CardIconButton>\n )}\n </Box>\n </MetricWithSkeleton>\n )}\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.marketCap')}\n width={200}\n height={24}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.marketCapUSD\n ? t('format.currency', {\n value: token.marketCapUSD,\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 2,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.volume24h')}\n width={200}\n height={24}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.volumeUSD24H\n ? t('format.currency', {\n value: token.volumeUSD24H,\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 2,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n </TokenDetailsSheetContainer>\n )\n}\n\ninterface MetricWithSkeletonProps {\n label: string\n isLoading: boolean\n width: number\n height: number\n}\n\nconst MetricWithSkeleton = ({\n label,\n width,\n height,\n isLoading,\n children,\n}: PropsWithChildren<MetricWithSkeletonProps>) => {\n return (\n <MetricContainer>\n <Label>{label}</Label>\n {isLoading ? (\n <Skeleton variant=\"rounded\" width={width} height={height} />\n ) : (\n children\n )}\n </MetricContainer>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TokenDetailsSheetContent.js","names":[],"sources":["../../../../src/components/TokenList/TokenDetailsSheetContent.tsx"],"sourcesContent":["import Close from '@mui/icons-material/Close'\nimport ContentCopyRounded from '@mui/icons-material/ContentCopyRounded'\nimport OpenInNewRounded from '@mui/icons-material/OpenInNewRounded'\nimport { Box, IconButton, Link, Skeleton, Typography } from '@mui/material'\nimport type React from 'react'\nimport { type JSX, type PropsWithChildren, useMemo } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useExplorer } from '../../hooks/useExplorer.js'\nimport { useToken } from '../../hooks/useToken.js'\nimport type { TokenAmount } from '../../types/token.js'\nimport {\n getTokenStatusTextKey,\n getTokenVerificationBadge,\n} from '../../utils/token.js'\nimport { shortenAddress } from '../../utils/wallet.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport { CardIconButton } from '../Card/CardIconButton.js'\nimport {\n Label,\n MetricContainer,\n TokenDetailsSheetContainer,\n TokenDetailsSheetHeader,\n} from './TokenDetailsSheetContent.style.js'\nimport { tokenVerificationIcons } from './tokenVerificationIcons.js'\n\ninterface TokenDetailsSheetContentProps {\n listToken: TokenAmount | undefined\n withoutContractAddress: boolean\n onClose: () => void\n}\n\nconst noDataLabel = '-'\n\nexport const TokenDetailsSheetContent = ({\n listToken,\n withoutContractAddress,\n onClose,\n}: TokenDetailsSheetContentProps): JSX.Element => {\n const { t } = useTranslation()\n const { getAddressLink } = useExplorer()\n const { getChainById } = useAvailableChains()\n\n const tokenAddress = listToken?.address\n const chainId = listToken?.chainId\n const { token, isLoading } = useToken(chainId, tokenAddress, true)\n const chain = useMemo(() => getChainById(chainId), [chainId, getChainById])\n\n // The row token, not the fetched one: only the list sets the flags.\n const statusBadge = listToken\n ? getTokenVerificationBadge(listToken)\n : undefined\n const statusIcon = statusBadge\n ? tokenVerificationIcons[statusBadge]\n : undefined\n const statusText = listToken\n ? t(getTokenStatusTextKey(listToken))\n : noDataLabel\n\n const copyContractAddress = async (e: React.MouseEvent) => {\n e.stopPropagation()\n try {\n // Clipboard API may throw if access is denied (e.g., in insecure contexts or older browsers)\n await navigator.clipboard.writeText(tokenAddress || '')\n } catch {\n // Silently fail to avoid crashing the UI if clipboard write fails\n }\n }\n\n return (\n <TokenDetailsSheetContainer>\n <TokenDetailsSheetHeader>\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n gap: 3,\n }}\n >\n <TokenAvatar\n token={token}\n chain={chain}\n tokenAvatarSize={72}\n chainAvatarSize={28}\n isLoading={isLoading}\n />\n <MetricContainer>\n {isLoading ? (\n <>\n <Skeleton variant=\"rounded\" width={80} height={24} />\n <Skeleton variant=\"rounded\" width={80} height={16} />\n </>\n ) : (\n <>\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '24px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.symbol || noDataLabel}\n </Typography>\n <Label>{token?.name || noDataLabel}</Label>\n </>\n )}\n </MetricContainer>\n </Box>\n <IconButton\n onClick={(e) => {\n e.stopPropagation()\n onClose()\n }}\n sx={{ mt: '-8px', mr: '-8px' }}\n >\n <Close />\n </IconButton>\n </TokenDetailsSheetHeader>\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.currentPrice')}\n width={200}\n height={40}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '32px',\n lineHeight: '40px',\n color: 'text.primary',\n }}\n >\n {token?.priceUSD\n ? t('format.currency', {\n value: token.priceUSD,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n {!withoutContractAddress && (\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.contractAddress')}\n width={200}\n height={24}\n >\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n gap: 1,\n }}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {shortenAddress(tokenAddress)}\n </Typography>\n {tokenAddress && (\n <CardIconButton size=\"small\" onClick={copyContractAddress}>\n <ContentCopyRounded fontSize=\"inherit\" />\n </CardIconButton>\n )}\n {tokenAddress && (\n <CardIconButton\n size=\"small\"\n LinkComponent={Link}\n href={getAddressLink(tokenAddress, chainId)}\n target=\"_blank\"\n rel=\"nofollow noreferrer\"\n onClick={(e) => e.stopPropagation()}\n >\n <OpenInNewRounded fontSize=\"inherit\" />\n </CardIconButton>\n )}\n </Box>\n </MetricWithSkeleton>\n )}\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.marketCap')}\n width={200}\n height={24}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.marketCapUSD\n ? t('format.currency', {\n value: token.marketCapUSD,\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 2,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n <MetricWithSkeleton\n isLoading={isLoading}\n label={t('tokenMetric.volume24h')}\n width={200}\n height={24}\n >\n <Typography\n sx={{\n fontWeight: 700,\n fontSize: '18px',\n lineHeight: '24px',\n color: 'text.primary',\n }}\n >\n {token?.volumeUSD24H\n ? t('format.currency', {\n value: token.volumeUSD24H,\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 2,\n })\n : noDataLabel}\n </Typography>\n </MetricWithSkeleton>\n <MetricContainer>\n <Label>{t('tokenMetric.status')}</Label>\n <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 1 }}>\n {statusIcon ? (\n <statusIcon.Icon\n sx={{\n flexShrink: 0,\n fontSize: 20,\n color: statusIcon.color,\n }}\n />\n ) : null}\n <Typography\n sx={{\n minWidth: 0,\n fontWeight: 500,\n fontSize: '14px',\n lineHeight: '20px',\n color: 'text.primary',\n }}\n >\n {statusText}\n </Typography>\n </Box>\n </MetricContainer>\n </TokenDetailsSheetContainer>\n )\n}\n\ninterface MetricWithSkeletonProps {\n label: string\n isLoading: boolean\n width: number\n height: number\n}\n\nconst MetricWithSkeleton = ({\n label,\n width,\n height,\n isLoading,\n children,\n}: PropsWithChildren<MetricWithSkeletonProps>) => {\n return (\n <MetricContainer>\n <Label>{label}</Label>\n {isLoading ? (\n <Skeleton variant=\"rounded\" width={width} height={height} />\n ) : (\n children\n )}\n </MetricContainer>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { formatTokenAmount, formatTokenPrice } from "../../utils/format.js";
|
|
2
|
-
import { getTokenVerificationProvider } from "../../utils/token.js";
|
|
2
|
+
import { getTokenVerificationBadge, getTokenVerificationProvider } from "../../utils/token.js";
|
|
3
3
|
import { TokenAvatar } from "../Avatar/TokenAvatar.js";
|
|
4
4
|
import { shortenAddress } from "../../utils/wallet.js";
|
|
5
|
+
import { tokenVerificationIcons } from "./tokenVerificationIcons.js";
|
|
5
6
|
import { IconButton as IconButton$1, ListItem as ListItem$1 } from "./TokenList.style.js";
|
|
6
7
|
import { useLongPress } from "../../hooks/useLongPress.js";
|
|
7
8
|
import { ListItemButton as ListItemButton$1 } from "../ListItem/ListItemButton.js";
|
|
@@ -13,8 +14,6 @@ import { Avatar, Box, ListItemAvatar, ListItemText, Skeleton, Slide, Tooltip, Ty
|
|
|
13
14
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
15
|
import { useTranslation } from "react-i18next";
|
|
15
16
|
import InfoOutlined from "@mui/icons-material/InfoOutlined";
|
|
16
|
-
import ReportRoundedIcon from "@mui/icons-material/ReportRounded";
|
|
17
|
-
import VerifiedIcon from "@mui/icons-material/Verified";
|
|
18
17
|
//#region src/components/TokenList/TokenListItem.tsx
|
|
19
18
|
const TokenListItem = memo(({ onClick, size, start, token, chain, chainName, isBalanceLoading, startAdornment, endAdornment, selected, onShowTokenDetails }) => {
|
|
20
19
|
return /* @__PURE__ */ jsxs(ListItem$1, {
|
|
@@ -48,14 +47,14 @@ const TokenListItemAvatar = memo(({ token }) => {
|
|
|
48
47
|
children: token.symbol?.[0]
|
|
49
48
|
});
|
|
50
49
|
});
|
|
51
|
-
const OpenTokenDetailsButton = ({
|
|
52
|
-
if (!
|
|
50
|
+
const OpenTokenDetailsButton = ({ token, withoutContractAddress, onClick }) => {
|
|
51
|
+
if (!token.address) return null;
|
|
53
52
|
return /* @__PURE__ */ jsx(IconButton$1, {
|
|
54
53
|
size: "small",
|
|
55
54
|
onClick: (e) => {
|
|
56
55
|
e.stopPropagation();
|
|
57
56
|
e.currentTarget.blur();
|
|
58
|
-
onClick(
|
|
57
|
+
onClick(token, withoutContractAddress);
|
|
59
58
|
},
|
|
60
59
|
children: /* @__PURE__ */ jsx(InfoOutlined, {})
|
|
61
60
|
});
|
|
@@ -85,41 +84,33 @@ const TokenListItemButton = memo(({ onClick, token, chain, chainName, isBalanceL
|
|
|
85
84
|
token.priceUSD,
|
|
86
85
|
token.decimals
|
|
87
86
|
]);
|
|
88
|
-
const longPressEvents = useLongPress(() => onShowTokenDetails(token
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
verificationBadge = {
|
|
106
|
-
Icon: VerifiedIcon,
|
|
107
|
-
color: "success.main",
|
|
108
|
-
title: provider ? t("tooltip.tokenVerifiedByProvider", {
|
|
87
|
+
const longPressEvents = useLongPress(() => onShowTokenDetails(token, withoutContractAddress));
|
|
88
|
+
const verificationBadge = getTokenVerificationBadge(token);
|
|
89
|
+
const verificationIcon = verificationBadge ? tokenVerificationIcons[verificationBadge] : void 0;
|
|
90
|
+
let verificationTitle = "";
|
|
91
|
+
switch (verificationBadge) {
|
|
92
|
+
case "native":
|
|
93
|
+
verificationTitle = chainName ? t("tooltip.tokenNativeOnChain", {
|
|
94
|
+
tokenSymbol: token.symbol,
|
|
95
|
+
chainName
|
|
96
|
+
}) : t("tooltip.tokenNative", { tokenSymbol: token.symbol });
|
|
97
|
+
break;
|
|
98
|
+
case "flagged":
|
|
99
|
+
verificationTitle = t("warning.message.tokenFlagged", { tokenSymbol: token.symbol });
|
|
100
|
+
break;
|
|
101
|
+
case "verified": {
|
|
102
|
+
const provider = getTokenVerificationProvider(token);
|
|
103
|
+
verificationTitle = provider ? t("tooltip.tokenVerifiedByProvider", {
|
|
109
104
|
tokenSymbol: token.symbol,
|
|
110
105
|
provider
|
|
111
|
-
}) : t("tooltip.tokenVerified", { tokenSymbol: token.symbol })
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
Icon: ReportRoundedIcon,
|
|
120
|
-
color: "warning.main",
|
|
121
|
-
title: t("warning.message.tokenUnverified")
|
|
122
|
-
};
|
|
106
|
+
}) : t("tooltip.tokenVerified", { tokenSymbol: token.symbol });
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
case "unverifiedByProvider":
|
|
110
|
+
verificationTitle = t("warning.message.tokenUnverifiedByProvider", { tokenSymbol: token.symbol });
|
|
111
|
+
break;
|
|
112
|
+
case "unverified": verificationTitle = t("warning.message.tokenUnverified");
|
|
113
|
+
}
|
|
123
114
|
return /* @__PURE__ */ jsxs(ListItemButton$1, {
|
|
124
115
|
onClick: handleClick,
|
|
125
116
|
onMouseEnter,
|
|
@@ -146,14 +137,14 @@ const TokenListItemButton = memo(({ onClick, token, chain, chainName, isBalanceL
|
|
|
146
137
|
alignItems: "center",
|
|
147
138
|
gap: .5
|
|
148
139
|
},
|
|
149
|
-
children: [token.symbol,
|
|
150
|
-
title:
|
|
140
|
+
children: [token.symbol, verificationIcon && /* @__PURE__ */ jsx(Tooltip, {
|
|
141
|
+
title: verificationTitle,
|
|
151
142
|
placement: "top",
|
|
152
143
|
arrow: true,
|
|
153
|
-
children: /* @__PURE__ */ jsx(
|
|
144
|
+
children: /* @__PURE__ */ jsx(verificationIcon.Icon, { sx: {
|
|
154
145
|
display: "flex",
|
|
155
146
|
fontSize: 16,
|
|
156
|
-
color:
|
|
147
|
+
color: verificationIcon.color,
|
|
157
148
|
cursor: "help"
|
|
158
149
|
} })
|
|
159
150
|
})]
|
|
@@ -179,9 +170,8 @@ const TokenListItemButton = memo(({ onClick, token, chain, chainName, isBalanceL
|
|
|
179
170
|
mountOnEnter: true,
|
|
180
171
|
children: /* @__PURE__ */ jsxs(Box, { children: [
|
|
181
172
|
/* @__PURE__ */ jsx(OpenTokenDetailsButton, {
|
|
182
|
-
|
|
173
|
+
token,
|
|
183
174
|
withoutContractAddress,
|
|
184
|
-
chainId: token.chainId,
|
|
185
175
|
onClick: onShowTokenDetails
|
|
186
176
|
}),
|
|
187
177
|
/* @__PURE__ */ jsx(PinTokenButton, {
|
|
@@ -233,9 +223,8 @@ const TokenListItemButton = memo(({ onClick, token, chain, chainName, isBalanceL
|
|
|
233
223
|
children: shortenAddress(token.address)
|
|
234
224
|
}), /* @__PURE__ */ jsxs(Box, { children: [
|
|
235
225
|
/* @__PURE__ */ jsx(OpenTokenDetailsButton, {
|
|
236
|
-
|
|
226
|
+
token,
|
|
237
227
|
withoutContractAddress,
|
|
238
|
-
chainId: token.chainId,
|
|
239
228
|
onClick: onShowTokenDetails
|
|
240
229
|
}),
|
|
241
230
|
/* @__PURE__ */ jsx(PinTokenButton, {
|