@lifi/widget 4.8.0 → 4.9.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/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/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 +2 -1
- package/dist/esm/i18n/de.json +2 -1
- package/dist/esm/i18n/en.json +2 -1
- package/dist/esm/i18n/es.json +2 -1
- package/dist/esm/i18n/fr.json +2 -1
- package/dist/esm/i18n/hi.json +2 -1
- package/dist/esm/i18n/id.json +2 -1
- package/dist/esm/i18n/it.json +2 -1
- package/dist/esm/i18n/ja.json +2 -1
- package/dist/esm/i18n/ko.json +2 -1
- package/dist/esm/i18n/pl.json +2 -1
- package/dist/esm/i18n/pt.json +2 -1
- package/dist/esm/i18n/th.json +2 -1
- package/dist/esm/i18n/tr.json +2 -1
- package/dist/esm/i18n/uk.json +2 -1
- package/dist/esm/i18n/vi.json +2 -1
- package/dist/esm/i18n/zh.json +2 -1
- 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/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/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
|
@@ -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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokenSelect.d.ts","names":[],"sources":["../../../../src/components/TokenList/useTokenSelect.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"useTokenSelect.d.ts","names":[],"sources":["../../../../src/components/TokenList/useTokenSelect.ts"],"mappings":";;qBAea,iBACX,UAAU,UACV,2BACG,sBAAsB"}
|
|
@@ -3,7 +3,9 @@ import "../../types/events.js";
|
|
|
3
3
|
import { isItemAllowed } from "../../utils/item.js";
|
|
4
4
|
import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
|
|
5
5
|
import { useSplitMode } from "../../stores/navigationTabs/useNavigationTabsStore.js";
|
|
6
|
+
import { useAvailableChains } from "../../hooks/useAvailableChains.js";
|
|
6
7
|
import { useFieldActions } from "../../stores/form/useFieldActions.js";
|
|
8
|
+
import { useToAddressReset } from "../../hooks/useToAddressReset.js";
|
|
7
9
|
import { useChainOrderStore } from "../../stores/chains/ChainOrderStore.js";
|
|
8
10
|
import { FormKeyHelper } from "../../stores/form/types.js";
|
|
9
11
|
import { useToAddressAutoPopulate } from "../../hooks/useToAddressAutoPopulate.js";
|
|
@@ -15,9 +17,12 @@ const useTokenSelect = (formType, onClick) => {
|
|
|
15
17
|
const emitter = useWidgetEvents();
|
|
16
18
|
const { setFieldValue, getFieldValues } = useFieldActions();
|
|
17
19
|
const autoPopulateToAddress = useToAddressAutoPopulate();
|
|
20
|
+
const { tryResetToAddress } = useToAddressReset();
|
|
21
|
+
const { getChainById } = useAvailableChains();
|
|
18
22
|
const [setChain, setIsAllNetworks] = useChainOrderStore((state) => [state.setChain, state.setIsAllNetworks]);
|
|
19
23
|
const tokenKey = FormKeyHelper.getTokenKey(formType);
|
|
20
24
|
return useCallback((tokenAddress, chainId) => {
|
|
25
|
+
const [toChainIdBefore] = getFieldValues("toChain");
|
|
21
26
|
setFieldValue(tokenKey, tokenAddress, {
|
|
22
27
|
isDirty: true,
|
|
23
28
|
isTouched: true
|
|
@@ -43,6 +48,9 @@ const useTokenSelect = (formType, onClick) => {
|
|
|
43
48
|
});
|
|
44
49
|
setChain(selectedChainId, oppositeFormType);
|
|
45
50
|
}
|
|
51
|
+
const [toChainId] = getFieldValues("toChain");
|
|
52
|
+
const toChain = getChainById(toChainId);
|
|
53
|
+
if (toChainId !== toChainIdBefore && toChain) tryResetToAddress(toChain);
|
|
46
54
|
autoPopulateToAddress({
|
|
47
55
|
formType,
|
|
48
56
|
selectedToAddress,
|
|
@@ -58,6 +66,8 @@ const useTokenSelect = (formType, onClick) => {
|
|
|
58
66
|
onClick?.();
|
|
59
67
|
}, [
|
|
60
68
|
autoPopulateToAddress,
|
|
69
|
+
tryResetToAddress,
|
|
70
|
+
getChainById,
|
|
61
71
|
disabledUI,
|
|
62
72
|
emitter,
|
|
63
73
|
formType,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokenSelect.js","names":[],"sources":["../../../../src/components/TokenList/useTokenSelect.ts"],"sourcesContent":["import { useCallback } from 'react'\nimport { useToAddressAutoPopulate } from '../../hooks/useToAddressAutoPopulate.js'\nimport { useWidgetEvents } from '../../hooks/useWidgetEvents.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useChainOrderStore } from '../../stores/chains/ChainOrderStore.js'\nimport type { FormType } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useSplitMode } from '../../stores/navigationTabs/useNavigationTabsStore.js'\nimport { WidgetEvent } from '../../types/events.js'\nimport type { DisabledUIConfig } from '../../types/widget.js'\nimport { isItemAllowed } from '../../utils/item.js'\n\nexport const useTokenSelect = (\n formType: FormType,\n onClick?: () => void\n): ((tokenAddress: string, chainId?: number) => void) => {\n const { mode, disabledUI, chains: chainsConfig } = useWidgetConfig()\n const splitMode = useSplitMode()\n const emitter = useWidgetEvents()\n const { setFieldValue, getFieldValues } = useFieldActions()\n const autoPopulateToAddress = useToAddressAutoPopulate()\n const [setChain, setIsAllNetworks] = useChainOrderStore((state) => [\n state.setChain,\n state.setIsAllNetworks,\n ])\n\n const tokenKey = FormKeyHelper.getTokenKey(formType)\n\n return useCallback(\n (tokenAddress: string, chainId?: number) => {\n setFieldValue(tokenKey, tokenAddress, { isDirty: true, isTouched: true })\n const selectedChainId =\n chainId ?? getFieldValues(FormKeyHelper.getChainKey(formType))[0]\n // Set chain again to trigger URL builder update\n setFieldValue(FormKeyHelper.getChainKey(formType), selectedChainId, {\n isDirty: true,\n isTouched: true,\n })\n const amountKey = FormKeyHelper.getAmountKey(formType)\n if (!disabledUI?.[amountKey as keyof DisabledUIConfig]) {\n setFieldValue(amountKey, '')\n }\n const oppositeFormType = formType === 'from' ? 'to' : 'from'\n const [\n selectedOppositeTokenAddress,\n selectedOppositeChainId,\n selectedToAddress,\n ] = getFieldValues(\n FormKeyHelper.getTokenKey(oppositeFormType),\n FormKeyHelper.getChainKey(oppositeFormType),\n 'toAddress'\n )\n\n // TODO: remove when we enable same chain/token transfers\n const isSameTokenTransfer =\n selectedOppositeTokenAddress === tokenAddress &&\n selectedOppositeChainId === selectedChainId\n\n const isBridgeToSameChain =\n mode === 'split' &&\n splitMode === 'bridge' &&\n selectedOppositeChainId === selectedChainId\n\n if ((isSameTokenTransfer || isBridgeToSameChain) && mode !== 'custom') {\n setFieldValue(FormKeyHelper.getTokenKey(oppositeFormType), '', {\n isDirty: true,\n isTouched: true,\n })\n }\n\n // If no opposite token is selected, synchronize the opposite chain\n // to match the currently selected chain (if allowed).\n // In default exchange mode, also collapse \"All Networks\" on the opposite\n // side - same-chain swap is the most common action.\n if (\n !selectedOppositeTokenAddress &&\n selectedChainId &&\n isItemAllowed(selectedChainId, chainsConfig?.[oppositeFormType])\n ) {\n const isDefaultExchange = !mode || mode === 'default'\n if (isDefaultExchange) {\n setIsAllNetworks(false, oppositeFormType)\n }\n setFieldValue(\n FormKeyHelper.getChainKey(oppositeFormType),\n selectedChainId,\n {\n isDirty: true,\n isTouched: true,\n }\n )\n setChain(selectedChainId, oppositeFormType)\n }\n\n // Automatically populate toAddress field if bridging across ecosystems and compatible wallet is connected\n autoPopulateToAddress({\n formType,\n selectedToAddress,\n selectedChainId,\n selectedOppositeChainId,\n selectedOppositeTokenAddress,\n })\n\n const eventToEmit =\n formType === 'from'\n ? WidgetEvent.SourceChainTokenSelected\n : WidgetEvent.DestinationChainTokenSelected\n\n if (selectedChainId) {\n emitter.emit(eventToEmit, {\n chainId: selectedChainId,\n tokenAddress,\n })\n }\n\n onClick?.()\n },\n [\n autoPopulateToAddress,\n disabledUI,\n emitter,\n formType,\n getFieldValues,\n onClick,\n setChain,\n setIsAllNetworks,\n setFieldValue,\n mode,\n splitMode,\n tokenKey,\n chainsConfig,\n ]\n )\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"useTokenSelect.js","names":[],"sources":["../../../../src/components/TokenList/useTokenSelect.ts"],"sourcesContent":["import { useCallback } from 'react'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useToAddressAutoPopulate } from '../../hooks/useToAddressAutoPopulate.js'\nimport { useToAddressReset } from '../../hooks/useToAddressReset.js'\nimport { useWidgetEvents } from '../../hooks/useWidgetEvents.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useChainOrderStore } from '../../stores/chains/ChainOrderStore.js'\nimport type { FormType } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useSplitMode } from '../../stores/navigationTabs/useNavigationTabsStore.js'\nimport { WidgetEvent } from '../../types/events.js'\nimport type { DisabledUIConfig } from '../../types/widget.js'\nimport { isItemAllowed } from '../../utils/item.js'\n\nexport const useTokenSelect = (\n formType: FormType,\n onClick?: () => void\n): ((tokenAddress: string, chainId?: number) => void) => {\n const { mode, disabledUI, chains: chainsConfig } = useWidgetConfig()\n const splitMode = useSplitMode()\n const emitter = useWidgetEvents()\n const { setFieldValue, getFieldValues } = useFieldActions()\n const autoPopulateToAddress = useToAddressAutoPopulate()\n const { tryResetToAddress } = useToAddressReset()\n const { getChainById } = useAvailableChains()\n const [setChain, setIsAllNetworks] = useChainOrderStore((state) => [\n state.setChain,\n state.setIsAllNetworks,\n ])\n\n const tokenKey = FormKeyHelper.getTokenKey(formType)\n\n return useCallback(\n (tokenAddress: string, chainId?: number) => {\n const [toChainIdBefore] = getFieldValues('toChain')\n setFieldValue(tokenKey, tokenAddress, { isDirty: true, isTouched: true })\n const selectedChainId =\n chainId ?? getFieldValues(FormKeyHelper.getChainKey(formType))[0]\n // Set chain again to trigger URL builder update\n setFieldValue(FormKeyHelper.getChainKey(formType), selectedChainId, {\n isDirty: true,\n isTouched: true,\n })\n const amountKey = FormKeyHelper.getAmountKey(formType)\n if (!disabledUI?.[amountKey as keyof DisabledUIConfig]) {\n setFieldValue(amountKey, '')\n }\n const oppositeFormType = formType === 'from' ? 'to' : 'from'\n const [\n selectedOppositeTokenAddress,\n selectedOppositeChainId,\n selectedToAddress,\n ] = getFieldValues(\n FormKeyHelper.getTokenKey(oppositeFormType),\n FormKeyHelper.getChainKey(oppositeFormType),\n 'toAddress'\n )\n\n // TODO: remove when we enable same chain/token transfers\n const isSameTokenTransfer =\n selectedOppositeTokenAddress === tokenAddress &&\n selectedOppositeChainId === selectedChainId\n\n const isBridgeToSameChain =\n mode === 'split' &&\n splitMode === 'bridge' &&\n selectedOppositeChainId === selectedChainId\n\n if ((isSameTokenTransfer || isBridgeToSameChain) && mode !== 'custom') {\n setFieldValue(FormKeyHelper.getTokenKey(oppositeFormType), '', {\n isDirty: true,\n isTouched: true,\n })\n }\n\n // If no opposite token is selected, synchronize the opposite chain\n // to match the currently selected chain (if allowed).\n // In default exchange mode, also collapse \"All Networks\" on the opposite\n // side - same-chain swap is the most common action.\n if (\n !selectedOppositeTokenAddress &&\n selectedChainId &&\n isItemAllowed(selectedChainId, chainsConfig?.[oppositeFormType])\n ) {\n const isDefaultExchange = !mode || mode === 'default'\n if (isDefaultExchange) {\n setIsAllNetworks(false, oppositeFormType)\n }\n setFieldValue(\n FormKeyHelper.getChainKey(oppositeFormType),\n selectedChainId,\n {\n isDirty: true,\n isTouched: true,\n }\n )\n setChain(selectedChainId, oppositeFormType)\n }\n\n // A token from \"All networks\" moves the destination without the chain select,\n // which resets a receiver the new chain cannot take.\n const [toChainId] = getFieldValues('toChain')\n const toChain = getChainById(toChainId)\n if (toChainId !== toChainIdBefore && toChain) {\n tryResetToAddress(toChain)\n }\n\n // Automatically populate toAddress field if bridging across ecosystems and compatible wallet is connected\n autoPopulateToAddress({\n formType,\n selectedToAddress,\n selectedChainId,\n selectedOppositeChainId,\n selectedOppositeTokenAddress,\n })\n\n const eventToEmit =\n formType === 'from'\n ? WidgetEvent.SourceChainTokenSelected\n : WidgetEvent.DestinationChainTokenSelected\n\n if (selectedChainId) {\n emitter.emit(eventToEmit, {\n chainId: selectedChainId,\n tokenAddress,\n })\n }\n\n onClick?.()\n },\n [\n autoPopulateToAddress,\n tryResetToAddress,\n getChainById,\n disabledUI,\n emitter,\n formType,\n getFieldValues,\n onClick,\n setChain,\n setIsAllNetworks,\n setFieldValue,\n mode,\n splitMode,\n tokenKey,\n chainsConfig,\n ]\n )\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,MAAa,kBACX,UACA,YACuD;CACvD,MAAM,EAAE,MAAM,YAAY,QAAQ,iBAAiB,gBAAgB;CACnE,MAAM,YAAY,aAAa;CAC/B,MAAM,UAAU,gBAAgB;CAChC,MAAM,EAAE,eAAe,mBAAmB,gBAAgB;CAC1D,MAAM,wBAAwB,yBAAyB;CACvD,MAAM,EAAE,sBAAsB,kBAAkB;CAChD,MAAM,EAAE,iBAAiB,mBAAmB;CAC5C,MAAM,CAAC,UAAU,oBAAoB,oBAAoB,UAAU,CACjE,MAAM,UACN,MAAM,gBACR,CAAC;CAED,MAAM,WAAW,cAAc,YAAY,QAAQ;CAEnD,OAAO,aACJ,cAAsB,YAAqB;EAC1C,MAAM,CAAC,mBAAmB,eAAe,SAAS;EAClD,cAAc,UAAU,cAAc;GAAE,SAAS;GAAM,WAAW;EAAK,CAAC;EACxE,MAAM,kBACJ,WAAW,eAAe,cAAc,YAAY,QAAQ,CAAC,CAAC,CAAC;EAEjE,cAAc,cAAc,YAAY,QAAQ,GAAG,iBAAiB;GAClE,SAAS;GACT,WAAW;EACb,CAAC;EACD,MAAM,YAAY,cAAc,aAAa,QAAQ;EACrD,IAAI,CAAC,aAAa,YAChB,cAAc,WAAW,EAAE;EAE7B,MAAM,mBAAmB,aAAa,SAAS,OAAO;EACtD,MAAM,CACJ,8BACA,yBACA,qBACE,eACF,cAAc,YAAY,gBAAgB,GAC1C,cAAc,YAAY,gBAAgB,GAC1C,WACF;EAYA,KARE,iCAAiC,gBACjC,4BAA4B,mBAG5B,SAAS,WACT,cAAc,YACd,4BAA4B,oBAEsB,SAAS,UAC3D,cAAc,cAAc,YAAY,gBAAgB,GAAG,IAAI;GAC7D,SAAS;GACT,WAAW;EACb,CAAC;EAOH,IACE,CAAC,gCACD,mBACA,cAAc,iBAAiB,eAAe,iBAAiB,GAC/D;GAEA,IAD0B,CAAC,QAAQ,SAAS,WAE1C,iBAAiB,OAAO,gBAAgB;GAE1C,cACE,cAAc,YAAY,gBAAgB,GAC1C,iBACA;IACE,SAAS;IACT,WAAW;GACb,CACF;GACA,SAAS,iBAAiB,gBAAgB;EAC5C;EAIA,MAAM,CAAC,aAAa,eAAe,SAAS;EAC5C,MAAM,UAAU,aAAa,SAAS;EACtC,IAAI,cAAc,mBAAmB,SACnC,kBAAkB,OAAO;EAI3B,sBAAsB;GACpB;GACA;GACA;GACA;GACA;EACF,CAAC;EAED,MAAM,cACJ,aAAa,SAAA,6BAAA;EAIf,IAAI,iBACF,QAAQ,KAAK,aAAa;GACxB,SAAS;GACT;EACF,CAAC;EAGH,UAAU;CACZ,GACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":[],"sources":["../../../src/config/constants.ts"],"sourcesContent":["export const defaultMaxHeight = 686\n\nexport const internalExplorerUrl = 'https://scan.li.fi'\n"],"mappings":";AAAA,MAAa,mBAAmB;AAEhC,MAAa,sBAAsB"}
|
|
1
|
+
{"version":3,"file":"constants.js","names":[],"sources":["../../../src/config/constants.ts"],"sourcesContent":["export const defaultMaxHeight = 686\n\nexport const internalExplorerUrl = 'https://scan.li.fi'\n\n// Fits the longest Zcash unified address in the official test vectors (509 characters).\nexport const addressInputMaxLength = 512\n"],"mappings":";AAAA,MAAa,mBAAmB;AAEhC,MAAa,sBAAsB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","names":[],"sources":["../../../src/config/version.ts"],"sourcesContent":["export const name = '@lifi/widget'\nexport const version = '4.
|
|
1
|
+
{"version":3,"file":"version.js","names":[],"sources":["../../../src/config/version.ts"],"sourcesContent":["export const name = '@lifi/widget'\nexport const version = '4.9.0'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useChains } from "./useChains.js";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
|
+
import { useAddressForChain } from "@lifi/widget-provider";
|
|
3
4
|
import { useAccount } from "@lifi/wallet-management";
|
|
4
5
|
//#region src/hooks/useAccountsBalancesData.ts
|
|
5
6
|
const useAccountsBalancesData = (selectedChainId, formType, isAllNetworks, allTokens) => {
|
|
@@ -19,6 +20,7 @@ const useAccountsBalancesData = (selectedChainId, formType, isAllNetworks, allTo
|
|
|
19
20
|
currentChain
|
|
20
21
|
]);
|
|
21
22
|
const { accounts: allAccounts, account: currentAccount } = useAccount(isAllNetworks ? void 0 : { chainType: currentChain?.chainType });
|
|
23
|
+
const { isAddressForChain } = useAddressForChain();
|
|
22
24
|
const accounts = useMemo(() => {
|
|
23
25
|
return isAllNetworks ? allAccounts : currentAccount ? [currentAccount] : void 0;
|
|
24
26
|
}, [
|
|
@@ -31,7 +33,7 @@ const useAccountsBalancesData = (selectedChainId, formType, isAllNetworks, allTo
|
|
|
31
33
|
if (!chains || !allTokens || !accounts?.length) return;
|
|
32
34
|
return accounts?.filter((account) => account.address).reduce((acc, account) => {
|
|
33
35
|
if (account.address) {
|
|
34
|
-
const accountChains = chains?.filter((chain) => account.chainType === chain?.chainType);
|
|
36
|
+
const accountChains = chains?.filter((chain) => account.chainType === chain?.chainType && isAddressForChain(account.address, chain));
|
|
35
37
|
if (accountChains) {
|
|
36
38
|
const chainIdSet = new Set(accountChains.map((chain) => chain.id));
|
|
37
39
|
acc[account.address] = Object.entries(allTokens).reduce((tokenAcc, [chainIdStr, tokens]) => {
|
|
@@ -46,7 +48,8 @@ const useAccountsBalancesData = (selectedChainId, formType, isAllNetworks, allTo
|
|
|
46
48
|
}, [
|
|
47
49
|
accounts,
|
|
48
50
|
chains,
|
|
49
|
-
allTokens
|
|
51
|
+
allTokens,
|
|
52
|
+
isAddressForChain
|
|
50
53
|
]),
|
|
51
54
|
isLoading: isChainsLoading
|
|
52
55
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAccountsBalancesData.js","names":[],"sources":["../../../src/hooks/useAccountsBalancesData.ts"],"sourcesContent":["import type { TokenExtended } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useMemo } from 'react'\nimport type { FormType } from '../stores/form/types.js'\nimport { useChains } from './useChains.js'\n\nexport const useAccountsBalancesData = (\n selectedChainId?: number,\n formType?: FormType,\n isAllNetworks?: boolean,\n allTokens?: Record<number, TokenExtended[]>\n): {\n data: Record<string, Record<number, TokenExtended[]>> | undefined\n isLoading: boolean\n} => {\n const {\n chains: allChains,\n isLoading: isChainsLoading,\n getChainById,\n } = useChains(formType)\n const currentChain = useMemo(() => {\n return selectedChainId\n ? getChainById(selectedChainId, allChains)\n : undefined\n }, [selectedChainId, allChains, getChainById])\n const chains = useMemo(() => {\n return isAllNetworks ? allChains : currentChain ? [currentChain] : undefined\n }, [allChains, isAllNetworks, currentChain])\n\n const { accounts: allAccounts, account: currentAccount } = useAccount(\n isAllNetworks ? undefined : { chainType: currentChain?.chainType }\n )\n const accounts = useMemo(() => {\n return isAllNetworks\n ? allAccounts\n : currentAccount\n ? [currentAccount]\n : undefined\n }, [allAccounts, currentAccount, isAllNetworks])\n\n const accountsWithTokens = useMemo(() => {\n if (!chains || !allTokens || !accounts?.length) {\n return undefined\n }\n return accounts\n ?.filter((account) => account.address)\n .reduce(\n (acc, account) => {\n if (account.address) {\n const accountChains = chains?.filter(\n (chain)
|
|
1
|
+
{"version":3,"file":"useAccountsBalancesData.js","names":[],"sources":["../../../src/hooks/useAccountsBalancesData.ts"],"sourcesContent":["import type { TokenExtended } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useAddressForChain } from '@lifi/widget-provider'\nimport { useMemo } from 'react'\nimport type { FormType } from '../stores/form/types.js'\nimport { useChains } from './useChains.js'\n\nexport const useAccountsBalancesData = (\n selectedChainId?: number,\n formType?: FormType,\n isAllNetworks?: boolean,\n allTokens?: Record<number, TokenExtended[]>\n): {\n data: Record<string, Record<number, TokenExtended[]>> | undefined\n isLoading: boolean\n} => {\n const {\n chains: allChains,\n isLoading: isChainsLoading,\n getChainById,\n } = useChains(formType)\n const currentChain = useMemo(() => {\n return selectedChainId\n ? getChainById(selectedChainId, allChains)\n : undefined\n }, [selectedChainId, allChains, getChainById])\n const chains = useMemo(() => {\n return isAllNetworks ? allChains : currentChain ? [currentChain] : undefined\n }, [allChains, isAllNetworks, currentChain])\n\n const { accounts: allAccounts, account: currentAccount } = useAccount(\n isAllNetworks ? undefined : { chainType: currentChain?.chainType }\n )\n const { isAddressForChain } = useAddressForChain()\n const accounts = useMemo(() => {\n return isAllNetworks\n ? allAccounts\n : currentAccount\n ? [currentAccount]\n : undefined\n }, [allAccounts, currentAccount, isAllNetworks])\n\n const accountsWithTokens = useMemo(() => {\n if (!chains || !allTokens || !accounts?.length) {\n return undefined\n }\n return accounts\n ?.filter((account) => account.address)\n .reduce(\n (acc, account) => {\n if (account.address) {\n const accountChains = chains?.filter(\n (chain) =>\n account.chainType === chain?.chainType &&\n isAddressForChain(account.address as string, chain)\n )\n if (accountChains) {\n const chainIdSet = new Set(accountChains.map((chain) => chain.id))\n acc[account.address] = Object.entries(allTokens).reduce(\n (tokenAcc, [chainIdStr, tokens]) => {\n const chainId = Number(chainIdStr)\n if (chainIdSet.has(chainId)) {\n tokenAcc[chainId] = tokens\n }\n return tokenAcc\n },\n {} as Record<number, TokenExtended[]>\n )\n }\n }\n return acc\n },\n {} as Record<string, Record<number, TokenExtended[]>>\n )\n }, [accounts, chains, allTokens, isAddressForChain])\n\n return {\n data: accountsWithTokens,\n isLoading: isChainsLoading,\n }\n}\n"],"mappings":";;;;;AAOA,MAAa,2BACX,iBACA,UACA,eACA,cAIG;CACH,MAAM,EACJ,QAAQ,WACR,WAAW,iBACX,iBACE,UAAU,QAAQ;CACtB,MAAM,eAAe,cAAc;EACjC,OAAO,kBACH,aAAa,iBAAiB,SAAS,IACvC,KAAA;CACN,GAAG;EAAC;EAAiB;EAAW;CAAY,CAAC;CAC7C,MAAM,SAAS,cAAc;EAC3B,OAAO,gBAAgB,YAAY,eAAe,CAAC,YAAY,IAAI,KAAA;CACrE,GAAG;EAAC;EAAW;EAAe;CAAY,CAAC;CAE3C,MAAM,EAAE,UAAU,aAAa,SAAS,mBAAmB,WACzD,gBAAgB,KAAA,IAAY,EAAE,WAAW,cAAc,UAAU,CACnE;CACA,MAAM,EAAE,sBAAsB,mBAAmB;CACjD,MAAM,WAAW,cAAc;EAC7B,OAAO,gBACH,cACA,iBACE,CAAC,cAAc,IACf,KAAA;CACR,GAAG;EAAC;EAAa;EAAgB;CAAa,CAAC;CAoC/C,OAAO;EACL,MAnCyB,cAAc;GACvC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,UAAU,QACtC;GAEF,OAAO,UACH,QAAQ,YAAY,QAAQ,OAAO,CAAC,CACrC,QACE,KAAK,YAAY;IAChB,IAAI,QAAQ,SAAS;KACnB,MAAM,gBAAgB,QAAQ,QAC3B,UACC,QAAQ,cAAc,OAAO,aAC7B,kBAAkB,QAAQ,SAAmB,KAAK,CACtD;KACA,IAAI,eAAe;MACjB,MAAM,aAAa,IAAI,IAAI,cAAc,KAAK,UAAU,MAAM,EAAE,CAAC;MACjE,IAAI,QAAQ,WAAW,OAAO,QAAQ,SAAS,CAAC,CAAC,QAC9C,UAAU,CAAC,YAAY,YAAY;OAClC,MAAM,UAAU,OAAO,UAAU;OACjC,IAAI,WAAW,IAAI,OAAO,GACxB,SAAS,WAAW;OAEtB,OAAO;MACT,GACA,CAAC,CACH;KACF;IACF;IACA,OAAO;GACT,GACA,CAAC,CACH;EACJ,GAAG;GAAC;GAAU;GAAQ;GAAW;EAAiB,CAGzB;EACvB,WAAW;CACb;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Chain, ChainType } from "@lifi/sdk";
|
|
1
|
+
import { Chain, ChainId, ChainType } from "@lifi/sdk";
|
|
2
2
|
//#region src/hooks/useAddressValidation.d.ts
|
|
3
3
|
export declare enum AddressType {
|
|
4
4
|
Address = 0,
|
|
@@ -6,13 +6,14 @@ export declare enum AddressType {
|
|
|
6
6
|
}
|
|
7
7
|
type ValidationArgs = {
|
|
8
8
|
value: string;
|
|
9
|
-
|
|
9
|
+
/** Strict: the receiver must be valid on this chain. */
|
|
10
10
|
chain?: Chain;
|
|
11
11
|
};
|
|
12
12
|
type ValidResponse = {
|
|
13
13
|
address: string;
|
|
14
14
|
addressType: AddressType;
|
|
15
15
|
chainType: ChainType;
|
|
16
|
+
chainId?: ChainId;
|
|
16
17
|
isValid: true;
|
|
17
18
|
};
|
|
18
19
|
type InvalidResponse = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAddressValidation.d.ts","names":[],"sources":["../../../src/hooks/useAddressValidation.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"useAddressValidation.d.ts","names":[],"sources":["../../../src/hooks/useAddressValidation.ts"],"mappings":";;oBAUY;EACV;EACA;;KAGG;EACH;;EAEA,QAAQ;;KAGL;EACH;EACA,aAAa;EACb,WAAW;EACX,UAAU;EACV;;KAGG;EACH;EACA;;qBAGW;EACX,kBACE,MAAM,mBACH,QAAQ,gBAAgB;EAC7B"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useSDKClient } from "../providers/SDKClientProvider.js";
|
|
2
|
-
import { getNameServiceAddress } from "@lifi/sdk";
|
|
2
|
+
import { ChainId, getNameServiceAddress } from "@lifi/sdk";
|
|
3
3
|
import { useTranslation } from "react-i18next";
|
|
4
4
|
import { useMutation } from "@tanstack/react-query";
|
|
5
|
-
import { useChainTypeFromAddress } from "@lifi/widget-provider";
|
|
5
|
+
import { useAddressForChain, useChainTypeFromAddress } from "@lifi/widget-provider";
|
|
6
6
|
//#region src/hooks/useAddressValidation.ts
|
|
7
7
|
let AddressType = /* @__PURE__ */ function(AddressType) {
|
|
8
8
|
AddressType[AddressType["Address"] = 0] = "Address";
|
|
@@ -11,28 +11,55 @@ let AddressType = /* @__PURE__ */ function(AddressType) {
|
|
|
11
11
|
}({});
|
|
12
12
|
const useAddressValidation = () => {
|
|
13
13
|
const { t } = useTranslation();
|
|
14
|
-
const {
|
|
14
|
+
const { getChainFromAddress } = useChainTypeFromAddress();
|
|
15
|
+
const { isAddressForChain } = useAddressForChain();
|
|
15
16
|
const sdkClient = useSDKClient();
|
|
16
|
-
const
|
|
17
|
+
const validFor = (address, addressType, chain) => ({
|
|
18
|
+
address,
|
|
19
|
+
addressType,
|
|
20
|
+
chainType: chain.chainType,
|
|
21
|
+
chainId: getChainFromAddress(address)?.chainId,
|
|
22
|
+
isValid: true
|
|
23
|
+
});
|
|
24
|
+
const validateForChain = async (value, chain) => {
|
|
25
|
+
if (isAddressForChain(value, chain)) return validFor(value, 0, chain);
|
|
26
|
+
if (getChainFromAddress(value)) return {
|
|
27
|
+
isValid: false,
|
|
28
|
+
error: t("error.title.walletChainTypeInvalid", { chainName: chain.name })
|
|
29
|
+
};
|
|
30
|
+
const resolved = await getNameServiceAddress(sdkClient, value, chain.chainType);
|
|
31
|
+
if (resolved && isAddressForChain(resolved, chain)) return validFor(resolved, 1, chain);
|
|
32
|
+
return {
|
|
33
|
+
isValid: false,
|
|
34
|
+
error: chain.id === ChainId.ZEC ? t("error.title.zcashAddressInvalid") : t("error.title.walletAddressInvalid", {
|
|
35
|
+
context: "chain",
|
|
36
|
+
chainName: chain.name
|
|
37
|
+
})
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
const validateWithoutChain = async (value) => {
|
|
41
|
+
const detected = getChainFromAddress(value);
|
|
42
|
+
if (detected) return {
|
|
43
|
+
address: value,
|
|
44
|
+
addressType: 0,
|
|
45
|
+
...detected,
|
|
46
|
+
isValid: true
|
|
47
|
+
};
|
|
48
|
+
const address = await getNameServiceAddress(sdkClient, value);
|
|
49
|
+
const resolved = address ? getChainFromAddress(address) : void 0;
|
|
50
|
+
if (address && resolved) return {
|
|
51
|
+
address,
|
|
52
|
+
addressType: 1,
|
|
53
|
+
...resolved,
|
|
54
|
+
isValid: true
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
const { mutateAsync: validateAddress, isPending: isValidating } = useMutation({ mutationFn: async ({ value, chain }) => {
|
|
17
58
|
try {
|
|
18
59
|
if (!value) throw new Error();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
addressType: 0,
|
|
23
|
-
chainType: _chainType,
|
|
24
|
-
isValid: true
|
|
25
|
-
};
|
|
26
|
-
const address = await getNameServiceAddress(sdkClient, value, chainType);
|
|
27
|
-
if (address) {
|
|
28
|
-
const _chainType = getChainTypeFromAddress(address);
|
|
29
|
-
if (_chainType) return {
|
|
30
|
-
address,
|
|
31
|
-
addressType: 1,
|
|
32
|
-
chainType: _chainType,
|
|
33
|
-
isValid: true
|
|
34
|
-
};
|
|
35
|
-
}
|
|
60
|
+
if (chain) return await validateForChain(value, chain);
|
|
61
|
+
const result = await validateWithoutChain(value);
|
|
62
|
+
if (result) return result;
|
|
36
63
|
throw new Error();
|
|
37
64
|
} catch (_) {
|
|
38
65
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAddressValidation.js","names":[],"sources":["../../../src/hooks/useAddressValidation.ts"],"sourcesContent":["import type { Chain, ChainType } from '@lifi/sdk'\nimport { getNameServiceAddress } from '@lifi/sdk'\nimport {
|
|
1
|
+
{"version":3,"file":"useAddressValidation.js","names":[],"sources":["../../../src/hooks/useAddressValidation.ts"],"sourcesContent":["import type { Chain, ChainType } from '@lifi/sdk'\nimport { ChainId, getNameServiceAddress } from '@lifi/sdk'\nimport {\n useAddressForChain,\n useChainTypeFromAddress,\n} from '@lifi/widget-provider'\nimport { useMutation } from '@tanstack/react-query'\nimport { useTranslation } from 'react-i18next'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\n\nexport enum AddressType {\n Address = 0,\n NameService = 1,\n}\n\ntype ValidationArgs = {\n value: string\n /** Strict: the receiver must be valid on this chain. */\n chain?: Chain\n}\n\ntype ValidResponse = {\n address: string\n addressType: AddressType\n chainType: ChainType\n chainId?: ChainId\n isValid: true\n}\n\ntype InvalidResponse = {\n error: string\n isValid: false\n}\n\nexport const useAddressValidation = (): {\n validateAddress: (\n args: ValidationArgs\n ) => Promise<ValidResponse | InvalidResponse>\n isValidating: boolean\n} => {\n const { t } = useTranslation()\n const { getChainFromAddress } = useChainTypeFromAddress()\n const { isAddressForChain } = useAddressForChain()\n const sdkClient = useSDKClient()\n\n const validFor = (\n address: string,\n addressType: AddressType,\n chain: Chain\n ): ValidResponse => ({\n address,\n addressType,\n chainType: chain.chainType,\n chainId: getChainFromAddress(address)?.chainId,\n isValid: true,\n })\n\n const validateForChain = async (\n value: string,\n chain: Chain\n ): Promise<ValidResponse | InvalidResponse> => {\n if (isAddressForChain(value, chain)) {\n return validFor(value, AddressType.Address, chain)\n }\n // A recognised address is no name to resolve.\n if (getChainFromAddress(value)) {\n return {\n isValid: false,\n error: t('error.title.walletChainTypeInvalid', {\n chainName: chain.name,\n }),\n }\n }\n const resolved = await getNameServiceAddress(\n sdkClient,\n value,\n chain.chainType\n )\n if (resolved && isAddressForChain(resolved, chain)) {\n return validFor(resolved, AddressType.NameService, chain)\n }\n return {\n isValid: false,\n error:\n chain.id === ChainId.ZEC\n ? t('error.title.zcashAddressInvalid')\n : t('error.title.walletAddressInvalid', {\n context: 'chain',\n chainName: chain.name,\n }),\n }\n }\n\n const validateWithoutChain = async (\n value: string\n ): Promise<ValidResponse | undefined> => {\n const detected = getChainFromAddress(value)\n if (detected) {\n return {\n address: value,\n addressType: AddressType.Address,\n ...detected,\n isValid: true,\n }\n }\n const address = await getNameServiceAddress(sdkClient, value)\n const resolved = address ? getChainFromAddress(address) : undefined\n if (address && resolved) {\n return {\n address,\n addressType: AddressType.NameService,\n ...resolved,\n isValid: true,\n }\n }\n return undefined\n }\n\n const { mutateAsync: validateAddress, isPending: isValidating } = useMutation(\n {\n mutationFn: async ({\n value,\n chain,\n }: ValidationArgs): Promise<ValidResponse | InvalidResponse> => {\n try {\n if (!value) {\n throw new Error()\n }\n if (chain) {\n return await validateForChain(value, chain)\n }\n const result = await validateWithoutChain(value)\n if (result) {\n return result\n }\n throw new Error()\n } catch (_) {\n return {\n isValid: false,\n error: t(\n 'error.title.walletAddressInvalid',\n chain?.name\n ? { context: 'chain', chainName: chain.name }\n : undefined\n ),\n }\n }\n },\n }\n )\n\n return {\n validateAddress,\n isValidating,\n }\n}\n"],"mappings":";;;;;;AAUA,IAAY,cAAL,yBAAA,aAAA;CACL,YAAA,YAAA,aAAA,KAAA;CACA,YAAA,YAAA,iBAAA,KAAA;;AACF,EAAA,CAAA,CAAA;AAqBA,MAAa,6BAKR;CACH,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,wBAAwB,wBAAwB;CACxD,MAAM,EAAE,sBAAsB,mBAAmB;CACjD,MAAM,YAAY,aAAa;CAE/B,MAAM,YACJ,SACA,aACA,WACmB;EACnB;EACA;EACA,WAAW,MAAM;EACjB,SAAS,oBAAoB,OAAO,CAAC,EAAE;EACvC,SAAS;CACX;CAEA,MAAM,mBAAmB,OACvB,OACA,UAC6C;EAC7C,IAAI,kBAAkB,OAAO,KAAK,GAChC,OAAO,SAAS,OAAA,GAA4B,KAAK;EAGnD,IAAI,oBAAoB,KAAK,GAC3B,OAAO;GACL,SAAS;GACT,OAAO,EAAE,sCAAsC,EAC7C,WAAW,MAAM,KACnB,CAAC;EACH;EAEF,MAAM,WAAW,MAAM,sBACrB,WACA,OACA,MAAM,SACR;EACA,IAAI,YAAY,kBAAkB,UAAU,KAAK,GAC/C,OAAO,SAAS,UAAA,GAAmC,KAAK;EAE1D,OAAO;GACL,SAAS;GACT,OACE,MAAM,OAAO,QAAQ,MACjB,EAAE,iCAAiC,IACnC,EAAE,oCAAoC;IACpC,SAAS;IACT,WAAW,MAAM;GACnB,CAAC;EACT;CACF;CAEA,MAAM,uBAAuB,OAC3B,UACuC;EACvC,MAAM,WAAW,oBAAoB,KAAK;EAC1C,IAAI,UACF,OAAO;GACL,SAAS;GACT,aAAA;GACA,GAAG;GACH,SAAS;EACX;EAEF,MAAM,UAAU,MAAM,sBAAsB,WAAW,KAAK;EAC5D,MAAM,WAAW,UAAU,oBAAoB,OAAO,IAAI,KAAA;EAC1D,IAAI,WAAW,UACb,OAAO;GACL;GACA,aAAA;GACA,GAAG;GACH,SAAS;EACX;CAGJ;CAEA,MAAM,EAAE,aAAa,iBAAiB,WAAW,iBAAiB,YAChE,EACE,YAAY,OAAO,EACjB,OACA,YAC8D;EAC9D,IAAI;GACF,IAAI,CAAC,OACH,MAAM,IAAI,MAAM;GAElB,IAAI,OACF,OAAO,MAAM,iBAAiB,OAAO,KAAK;GAE5C,MAAM,SAAS,MAAM,qBAAqB,KAAK;GAC/C,IAAI,QACF,OAAO;GAET,MAAM,IAAI,MAAM;EAClB,SAAS,GAAG;GACV,OAAO;IACL,SAAS;IACT,OAAO,EACL,oCACA,OAAO,OACH;KAAE,SAAS;KAAS,WAAW,MAAM;IAAK,IAC1C,KAAA,CACN;GACF;EACF;CACF,EACF,CACF;CAEA,OAAO;EACL;EACA;CACF;AACF"}
|
|
@@ -5,6 +5,7 @@ import { useGasRecommendation } from "./useGasRecommendation.js";
|
|
|
5
5
|
import { useIsContractAddress } from "./useIsContractAddress.js";
|
|
6
6
|
import { useTokenBalance } from "./useTokenBalance.js";
|
|
7
7
|
import { useMemo } from "react";
|
|
8
|
+
import { useAddressForChain } from "@lifi/widget-provider";
|
|
8
9
|
import { useAccount } from "@lifi/wallet-management";
|
|
9
10
|
//#region src/hooks/useGasRefuel.ts
|
|
10
11
|
const useGasRefuel = () => {
|
|
@@ -14,7 +15,9 @@ const useGasRefuel = () => {
|
|
|
14
15
|
const toChain = getChainById(toChainId);
|
|
15
16
|
const fromChain = getChainById(fromChainId);
|
|
16
17
|
const { account: toAccount } = useAccount({ chainType: toChain?.chainType });
|
|
17
|
-
const
|
|
18
|
+
const { isAddressForChain } = useAddressForChain();
|
|
19
|
+
const toAccountAddress = toAccount?.address && toChain && isAddressForChain(toAccount.address, toChain) ? toAccount.address : void 0;
|
|
20
|
+
const effectiveToAddress = toAddress || toAccountAddress;
|
|
18
21
|
const { isContractAddress: isToContractAddress } = useIsContractAddress(effectiveToAddress, toChainId, toChain?.chainType);
|
|
19
22
|
const { token: destinationNativeToken } = useTokenBalance(effectiveToAddress, toChainId ? toChain?.nativeToken : void 0);
|
|
20
23
|
const { data: gasRecommendation, isLoading } = useGasRecommendation(toChainId, fromChainId, fromTokenAddress);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGasRefuel.js","names":[],"sources":["../../../src/hooks/useGasRefuel.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useMemo } from 'react'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { useAvailableChains } from './useAvailableChains.js'\nimport { useGasRecommendation } from './useGasRecommendation.js'\nimport { useIsContractAddress } from './useIsContractAddress.js'\nimport { useTokenBalance } from './useTokenBalance.js'\n\nexport const useGasRefuel = (): {\n enabled: boolean\n availble: boolean | undefined\n isLoading: boolean\n chain: ExtendedChain | undefined\n fromAmount: string | undefined\n} => {\n const { getChainById } = useAvailableChains()\n const { hiddenUI } = useWidgetConfig()\n const [fromChainId, fromTokenAddress, toChainId, toAddress] = useFieldValues(\n 'fromChain',\n 'fromToken',\n 'toChain',\n 'toAddress'\n )\n\n const toChain = getChainById(toChainId)\n const fromChain = getChainById(fromChainId)\n\n const { account: toAccount } = useAccount({ chainType: toChain?.chainType })\n\n const effectiveToAddress = toAddress ||
|
|
1
|
+
{"version":3,"file":"useGasRefuel.js","names":[],"sources":["../../../src/hooks/useGasRefuel.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { useAddressForChain } from '@lifi/widget-provider'\nimport { useMemo } from 'react'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { useAvailableChains } from './useAvailableChains.js'\nimport { useGasRecommendation } from './useGasRecommendation.js'\nimport { useIsContractAddress } from './useIsContractAddress.js'\nimport { useTokenBalance } from './useTokenBalance.js'\n\nexport const useGasRefuel = (): {\n enabled: boolean\n availble: boolean | undefined\n isLoading: boolean\n chain: ExtendedChain | undefined\n fromAmount: string | undefined\n} => {\n const { getChainById } = useAvailableChains()\n const { hiddenUI } = useWidgetConfig()\n const [fromChainId, fromTokenAddress, toChainId, toAddress] = useFieldValues(\n 'fromChain',\n 'fromToken',\n 'toChain',\n 'toAddress'\n )\n\n const toChain = getChainById(toChainId)\n const fromChain = getChainById(fromChainId)\n\n const { account: toAccount } = useAccount({ chainType: toChain?.chainType })\n const { isAddressForChain } = useAddressForChain()\n\n // A shared chain type is not a shared format: a Bitcoin account cannot receive on ZEC.\n const toAccountAddress =\n toAccount?.address &&\n toChain &&\n isAddressForChain(toAccount.address, toChain)\n ? toAccount.address\n : undefined\n\n const effectiveToAddress = toAddress || toAccountAddress\n\n const { isContractAddress: isToContractAddress } = useIsContractAddress(\n effectiveToAddress,\n toChainId,\n toChain?.chainType\n )\n\n const { token: destinationNativeToken } = useTokenBalance(\n effectiveToAddress,\n toChainId ? toChain?.nativeToken : undefined\n )\n\n const { data: gasRecommendation, isLoading } = useGasRecommendation(\n toChainId,\n fromChainId,\n fromTokenAddress\n )\n\n // When we bridge between ecosystems we need to be sure toAddress is set\n const isChainTypeSatisfied =\n fromChain?.chainType !== toChain?.chainType ? Boolean(toAddress) : true\n\n // We should not refuel to the contract address\n const isToAddressSatisfied = effectiveToAddress && !isToContractAddress\n\n const enabled = useMemo(() => {\n if (\n // Same chain refuel is not allowed since users need gas on source chain to initiate transaction\n // We allow refuel when bridging to native token since bridging routes may require gas for destination swaps\n fromChainId === toChainId ||\n !gasRecommendation?.available ||\n !gasRecommendation?.recommended ||\n !destinationNativeToken ||\n !isChainTypeSatisfied ||\n !isToAddressSatisfied ||\n hiddenUI?.gasRefuelMessage\n ) {\n return false\n }\n const tokenBalance = destinationNativeToken.amount ?? 0n\n\n // Check if the user balance < 50% of the recommended amount\n const recommendedAmount = BigInt(gasRecommendation.recommended.amount) / 2n\n\n const insufficientGas = tokenBalance < recommendedAmount\n return insufficientGas\n }, [\n fromChainId,\n gasRecommendation,\n isChainTypeSatisfied,\n isToAddressSatisfied,\n destinationNativeToken,\n toChainId,\n hiddenUI,\n ])\n\n return {\n enabled: enabled,\n availble: gasRecommendation?.available,\n isLoading: isLoading,\n chain: toChain,\n fromAmount: gasRecommendation?.available\n ? gasRecommendation.fromAmount\n : undefined,\n }\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAa,qBAMR;CACH,MAAM,EAAE,iBAAiB,mBAAmB;CAC5C,MAAM,EAAE,aAAa,gBAAgB;CACrC,MAAM,CAAC,aAAa,kBAAkB,WAAW,aAAa,eAC5D,aACA,aACA,WACA,WACF;CAEA,MAAM,UAAU,aAAa,SAAS;CACtC,MAAM,YAAY,aAAa,WAAW;CAE1C,MAAM,EAAE,SAAS,cAAc,WAAW,EAAE,WAAW,SAAS,UAAU,CAAC;CAC3E,MAAM,EAAE,sBAAsB,mBAAmB;CAGjD,MAAM,mBACJ,WAAW,WACX,WACA,kBAAkB,UAAU,SAAS,OAAO,IACxC,UAAU,UACV,KAAA;CAEN,MAAM,qBAAqB,aAAa;CAExC,MAAM,EAAE,mBAAmB,wBAAwB,qBACjD,oBACA,WACA,SAAS,SACX;CAEA,MAAM,EAAE,OAAO,2BAA2B,gBACxC,oBACA,YAAY,SAAS,cAAc,KAAA,CACrC;CAEA,MAAM,EAAE,MAAM,mBAAmB,cAAc,qBAC7C,WACA,aACA,gBACF;CAGA,MAAM,uBACJ,WAAW,cAAc,SAAS,YAAY,QAAQ,SAAS,IAAI;CAGrE,MAAM,uBAAuB,sBAAsB,CAAC;CAiCpD,OAAO;EACL,SAhCc,cAAc;GAC5B,IAGE,gBAAgB,aAChB,CAAC,mBAAmB,aACpB,CAAC,mBAAmB,eACpB,CAAC,0BACD,CAAC,wBACD,CAAC,wBACD,UAAU,kBAEV,OAAO;GAQT,QANqB,uBAAuB,UAAU,MAG5B,OAAO,kBAAkB,YAAY,MAAM,IAAI;EAI3E,GAAG;GACD;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAGiB;EACf,UAAU,mBAAmB;EAClB;EACX,OAAO;EACP,YAAY,mBAAmB,YAC3B,kBAAkB,aAClB,KAAA;CACN;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRoutes.d.ts","names":[],"sources":["../../../src/hooks/useRoutes.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"useRoutes.d.ts","names":[],"sources":["../../../src/hooks/useRoutes.ts"],"mappings":";;UA6CU;EACR,kBAAkB;;;;;EAKlB;;;;;EAKA;;qBAGW,cACX,iBACA,kBACA,kBAAkB,4BACjB;EACD,QAAQ;EACR;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;EACX,SAAS;EACT;EACA,qBAAqB,OAAO"}
|
|
@@ -8,7 +8,7 @@ import { useFieldValues } from "../stores/form/useFieldValues.js";
|
|
|
8
8
|
import { useIntermediateRoutesStore } from "../stores/routes/useIntermediateRoutesStore.js";
|
|
9
9
|
import { useSetExecutableRoute } from "../stores/routes/useSetExecutableRoute.js";
|
|
10
10
|
import { useSettings } from "../stores/settings/useSettings.js";
|
|
11
|
-
import { isCustomReceiverBlocked } from "../utils/customReceiver.js";
|
|
11
|
+
import { canQuoteWithToAddress, isCustomReceiverBlocked, isSignerInvalidReceiver } from "../utils/customReceiver.js";
|
|
12
12
|
import { getQueryKey } from "../utils/queries.js";
|
|
13
13
|
import { updateTokenInCache } from "../utils/token.js";
|
|
14
14
|
import { useChain } from "./useChain.js";
|
|
@@ -19,7 +19,7 @@ import { useToken } from "./useToken.js";
|
|
|
19
19
|
import { ChainType, LiFiErrorCode, convertQuoteToRoute, getContractCallsQuote, getRelayerQuote, getRoutes, parseUnits } from "@lifi/sdk";
|
|
20
20
|
import { useCallback, useMemo } from "react";
|
|
21
21
|
import { keepPreviousData, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
22
|
-
import {
|
|
22
|
+
import { useAddressForChain, useEthereumContext } from "@lifi/widget-provider";
|
|
23
23
|
import { useAccount } from "@lifi/wallet-management";
|
|
24
24
|
//#region src/hooks/useRoutes.ts
|
|
25
25
|
const refetchTime = 6e4;
|
|
@@ -49,16 +49,21 @@ const useRoutes = ({ observableRoute, quoteFromAddress, keepPreviousData: keepPr
|
|
|
49
49
|
const { chain: fromChain } = useChain(fromChainId);
|
|
50
50
|
const { chain: toChain } = useChain(toChainId);
|
|
51
51
|
const { enabled: enabledRefuel, fromAmount: gasRecommendationFromAmount } = useGasRefuel();
|
|
52
|
-
const {
|
|
52
|
+
const { isAddressForChain } = useAddressForChain();
|
|
53
53
|
const { isGaslessStep, disableMessageSigning } = useEthereumContext();
|
|
54
54
|
const { account } = useAccount({ chainType: fromChain?.chainType });
|
|
55
55
|
const { isBatchingSupported, isBatchingSupportedLoading } = useIsBatchingSupported(fromChain, account.address);
|
|
56
56
|
const hasAmount = mode === "limit" ? Number(fromTokenAmount) > 0 && Number(toTokenAmount) > 0 : Number(fromTokenAmount) > 0 || Number(toTokenAmount) > 0;
|
|
57
57
|
const customType = mode === "custom" ? modeOptions?.custom?.type : void 0;
|
|
58
58
|
const contractCallQuoteEnabled = mode === "custom" && Boolean(contractCalls?.length) ? Boolean(account.address) : mode !== "custom" || customType === "deposit";
|
|
59
|
-
const effectiveFromAddress =
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
const effectiveFromAddress = isSignerInvalidReceiver({
|
|
60
|
+
signerAddress: account.address,
|
|
61
|
+
toAddress,
|
|
62
|
+
fromChain,
|
|
63
|
+
toChain,
|
|
64
|
+
isAddressForChain
|
|
65
|
+
}) ? quoteFromAddress : account.address ?? quoteFromAddress;
|
|
66
|
+
const isToAddressSatisfied = canQuoteWithToAddress(toAddress, toChain, isAddressForChain);
|
|
62
67
|
const customReceiverBlocked = isCustomReceiverBlocked({
|
|
63
68
|
fromChainType: fromChain?.chainType,
|
|
64
69
|
toChainType: toChain?.chainType,
|