@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.
Files changed (115) hide show
  1. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js +5 -2
  2. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -1
  3. package/dist/esm/components/SelectChainAndToken.js +5 -2
  4. package/dist/esm/components/SelectChainAndToken.js.map +1 -1
  5. package/dist/esm/components/SendToWallet/SendToWalletButton.js +5 -4
  6. package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
  7. package/dist/esm/components/TokenList/useTokenSelect.d.ts.map +1 -1
  8. package/dist/esm/components/TokenList/useTokenSelect.js +10 -0
  9. package/dist/esm/components/TokenList/useTokenSelect.js.map +1 -1
  10. package/dist/esm/config/constants.js.map +1 -1
  11. package/dist/esm/config/version.d.ts +1 -1
  12. package/dist/esm/config/version.js +1 -1
  13. package/dist/esm/config/version.js.map +1 -1
  14. package/dist/esm/hooks/useAccountsBalancesData.js +5 -2
  15. package/dist/esm/hooks/useAccountsBalancesData.js.map +1 -1
  16. package/dist/esm/hooks/useAddressValidation.d.ts +3 -2
  17. package/dist/esm/hooks/useAddressValidation.d.ts.map +1 -1
  18. package/dist/esm/hooks/useAddressValidation.js +48 -21
  19. package/dist/esm/hooks/useAddressValidation.js.map +1 -1
  20. package/dist/esm/hooks/useGasRefuel.js +4 -1
  21. package/dist/esm/hooks/useGasRefuel.js.map +1 -1
  22. package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
  23. package/dist/esm/hooks/useRoutes.js +11 -6
  24. package/dist/esm/hooks/useRoutes.js.map +1 -1
  25. package/dist/esm/hooks/useToAddressAutoPopulate.js +6 -8
  26. package/dist/esm/hooks/useToAddressAutoPopulate.js.map +1 -1
  27. package/dist/esm/hooks/useToAddressRequirements.d.ts +3 -2
  28. package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
  29. package/dist/esm/hooks/useToAddressRequirements.js +8 -7
  30. package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
  31. package/dist/esm/hooks/useToAddressReset.js +6 -3
  32. package/dist/esm/hooks/useToAddressReset.js.map +1 -1
  33. package/dist/esm/hooks/useTokenBalance.js +2 -1
  34. package/dist/esm/hooks/useTokenBalance.js.map +1 -1
  35. package/dist/esm/hooks/useTokens.js +1 -1
  36. package/dist/esm/i18n/bn.json +2 -1
  37. package/dist/esm/i18n/de.json +2 -1
  38. package/dist/esm/i18n/en.json +2 -1
  39. package/dist/esm/i18n/es.json +2 -1
  40. package/dist/esm/i18n/fr.json +2 -1
  41. package/dist/esm/i18n/hi.json +2 -1
  42. package/dist/esm/i18n/id.json +2 -1
  43. package/dist/esm/i18n/it.json +2 -1
  44. package/dist/esm/i18n/ja.json +2 -1
  45. package/dist/esm/i18n/ko.json +2 -1
  46. package/dist/esm/i18n/pl.json +2 -1
  47. package/dist/esm/i18n/pt.json +2 -1
  48. package/dist/esm/i18n/th.json +2 -1
  49. package/dist/esm/i18n/tr.json +2 -1
  50. package/dist/esm/i18n/uk.json +2 -1
  51. package/dist/esm/i18n/vi.json +2 -1
  52. package/dist/esm/i18n/zh.json +2 -1
  53. package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js +7 -4
  54. package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js.map +1 -1
  55. package/dist/esm/pages/SendToWallet/BookmarksPage.js +35 -31
  56. package/dist/esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
  57. package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js +4 -3
  58. package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js.map +1 -1
  59. package/dist/esm/pages/SendToWallet/RecentWalletsPage.js +43 -39
  60. package/dist/esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
  61. package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js +32 -26
  62. package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js.map +1 -1
  63. package/dist/esm/pages/SendToWallet/SendToWalletPage.js +5 -10
  64. package/dist/esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
  65. package/dist/esm/providers/WalletProvider/WalletProvider.d.ts.map +1 -1
  66. package/dist/esm/providers/WalletProvider/WalletProvider.js +14 -2
  67. package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
  68. package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
  69. package/dist/esm/providers/WidgetProvider/WidgetProvider.js +10 -14
  70. package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
  71. package/dist/esm/stores/bookmarks/types.d.ts +3 -0
  72. package/dist/esm/stores/bookmarks/types.d.ts.map +1 -1
  73. package/dist/esm/stores/chains/ChainOrderStore.d.ts.map +1 -1
  74. package/dist/esm/stores/chains/ChainOrderStore.js +4 -1
  75. package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
  76. package/dist/esm/stores/form/FormStore.js +3 -2
  77. package/dist/esm/stores/form/FormStore.js.map +1 -1
  78. package/dist/esm/stores/form/URLSearchParamsBuilder.js +7 -3
  79. package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
  80. package/dist/esm/stores/form/getDefaultValuesFromQueryString.js +4 -1
  81. package/dist/esm/stores/form/getDefaultValuesFromQueryString.js.map +1 -1
  82. package/dist/esm/utils/chainType.js +32 -1
  83. package/dist/esm/utils/chainType.js.map +1 -1
  84. package/dist/esm/utils/customReceiver.js +6 -1
  85. package/dist/esm/utils/customReceiver.js.map +1 -1
  86. package/package.json +7 -7
  87. package/src/components/AmountInputCard/AmountInputCardPair.tsx +6 -2
  88. package/src/components/SelectChainAndToken.tsx +5 -1
  89. package/src/components/SendToWallet/SendToWalletButton.tsx +13 -8
  90. package/src/components/TokenList/useTokenSelect.ts +15 -0
  91. package/src/config/constants.ts +3 -0
  92. package/src/config/version.ts +1 -1
  93. package/src/hooks/useAccountsBalancesData.ts +6 -2
  94. package/src/hooks/useAddressValidation.ts +87 -32
  95. package/src/hooks/useGasRefuel.ts +11 -1
  96. package/src/hooks/useRoutes.ts +23 -18
  97. package/src/hooks/useToAddressAutoPopulate.ts +13 -17
  98. package/src/hooks/useToAddressRequirements.ts +19 -4
  99. package/src/hooks/useToAddressReset.ts +13 -4
  100. package/src/hooks/useTokenBalance.ts +6 -1
  101. package/src/pages/SendToWallet/BookmarkAddressSheet.tsx +5 -1
  102. package/src/pages/SendToWallet/BookmarksPage.tsx +42 -52
  103. package/src/pages/SendToWallet/ConnectedWalletsPage.tsx +4 -14
  104. package/src/pages/SendToWallet/RecentWalletsPage.tsx +59 -66
  105. package/src/pages/SendToWallet/SendToConfiguredWalletPage.tsx +45 -50
  106. package/src/pages/SendToWallet/SendToWalletPage.tsx +4 -16
  107. package/src/providers/WalletProvider/WalletProvider.tsx +28 -3
  108. package/src/providers/WidgetProvider/WidgetProvider.tsx +20 -19
  109. package/src/stores/bookmarks/types.ts +3 -0
  110. package/src/stores/chains/ChainOrderStore.tsx +4 -1
  111. package/src/stores/form/FormStore.tsx +2 -0
  112. package/src/stores/form/URLSearchParamsBuilder.tsx +4 -2
  113. package/src/stores/form/getDefaultValuesFromQueryString.ts +19 -0
  114. package/src/utils/chainType.ts +73 -1
  115. package/src/utils/customReceiver.ts +36 -0
@@ -5,7 +5,6 @@ import { useBookmarks } from "../../stores/bookmarks/useBookmarks.js";
5
5
  import { useFieldActions } from "../../stores/form/useFieldActions.js";
6
6
  import { useFieldValues } from "../../stores/form/useFieldValues.js";
7
7
  import { useChain } from "../../hooks/useChain.js";
8
- import { useToAddressRequirements } from "../../hooks/useToAddressRequirements.js";
9
8
  import { useAddressValidation } from "../../hooks/useAddressValidation.js";
10
9
  import { useHeader } from "../../hooks/useHeader.js";
11
10
  import { ButtonTertiary } from "../../components/ButtonTertiary.js";
@@ -37,7 +36,6 @@ const SendToWalletPage = () => {
37
36
  const [validatedWallet, setValidatedWallet] = useState();
38
37
  const [errorMessage, setErrorMessage] = useState("");
39
38
  const { validateAddress, isValidating } = useAddressValidation();
40
- const { requiredToChainType } = useToAddressRequirements();
41
39
  const [toChainId] = useFieldValues("toChain");
42
40
  const { chain: toChain } = useChain(toChainId);
43
41
  const [isDoneButtonLoading, setIsDoneButtonLoading] = useState(false);
@@ -63,7 +61,6 @@ const SendToWalletPage = () => {
63
61
  setIsDoneButtonLoading(true);
64
62
  const validationResult = await validateAddress({
65
63
  value: inputAddressValue,
66
- chainType: requiredToChainType,
67
64
  chain: toChain
68
65
  });
69
66
  setIsDoneButtonLoading(false);
@@ -71,14 +68,11 @@ const SendToWalletPage = () => {
71
68
  setErrorMessage(validationResult.error);
72
69
  return;
73
70
  }
74
- if (requiredToChainType && requiredToChainType !== validationResult.chainType) {
75
- setErrorMessage(t("error.title.walletChainTypeInvalid", { chainName: toChain?.name }));
76
- return;
77
- }
78
71
  setValidatedWallet({
79
72
  name: validationResult.addressType === 1 ? inputAddressValue : void 0,
80
73
  address: validationResult.address,
81
- chainType: validationResult.chainType
74
+ chainType: validationResult.chainType,
75
+ chainId: validationResult.chainId
82
76
  });
83
77
  confirmAddressSheetRef.current?.open();
84
78
  };
@@ -100,7 +94,8 @@ const SendToWalletPage = () => {
100
94
  setValidatedWallet({
101
95
  name: validationResult.addressType === 1 ? inputAddressValue : void 0,
102
96
  address: validationResult.address,
103
- chainType: validationResult.chainType
97
+ chainType: validationResult.chainType,
98
+ chainId: validationResult.chainId
104
99
  });
105
100
  bookmarkAddressSheetRef.current?.open();
106
101
  } else setErrorMessage(validationResult.error);
@@ -148,7 +143,7 @@ const SendToWalletPage = () => {
148
143
  placeholder,
149
144
  "aria-label": placeholder,
150
145
  maxRows: 2,
151
- inputProps: { maxLength: 128 },
146
+ inputProps: { maxLength: 512 },
152
147
  multiline: true
153
148
  }),
154
149
  errorMessage ? /* @__PURE__ */ jsx(ValidationAlert, {
@@ -1 +1 @@
1
- {"version":3,"file":"SendToWalletPage.js","names":[],"sources":["../../../../src/pages/SendToWallet/SendToWalletPage.tsx"],"sourcesContent":["import { useAccount } from '@lifi/wallet-management'\nimport AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet'\nimport ErrorIcon from '@mui/icons-material/Error'\nimport TurnedIn from '@mui/icons-material/TurnedIn'\nimport Wallet from '@mui/icons-material/Wallet'\nimport { Box, Tooltip, Typography } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport type { ChangeEvent } from 'react'\nimport { useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport type { BottomSheetBase } from '../../components/BottomSheet/types.js'\nimport { ButtonTertiary } from '../../components/ButtonTertiary.js'\nimport { CardButton } from '../../components/Card/CardButton.js'\nimport { AccountDeployedMessage } from '../../components/Messages/AccountDeployedMessage.js'\nimport {\n AddressType,\n useAddressValidation,\n} from '../../hooks/useAddressValidation.js'\nimport { useChain } from '../../hooks/useChain.js'\nimport { useHeader } from '../../hooks/useHeader.js'\nimport { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport type { Bookmark } from '../../stores/bookmarks/types.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 { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { BookmarkAddressSheet } from './BookmarkAddressSheet.js'\nimport { ConfirmAddressSheet } from './ConfirmAddressSheet.js'\nimport {\n AddressInput,\n FullHeightAdjustablePageContainer,\n SendToWalletButtonRow,\n SendToWalletCard,\n SendToWalletIconButton,\n ValidationAlert,\n} from './SendToWalletPage.style.js'\n\nexport const SendToWalletPage: React.FC = () => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const bookmarkAddressSheetRef = useRef<BottomSheetBase>(null)\n const confirmAddressSheetRef = useRef<BottomSheetBase>(null)\n const { bookmarks, recentWallets } = useBookmarks()\n const {\n addBookmark,\n getBookmark,\n setSelectedBookmark,\n getSelectedBookmark,\n addRecentWallet,\n } = useBookmarkActions()\n const { setFieldValue } = useFieldActions()\n const [inputAddressValue, setInputAddressValue] = useState(\n () => getSelectedBookmark()?.address ?? ''\n )\n const [validatedWallet, setValidatedWallet] = useState<Bookmark>()\n const [errorMessage, setErrorMessage] = useState('')\n const { validateAddress, isValidating } = useAddressValidation()\n const { requiredToChainType } = useToAddressRequirements()\n const [toChainId] = useFieldValues('toChain')\n const { chain: toChain } = useChain(toChainId)\n const [isDoneButtonLoading, setIsDoneButtonLoading] = useState(false)\n const [isBookmarkButtonLoading, setIsBookmarkButtonLoading] = useState(false)\n const { variant, hiddenUI, requiredUI } = useWidgetConfig()\n\n const { accounts } = useAccount()\n const connectedWallets = accounts.filter((account) => account.isConnected)\n\n useHeader(t('header.sendToWallet'))\n\n const handleInputChange = (e: ChangeEvent) => {\n if (errorMessage) {\n setErrorMessage('')\n }\n if (getSelectedBookmark()) {\n setFieldValue('toAddress', '', { isTouched: true })\n setSelectedBookmark()\n }\n setInputAddressValue((e.target as HTMLInputElement).value.trim())\n }\n\n const handleDone = async () => {\n if (isValidating) {\n return\n }\n if (!inputAddressValue) {\n setErrorMessage(t('error.title.walletAddressRequired'))\n return\n }\n setIsDoneButtonLoading(true)\n const validationResult = await validateAddress({\n value: inputAddressValue,\n chainType: requiredToChainType,\n chain: toChain,\n })\n setIsDoneButtonLoading(false)\n if (!validationResult.isValid) {\n setErrorMessage(validationResult.error)\n return\n }\n\n if (\n requiredToChainType &&\n requiredToChainType !== validationResult.chainType\n ) {\n setErrorMessage(\n t('error.title.walletChainTypeInvalid', {\n chainName: toChain?.name,\n })\n )\n return\n }\n\n setValidatedWallet({\n name:\n validationResult.addressType === AddressType.NameService\n ? inputAddressValue\n : undefined,\n address: validationResult.address,\n chainType: validationResult.chainType,\n })\n confirmAddressSheetRef.current?.open()\n }\n\n const handleBookmarkAddress = async () => {\n if (isValidating) {\n return\n }\n if (!inputAddressValue) {\n setErrorMessage(t('error.title.walletAddressRequired'))\n return\n }\n\n const existingBookmarkWallet = getBookmark(inputAddressValue)\n if (existingBookmarkWallet) {\n setErrorMessage(\n t('error.title.bookmarkAlreadyExists', {\n name: existingBookmarkWallet.name,\n })\n )\n return\n }\n setIsBookmarkButtonLoading(true)\n const validationResult = await validateAddress({\n value: inputAddressValue,\n })\n setIsBookmarkButtonLoading(false)\n\n if (validationResult.isValid) {\n setValidatedWallet({\n name:\n validationResult.addressType === AddressType.NameService\n ? inputAddressValue\n : undefined,\n address: validationResult.address,\n chainType: validationResult.chainType,\n })\n bookmarkAddressSheetRef.current?.open()\n } else {\n setErrorMessage(validationResult.error)\n }\n }\n\n const handleRecentWalletsClick = () => {\n navigate({ to: navigationRoutes.recentWallets })\n }\n\n const handleConnectedWalletsClick = () => {\n navigate({ to: navigationRoutes.connectedWallets })\n }\n const handleBookmarkedWalletsClick = () => {\n navigate({ to: navigationRoutes.bookmarks })\n }\n\n const handleAddBookmark = (bookmark: Bookmark) => {\n addBookmark(bookmark)\n navigate({ to: navigationRoutes.bookmarks })\n }\n\n const handleOnConfirm = (confirmedWallet: Bookmark) => {\n setSelectedBookmark(confirmedWallet)\n addRecentWallet(confirmedWallet)\n }\n\n const placeholder = t('sendToWallet.enterAddress', {\n context: 'long',\n })\n\n return (\n <FullHeightAdjustablePageContainer\n topGutters\n bottomGutters\n enableFullHeight={variant !== 'drawer'}\n >\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n marginBottom: 6,\n }}\n >\n <SendToWalletCard type={errorMessage ? 'error' : 'default'}>\n <AddressInput\n size=\"small\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n spellCheck=\"false\"\n onChange={handleInputChange}\n value={inputAddressValue}\n placeholder={placeholder}\n aria-label={placeholder}\n maxRows={2}\n inputProps={{ maxLength: 128 }}\n multiline\n />\n {errorMessage ? (\n <ValidationAlert icon={<ErrorIcon />} sx={{ pb: 2, paddingX: 2 }}>\n {errorMessage}\n </ValidationAlert>\n ) : null}\n <SendToWalletButtonRow sx={{ paddingX: 2, paddingBottom: 2 }}>\n <ButtonTertiary\n variant=\"text\"\n onClick={handleDone}\n loading={isDoneButtonLoading}\n loadingPosition=\"center\"\n sx={{ flexGrow: 1 }}\n >\n {t('button.done')}\n </ButtonTertiary>\n <Tooltip title={t('button.bookmark')}>\n <SendToWalletIconButton\n onClick={handleBookmarkAddress}\n loading={isBookmarkButtonLoading}\n loadingPosition=\"center\"\n >\n <TurnedIn fontSize=\"small\" />\n </SendToWalletIconButton>\n </Tooltip>\n </SendToWalletButtonRow>\n <ConfirmAddressSheet\n ref={confirmAddressSheetRef}\n validatedBookmark={validatedWallet}\n onConfirm={handleOnConfirm}\n />\n <BookmarkAddressSheet\n ref={bookmarkAddressSheetRef}\n validatedWallet={validatedWallet}\n onAddBookmark={handleAddBookmark}\n />\n </SendToWalletCard>\n {requiredUI?.accountDeployedMessage && <AccountDeployedMessage />}\n </Box>\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>\n <CardButton\n title={t('header.recentWallets')}\n icon={<AccountBalanceWalletIcon />}\n onClick={handleRecentWalletsClick}\n >\n {!!recentWallets.length && (\n <Typography\n sx={{\n color: 'text.secondary',\n }}\n >\n {recentWallets.length}\n </Typography>\n )}\n </CardButton>\n {!hiddenUI?.addressBookConnectedWallets && (\n <CardButton\n title={t('sendToWallet.connectedWallets')}\n icon={<Wallet />}\n onClick={handleConnectedWalletsClick}\n >\n {!!connectedWallets.length && (\n <Typography\n sx={{\n color: 'text.secondary',\n }}\n >\n {connectedWallets.length}\n </Typography>\n )}\n </CardButton>\n )}\n <CardButton\n title={t('header.bookmarkedWallets')}\n icon={<TurnedIn />}\n onClick={handleBookmarkedWalletsClick}\n >\n {!!bookmarks.length && (\n <Typography\n sx={{\n color: 'text.secondary',\n }}\n >\n {bookmarks.length}\n </Typography>\n )}\n </CardButton>\n </Box>\n </FullHeightAdjustablePageContainer>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SendToWalletPage.js","names":[],"sources":["../../../../src/pages/SendToWallet/SendToWalletPage.tsx"],"sourcesContent":["import { useAccount } from '@lifi/wallet-management'\nimport AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet'\nimport ErrorIcon from '@mui/icons-material/Error'\nimport TurnedIn from '@mui/icons-material/TurnedIn'\nimport Wallet from '@mui/icons-material/Wallet'\nimport { Box, Tooltip, Typography } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport type { ChangeEvent } from 'react'\nimport { useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport type { BottomSheetBase } from '../../components/BottomSheet/types.js'\nimport { ButtonTertiary } from '../../components/ButtonTertiary.js'\nimport { CardButton } from '../../components/Card/CardButton.js'\nimport { AccountDeployedMessage } from '../../components/Messages/AccountDeployedMessage.js'\nimport { addressInputMaxLength } from '../../config/constants.js'\nimport {\n AddressType,\n useAddressValidation,\n} from '../../hooks/useAddressValidation.js'\nimport { useChain } from '../../hooks/useChain.js'\nimport { useHeader } from '../../hooks/useHeader.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport type { Bookmark } from '../../stores/bookmarks/types.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 { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { BookmarkAddressSheet } from './BookmarkAddressSheet.js'\nimport { ConfirmAddressSheet } from './ConfirmAddressSheet.js'\nimport {\n AddressInput,\n FullHeightAdjustablePageContainer,\n SendToWalletButtonRow,\n SendToWalletCard,\n SendToWalletIconButton,\n ValidationAlert,\n} from './SendToWalletPage.style.js'\n\nexport const SendToWalletPage: React.FC = () => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const bookmarkAddressSheetRef = useRef<BottomSheetBase>(null)\n const confirmAddressSheetRef = useRef<BottomSheetBase>(null)\n const { bookmarks, recentWallets } = useBookmarks()\n const {\n addBookmark,\n getBookmark,\n setSelectedBookmark,\n getSelectedBookmark,\n addRecentWallet,\n } = useBookmarkActions()\n const { setFieldValue } = useFieldActions()\n const [inputAddressValue, setInputAddressValue] = useState(\n () => getSelectedBookmark()?.address ?? ''\n )\n const [validatedWallet, setValidatedWallet] = useState<Bookmark>()\n const [errorMessage, setErrorMessage] = useState('')\n const { validateAddress, isValidating } = useAddressValidation()\n const [toChainId] = useFieldValues('toChain')\n const { chain: toChain } = useChain(toChainId)\n const [isDoneButtonLoading, setIsDoneButtonLoading] = useState(false)\n const [isBookmarkButtonLoading, setIsBookmarkButtonLoading] = useState(false)\n const { variant, hiddenUI, requiredUI } = useWidgetConfig()\n\n const { accounts } = useAccount()\n const connectedWallets = accounts.filter((account) => account.isConnected)\n\n useHeader(t('header.sendToWallet'))\n\n const handleInputChange = (e: ChangeEvent) => {\n if (errorMessage) {\n setErrorMessage('')\n }\n if (getSelectedBookmark()) {\n setFieldValue('toAddress', '', { isTouched: true })\n setSelectedBookmark()\n }\n setInputAddressValue((e.target as HTMLInputElement).value.trim())\n }\n\n const handleDone = async () => {\n if (isValidating) {\n return\n }\n if (!inputAddressValue) {\n setErrorMessage(t('error.title.walletAddressRequired'))\n return\n }\n setIsDoneButtonLoading(true)\n const validationResult = await validateAddress({\n value: inputAddressValue,\n chain: toChain,\n })\n setIsDoneButtonLoading(false)\n if (!validationResult.isValid) {\n setErrorMessage(validationResult.error)\n return\n }\n\n setValidatedWallet({\n name:\n validationResult.addressType === AddressType.NameService\n ? inputAddressValue\n : undefined,\n address: validationResult.address,\n chainType: validationResult.chainType,\n chainId: validationResult.chainId,\n })\n confirmAddressSheetRef.current?.open()\n }\n\n const handleBookmarkAddress = async () => {\n if (isValidating) {\n return\n }\n if (!inputAddressValue) {\n setErrorMessage(t('error.title.walletAddressRequired'))\n return\n }\n\n const existingBookmarkWallet = getBookmark(inputAddressValue)\n if (existingBookmarkWallet) {\n setErrorMessage(\n t('error.title.bookmarkAlreadyExists', {\n name: existingBookmarkWallet.name,\n })\n )\n return\n }\n setIsBookmarkButtonLoading(true)\n const validationResult = await validateAddress({\n value: inputAddressValue,\n })\n setIsBookmarkButtonLoading(false)\n\n if (validationResult.isValid) {\n setValidatedWallet({\n name:\n validationResult.addressType === AddressType.NameService\n ? inputAddressValue\n : undefined,\n address: validationResult.address,\n chainType: validationResult.chainType,\n chainId: validationResult.chainId,\n })\n bookmarkAddressSheetRef.current?.open()\n } else {\n setErrorMessage(validationResult.error)\n }\n }\n\n const handleRecentWalletsClick = () => {\n navigate({ to: navigationRoutes.recentWallets })\n }\n\n const handleConnectedWalletsClick = () => {\n navigate({ to: navigationRoutes.connectedWallets })\n }\n const handleBookmarkedWalletsClick = () => {\n navigate({ to: navigationRoutes.bookmarks })\n }\n\n const handleAddBookmark = (bookmark: Bookmark) => {\n addBookmark(bookmark)\n navigate({ to: navigationRoutes.bookmarks })\n }\n\n const handleOnConfirm = (confirmedWallet: Bookmark) => {\n setSelectedBookmark(confirmedWallet)\n addRecentWallet(confirmedWallet)\n }\n\n const placeholder = t('sendToWallet.enterAddress', {\n context: 'long',\n })\n\n return (\n <FullHeightAdjustablePageContainer\n topGutters\n bottomGutters\n enableFullHeight={variant !== 'drawer'}\n >\n <Box\n sx={{\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n marginBottom: 6,\n }}\n >\n <SendToWalletCard type={errorMessage ? 'error' : 'default'}>\n <AddressInput\n size=\"small\"\n autoComplete=\"off\"\n autoCorrect=\"off\"\n autoCapitalize=\"off\"\n spellCheck=\"false\"\n onChange={handleInputChange}\n value={inputAddressValue}\n placeholder={placeholder}\n aria-label={placeholder}\n maxRows={2}\n inputProps={{ maxLength: addressInputMaxLength }}\n multiline\n />\n {errorMessage ? (\n <ValidationAlert icon={<ErrorIcon />} sx={{ pb: 2, paddingX: 2 }}>\n {errorMessage}\n </ValidationAlert>\n ) : null}\n <SendToWalletButtonRow sx={{ paddingX: 2, paddingBottom: 2 }}>\n <ButtonTertiary\n variant=\"text\"\n onClick={handleDone}\n loading={isDoneButtonLoading}\n loadingPosition=\"center\"\n sx={{ flexGrow: 1 }}\n >\n {t('button.done')}\n </ButtonTertiary>\n <Tooltip title={t('button.bookmark')}>\n <SendToWalletIconButton\n onClick={handleBookmarkAddress}\n loading={isBookmarkButtonLoading}\n loadingPosition=\"center\"\n >\n <TurnedIn fontSize=\"small\" />\n </SendToWalletIconButton>\n </Tooltip>\n </SendToWalletButtonRow>\n <ConfirmAddressSheet\n ref={confirmAddressSheetRef}\n validatedBookmark={validatedWallet}\n onConfirm={handleOnConfirm}\n />\n <BookmarkAddressSheet\n ref={bookmarkAddressSheetRef}\n validatedWallet={validatedWallet}\n onAddBookmark={handleAddBookmark}\n />\n </SendToWalletCard>\n {requiredUI?.accountDeployedMessage && <AccountDeployedMessage />}\n </Box>\n <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>\n <CardButton\n title={t('header.recentWallets')}\n icon={<AccountBalanceWalletIcon />}\n onClick={handleRecentWalletsClick}\n >\n {!!recentWallets.length && (\n <Typography\n sx={{\n color: 'text.secondary',\n }}\n >\n {recentWallets.length}\n </Typography>\n )}\n </CardButton>\n {!hiddenUI?.addressBookConnectedWallets && (\n <CardButton\n title={t('sendToWallet.connectedWallets')}\n icon={<Wallet />}\n onClick={handleConnectedWalletsClick}\n >\n {!!connectedWallets.length && (\n <Typography\n sx={{\n color: 'text.secondary',\n }}\n >\n {connectedWallets.length}\n </Typography>\n )}\n </CardButton>\n )}\n <CardButton\n title={t('header.bookmarkedWallets')}\n icon={<TurnedIn />}\n onClick={handleBookmarkedWalletsClick}\n >\n {!!bookmarks.length && (\n <Typography\n sx={{\n color: 'text.secondary',\n }}\n >\n {bookmarks.length}\n </Typography>\n )}\n </CardButton>\n </Box>\n </FullHeightAdjustablePageContainer>\n )\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"WalletProvider.d.ts","names":[],"sources":["../../../../src/providers/WalletProvider/WalletProvider.tsx"],"mappings":";;;UAgBU,4BAA4B;EACpC,aAAa,OAAO,kBAAkB,yBAAyB;;qBAGpD,mBACX,UACA,aACC,kBAAkB,yBAAuB,IAAI"}
1
+ {"version":3,"file":"WalletProvider.d.ts","names":[],"sources":["../../../../src/providers/WalletProvider/WalletProvider.tsx"],"mappings":";;;UA0BU,4BAA4B;EACpC,aAAa,OAAO,kBAAkB,yBAAyB;;qBAGpD,mBACX,UACA,aACC,kBAAkB,yBAAuB,IAAI"}
@@ -1,11 +1,13 @@
1
1
  import { getConfigItemSets, isItemAllowedForSets } from "../../utils/item.js";
2
- import { useWidgetConfig } from "../WidgetProvider/WidgetProvider.js";
2
+ import { withServedDestinationChains, withoutUnservedToChain } from "../../utils/chainType.js";
3
+ import { WidgetContext, useWidgetConfig } from "../WidgetProvider/WidgetProvider.js";
3
4
  import { useAvailableChains } from "../../hooks/useAvailableChains.js";
4
5
  import { useExternalWalletProvider } from "./useExternalWalletProvider.js";
5
6
  import { useInitializeSDKProviders } from "../../hooks/useInitializeSDKProviders.js";
6
7
  import { useMemo } from "react";
7
8
  import { jsx } from "react/jsx-runtime";
8
9
  import { useTranslation } from "react-i18next";
10
+ import { useSDKProviders } from "@lifi/widget-provider";
9
11
  import { WalletManagementProviders } from "@lifi/wallet-management";
10
12
  //#region src/providers/WalletProvider/WalletProvider.tsx
11
13
  const WalletProvider = ({ children, providers }) => {
@@ -38,7 +40,17 @@ const WalletProvider = ({ children, providers }) => {
38
40
  };
39
41
  const SDKProviderInitializer = ({ children }) => {
40
42
  useInitializeSDKProviders();
41
- return children;
43
+ const config = useWidgetConfig();
44
+ const sdkProviders = useSDKProviders();
45
+ const chains = useMemo(() => withServedDestinationChains(config.chains, sdkProviders), [config.chains, sdkProviders]);
46
+ const value = useMemo(() => withoutUnservedToChain(chains === config.chains ? config : {
47
+ ...config,
48
+ chains
49
+ }), [config, chains]);
50
+ return /* @__PURE__ */ jsx(WidgetContext, {
51
+ value,
52
+ children
53
+ });
42
54
  };
43
55
  //#endregion
44
56
  export { WalletProvider };
@@ -1 +1 @@
1
- {"version":3,"file":"WalletProvider.js","names":[],"sources":["../../../../src/providers/WalletProvider/WalletProvider.tsx"],"sourcesContent":["import { WalletManagementProviders } from '@lifi/wallet-management'\nimport type { WidgetProviderProps } from '@lifi/widget-provider'\nimport {\n type FC,\n type JSX,\n type PropsWithChildren,\n type ReactNode,\n useMemo,\n} from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useInitializeSDKProviders } from '../../hooks/useInitializeSDKProviders.js'\nimport { getConfigItemSets, isItemAllowedForSets } from '../../utils/item.js'\nimport { useWidgetConfig } from '../WidgetProvider/WidgetProvider.js'\nimport { useExternalWalletProvider } from './useExternalWalletProvider.js'\n\ninterface WalletProviderProps extends PropsWithChildren {\n providers: ((props: PropsWithChildren<WidgetProviderProps>) => ReactNode)[]\n}\n\nexport const WalletProvider = ({\n children,\n providers,\n}: PropsWithChildren<WalletProviderProps>): JSX.Element => {\n const { walletConfig, chains: chainsConfig } = useWidgetConfig()\n const { chains } = useAvailableChains()\n const { i18n } = useTranslation()\n const { useExternalWalletProvidersOnly, internalChainTypes } =\n useExternalWalletProvider()\n\n // Restrict offered wallets to the ecosystems allowed by chains.types config.\n const enabledChainTypes = useMemo(() => {\n const chainTypeSets = getConfigItemSets(\n chainsConfig?.types,\n (items) => new Set(items)\n )\n return internalChainTypes.filter((chainType) =>\n isItemAllowedForSets(chainType, chainTypeSets)\n )\n }, [internalChainTypes, chainsConfig?.types])\n\n if (\n !providers.length &&\n !useExternalWalletProvidersOnly &&\n process.env.NODE_ENV === 'development'\n ) {\n console.warn('No widget providers specified')\n }\n\n const effectiveProviders = useExternalWalletProvidersOnly ? [] : providers\n\n const walletManagementConfig = useMemo(\n () => ({\n locale: i18n.resolvedLanguage as never,\n enabledChainTypes,\n walletEcosystemsOrder: walletConfig?.walletEcosystemsOrder,\n }),\n [\n i18n.resolvedLanguage,\n enabledChainTypes,\n walletConfig?.walletEcosystemsOrder,\n ]\n )\n\n return (\n <WalletManagementProviders\n config={walletManagementConfig}\n providers={effectiveProviders}\n chains={chains}\n forceInternalWalletManagement={\n walletConfig?.forceInternalWalletManagement\n }\n >\n <SDKProviderInitializer>{children}</SDKProviderInitializer>\n </WalletManagementProviders>\n )\n}\n\nconst SDKProviderInitializer: FC<PropsWithChildren> = ({ children }) => {\n useInitializeSDKProviders()\n return children\n}\n"],"mappings":";;;;;;;;;;AAoBA,MAAa,kBAAkB,EAC7B,UACA,gBACyD;CACzD,MAAM,EAAE,cAAc,QAAQ,iBAAiB,gBAAgB;CAC/D,MAAM,EAAE,WAAW,mBAAmB;CACtC,MAAM,EAAE,SAAS,eAAe;CAChC,MAAM,EAAE,gCAAgC,uBACtC,0BAA0B;CAG5B,MAAM,oBAAoB,cAAc;EACtC,MAAM,gBAAgB,kBACpB,cAAc,QACb,UAAU,IAAI,IAAI,KAAK,CAC1B;EACA,OAAO,mBAAmB,QAAQ,cAChC,qBAAqB,WAAW,aAAa,CAC/C;CACF,GAAG,CAAC,oBAAoB,cAAc,KAAK,CAAC;CAE5C,IACE,CAAC,UAAU,UACX,CAAC,kCACD,QAAQ,IAAI,aAAa,eAEzB,QAAQ,KAAK,+BAA+B;CAG9C,MAAM,qBAAqB,iCAAiC,CAAC,IAAI;CAEjE,MAAM,yBAAyB,eACtB;EACL,QAAQ,KAAK;EACb;EACA,uBAAuB,cAAc;CACvC,IACA;EACE,KAAK;EACL;EACA,cAAc;CAChB,CACF;CAEA,OACE,oBAAC,2BAAD;EACE,QAAQ;EACR,WAAW;EACH;EACR,+BACE,cAAc;EAGhB,UAAA,oBAAC,wBAAD,EAAyB,SAAiC,CAAA;CACjC,CAAA;AAE/B;AAEA,MAAM,0BAAiD,EAAE,eAAe;CACtE,0BAA0B;CAC1B,OAAO;AACT"}
1
+ {"version":3,"file":"WalletProvider.js","names":[],"sources":["../../../../src/providers/WalletProvider/WalletProvider.tsx"],"sourcesContent":["import { WalletManagementProviders } from '@lifi/wallet-management'\nimport {\n useSDKProviders,\n type WidgetProviderProps,\n} from '@lifi/widget-provider'\nimport {\n type FC,\n type JSX,\n type PropsWithChildren,\n type ReactNode,\n useMemo,\n} from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useInitializeSDKProviders } from '../../hooks/useInitializeSDKProviders.js'\nimport {\n withoutUnservedToChain,\n withServedDestinationChains,\n} from '../../utils/chainType.js'\nimport { getConfigItemSets, isItemAllowedForSets } from '../../utils/item.js'\nimport {\n useWidgetConfig,\n WidgetContext,\n} from '../WidgetProvider/WidgetProvider.js'\nimport { useExternalWalletProvider } from './useExternalWalletProvider.js'\n\ninterface WalletProviderProps extends PropsWithChildren {\n providers: ((props: PropsWithChildren<WidgetProviderProps>) => ReactNode)[]\n}\n\nexport const WalletProvider = ({\n children,\n providers,\n}: PropsWithChildren<WalletProviderProps>): JSX.Element => {\n const { walletConfig, chains: chainsConfig } = useWidgetConfig()\n const { chains } = useAvailableChains()\n const { i18n } = useTranslation()\n const { useExternalWalletProvidersOnly, internalChainTypes } =\n useExternalWalletProvider()\n\n // Restrict offered wallets to the ecosystems allowed by chains.types config.\n const enabledChainTypes = useMemo(() => {\n const chainTypeSets = getConfigItemSets(\n chainsConfig?.types,\n (items) => new Set(items)\n )\n return internalChainTypes.filter((chainType) =>\n isItemAllowedForSets(chainType, chainTypeSets)\n )\n }, [internalChainTypes, chainsConfig?.types])\n\n if (\n !providers.length &&\n !useExternalWalletProvidersOnly &&\n process.env.NODE_ENV === 'development'\n ) {\n console.warn('No widget providers specified')\n }\n\n const effectiveProviders = useExternalWalletProvidersOnly ? [] : providers\n\n const walletManagementConfig = useMemo(\n () => ({\n locale: i18n.resolvedLanguage as never,\n enabledChainTypes,\n walletEcosystemsOrder: walletConfig?.walletEcosystemsOrder,\n }),\n [\n i18n.resolvedLanguage,\n enabledChainTypes,\n walletConfig?.walletEcosystemsOrder,\n ]\n )\n\n return (\n <WalletManagementProviders\n config={walletManagementConfig}\n providers={effectiveProviders}\n chains={chains}\n forceInternalWalletManagement={\n walletConfig?.forceInternalWalletManagement\n }\n >\n <SDKProviderInitializer>{children}</SDKProviderInitializer>\n </WalletManagementProviders>\n )\n}\n\nconst SDKProviderInitializer: FC<PropsWithChildren> = ({ children }) => {\n useInitializeSDKProviders()\n const config = useWidgetConfig()\n const sdkProviders = useSDKProviders()\n // Only below the provider components is it known which chains are served.\n // Keyed on `config.chains`: the config object is new on every render.\n const chains = useMemo(\n () => withServedDestinationChains(config.chains, sdkProviders),\n [config.chains, sdkProviders]\n )\n const value = useMemo(\n () =>\n withoutUnservedToChain(\n chains === config.chains ? config : { ...config, chains }\n ),\n [config, chains]\n )\n return <WidgetContext value={value}>{children}</WidgetContext>\n}\n"],"mappings":";;;;;;;;;;;;AA8BA,MAAa,kBAAkB,EAC7B,UACA,gBACyD;CACzD,MAAM,EAAE,cAAc,QAAQ,iBAAiB,gBAAgB;CAC/D,MAAM,EAAE,WAAW,mBAAmB;CACtC,MAAM,EAAE,SAAS,eAAe;CAChC,MAAM,EAAE,gCAAgC,uBACtC,0BAA0B;CAG5B,MAAM,oBAAoB,cAAc;EACtC,MAAM,gBAAgB,kBACpB,cAAc,QACb,UAAU,IAAI,IAAI,KAAK,CAC1B;EACA,OAAO,mBAAmB,QAAQ,cAChC,qBAAqB,WAAW,aAAa,CAC/C;CACF,GAAG,CAAC,oBAAoB,cAAc,KAAK,CAAC;CAE5C,IACE,CAAC,UAAU,UACX,CAAC,kCACD,QAAQ,IAAI,aAAa,eAEzB,QAAQ,KAAK,+BAA+B;CAG9C,MAAM,qBAAqB,iCAAiC,CAAC,IAAI;CAEjE,MAAM,yBAAyB,eACtB;EACL,QAAQ,KAAK;EACb;EACA,uBAAuB,cAAc;CACvC,IACA;EACE,KAAK;EACL;EACA,cAAc;CAChB,CACF;CAEA,OACE,oBAAC,2BAAD;EACE,QAAQ;EACR,WAAW;EACH;EACR,+BACE,cAAc;EAGhB,UAAA,oBAAC,wBAAD,EAAyB,SAAiC,CAAA;CACjC,CAAA;AAE/B;AAEA,MAAM,0BAAiD,EAAE,eAAe;CACtE,0BAA0B;CAC1B,MAAM,SAAS,gBAAgB;CAC/B,MAAM,eAAe,gBAAgB;CAGrC,MAAM,SAAS,cACP,4BAA4B,OAAO,QAAQ,YAAY,GAC7D,CAAC,OAAO,QAAQ,YAAY,CAC9B;CACA,MAAM,QAAQ,cAEV,uBACE,WAAW,OAAO,SAAS,SAAS;EAAE,GAAG;EAAQ;CAAO,CAC1D,GACF,CAAC,QAAQ,MAAM,CACjB;CACA,OAAO,oBAAC,eAAD;EAAsB;EAAQ;CAAwB,CAAA;AAC/D"}
@@ -1 +1 @@
1
- {"version":3,"file":"WidgetProvider.d.ts","names":[],"sources":["../../../../src/providers/WidgetProvider/WidgetProvider.tsx"],"mappings":";;;qBAmBa,uBAAsB;qBAEtB,gBAAgB,MAAM,GACjC,MAAM,kBAAkB"}
1
+ {"version":3,"file":"WidgetProvider.d.ts","names":[],"sources":["../../../../src/providers/WidgetProvider/WidgetProvider.tsx"],"mappings":";;;qBAuBa,uBAAsB;qBAEtB,gBAAgB,MAAM,GACjC,MAAM,kBAAkB"}
@@ -1,4 +1,5 @@
1
1
  import { useSettingsActions } from "../../stores/settings/useSettingsActions.js";
2
+ import { isDestinationOnlyChain, withDestinationOnlyChains } from "../../utils/chainType.js";
2
3
  import { defaultQueryScopeKey, resolveQueryScopeKey, resolveStorageScopeKey } from "../../utils/scopeKeys.js";
3
4
  import { createContext, use, useId, useMemo } from "react";
4
5
  import { jsx } from "react/jsx-runtime";
@@ -12,31 +13,26 @@ const WidgetProvider = ({ children, config: widgetConfig }) => {
12
13
  const elementId = useId();
13
14
  const { setDefaultSettings } = useSettingsActions();
14
15
  if (!widgetConfig?.integrator) throw new Error("Required property \"integrator\" is missing.");
16
+ const chains = useMemo(() => withDestinationOnlyChains(widgetConfig.chains), [widgetConfig.chains]);
15
17
  const value = useMemo(() => {
16
- const scopeKeys = {
18
+ const { fromChain, fromToken, ...config } = widgetConfig;
19
+ const value = {
20
+ ...isDestinationOnlyChain(fromChain) ? config : widgetConfig,
21
+ chains,
17
22
  storageScopeKey: resolveStorageScopeKey(widgetConfig),
18
- queryScopeKey: resolveQueryScopeKey(widgetConfig)
23
+ queryScopeKey: resolveQueryScopeKey(widgetConfig),
24
+ elementId
19
25
  };
20
26
  try {
21
- const value = {
22
- ...widgetConfig,
23
- ...scopeKeys,
24
- elementId
25
- };
26
27
  setDefaultSettings(value);
27
- return value;
28
28
  } catch (e) {
29
29
  console.warn(e);
30
- return {
31
- ...widgetConfig,
32
- ...scopeKeys,
33
- elementId,
34
- integrator: widgetConfig.integrator
35
- };
36
30
  }
31
+ return value;
37
32
  }, [
38
33
  elementId,
39
34
  widgetConfig,
35
+ chains,
40
36
  setDefaultSettings
41
37
  ]);
42
38
  return /* @__PURE__ */ jsx(WidgetContext, {
@@ -1 +1 @@
1
- {"version":3,"file":"WidgetProvider.js","names":[],"sources":["../../../../src/providers/WidgetProvider/WidgetProvider.tsx"],"sourcesContent":["import type { Context } from 'react'\nimport { createContext, use, useId, useMemo } from 'react'\nimport { useSettingsActions } from '../../stores/settings/useSettingsActions.js'\nimport {\n defaultQueryScopeKey,\n resolveQueryScopeKey,\n resolveStorageScopeKey,\n} from '../../utils/scopeKeys.js'\nimport type { WidgetContextProps, WidgetProviderProps } from './types.js'\n\nconst initialContext: WidgetContextProps = {\n elementId: '',\n integrator: '',\n queryScopeKey: defaultQueryScopeKey,\n}\n\nexport const WidgetContext: Context<WidgetContextProps> =\n createContext<WidgetContextProps>(initialContext)\n\nexport const useWidgetConfig = (): WidgetContextProps => use(WidgetContext)\n\nexport const WidgetProvider: React.FC<\n React.PropsWithChildren<WidgetProviderProps>\n> = ({ children, config: widgetConfig }) => {\n const elementId = useId()\n const { setDefaultSettings } = useSettingsActions()\n\n if (!widgetConfig?.integrator) {\n throw new Error('Required property \"integrator\" is missing.')\n }\n\n const value = useMemo((): WidgetContextProps => {\n // Resolved once, so nothing below reads the deprecated keyPrefix.\n const scopeKeys = {\n storageScopeKey: resolveStorageScopeKey(widgetConfig),\n queryScopeKey: resolveQueryScopeKey(widgetConfig),\n }\n try {\n // Create widget configuration object\n const value = {\n ...widgetConfig,\n ...scopeKeys,\n elementId,\n } as WidgetContextProps\n\n // Set default settings for widget settings store\n setDefaultSettings(value)\n\n return value\n } catch (e) {\n console.warn(e)\n return {\n ...widgetConfig,\n ...scopeKeys,\n elementId,\n integrator: widgetConfig.integrator,\n }\n }\n }, [elementId, widgetConfig, setDefaultSettings])\n return <WidgetContext value={value}>{children}</WidgetContext>\n}\n"],"mappings":";;;;AAgBA,MAAa,gBACX,cAAkC;CANlC,WAAW;CACX,YAAY;CACZ,eAAe;AAImB,CAAc;AAElD,MAAa,wBAA4C,IAAI,aAAa;AAE1E,MAAa,kBAER,EAAE,UAAU,QAAQ,mBAAmB;CAC1C,MAAM,YAAY,MAAM;CACxB,MAAM,EAAE,uBAAuB,mBAAmB;CAElD,IAAI,CAAC,cAAc,YACjB,MAAM,IAAI,MAAM,8CAA4C;CAG9D,MAAM,QAAQ,cAAkC;EAE9C,MAAM,YAAY;GAChB,iBAAiB,uBAAuB,YAAY;GACpD,eAAe,qBAAqB,YAAY;EAClD;EACA,IAAI;GAEF,MAAM,QAAQ;IACZ,GAAG;IACH,GAAG;IACH;GACF;GAGA,mBAAmB,KAAK;GAExB,OAAO;EACT,SAAS,GAAG;GACV,QAAQ,KAAK,CAAC;GACd,OAAO;IACL,GAAG;IACH,GAAG;IACH;IACA,YAAY,aAAa;GAC3B;EACF;CACF,GAAG;EAAC;EAAW;EAAc;CAAkB,CAAC;CAChD,OAAO,oBAAC,eAAD;EAAsB;EAAQ;CAAwB,CAAA;AAC/D"}
1
+ {"version":3,"file":"WidgetProvider.js","names":[],"sources":["../../../../src/providers/WidgetProvider/WidgetProvider.tsx"],"sourcesContent":["import type { Context } from 'react'\nimport { createContext, use, useId, useMemo } from 'react'\nimport { useSettingsActions } from '../../stores/settings/useSettingsActions.js'\nimport {\n isDestinationOnlyChain,\n withDestinationOnlyChains,\n} from '../../utils/chainType.js'\nimport {\n defaultQueryScopeKey,\n resolveQueryScopeKey,\n resolveStorageScopeKey,\n} from '../../utils/scopeKeys.js'\nimport type { WidgetContextProps, WidgetProviderProps } from './types.js'\n\nconst initialContext: WidgetContextProps = {\n elementId: '',\n integrator: '',\n queryScopeKey: defaultQueryScopeKey,\n}\n\nexport const WidgetContext: Context<WidgetContextProps> =\n createContext<WidgetContextProps>(initialContext)\n\nexport const useWidgetConfig = (): WidgetContextProps => use(WidgetContext)\n\nexport const WidgetProvider: React.FC<\n React.PropsWithChildren<WidgetProviderProps>\n> = ({ children, config: widgetConfig }) => {\n const elementId = useId()\n const { setDefaultSettings } = useSettingsActions()\n\n if (!widgetConfig?.integrator) {\n throw new Error('Required property \"integrator\" is missing.')\n }\n\n // Keyed on the integrator's `chains`: the config object is new on every render.\n const chains = useMemo(\n () => withDestinationOnlyChains(widgetConfig.chains),\n [widgetConfig.chains]\n )\n\n const value = useMemo((): WidgetContextProps => {\n // Omitted, not undefined: an own undefined key resets the form field.\n const { fromChain, fromToken, ...config } = widgetConfig\n const value = {\n ...(isDestinationOnlyChain(fromChain) ? config : widgetConfig),\n chains,\n // Resolved once, so nothing below reads the deprecated keyPrefix.\n storageScopeKey: resolveStorageScopeKey(widgetConfig),\n queryScopeKey: resolveQueryScopeKey(widgetConfig),\n elementId,\n } as WidgetContextProps\n try {\n // Set default settings for widget settings store\n setDefaultSettings(value)\n } catch (e) {\n console.warn(e)\n }\n return value\n }, [elementId, widgetConfig, chains, setDefaultSettings])\n return <WidgetContext value={value}>{children}</WidgetContext>\n}\n"],"mappings":";;;;;AAoBA,MAAa,gBACX,cAAkC;CANlC,WAAW;CACX,YAAY;CACZ,eAAe;AAImB,CAAc;AAElD,MAAa,wBAA4C,IAAI,aAAa;AAE1E,MAAa,kBAER,EAAE,UAAU,QAAQ,mBAAmB;CAC1C,MAAM,YAAY,MAAM;CACxB,MAAM,EAAE,uBAAuB,mBAAmB;CAElD,IAAI,CAAC,cAAc,YACjB,MAAM,IAAI,MAAM,8CAA4C;CAI9D,MAAM,SAAS,cACP,0BAA0B,aAAa,MAAM,GACnD,CAAC,aAAa,MAAM,CACtB;CAEA,MAAM,QAAQ,cAAkC;EAE9C,MAAM,EAAE,WAAW,WAAW,GAAG,WAAW;EAC5C,MAAM,QAAQ;GACZ,GAAI,uBAAuB,SAAS,IAAI,SAAS;GACjD;GAEA,iBAAiB,uBAAuB,YAAY;GACpD,eAAe,qBAAqB,YAAY;GAChD;EACF;EACA,IAAI;GAEF,mBAAmB,KAAK;EAC1B,SAAS,GAAG;GACV,QAAQ,KAAK,CAAC;EAChB;EACA,OAAO;CACT,GAAG;EAAC;EAAW;EAAc;EAAQ;CAAkB,CAAC;CACxD,OAAO,oBAAC,eAAD;EAAsB;EAAQ;CAAwB,CAAA;AAC/D"}
@@ -1,8 +1,11 @@
1
1
  import { ToAddress } from "../../types/widget.js";
2
+ import { ChainId } from "@lifi/sdk";
2
3
  import { StoreApi, UseBoundStore } from "zustand";
3
4
  //#region src/stores/bookmarks/types.d.ts
4
5
  export interface Bookmark extends ToAddress {
5
6
  isConnectedAccount?: boolean;
7
+ /** Display only: set when the ecosystem's default chain rejects the address. */
8
+ chainId?: ChainId;
6
9
  }
7
10
  export interface BookmarkProps {
8
11
  selectedBookmark?: Bookmark;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/stores/bookmarks/types.ts"],"mappings":";;;iBAGiB,iBAAiB;EAChC;;iBAGe;EACf,mBAAmB;EACnB,WAAW;EACX,eAAe;;iBAGA;EACf,cAAc,oBAAoB;EAClC,cAAc,UAAU;EACxB,iBAAiB;EACjB,sBAAsB,WAAW;EACjC,2BAA2B;EAC3B,kBAAkB,UAAU;EAC5B,qBAAqB;;YAGX,gBAAgB,gBAAgB;YAEhC,gBAAgB,cAAc,SAAS"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/stores/bookmarks/types.ts"],"mappings":";;;;iBAIiB,iBAAiB;EAChC;;EAEA,UAAU;;iBAGK;EACf,mBAAmB;EACnB,WAAW;EACX,eAAe;;iBAGA;EACf,cAAc,oBAAoB;EAClC,cAAc,UAAU;EACxB,iBAAiB;EACjB,sBAAsB,WAAW;EACjC,2BAA2B;EAC3B,kBAAkB,UAAU;EAC5B,qBAAqB;;YAGX,gBAAgB,gBAAgB;YAEhC,gBAAgB,cAAc,SAAS"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChainOrderStore.d.ts","names":[],"sources":["../../../../src/stores/chains/ChainOrderStore.tsx"],"mappings":";;;;wBAkLgB,mBAAmB,GACjC,WAAW,OAAO,oBAAoB,IACrC"}
1
+ {"version":3,"file":"ChainOrderStore.d.ts","names":[],"sources":["../../../../src/stores/chains/ChainOrderStore.tsx"],"mappings":";;;;wBAqLgB,mBAAmB,GACjC,WAAW,OAAO,oBAAoB,IACrC"}
@@ -33,7 +33,10 @@ function ChainOrderStoreProvider({ children, ...props }) {
33
33
  const chainOrder = storeRef.current?.getState().initializeChains(filteredChains.map((chain) => chain.id), key);
34
34
  const isSwapTo = swapOnly && key === "to";
35
35
  const showAllNetworks = filteredChains.length > 1 && !hiddenUI?.allNetworks && !isSwapTo;
36
- const urlValues = getDefaultValuesFromQueryString({ buildUrl });
36
+ const urlValues = getDefaultValuesFromQueryString({
37
+ buildUrl,
38
+ chains: chainsConfig
39
+ });
37
40
  const urlChainValue = key === "from" ? urlValues.fromChain : urlValues.toChain;
38
41
  const configChainValue = key === "from" ? fromChainConfig : toChainConfig;
39
42
  const [chainValue] = getFieldValues(`${key}Chain`);
@@ -1 +1 @@
1
- {"version":3,"file":"ChainOrderStore.js","names":[],"sources":["../../../../src/stores/chains/ChainOrderStore.tsx"],"sourcesContent":["import { createContext, type JSX, use, useEffect, useRef } from 'react'\nimport type { StoreApi, UseBoundStore } from 'zustand'\nimport { useShallow } from 'zustand/shallow'\nimport { useChains } from '../../hooks/useChains.js'\nimport { useSwapOnly } from '../../hooks/useSwapOnly.js'\nimport { useExternalWalletProvider } from '../../providers/WalletProvider/useExternalWalletProvider.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { getConfigItemSets, isItemAllowedForSets } from '../../utils/item.js'\nimport { getDefaultValuesFromQueryString } from '../form/getDefaultValuesFromQueryString.js'\nimport type { FormType } from '../form/types.js'\nimport { useFieldActions } from '../form/useFieldActions.js'\nimport type { PersistStoreProviderProps } from '../types.js'\nimport { createChainOrderStore } from './createChainOrderStore.js'\nimport type { ChainOrderState } from './types.js'\n\ntype ChainOrderStore = UseBoundStore<StoreApi<ChainOrderState>>\n\nconst ChainOrderStoreContext = createContext<ChainOrderStore | null>(null)\n\nexport function ChainOrderStoreProvider({\n children,\n ...props\n}: PersistStoreProviderProps): JSX.Element {\n const {\n chains: chainsConfig,\n hiddenUI,\n fromChain: fromChainConfig,\n toChain: toChainConfig,\n buildUrl,\n } = useWidgetConfig()\n const storeRef = useRef<ChainOrderStore>(null)\n const { chains } = useChains()\n const { setFieldValue, getFieldValues, isTouched } = useFieldActions()\n const swapOnly = useSwapOnly()\n const { variant } = useWidgetConfig()\n const { externalChainTypes, useExternalWalletProvidersOnly } =\n useExternalWalletProvider()\n\n if (!storeRef.current) {\n storeRef.current = createChainOrderStore({\n ...props,\n })\n }\n\n useEffect(() => {\n if (chains) {\n ;(['from', 'to'] as FormType[]).forEach((key) => {\n const configChainIds = chainsConfig?.[key]\n const isFromKey = key === 'from'\n\n // Convert configChainIds to Sets for O(1) lookup\n const configChainIdsSet = getConfigItemSets(\n configChainIds,\n (chainIds) => new Set(chainIds)\n )\n const filteredChains = chains.filter((chain) => {\n const passesChainsConfigFilter = configChainIdsSet\n ? isItemAllowedForSets(chain.id, configChainIdsSet)\n : true\n // If the integrator uses external wallet management and has not opted in for partial wallet management,\n // restrict the displayed chains to those compatible with external wallet management.\n // This ensures users only see chains for which they can sign transactions.\n const passesWalletConfigFilter = isFromKey\n ? !useExternalWalletProvidersOnly ||\n externalChainTypes.includes(chain.chainType)\n : true\n return passesChainsConfigFilter && passesWalletConfigFilter\n })\n\n const chainOrder = storeRef.current?.getState().initializeChains(\n filteredChains.map((chain) => chain.id),\n key\n )\n\n const isSwapTo = swapOnly && key === 'to'\n\n // Show \"All networks\" button if there are multiple networks\n const showAllNetworks =\n filteredChains.length > 1 && !hiddenUI?.allNetworks && !isSwapTo\n\n // Initialize the isAllNetworks with true if the tab is shown,\n // there is no config chain value and no url chain value\n const urlValues = getDefaultValuesFromQueryString({ buildUrl })\n const urlChainValue =\n key === 'from' ? urlValues.fromChain : urlValues.toChain\n const configChainValue =\n key === 'from' ? fromChainConfig : toChainConfig\n\n // A touched, empty chain field was cleared deliberately — \"All\n // networks\". It has to outrank the two values above, because both\n // still name the chain the page was opened on at that moment: the\n // query string is rewritten a commit later, and an integrator that\n // seeds its config from the URL never rewrites it.\n const [chainValue] = getFieldValues(`${key}Chain`)\n const clearedForAllNetworks = !chainValue && isTouched(`${key}Chain`)\n\n const initialIsAllNetworks =\n showAllNetworks &&\n (clearedForAllNetworks || (!configChainValue && !urlChainValue))\n storeRef.current?.getState().setIsAllNetworks(initialIsAllNetworks, key)\n storeRef.current?.getState().setShowAllNetworks(showAllNetworks, key)\n\n // Copying an empty source would alternate with the fallback below.\n if (isSwapTo) {\n const [fromChainValue] = getFieldValues('fromChain')\n if (fromChainValue) {\n if (fromChainValue !== chainValue) {\n setFieldValue('toChain', fromChainValue)\n }\n return\n }\n }\n\n // When \"All Networks\" is active, don't auto-select a chain from the\n // persisted chain order. This prevents stale cross-ecosystem selections\n // (e.g. EVM from + Solana to) from triggering the \"destination wallet\n // address required\" message after a page refresh.\n if (initialIsAllNetworks) {\n return\n }\n\n // With no source to follow, drop a destination the list no longer offers.\n const keepsChain =\n chainValue &&\n (!isSwapTo || filteredChains.some((chain) => chain.id === chainValue))\n if (keepsChain) {\n return\n }\n\n const firstAllowedPinnedChain = storeRef.current\n ?.getState()\n .pinnedChains?.find((chainId) =>\n filteredChains.some((chain) => chain.id === chainId)\n )\n if (\n variant === 'wide' &&\n !hiddenUI?.chainSidebar &&\n firstAllowedPinnedChain\n ) {\n setFieldValue(`${key}Chain`, firstAllowedPinnedChain)\n } else if (chainOrder?.length) {\n setFieldValue(`${key}Chain`, chainOrder[0])\n }\n })\n }\n }, [\n chains,\n chainsConfig,\n externalChainTypes,\n getFieldValues,\n isTouched,\n setFieldValue,\n useExternalWalletProvidersOnly,\n variant,\n hiddenUI,\n swapOnly,\n fromChainConfig,\n toChainConfig,\n buildUrl,\n ])\n\n return (\n <ChainOrderStoreContext value={storeRef.current}>\n {children}\n </ChainOrderStoreContext>\n )\n}\n\nfunction useChainOrderStoreContext() {\n const useStore = use(ChainOrderStoreContext)\n if (!useStore) {\n throw new Error(\n `You forgot to wrap your component in <${ChainOrderStoreProvider.name}>.`\n )\n }\n return useStore\n}\n\nexport function useChainOrderStore<T>(\n selector: (state: ChainOrderState) => T\n): T {\n const useStore = useChainOrderStoreContext()\n return useStore(useShallow(selector))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ChainOrderStore.js","names":[],"sources":["../../../../src/stores/chains/ChainOrderStore.tsx"],"sourcesContent":["import { createContext, type JSX, use, useEffect, useRef } from 'react'\nimport type { StoreApi, UseBoundStore } from 'zustand'\nimport { useShallow } from 'zustand/shallow'\nimport { useChains } from '../../hooks/useChains.js'\nimport { useSwapOnly } from '../../hooks/useSwapOnly.js'\nimport { useExternalWalletProvider } from '../../providers/WalletProvider/useExternalWalletProvider.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { getConfigItemSets, isItemAllowedForSets } from '../../utils/item.js'\nimport { getDefaultValuesFromQueryString } from '../form/getDefaultValuesFromQueryString.js'\nimport type { FormType } from '../form/types.js'\nimport { useFieldActions } from '../form/useFieldActions.js'\nimport type { PersistStoreProviderProps } from '../types.js'\nimport { createChainOrderStore } from './createChainOrderStore.js'\nimport type { ChainOrderState } from './types.js'\n\ntype ChainOrderStore = UseBoundStore<StoreApi<ChainOrderState>>\n\nconst ChainOrderStoreContext = createContext<ChainOrderStore | null>(null)\n\nexport function ChainOrderStoreProvider({\n children,\n ...props\n}: PersistStoreProviderProps): JSX.Element {\n const {\n chains: chainsConfig,\n hiddenUI,\n fromChain: fromChainConfig,\n toChain: toChainConfig,\n buildUrl,\n } = useWidgetConfig()\n const storeRef = useRef<ChainOrderStore>(null)\n const { chains } = useChains()\n const { setFieldValue, getFieldValues, isTouched } = useFieldActions()\n const swapOnly = useSwapOnly()\n const { variant } = useWidgetConfig()\n const { externalChainTypes, useExternalWalletProvidersOnly } =\n useExternalWalletProvider()\n\n if (!storeRef.current) {\n storeRef.current = createChainOrderStore({\n ...props,\n })\n }\n\n useEffect(() => {\n if (chains) {\n ;(['from', 'to'] as FormType[]).forEach((key) => {\n const configChainIds = chainsConfig?.[key]\n const isFromKey = key === 'from'\n\n // Convert configChainIds to Sets for O(1) lookup\n const configChainIdsSet = getConfigItemSets(\n configChainIds,\n (chainIds) => new Set(chainIds)\n )\n const filteredChains = chains.filter((chain) => {\n const passesChainsConfigFilter = configChainIdsSet\n ? isItemAllowedForSets(chain.id, configChainIdsSet)\n : true\n // If the integrator uses external wallet management and has not opted in for partial wallet management,\n // restrict the displayed chains to those compatible with external wallet management.\n // This ensures users only see chains for which they can sign transactions.\n const passesWalletConfigFilter = isFromKey\n ? !useExternalWalletProvidersOnly ||\n externalChainTypes.includes(chain.chainType)\n : true\n return passesChainsConfigFilter && passesWalletConfigFilter\n })\n\n const chainOrder = storeRef.current?.getState().initializeChains(\n filteredChains.map((chain) => chain.id),\n key\n )\n\n const isSwapTo = swapOnly && key === 'to'\n\n // Show \"All networks\" button if there are multiple networks\n const showAllNetworks =\n filteredChains.length > 1 && !hiddenUI?.allNetworks && !isSwapTo\n\n // Initialize the isAllNetworks with true if the tab is shown,\n // there is no config chain value and no url chain value\n const urlValues = getDefaultValuesFromQueryString({\n buildUrl,\n chains: chainsConfig,\n })\n const urlChainValue =\n key === 'from' ? urlValues.fromChain : urlValues.toChain\n const configChainValue =\n key === 'from' ? fromChainConfig : toChainConfig\n\n // A touched, empty chain field was cleared deliberately — \"All\n // networks\". It has to outrank the two values above, because both\n // still name the chain the page was opened on at that moment: the\n // query string is rewritten a commit later, and an integrator that\n // seeds its config from the URL never rewrites it.\n const [chainValue] = getFieldValues(`${key}Chain`)\n const clearedForAllNetworks = !chainValue && isTouched(`${key}Chain`)\n\n const initialIsAllNetworks =\n showAllNetworks &&\n (clearedForAllNetworks || (!configChainValue && !urlChainValue))\n storeRef.current?.getState().setIsAllNetworks(initialIsAllNetworks, key)\n storeRef.current?.getState().setShowAllNetworks(showAllNetworks, key)\n\n // Copying an empty source would alternate with the fallback below.\n if (isSwapTo) {\n const [fromChainValue] = getFieldValues('fromChain')\n if (fromChainValue) {\n if (fromChainValue !== chainValue) {\n setFieldValue('toChain', fromChainValue)\n }\n return\n }\n }\n\n // When \"All Networks\" is active, don't auto-select a chain from the\n // persisted chain order. This prevents stale cross-ecosystem selections\n // (e.g. EVM from + Solana to) from triggering the \"destination wallet\n // address required\" message after a page refresh.\n if (initialIsAllNetworks) {\n return\n }\n\n // With no source to follow, drop a destination the list no longer offers.\n const keepsChain =\n chainValue &&\n (!isSwapTo || filteredChains.some((chain) => chain.id === chainValue))\n if (keepsChain) {\n return\n }\n\n const firstAllowedPinnedChain = storeRef.current\n ?.getState()\n .pinnedChains?.find((chainId) =>\n filteredChains.some((chain) => chain.id === chainId)\n )\n if (\n variant === 'wide' &&\n !hiddenUI?.chainSidebar &&\n firstAllowedPinnedChain\n ) {\n setFieldValue(`${key}Chain`, firstAllowedPinnedChain)\n } else if (chainOrder?.length) {\n setFieldValue(`${key}Chain`, chainOrder[0])\n }\n })\n }\n }, [\n chains,\n chainsConfig,\n externalChainTypes,\n getFieldValues,\n isTouched,\n setFieldValue,\n useExternalWalletProvidersOnly,\n variant,\n hiddenUI,\n swapOnly,\n fromChainConfig,\n toChainConfig,\n buildUrl,\n ])\n\n return (\n <ChainOrderStoreContext value={storeRef.current}>\n {children}\n </ChainOrderStoreContext>\n )\n}\n\nfunction useChainOrderStoreContext() {\n const useStore = use(ChainOrderStoreContext)\n if (!useStore) {\n throw new Error(\n `You forgot to wrap your component in <${ChainOrderStoreProvider.name}>.`\n )\n }\n return useStore\n}\n\nexport function useChainOrderStore<T>(\n selector: (state: ChainOrderState) => T\n): T {\n const useStore = useChainOrderStoreContext()\n return useStore(useShallow(selector))\n}\n"],"mappings":";;;;;;;;;;;;AAiBA,MAAM,yBAAyB,cAAsC,IAAI;AAEzE,SAAgB,wBAAwB,EACtC,UACA,GAAG,SACsC;CACzC,MAAM,EACJ,QAAQ,cACR,UACA,WAAW,iBACX,SAAS,eACT,aACE,gBAAgB;CACpB,MAAM,WAAW,OAAwB,IAAI;CAC7C,MAAM,EAAE,WAAW,UAAU;CAC7B,MAAM,EAAE,eAAe,gBAAgB,cAAc,gBAAgB;CACrE,MAAM,WAAW,YAAY;CAC7B,MAAM,EAAE,YAAY,gBAAgB;CACpC,MAAM,EAAE,oBAAoB,mCAC1B,0BAA0B;CAE5B,IAAI,CAAC,SAAS,SACZ,SAAS,UAAU,sBAAsB,EACvC,GAAG,MACL,CAAC;CAGH,gBAAgB;EACd,IAAI,QACD,CAAE,QAAQ,IAAI,CAAC,CAAgB,SAAS,QAAQ;GAC/C,MAAM,iBAAiB,eAAe;GACtC,MAAM,YAAY,QAAQ;GAG1B,MAAM,oBAAoB,kBACxB,iBACC,aAAa,IAAI,IAAI,QAAQ,CAChC;GACA,MAAM,iBAAiB,OAAO,QAAQ,UAAU;IAC9C,MAAM,2BAA2B,oBAC7B,qBAAqB,MAAM,IAAI,iBAAiB,IAChD;IAIJ,MAAM,2BAA2B,YAC7B,CAAC,kCACD,mBAAmB,SAAS,MAAM,SAAS,IAC3C;IACJ,OAAO,4BAA4B;GACrC,CAAC;GAED,MAAM,aAAa,SAAS,SAAS,SAAS,CAAC,CAAC,iBAC9C,eAAe,KAAK,UAAU,MAAM,EAAE,GACtC,GACF;GAEA,MAAM,WAAW,YAAY,QAAQ;GAGrC,MAAM,kBACJ,eAAe,SAAS,KAAK,CAAC,UAAU,eAAe,CAAC;GAI1D,MAAM,YAAY,gCAAgC;IAChD;IACA,QAAQ;GACV,CAAC;GACD,MAAM,gBACJ,QAAQ,SAAS,UAAU,YAAY,UAAU;GACnD,MAAM,mBACJ,QAAQ,SAAS,kBAAkB;GAOrC,MAAM,CAAC,cAAc,eAAe,GAAG,IAAI,MAAM;GACjD,MAAM,wBAAwB,CAAC,cAAc,UAAU,GAAG,IAAI,MAAM;GAEpE,MAAM,uBACJ,oBACC,yBAA0B,CAAC,oBAAoB,CAAC;GACnD,SAAS,SAAS,SAAS,CAAC,CAAC,iBAAiB,sBAAsB,GAAG;GACvE,SAAS,SAAS,SAAS,CAAC,CAAC,mBAAmB,iBAAiB,GAAG;GAGpE,IAAI,UAAU;IACZ,MAAM,CAAC,kBAAkB,eAAe,WAAW;IACnD,IAAI,gBAAgB;KAClB,IAAI,mBAAmB,YACrB,cAAc,WAAW,cAAc;KAEzC;IACF;GACF;GAMA,IAAI,sBACF;GAOF,IAFE,eACC,CAAC,YAAY,eAAe,MAAM,UAAU,MAAM,OAAO,UAAU,IAEpE;GAGF,MAAM,0BAA0B,SAAS,SACrC,SAAS,CAAC,CACX,cAAc,MAAM,YACnB,eAAe,MAAM,UAAU,MAAM,OAAO,OAAO,CACrD;GACF,IACE,YAAY,UACZ,CAAC,UAAU,gBACX,yBAEA,cAAc,GAAG,IAAI,QAAQ,uBAAuB;QAC/C,IAAI,YAAY,QACrB,cAAc,GAAG,IAAI,QAAQ,WAAW,EAAE;EAE9C,CAAC;CAEL,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,OACE,oBAAC,wBAAD;EAAwB,OAAO,SAAS;EACrC;CACqB,CAAA;AAE5B;AAEA,SAAS,4BAA4B;CACnC,MAAM,WAAW,IAAI,sBAAsB;CAC3C,IAAI,CAAC,UACH,MAAM,IAAI,MACR,yCAAyC,wBAAwB,KAAK,GACxE;CAEF,OAAO;AACT;AAEA,SAAgB,mBACd,UACG;CAEH,OADiB,0BACH,CAAC,CAAC,WAAW,QAAQ,CAAC;AACtC"}
@@ -16,7 +16,7 @@ const initialiseDefaultValues = (defaultValues) => ({
16
16
  });
17
17
  const FormStoreProvider = ({ children, formRef }) => {
18
18
  const widgetConfig = useWidgetConfig();
19
- const { fromChain, fromToken, toChain, toToken, fromAmount, toAmount, toAddress, formUpdateKey, buildUrl } = widgetConfig;
19
+ const { fromChain, fromToken, toChain, toToken, fromAmount, toAmount, toAddress, formUpdateKey, buildUrl, chains } = widgetConfig;
20
20
  const storeRef = useRef(null);
21
21
  const configHasFromChain = Object.hasOwn(widgetConfig, "fromChain");
22
22
  const configHasFromToken = Object.hasOwn(widgetConfig, "fromToken");
@@ -53,7 +53,8 @@ const FormStoreProvider = ({ children, formRef }) => {
53
53
  if (!storeRef.current) {
54
54
  const queryDefaults = getDefaultValuesFromQueryString({
55
55
  buildUrl,
56
- includeToAddress: false
56
+ includeToAddress: false,
57
+ chains
57
58
  });
58
59
  storeRef.current = createFormStore(initialiseDefaultValues({
59
60
  ...reactiveFormValues,
@@ -1 +1 @@
1
- {"version":3,"file":"FormStore.js","names":[],"sources":["../../../../src/stores/form/FormStore.tsx"],"sourcesContent":["import type { PropsWithChildren } from 'react'\nimport { useMemo, useRef } from 'react'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormRef } from '../../types/widget.js'\nimport { createFormStore, formDefaultValues } from './createFormStore.js'\nimport { FormStoreContext } from './FormStoreContext.js'\nimport { FormUpdater } from './FormUpdater.js'\nimport { getDefaultValuesFromQueryString } from './getDefaultValuesFromQueryString.js'\nimport type { DefaultValues, FormStoreStore } from './types.js'\nimport { useFormRef } from './useFormRef.js'\n\n// decorates and initialise the form date for use in the form store\nconst initialiseDefaultValues = (defaultValues: Partial<DefaultValues>) => ({\n ...formDefaultValues,\n ...defaultValues,\n fromAmount:\n (typeof defaultValues.fromAmount === 'number'\n ? (defaultValues.fromAmount as number)?.toPrecision?.()\n : defaultValues.fromAmount) || formDefaultValues.fromAmount,\n toAmount:\n (typeof defaultValues.toAmount === 'number'\n ? (defaultValues.toAmount as number)?.toPrecision?.()\n : defaultValues.toAmount) || formDefaultValues.toAmount,\n // Prevent setting address when the field is hidden\n toAddress: defaultValues.toAddress || formDefaultValues.toAddress,\n})\n\ninterface FormStoreProviderProps extends PropsWithChildren {\n formRef?: FormRef\n}\n\nexport const FormStoreProvider: React.FC<FormStoreProviderProps> = ({\n children,\n formRef,\n}) => {\n const widgetConfig = useWidgetConfig()\n\n const {\n fromChain,\n fromToken,\n toChain,\n toToken,\n fromAmount,\n toAmount,\n toAddress,\n formUpdateKey,\n buildUrl,\n } = widgetConfig\n\n const storeRef = useRef<FormStoreStore>(null)\n\n const configHasFromChain = Object.hasOwn(widgetConfig, 'fromChain')\n const configHasFromToken = Object.hasOwn(widgetConfig, 'fromToken')\n const configHasFromAmount = Object.hasOwn(widgetConfig, 'fromAmount')\n const configHasToAmount = Object.hasOwn(widgetConfig, 'toAmount')\n const configHasToAddress = Object.hasOwn(widgetConfig, 'toAddress')\n const configHasToChain = Object.hasOwn(widgetConfig, 'toChain')\n const configHasToToken = Object.hasOwn(widgetConfig, 'toToken')\n\n // We use the presence/absence of a property to decide if the form values in state need to be updated\n // We only build and set a property on the memoized form values here if they are included in the\n // config - undefined is considered a valid value that will reset that form field\n // biome-ignore lint/correctness/useExhaustiveDependencies: formUpdateKey is needed here.\n const reactiveFormValues = useMemo(\n () => ({\n ...(configHasFromChain ? { fromChain } : undefined),\n ...(configHasFromToken ? { fromToken } : undefined),\n ...(configHasFromAmount\n ? {\n fromAmount:\n (typeof fromAmount === 'number'\n ? fromAmount?.toPrecision()\n : fromAmount) || formDefaultValues.fromAmount,\n }\n : undefined),\n ...(configHasToAmount\n ? {\n toAmount:\n (typeof toAmount === 'number'\n ? toAmount?.toPrecision()\n : toAmount) || formDefaultValues.toAmount,\n }\n : undefined),\n ...(configHasToChain ? { toChain } : undefined),\n ...(configHasToToken ? { toToken } : undefined),\n ...(configHasToAddress\n ? {\n toAddress: toAddress?.address || formDefaultValues.toAddress,\n }\n : undefined),\n }),\n [\n fromAmount,\n toAmount,\n fromChain,\n fromToken,\n toAddress,\n toChain,\n toToken,\n // formUpdateKey should be a randomly assigned unique key. It can be used to force updates for the form field values\n formUpdateKey,\n configHasFromChain,\n configHasFromToken,\n configHasFromAmount,\n configHasToAmount,\n configHasToAddress,\n configHasToChain,\n configHasToToken,\n ]\n )\n\n if (!storeRef.current) {\n const queryDefaults = getDefaultValuesFromQueryString({\n buildUrl,\n includeToAddress: false,\n })\n storeRef.current = createFormStore(\n initialiseDefaultValues({\n ...reactiveFormValues,\n ...queryDefaults,\n })\n )\n }\n\n useFormRef(storeRef.current, formRef)\n\n return (\n <FormStoreContext value={storeRef.current}>\n {children}\n <FormUpdater reactiveFormValues={reactiveFormValues} />\n </FormStoreContext>\n )\n}\n"],"mappings":";;;;;;;;;AAYA,MAAM,2BAA2B,mBAA2C;CAC1E,GAAG;CACH,GAAG;CACH,aACG,OAAO,cAAc,eAAe,WAChC,cAAc,YAAuB,cAAc,IACpD,cAAc,eAAe,kBAAkB;CACrD,WACG,OAAO,cAAc,aAAa,WAC9B,cAAc,UAAqB,cAAc,IAClD,cAAc,aAAa,kBAAkB;CAEnD,WAAW,cAAc,aAAa,kBAAkB;AAC1D;AAMA,MAAa,qBAAuD,EAClE,UACA,cACI;CACJ,MAAM,eAAe,gBAAgB;CAErC,MAAM,EACJ,WACA,WACA,SACA,SACA,YACA,UACA,WACA,eACA,aACE;CAEJ,MAAM,WAAW,OAAuB,IAAI;CAE5C,MAAM,qBAAqB,OAAO,OAAO,cAAc,WAAW;CAClE,MAAM,qBAAqB,OAAO,OAAO,cAAc,WAAW;CAClE,MAAM,sBAAsB,OAAO,OAAO,cAAc,YAAY;CACpE,MAAM,oBAAoB,OAAO,OAAO,cAAc,UAAU;CAChE,MAAM,qBAAqB,OAAO,OAAO,cAAc,WAAW;CAClE,MAAM,mBAAmB,OAAO,OAAO,cAAc,SAAS;CAC9D,MAAM,mBAAmB,OAAO,OAAO,cAAc,SAAS;CAM9D,MAAM,qBAAqB,eAClB;EACL,GAAI,qBAAqB,EAAE,UAAU,IAAI,KAAA;EACzC,GAAI,qBAAqB,EAAE,UAAU,IAAI,KAAA;EACzC,GAAI,sBACA,EACE,aACG,OAAO,eAAe,WACnB,YAAY,YAAY,IACxB,eAAe,kBAAkB,WACzC,IACA,KAAA;EACJ,GAAI,oBACA,EACE,WACG,OAAO,aAAa,WACjB,UAAU,YAAY,IACtB,aAAa,kBAAkB,SACvC,IACA,KAAA;EACJ,GAAI,mBAAmB,EAAE,QAAQ,IAAI,KAAA;EACrC,GAAI,mBAAmB,EAAE,QAAQ,IAAI,KAAA;EACrC,GAAI,qBACA,EACE,WAAW,WAAW,WAAW,kBAAkB,UACrD,IACA,KAAA;CACN,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,IAAI,CAAC,SAAS,SAAS;EACrB,MAAM,gBAAgB,gCAAgC;GACpD;GACA,kBAAkB;EACpB,CAAC;EACD,SAAS,UAAU,gBACjB,wBAAwB;GACtB,GAAG;GACH,GAAG;EACL,CAAC,CACH;CACF;CAEA,WAAW,SAAS,SAAS,OAAO;CAEpC,OACE,qBAAC,kBAAD;EAAkB,OAAO,SAAS;EAAlC,UAAA,CACG,UACD,oBAAC,aAAD,EAAiC,mBAAqB,CAAA,CACtC;;AAEtB"}
1
+ {"version":3,"file":"FormStore.js","names":[],"sources":["../../../../src/stores/form/FormStore.tsx"],"sourcesContent":["import type { PropsWithChildren } from 'react'\nimport { useMemo, useRef } from 'react'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormRef } from '../../types/widget.js'\nimport { createFormStore, formDefaultValues } from './createFormStore.js'\nimport { FormStoreContext } from './FormStoreContext.js'\nimport { FormUpdater } from './FormUpdater.js'\nimport { getDefaultValuesFromQueryString } from './getDefaultValuesFromQueryString.js'\nimport type { DefaultValues, FormStoreStore } from './types.js'\nimport { useFormRef } from './useFormRef.js'\n\n// decorates and initialise the form date for use in the form store\nconst initialiseDefaultValues = (defaultValues: Partial<DefaultValues>) => ({\n ...formDefaultValues,\n ...defaultValues,\n fromAmount:\n (typeof defaultValues.fromAmount === 'number'\n ? (defaultValues.fromAmount as number)?.toPrecision?.()\n : defaultValues.fromAmount) || formDefaultValues.fromAmount,\n toAmount:\n (typeof defaultValues.toAmount === 'number'\n ? (defaultValues.toAmount as number)?.toPrecision?.()\n : defaultValues.toAmount) || formDefaultValues.toAmount,\n // Prevent setting address when the field is hidden\n toAddress: defaultValues.toAddress || formDefaultValues.toAddress,\n})\n\ninterface FormStoreProviderProps extends PropsWithChildren {\n formRef?: FormRef\n}\n\nexport const FormStoreProvider: React.FC<FormStoreProviderProps> = ({\n children,\n formRef,\n}) => {\n const widgetConfig = useWidgetConfig()\n\n const {\n fromChain,\n fromToken,\n toChain,\n toToken,\n fromAmount,\n toAmount,\n toAddress,\n formUpdateKey,\n buildUrl,\n chains,\n } = widgetConfig\n\n const storeRef = useRef<FormStoreStore>(null)\n\n const configHasFromChain = Object.hasOwn(widgetConfig, 'fromChain')\n const configHasFromToken = Object.hasOwn(widgetConfig, 'fromToken')\n const configHasFromAmount = Object.hasOwn(widgetConfig, 'fromAmount')\n const configHasToAmount = Object.hasOwn(widgetConfig, 'toAmount')\n const configHasToAddress = Object.hasOwn(widgetConfig, 'toAddress')\n const configHasToChain = Object.hasOwn(widgetConfig, 'toChain')\n const configHasToToken = Object.hasOwn(widgetConfig, 'toToken')\n\n // We use the presence/absence of a property to decide if the form values in state need to be updated\n // We only build and set a property on the memoized form values here if they are included in the\n // config - undefined is considered a valid value that will reset that form field\n // biome-ignore lint/correctness/useExhaustiveDependencies: formUpdateKey is needed here.\n const reactiveFormValues = useMemo(\n () => ({\n ...(configHasFromChain ? { fromChain } : undefined),\n ...(configHasFromToken ? { fromToken } : undefined),\n ...(configHasFromAmount\n ? {\n fromAmount:\n (typeof fromAmount === 'number'\n ? fromAmount?.toPrecision()\n : fromAmount) || formDefaultValues.fromAmount,\n }\n : undefined),\n ...(configHasToAmount\n ? {\n toAmount:\n (typeof toAmount === 'number'\n ? toAmount?.toPrecision()\n : toAmount) || formDefaultValues.toAmount,\n }\n : undefined),\n ...(configHasToChain ? { toChain } : undefined),\n ...(configHasToToken ? { toToken } : undefined),\n ...(configHasToAddress\n ? {\n toAddress: toAddress?.address || formDefaultValues.toAddress,\n }\n : undefined),\n }),\n [\n fromAmount,\n toAmount,\n fromChain,\n fromToken,\n toAddress,\n toChain,\n toToken,\n // formUpdateKey should be a randomly assigned unique key. It can be used to force updates for the form field values\n formUpdateKey,\n configHasFromChain,\n configHasFromToken,\n configHasFromAmount,\n configHasToAmount,\n configHasToAddress,\n configHasToChain,\n configHasToToken,\n ]\n )\n\n if (!storeRef.current) {\n const queryDefaults = getDefaultValuesFromQueryString({\n buildUrl,\n includeToAddress: false,\n chains,\n })\n storeRef.current = createFormStore(\n initialiseDefaultValues({\n ...reactiveFormValues,\n ...queryDefaults,\n })\n )\n }\n\n useFormRef(storeRef.current, formRef)\n\n return (\n <FormStoreContext value={storeRef.current}>\n {children}\n <FormUpdater reactiveFormValues={reactiveFormValues} />\n </FormStoreContext>\n )\n}\n"],"mappings":";;;;;;;;;AAYA,MAAM,2BAA2B,mBAA2C;CAC1E,GAAG;CACH,GAAG;CACH,aACG,OAAO,cAAc,eAAe,WAChC,cAAc,YAAuB,cAAc,IACpD,cAAc,eAAe,kBAAkB;CACrD,WACG,OAAO,cAAc,aAAa,WAC9B,cAAc,UAAqB,cAAc,IAClD,cAAc,aAAa,kBAAkB;CAEnD,WAAW,cAAc,aAAa,kBAAkB;AAC1D;AAMA,MAAa,qBAAuD,EAClE,UACA,cACI;CACJ,MAAM,eAAe,gBAAgB;CAErC,MAAM,EACJ,WACA,WACA,SACA,SACA,YACA,UACA,WACA,eACA,UACA,WACE;CAEJ,MAAM,WAAW,OAAuB,IAAI;CAE5C,MAAM,qBAAqB,OAAO,OAAO,cAAc,WAAW;CAClE,MAAM,qBAAqB,OAAO,OAAO,cAAc,WAAW;CAClE,MAAM,sBAAsB,OAAO,OAAO,cAAc,YAAY;CACpE,MAAM,oBAAoB,OAAO,OAAO,cAAc,UAAU;CAChE,MAAM,qBAAqB,OAAO,OAAO,cAAc,WAAW;CAClE,MAAM,mBAAmB,OAAO,OAAO,cAAc,SAAS;CAC9D,MAAM,mBAAmB,OAAO,OAAO,cAAc,SAAS;CAM9D,MAAM,qBAAqB,eAClB;EACL,GAAI,qBAAqB,EAAE,UAAU,IAAI,KAAA;EACzC,GAAI,qBAAqB,EAAE,UAAU,IAAI,KAAA;EACzC,GAAI,sBACA,EACE,aACG,OAAO,eAAe,WACnB,YAAY,YAAY,IACxB,eAAe,kBAAkB,WACzC,IACA,KAAA;EACJ,GAAI,oBACA,EACE,WACG,OAAO,aAAa,WACjB,UAAU,YAAY,IACtB,aAAa,kBAAkB,SACvC,IACA,KAAA;EACJ,GAAI,mBAAmB,EAAE,QAAQ,IAAI,KAAA;EACrC,GAAI,mBAAmB,EAAE,QAAQ,IAAI,KAAA;EACrC,GAAI,qBACA,EACE,WAAW,WAAW,WAAW,kBAAkB,UACrD,IACA,KAAA;CACN,IACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CACF;CAEA,IAAI,CAAC,SAAS,SAAS;EACrB,MAAM,gBAAgB,gCAAgC;GACpD;GACA,kBAAkB;GAClB;EACF,CAAC;EACD,SAAS,UAAU,gBACjB,wBAAwB;GACtB,GAAG;GACH,GAAG;EACL,CAAC,CACH;CACF;CAEA,WAAW,SAAS,SAAS,OAAO;CAEpC,OACE,qBAAC,kBAAD;EAAkB,OAAO,SAAS;EAAlC,UAAA,CACG,UACD,oBAAC,aAAD,EAAiC,mBAAqB,CAAA,CACtC;;AAEtB"}
@@ -27,10 +27,13 @@ const URLSearchParamsBuilder = () => {
27
27
  const values = useFieldValues(...formValueKeys, ...limitFormValueKeys);
28
28
  const { setSelectedBookmark, addRecentWallet } = useBookmarkActions();
29
29
  const { validateAddress } = useAddressValidation();
30
- const { buildUrl, mode } = useWidgetConfig();
30
+ const { buildUrl, mode, chains } = useWidgetConfig();
31
31
  const { getFieldValues, isTouched, setUserAndDefaultValues } = useFieldActions();
32
32
  useEffect(() => {
33
- const { toAddress, ...initialFormValues } = getDefaultValuesFromQueryString({ buildUrl });
33
+ const { toAddress, ...initialFormValues } = getDefaultValuesFromQueryString({
34
+ buildUrl,
35
+ chains
36
+ });
34
37
  /**
35
38
  * When URL builder is enabled and user opens a page with toAddress parameter,
36
39
  * validate the address and set it up as a bookmark. This allows direct linking
@@ -43,7 +46,8 @@ const URLSearchParamsBuilder = () => {
43
46
  if (validationResult.isValid && toAddress) {
44
47
  const bookmark = {
45
48
  address: validationResult.address,
46
- chainType: validationResult.chainType
49
+ chainType: validationResult.chainType,
50
+ chainId: validationResult.chainId
47
51
  };
48
52
  setUserAndDefaultValues({ toAddress });
49
53
  setSelectedBookmark(bookmark);
@@ -1 +1 @@
1
- {"version":3,"file":"URLSearchParamsBuilder.js","names":[],"sources":["../../../../src/stores/form/URLSearchParamsBuilder.tsx"],"sourcesContent":["import { useLocation } from '@tanstack/react-router'\nimport { useEffect } from 'react'\nimport { useAddressValidation } from '../../hooks/useAddressValidation.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useBookmarkActions } from '../bookmarks/useBookmarkActions.js'\nimport type { FormFieldNames } from '../form/types.js'\nimport { useFieldActions } from '../form/useFieldActions.js'\nimport { useFieldValues } from '../form/useFieldValues.js'\nimport { useTouchedFields } from '../form/useTouchedFields.js'\nimport { getDefaultValuesFromQueryString } from './getDefaultValuesFromQueryString.js'\n\nconst formValueKeys: FormFieldNames[] = [\n 'fromAmount',\n 'fromChain',\n 'fromToken',\n 'toAddress',\n 'toChain',\n 'toToken',\n]\n\n// Limit-order params are only mirrored to the URL while the limit tab is\n// active, and stripped when the user leaves it. Unlike the base keys these are\n// presence-gated (not touched-gated) so the URL fully reproduces the limit\n// order — including the boolean/number fields, which are never \"falsy-empty\".\nconst limitFormValueKeys: FormFieldNames[] = [\n 'toAmount',\n 'validUntil',\n 'partiallyFillable',\n]\n\nexport const URLSearchParamsBuilder = () => {\n const { pathname } = useLocation()\n const touchedFields = useTouchedFields()\n const values = useFieldValues(...formValueKeys, ...limitFormValueKeys)\n const { setSelectedBookmark, addRecentWallet } = useBookmarkActions()\n const { validateAddress } = useAddressValidation()\n const { buildUrl, mode } = useWidgetConfig()\n // Using these methods as trying to use the touchedFields and values above\n // often has a lag that can effect the widgets initialisation sequence\n // and accidentally cause values to be wiped from the query string\n const { getFieldValues, isTouched, setUserAndDefaultValues } =\n useFieldActions()\n\n useEffect(() => {\n // get the initial values from the querystring\n const formValues = getDefaultValuesFromQueryString({ buildUrl })\n const { toAddress, ...initialFormValues } = formValues\n\n /**\n * When URL builder is enabled and user opens a page with toAddress parameter,\n * validate the address and set it up as a bookmark. This allows direct linking\n * to the widget with a pre-filled destination address that will be treated the\n * same way as a manually entered and validated address.\n */\n const initializeFromAddress = async () => {\n if (toAddress) {\n try {\n const validationResult = await validateAddress({\n value: toAddress,\n })\n if (validationResult.isValid && toAddress) {\n const bookmark = {\n address: validationResult.address,\n chainType: validationResult.chainType,\n }\n setUserAndDefaultValues({ toAddress })\n setSelectedBookmark(bookmark)\n addRecentWallet(bookmark)\n }\n } catch (_) {\n // Address validation failed\n }\n }\n }\n\n setUserAndDefaultValues(initialFormValues)\n initializeFromAddress()\n }, [\n setUserAndDefaultValues,\n validateAddress,\n setSelectedBookmark,\n addRecentWallet,\n buildUrl,\n ])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when pathname changes\n useEffect(() => {\n // set the values on the querysting\n const url = new URL(window.location as any)\n formValueKeys.forEach((key, _index) => {\n const value = getFieldValues(key)[0]\n if (isTouched(key) && value) {\n url.searchParams.set(key, value.toString())\n } else if (url.searchParams.has(key) && !value) {\n url.searchParams.delete(key)\n }\n })\n // Limit params live in the URL only while the limit tab is active.\n limitFormValueKeys.forEach((key) => {\n const value = getFieldValues(key)[0]\n // Booleans are always \"set\" (false is meaningful); strings/numbers use\n // truthiness so an empty toAmount is treated as absent.\n const hasValue = typeof value === 'boolean' ? true : Boolean(value)\n if (mode === 'limit' && hasValue) {\n url.searchParams.set(key, String(value))\n } else {\n url.searchParams.delete(key)\n }\n })\n url.searchParams.sort()\n window.history.replaceState(window.history.state, '', url)\n }, [pathname, touchedFields, values, isTouched, getFieldValues, mode])\n\n return null\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAM,gBAAkC;CACtC;CACA;CACA;CACA;CACA;CACA;AACF;AAMA,MAAM,qBAAuC;CAC3C;CACA;CACA;AACF;AAEA,MAAa,+BAA+B;CAC1C,MAAM,EAAE,aAAa,YAAY;CACjC,MAAM,gBAAgB,iBAAiB;CACvC,MAAM,SAAS,eAAe,GAAG,eAAe,GAAG,kBAAkB;CACrE,MAAM,EAAE,qBAAqB,oBAAoB,mBAAmB;CACpE,MAAM,EAAE,oBAAoB,qBAAqB;CACjD,MAAM,EAAE,UAAU,SAAS,gBAAgB;CAI3C,MAAM,EAAE,gBAAgB,WAAW,4BACjC,gBAAgB;CAElB,gBAAgB;EAGd,MAAM,EAAE,WAAW,GAAG,sBADH,gCAAgC,EAAE,SAAS,CACT;;;;;;;EAQrD,MAAM,wBAAwB,YAAY;GACxC,IAAI,WACF,IAAI;IACF,MAAM,mBAAmB,MAAM,gBAAgB,EAC7C,OAAO,UACT,CAAC;IACD,IAAI,iBAAiB,WAAW,WAAW;KACzC,MAAM,WAAW;MACf,SAAS,iBAAiB;MAC1B,WAAW,iBAAiB;KAC9B;KACA,wBAAwB,EAAE,UAAU,CAAC;KACrC,oBAAoB,QAAQ;KAC5B,gBAAgB,QAAQ;IAC1B;GACF,SAAS,GAAG,CAEZ;EAEJ;EAEA,wBAAwB,iBAAiB;EACzC,sBAAsB;CACxB,GAAG;EACD;EACA;EACA;EACA;EACA;CACF,CAAC;CAGD,gBAAgB;EAEd,MAAM,MAAM,IAAI,IAAI,OAAO,QAAe;EAC1C,cAAc,SAAS,KAAK,WAAW;GACrC,MAAM,QAAQ,eAAe,GAAG,CAAC,CAAC;GAClC,IAAI,UAAU,GAAG,KAAK,OACpB,IAAI,aAAa,IAAI,KAAK,MAAM,SAAS,CAAC;QACrC,IAAI,IAAI,aAAa,IAAI,GAAG,KAAK,CAAC,OACvC,IAAI,aAAa,OAAO,GAAG;EAE/B,CAAC;EAED,mBAAmB,SAAS,QAAQ;GAClC,MAAM,QAAQ,eAAe,GAAG,CAAC,CAAC;GAIlC,IAAI,SAAS,YADI,OAAO,UAAU,YAAY,OAAO,QAAQ,KAAK,IAEhE,IAAI,aAAa,IAAI,KAAK,OAAO,KAAK,CAAC;QAEvC,IAAI,aAAa,OAAO,GAAG;EAE/B,CAAC;EACD,IAAI,aAAa,KAAK;EACtB,OAAO,QAAQ,aAAa,OAAO,QAAQ,OAAO,IAAI,GAAG;CAC3D,GAAG;EAAC;EAAU;EAAe;EAAQ;EAAW;EAAgB;CAAI,CAAC;CAErE,OAAO;AACT"}
1
+ {"version":3,"file":"URLSearchParamsBuilder.js","names":[],"sources":["../../../../src/stores/form/URLSearchParamsBuilder.tsx"],"sourcesContent":["import { useLocation } from '@tanstack/react-router'\nimport { useEffect } from 'react'\nimport { useAddressValidation } from '../../hooks/useAddressValidation.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useBookmarkActions } from '../bookmarks/useBookmarkActions.js'\nimport type { FormFieldNames } from '../form/types.js'\nimport { useFieldActions } from '../form/useFieldActions.js'\nimport { useFieldValues } from '../form/useFieldValues.js'\nimport { useTouchedFields } from '../form/useTouchedFields.js'\nimport { getDefaultValuesFromQueryString } from './getDefaultValuesFromQueryString.js'\n\nconst formValueKeys: FormFieldNames[] = [\n 'fromAmount',\n 'fromChain',\n 'fromToken',\n 'toAddress',\n 'toChain',\n 'toToken',\n]\n\n// Limit-order params are only mirrored to the URL while the limit tab is\n// active, and stripped when the user leaves it. Unlike the base keys these are\n// presence-gated (not touched-gated) so the URL fully reproduces the limit\n// order — including the boolean/number fields, which are never \"falsy-empty\".\nconst limitFormValueKeys: FormFieldNames[] = [\n 'toAmount',\n 'validUntil',\n 'partiallyFillable',\n]\n\nexport const URLSearchParamsBuilder = () => {\n const { pathname } = useLocation()\n const touchedFields = useTouchedFields()\n const values = useFieldValues(...formValueKeys, ...limitFormValueKeys)\n const { setSelectedBookmark, addRecentWallet } = useBookmarkActions()\n const { validateAddress } = useAddressValidation()\n const { buildUrl, mode, chains } = useWidgetConfig()\n // Using these methods as trying to use the touchedFields and values above\n // often has a lag that can effect the widgets initialisation sequence\n // and accidentally cause values to be wiped from the query string\n const { getFieldValues, isTouched, setUserAndDefaultValues } =\n useFieldActions()\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: the URL is read once, not again on each config render\n useEffect(() => {\n // get the initial values from the querystring\n const formValues = getDefaultValuesFromQueryString({ buildUrl, chains })\n const { toAddress, ...initialFormValues } = formValues\n\n /**\n * When URL builder is enabled and user opens a page with toAddress parameter,\n * validate the address and set it up as a bookmark. This allows direct linking\n * to the widget with a pre-filled destination address that will be treated the\n * same way as a manually entered and validated address.\n */\n const initializeFromAddress = async () => {\n if (toAddress) {\n try {\n const validationResult = await validateAddress({\n value: toAddress,\n })\n if (validationResult.isValid && toAddress) {\n const bookmark = {\n address: validationResult.address,\n chainType: validationResult.chainType,\n chainId: validationResult.chainId,\n }\n setUserAndDefaultValues({ toAddress })\n setSelectedBookmark(bookmark)\n addRecentWallet(bookmark)\n }\n } catch (_) {\n // Address validation failed\n }\n }\n }\n\n setUserAndDefaultValues(initialFormValues)\n initializeFromAddress()\n }, [\n setUserAndDefaultValues,\n validateAddress,\n setSelectedBookmark,\n addRecentWallet,\n buildUrl,\n ])\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: run only when pathname changes\n useEffect(() => {\n // set the values on the querysting\n const url = new URL(window.location as any)\n formValueKeys.forEach((key, _index) => {\n const value = getFieldValues(key)[0]\n if (isTouched(key) && value) {\n url.searchParams.set(key, value.toString())\n } else if (url.searchParams.has(key) && !value) {\n url.searchParams.delete(key)\n }\n })\n // Limit params live in the URL only while the limit tab is active.\n limitFormValueKeys.forEach((key) => {\n const value = getFieldValues(key)[0]\n // Booleans are always \"set\" (false is meaningful); strings/numbers use\n // truthiness so an empty toAmount is treated as absent.\n const hasValue = typeof value === 'boolean' ? true : Boolean(value)\n if (mode === 'limit' && hasValue) {\n url.searchParams.set(key, String(value))\n } else {\n url.searchParams.delete(key)\n }\n })\n url.searchParams.sort()\n window.history.replaceState(window.history.state, '', url)\n }, [pathname, touchedFields, values, isTouched, getFieldValues, mode])\n\n return null\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAM,gBAAkC;CACtC;CACA;CACA;CACA;CACA;CACA;AACF;AAMA,MAAM,qBAAuC;CAC3C;CACA;CACA;AACF;AAEA,MAAa,+BAA+B;CAC1C,MAAM,EAAE,aAAa,YAAY;CACjC,MAAM,gBAAgB,iBAAiB;CACvC,MAAM,SAAS,eAAe,GAAG,eAAe,GAAG,kBAAkB;CACrE,MAAM,EAAE,qBAAqB,oBAAoB,mBAAmB;CACpE,MAAM,EAAE,oBAAoB,qBAAqB;CACjD,MAAM,EAAE,UAAU,MAAM,WAAW,gBAAgB;CAInD,MAAM,EAAE,gBAAgB,WAAW,4BACjC,gBAAgB;CAGlB,gBAAgB;EAGd,MAAM,EAAE,WAAW,GAAG,sBADH,gCAAgC;GAAE;GAAU;EAAO,CACjB;;;;;;;EAQrD,MAAM,wBAAwB,YAAY;GACxC,IAAI,WACF,IAAI;IACF,MAAM,mBAAmB,MAAM,gBAAgB,EAC7C,OAAO,UACT,CAAC;IACD,IAAI,iBAAiB,WAAW,WAAW;KACzC,MAAM,WAAW;MACf,SAAS,iBAAiB;MAC1B,WAAW,iBAAiB;MAC5B,SAAS,iBAAiB;KAC5B;KACA,wBAAwB,EAAE,UAAU,CAAC;KACrC,oBAAoB,QAAQ;KAC5B,gBAAgB,QAAQ;IAC1B;GACF,SAAS,GAAG,CAEZ;EAEJ;EAEA,wBAAwB,iBAAiB;EACzC,sBAAsB;CACxB,GAAG;EACD;EACA;EACA;EACA;EACA;CACF,CAAC;CAGD,gBAAgB;EAEd,MAAM,MAAM,IAAI,IAAI,OAAO,QAAe;EAC1C,cAAc,SAAS,KAAK,WAAW;GACrC,MAAM,QAAQ,eAAe,GAAG,CAAC,CAAC;GAClC,IAAI,UAAU,GAAG,KAAK,OACpB,IAAI,aAAa,IAAI,KAAK,MAAM,SAAS,CAAC;QACrC,IAAI,IAAI,aAAa,IAAI,GAAG,KAAK,CAAC,OACvC,IAAI,aAAa,OAAO,GAAG;EAE/B,CAAC;EAED,mBAAmB,SAAS,QAAQ;GAClC,MAAM,QAAQ,eAAe,GAAG,CAAC,CAAC;GAIlC,IAAI,SAAS,YADI,OAAO,UAAU,YAAY,OAAO,QAAQ,KAAK,IAEhE,IAAI,aAAa,IAAI,KAAK,OAAO,KAAK,CAAC;QAEvC,IAAI,aAAa,OAAO,GAAG;EAE/B,CAAC;EACD,IAAI,aAAa,KAAK;EACtB,OAAO,QAAQ,aAAa,OAAO,QAAQ,OAAO,IAAI,GAAG;CAC3D,GAAG;EAAC;EAAU;EAAe;EAAQ;EAAW;EAAgB;CAAI,CAAC;CAErE,OAAO;AACT"}
@@ -1,9 +1,12 @@
1
+ import { isDestinationOnlyChain, isUnservedDestinationChain } from "../../utils/chainType.js";
1
2
  import { formatInputAmount } from "../../utils/format.js";
2
3
  //#region src/stores/form/getDefaultValuesFromQueryString.ts
3
- const getDefaultValuesFromQueryString = ({ buildUrl = false, includeToAddress = true }) => {
4
+ const getDefaultValuesFromQueryString = ({ buildUrl = false, includeToAddress = true, chains }) => {
4
5
  if (typeof window === "undefined") return {};
5
6
  if (!buildUrl) return {};
6
7
  const searchParams = Object.fromEntries(new URLSearchParams(window.location.search));
8
+ if (isDestinationOnlyChain(Number.parseInt(searchParams.fromChain, 10))) delete searchParams.fromChain;
9
+ if (isUnservedDestinationChain(Number.parseInt(searchParams.toChain, 10), chains)) delete searchParams.toChain;
7
10
  ["from", "to"].forEach((key) => {
8
11
  if (searchParams[`${key}Token`] && !searchParams[`${key}Chain`]) delete searchParams[`${key}Token`];
9
12
  });
@@ -1 +1 @@
1
- {"version":3,"file":"getDefaultValuesFromQueryString.js","names":[],"sources":["../../../../src/stores/form/getDefaultValuesFromQueryString.ts"],"sourcesContent":["import { formatInputAmount } from '../../utils/format.js'\nimport type { DefaultValues } from './types.js'\n\ninterface GetDefaultValuesFromQueryStringOptions {\n includeToAddress?: boolean\n buildUrl?: boolean\n}\n\nexport const getDefaultValuesFromQueryString = ({\n buildUrl = false,\n includeToAddress = true,\n}: GetDefaultValuesFromQueryStringOptions): Partial<DefaultValues> => {\n if (typeof window === 'undefined') {\n return {}\n }\n\n if (!buildUrl) {\n return {}\n }\n\n const searchParams = Object.fromEntries(\n new URLSearchParams(window.location.search)\n )\n\n // Prevent using fromToken/toToken params if chain is not selected.\n ;(['from', 'to'] as const).forEach((key) => {\n if (searchParams[`${key}Token`] && !searchParams[`${key}Chain`]) {\n delete searchParams[`${key}Token`]\n }\n })\n\n return {\n ...(Number.isFinite(Number.parseInt(searchParams.fromChain, 10))\n ? { fromChain: Number.parseInt(searchParams.fromChain, 10) }\n : {}),\n ...(Number.isFinite(Number.parseInt(searchParams.toChain, 10))\n ? { toChain: Number.parseInt(searchParams.toChain, 10) }\n : {}),\n ...(searchParams.fromToken ? { fromToken: searchParams.fromToken } : {}),\n ...(searchParams.toToken ? { toToken: searchParams.toToken } : {}),\n ...(Number.isFinite(Number.parseFloat(searchParams.fromAmount))\n ? { fromAmount: formatInputAmount(searchParams.fromAmount) }\n : {}),\n ...(Number.isFinite(Number.parseFloat(searchParams.toAmount))\n ? { toAmount: formatInputAmount(searchParams.toAmount) }\n : {}),\n // Limit-order params (written only while on the limit tab).\n ...(Number.isFinite(Number.parseInt(searchParams.validUntil, 10))\n ? { validUntil: Number.parseInt(searchParams.validUntil, 10) }\n : {}),\n ...(searchParams.partiallyFillable === 'true' ||\n searchParams.partiallyFillable === 'false'\n ? { partiallyFillable: searchParams.partiallyFillable === 'true' }\n : {}),\n ...(includeToAddress && searchParams.toAddress\n ? { toAddress: searchParams.toAddress }\n : {}),\n }\n}\n"],"mappings":";;AAQA,MAAa,mCAAmC,EAC9C,WAAW,OACX,mBAAmB,WACiD;CACpE,IAAI,OAAO,WAAW,aACpB,OAAO,CAAC;CAGV,IAAI,CAAC,UACH,OAAO,CAAC;CAGV,MAAM,eAAe,OAAO,YAC1B,IAAI,gBAAgB,OAAO,SAAS,MAAM,CAC5C;CAGC,CAAE,QAAQ,IAAI,CAAC,CAAW,SAAS,QAAQ;EAC1C,IAAI,aAAa,GAAG,IAAI,WAAW,CAAC,aAAa,GAAG,IAAI,SACtD,OAAO,aAAa,GAAG,IAAI;CAE/B,CAAC;CAED,OAAO;EACL,GAAI,OAAO,SAAS,OAAO,SAAS,aAAa,WAAW,EAAE,CAAC,IAC3D,EAAE,WAAW,OAAO,SAAS,aAAa,WAAW,EAAE,EAAE,IACzD,CAAC;EACL,GAAI,OAAO,SAAS,OAAO,SAAS,aAAa,SAAS,EAAE,CAAC,IACzD,EAAE,SAAS,OAAO,SAAS,aAAa,SAAS,EAAE,EAAE,IACrD,CAAC;EACL,GAAI,aAAa,YAAY,EAAE,WAAW,aAAa,UAAU,IAAI,CAAC;EACtE,GAAI,aAAa,UAAU,EAAE,SAAS,aAAa,QAAQ,IAAI,CAAC;EAChE,GAAI,OAAO,SAAS,OAAO,WAAW,aAAa,UAAU,CAAC,IAC1D,EAAE,YAAY,kBAAkB,aAAa,UAAU,EAAE,IACzD,CAAC;EACL,GAAI,OAAO,SAAS,OAAO,WAAW,aAAa,QAAQ,CAAC,IACxD,EAAE,UAAU,kBAAkB,aAAa,QAAQ,EAAE,IACrD,CAAC;EAEL,GAAI,OAAO,SAAS,OAAO,SAAS,aAAa,YAAY,EAAE,CAAC,IAC5D,EAAE,YAAY,OAAO,SAAS,aAAa,YAAY,EAAE,EAAE,IAC3D,CAAC;EACL,GAAI,aAAa,sBAAsB,UACvC,aAAa,sBAAsB,UAC/B,EAAE,mBAAmB,aAAa,sBAAsB,OAAO,IAC/D,CAAC;EACL,GAAI,oBAAoB,aAAa,YACjC,EAAE,WAAW,aAAa,UAAU,IACpC,CAAC;CACP;AACF"}
1
+ {"version":3,"file":"getDefaultValuesFromQueryString.js","names":[],"sources":["../../../../src/stores/form/getDefaultValuesFromQueryString.ts"],"sourcesContent":["import type { WidgetChains } from '../../types/widget.js'\nimport {\n isDestinationOnlyChain,\n isUnservedDestinationChain,\n} from '../../utils/chainType.js'\nimport { formatInputAmount } from '../../utils/format.js'\nimport type { DefaultValues } from './types.js'\n\ninterface GetDefaultValuesFromQueryStringOptions {\n includeToAddress?: boolean\n buildUrl?: boolean\n chains?: WidgetChains\n}\n\nexport const getDefaultValuesFromQueryString = ({\n buildUrl = false,\n includeToAddress = true,\n chains,\n}: GetDefaultValuesFromQueryStringOptions): Partial<DefaultValues> => {\n if (typeof window === 'undefined') {\n return {}\n }\n\n if (!buildUrl) {\n return {}\n }\n\n const searchParams = Object.fromEntries(\n new URLSearchParams(window.location.search)\n )\n\n // The loop below then drops their tokens too.\n if (isDestinationOnlyChain(Number.parseInt(searchParams.fromChain, 10))) {\n delete searchParams.fromChain\n }\n if (\n isUnservedDestinationChain(\n Number.parseInt(searchParams.toChain, 10),\n chains\n )\n ) {\n delete searchParams.toChain\n }\n // Prevent using fromToken/toToken params if chain is not selected.\n ;(['from', 'to'] as const).forEach((key) => {\n if (searchParams[`${key}Token`] && !searchParams[`${key}Chain`]) {\n delete searchParams[`${key}Token`]\n }\n })\n\n return {\n ...(Number.isFinite(Number.parseInt(searchParams.fromChain, 10))\n ? { fromChain: Number.parseInt(searchParams.fromChain, 10) }\n : {}),\n ...(Number.isFinite(Number.parseInt(searchParams.toChain, 10))\n ? { toChain: Number.parseInt(searchParams.toChain, 10) }\n : {}),\n ...(searchParams.fromToken ? { fromToken: searchParams.fromToken } : {}),\n ...(searchParams.toToken ? { toToken: searchParams.toToken } : {}),\n ...(Number.isFinite(Number.parseFloat(searchParams.fromAmount))\n ? { fromAmount: formatInputAmount(searchParams.fromAmount) }\n : {}),\n ...(Number.isFinite(Number.parseFloat(searchParams.toAmount))\n ? { toAmount: formatInputAmount(searchParams.toAmount) }\n : {}),\n // Limit-order params (written only while on the limit tab).\n ...(Number.isFinite(Number.parseInt(searchParams.validUntil, 10))\n ? { validUntil: Number.parseInt(searchParams.validUntil, 10) }\n : {}),\n ...(searchParams.partiallyFillable === 'true' ||\n searchParams.partiallyFillable === 'false'\n ? { partiallyFillable: searchParams.partiallyFillable === 'true' }\n : {}),\n ...(includeToAddress && searchParams.toAddress\n ? { toAddress: searchParams.toAddress }\n : {}),\n }\n}\n"],"mappings":";;;AAcA,MAAa,mCAAmC,EAC9C,WAAW,OACX,mBAAmB,MACnB,aACoE;CACpE,IAAI,OAAO,WAAW,aACpB,OAAO,CAAC;CAGV,IAAI,CAAC,UACH,OAAO,CAAC;CAGV,MAAM,eAAe,OAAO,YAC1B,IAAI,gBAAgB,OAAO,SAAS,MAAM,CAC5C;CAGA,IAAI,uBAAuB,OAAO,SAAS,aAAa,WAAW,EAAE,CAAC,GACpE,OAAO,aAAa;CAEtB,IACE,2BACE,OAAO,SAAS,aAAa,SAAS,EAAE,GACxC,MACF,GAEA,OAAO,aAAa;CAGrB,CAAE,QAAQ,IAAI,CAAC,CAAW,SAAS,QAAQ;EAC1C,IAAI,aAAa,GAAG,IAAI,WAAW,CAAC,aAAa,GAAG,IAAI,SACtD,OAAO,aAAa,GAAG,IAAI;CAE/B,CAAC;CAED,OAAO;EACL,GAAI,OAAO,SAAS,OAAO,SAAS,aAAa,WAAW,EAAE,CAAC,IAC3D,EAAE,WAAW,OAAO,SAAS,aAAa,WAAW,EAAE,EAAE,IACzD,CAAC;EACL,GAAI,OAAO,SAAS,OAAO,SAAS,aAAa,SAAS,EAAE,CAAC,IACzD,EAAE,SAAS,OAAO,SAAS,aAAa,SAAS,EAAE,EAAE,IACrD,CAAC;EACL,GAAI,aAAa,YAAY,EAAE,WAAW,aAAa,UAAU,IAAI,CAAC;EACtE,GAAI,aAAa,UAAU,EAAE,SAAS,aAAa,QAAQ,IAAI,CAAC;EAChE,GAAI,OAAO,SAAS,OAAO,WAAW,aAAa,UAAU,CAAC,IAC1D,EAAE,YAAY,kBAAkB,aAAa,UAAU,EAAE,IACzD,CAAC;EACL,GAAI,OAAO,SAAS,OAAO,WAAW,aAAa,QAAQ,CAAC,IACxD,EAAE,UAAU,kBAAkB,aAAa,QAAQ,EAAE,IACrD,CAAC;EAEL,GAAI,OAAO,SAAS,OAAO,SAAS,aAAa,YAAY,EAAE,CAAC,IAC5D,EAAE,YAAY,OAAO,SAAS,aAAa,YAAY,EAAE,EAAE,IAC3D,CAAC;EACL,GAAI,aAAa,sBAAsB,UACvC,aAAa,sBAAsB,UAC/B,EAAE,mBAAmB,aAAa,sBAAsB,OAAO,IAC/D,CAAC;EACL,GAAI,oBAAoB,aAAa,YACjC,EAAE,WAAW,aAAa,UAAU,IACpC,CAAC;CACP;AACF"}
@@ -1,3 +1,4 @@
1
+ import { isItemAllowed } from "./item.js";
1
2
  import { ChainId, ChainType } from "@lifi/sdk";
2
3
  //#region src/utils/chainType.ts
3
4
  const defaultChainIdsByType = {
@@ -8,7 +9,37 @@ const defaultChainIdsByType = {
8
9
  [ChainType.TVM]: ChainId.TRN,
9
10
  [ChainType.STL]: ChainId.XLM
10
11
  };
12
+ const destinationOnlyChainIds = /* @__PURE__ */ new Set([ChainId.ZEC]);
13
+ const isDestinationOnlyChain = (chainId) => chainId !== void 0 && destinationOnlyChainIds.has(chainId);
14
+ const withDestinationOnlyChains = (chains) => {
15
+ const allow = chains?.from?.allow?.filter((chainId) => !isDestinationOnlyChain(chainId));
16
+ return {
17
+ ...chains,
18
+ from: {
19
+ ...chains?.from,
20
+ ...allow && { allow },
21
+ deny: [...chains?.from?.deny ?? [], ...destinationOnlyChainIds]
22
+ }
23
+ };
24
+ };
25
+ const withServedDestinationChains = (chains, providers) => {
26
+ const unserved = [...destinationOnlyChainIds].filter((chainId) => !providers.some((provider) => provider.chainIds?.some((id) => id === chainId)));
27
+ if (!unserved.length) return chains;
28
+ const allow = chains?.allow?.filter((chainId) => !unserved.includes(chainId));
29
+ return {
30
+ ...chains,
31
+ ...allow && { allow },
32
+ deny: [...chains?.deny ?? [], ...unserved]
33
+ };
34
+ };
35
+ const isUnservedDestinationChain = (chainId, chains) => isDestinationOnlyChain(chainId) && !isItemAllowed(chainId, chains);
36
+ const withoutUnservedToChain = (config) => {
37
+ if (!isUnservedDestinationChain(config.toChain, config.chains)) return config;
38
+ const { toChain: _toChain, toToken: _toToken, ...rest } = config;
39
+ return rest;
40
+ };
41
+ const isDestinationAllowedAsSource = (toChainId, chains) => !toChainId || isItemAllowed(toChainId, chains?.from);
11
42
  //#endregion
12
- export { defaultChainIdsByType };
43
+ export { defaultChainIdsByType, isDestinationAllowedAsSource, isDestinationOnlyChain, isUnservedDestinationChain, withDestinationOnlyChains, withServedDestinationChains, withoutUnservedToChain };
13
44
 
14
45
  //# sourceMappingURL=chainType.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chainType.js","names":[],"sources":["../../../src/utils/chainType.ts"],"sourcesContent":["import { ChainId, ChainType } from '@lifi/sdk'\n\nexport const defaultChainIdsByType: Record<ChainType, ChainId> = {\n [ChainType.EVM]: ChainId.ETH,\n [ChainType.SVM]: ChainId.SOL,\n [ChainType.UTXO]: ChainId.BTC,\n [ChainType.MVM]: ChainId.SUI,\n [ChainType.TVM]: ChainId.TRN,\n [ChainType.STL]: ChainId.XLM,\n}\n"],"mappings":";;AAEA,MAAa,wBAAoD;EAC9D,UAAU,MAAM,QAAQ;EACxB,UAAU,MAAM,QAAQ;EACxB,UAAU,OAAO,QAAQ;EACzB,UAAU,MAAM,QAAQ;EACxB,UAAU,MAAM,QAAQ;EACxB,UAAU,MAAM,QAAQ;AAC3B"}
1
+ {"version":3,"file":"chainType.js","names":[],"sources":["../../../src/utils/chainType.ts"],"sourcesContent":["import { ChainId, ChainType, type SDKProvider } from '@lifi/sdk'\nimport type { WidgetChains, WidgetConfig } from '../types/widget.js'\nimport { isItemAllowed } from './item.js'\n\nexport const defaultChainIdsByType: Record<ChainType, ChainId> = {\n [ChainType.EVM]: ChainId.ETH,\n [ChainType.SVM]: ChainId.SOL,\n [ChainType.UTXO]: ChainId.BTC,\n [ChainType.MVM]: ChainId.SUI,\n [ChainType.TVM]: ChainId.TRN,\n [ChainType.STL]: ChainId.XLM,\n}\n\n// No wallet can sign on these chains yet, so a route may only deliver to them.\nconst destinationOnlyChainIds: ReadonlySet<number> = new Set<number>([\n ChainId.ZEC,\n])\n\nexport const isDestinationOnlyChain = (chainId?: number): boolean =>\n chainId !== undefined && destinationOnlyChainIds.has(chainId)\n\nexport const withDestinationOnlyChains = (\n chains: WidgetChains | undefined\n): WidgetChains => {\n const allow = chains?.from?.allow?.filter(\n (chainId) => !isDestinationOnlyChain(chainId)\n )\n return {\n ...chains,\n from: {\n ...chains?.from,\n ...(allow && { allow }),\n deny: [...(chains?.from?.deny ?? []), ...destinationOnlyChainIds],\n },\n }\n}\n\n// A destination-only chain takes a receiver only through a provider that lists it.\nexport const withServedDestinationChains = (\n chains: WidgetChains | undefined,\n providers: readonly Pick<SDKProvider, 'chainIds'>[]\n): WidgetChains | undefined => {\n const unserved = [...destinationOnlyChainIds].filter(\n (chainId) =>\n !providers.some((provider) =>\n provider.chainIds?.some((id) => id === chainId)\n )\n )\n if (!unserved.length) {\n return chains\n }\n const allow = chains?.allow?.filter((chainId) => !unserved.includes(chainId))\n return {\n ...chains,\n ...(allow && { allow }),\n deny: [...(chains?.deny ?? []), ...unserved],\n }\n}\n\n// The form keeps a preset chain that the chain list does not offer.\nexport const isUnservedDestinationChain = (\n chainId: number | undefined,\n chains: WidgetChains | undefined\n): boolean => isDestinationOnlyChain(chainId) && !isItemAllowed(chainId, chains)\n\n// Omitted, not undefined: an own undefined key resets the form field.\nexport const withoutUnservedToChain = <\n T extends Pick<WidgetConfig, 'chains' | 'toChain' | 'toToken'>,\n>(\n config: T\n): T => {\n if (!isUnservedDestinationChain(config.toChain, config.chains)) {\n return config\n }\n const { toChain: _toChain, toToken: _toToken, ...rest } = config\n return rest as T\n}\n\nexport const isDestinationAllowedAsSource = (\n toChainId: number | undefined,\n chains: WidgetChains | undefined\n): boolean => !toChainId || isItemAllowed(toChainId, chains?.from)\n"],"mappings":";;;AAIA,MAAa,wBAAoD;EAC9D,UAAU,MAAM,QAAQ;EACxB,UAAU,MAAM,QAAQ;EACxB,UAAU,OAAO,QAAQ;EACzB,UAAU,MAAM,QAAQ;EACxB,UAAU,MAAM,QAAQ;EACxB,UAAU,MAAM,QAAQ;AAC3B;AAGA,MAAM,0CAA+C,IAAI,IAAY,CACnE,QAAQ,GACV,CAAC;AAED,MAAa,0BAA0B,YACrC,YAAY,KAAA,KAAa,wBAAwB,IAAI,OAAO;AAE9D,MAAa,6BACX,WACiB;CACjB,MAAM,QAAQ,QAAQ,MAAM,OAAO,QAChC,YAAY,CAAC,uBAAuB,OAAO,CAC9C;CACA,OAAO;EACL,GAAG;EACH,MAAM;GACJ,GAAG,QAAQ;GACX,GAAI,SAAS,EAAE,MAAM;GACrB,MAAM,CAAC,GAAI,QAAQ,MAAM,QAAQ,CAAC,GAAI,GAAG,uBAAuB;EAClE;CACF;AACF;AAGA,MAAa,+BACX,QACA,cAC6B;CAC7B,MAAM,WAAW,CAAC,GAAG,uBAAuB,CAAC,CAAC,QAC3C,YACC,CAAC,UAAU,MAAM,aACf,SAAS,UAAU,MAAM,OAAO,OAAO,OAAO,CAChD,CACJ;CACA,IAAI,CAAC,SAAS,QACZ,OAAO;CAET,MAAM,QAAQ,QAAQ,OAAO,QAAQ,YAAY,CAAC,SAAS,SAAS,OAAO,CAAC;CAC5E,OAAO;EACL,GAAG;EACH,GAAI,SAAS,EAAE,MAAM;EACrB,MAAM,CAAC,GAAI,QAAQ,QAAQ,CAAC,GAAI,GAAG,QAAQ;CAC7C;AACF;AAGA,MAAa,8BACX,SACA,WACY,uBAAuB,OAAO,KAAK,CAAC,cAAc,SAAS,MAAM;AAG/E,MAAa,0BAGX,WACM;CACN,IAAI,CAAC,2BAA2B,OAAO,SAAS,OAAO,MAAM,GAC3D,OAAO;CAET,MAAM,EAAE,SAAS,UAAU,SAAS,UAAU,GAAG,SAAS;CAC1D,OAAO;AACT;AAEA,MAAa,gCACX,WACA,WACY,CAAC,aAAa,cAAc,WAAW,QAAQ,IAAI"}
@@ -6,7 +6,12 @@ const isCustomReceiverBlocked = ({ fromChainType, toChainType, toAddress, signer
6
6
  if (!toAddress) return Boolean(receiverRequired);
7
7
  return toAddress.toLowerCase() !== signerAddress?.toLowerCase();
8
8
  };
9
+ const isSignerInvalidReceiver = ({ signerAddress, toAddress, fromChain, toChain, isAddressForChain }) => Boolean(signerAddress && !toAddress && fromChain && toChain && fromChain.chainType === toChain.chainType && !isAddressForChain(signerAddress, toChain));
10
+ const canQuoteWithToAddress = (toAddress, toChain, isAddressForChain) => {
11
+ if (!toAddress) return true;
12
+ return toChain ? isAddressForChain(toAddress, toChain) : false;
13
+ };
9
14
  //#endregion
10
- export { isCustomReceiverBlocked, isCustomReceiverUnsupported };
15
+ export { canQuoteWithToAddress, isCustomReceiverBlocked, isCustomReceiverUnsupported, isSignerInvalidReceiver };
11
16
 
12
17
  //# sourceMappingURL=customReceiver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"customReceiver.js","names":[],"sources":["../../../src/utils/customReceiver.ts"],"sourcesContent":["import { ChainType } from '@lifi/sdk'\n\n// Stellar routes always settle to the account that signs them.\nexport const isCustomReceiverUnsupported = (\n fromChainType?: ChainType,\n toChainType?: ChainType\n): boolean => fromChainType === ChainType.STL && toChainType === ChainType.STL\n\nexport interface CustomReceiverBlockedArgs {\n fromChainType?: ChainType\n toChainType?: ChainType\n toAddress?: string\n signerAddress?: string\n receiverRequired?: boolean\n}\n\nexport const isCustomReceiverBlocked = ({\n fromChainType,\n toChainType,\n toAddress,\n signerAddress,\n receiverRequired,\n}: CustomReceiverBlockedArgs): boolean => {\n if (!isCustomReceiverUnsupported(fromChainType, toChainType)) {\n return false\n }\n if (!toAddress) {\n return Boolean(receiverRequired)\n }\n return toAddress.toLowerCase() !== signerAddress?.toLowerCase()\n}\n"],"mappings":";;AAGA,MAAa,+BACX,eACA,gBACY,kBAAkB,UAAU,OAAO,gBAAgB,UAAU;AAU3E,MAAa,2BAA2B,EACtC,eACA,aACA,WACA,eACA,uBACwC;CACxC,IAAI,CAAC,4BAA4B,eAAe,WAAW,GACzD,OAAO;CAET,IAAI,CAAC,WACH,OAAO,QAAQ,gBAAgB;CAEjC,OAAO,UAAU,YAAY,MAAM,eAAe,YAAY;AAChE"}
1
+ {"version":3,"file":"customReceiver.js","names":[],"sources":["../../../src/utils/customReceiver.ts"],"sourcesContent":["import { ChainType } from '@lifi/sdk'\nimport type { ChainRef, IsAddressForChain } from '@lifi/widget-provider'\n\n// Stellar routes always settle to the account that signs them.\nexport const isCustomReceiverUnsupported = (\n fromChainType?: ChainType,\n toChainType?: ChainType\n): boolean => fromChainType === ChainType.STL && toChainType === ChainType.STL\n\nexport interface CustomReceiverBlockedArgs {\n fromChainType?: ChainType\n toChainType?: ChainType\n toAddress?: string\n signerAddress?: string\n receiverRequired?: boolean\n}\n\nexport const isCustomReceiverBlocked = ({\n fromChainType,\n toChainType,\n toAddress,\n signerAddress,\n receiverRequired,\n}: CustomReceiverBlockedArgs): boolean => {\n if (!isCustomReceiverUnsupported(fromChainType, toChainType)) {\n return false\n }\n if (!toAddress) {\n return Boolean(receiverRequired)\n }\n return toAddress.toLowerCase() !== signerAddress?.toLowerCase()\n}\n\n// Without a receiver the API delivers to the signer when both chains share a\n// chain type, and a Bitcoin signer cannot receive on ZEC.\nexport const isSignerInvalidReceiver = ({\n signerAddress,\n toAddress,\n fromChain,\n toChain,\n isAddressForChain,\n}: {\n signerAddress: string | undefined\n toAddress: string | undefined\n fromChain: ChainRef | undefined\n toChain: ChainRef | undefined\n isAddressForChain: IsAddressForChain\n}): boolean =>\n Boolean(\n signerAddress &&\n !toAddress &&\n fromChain &&\n toChain &&\n fromChain.chainType === toChain.chainType &&\n !isAddressForChain(signerAddress, toChain)\n )\n\nexport const canQuoteWithToAddress = (\n toAddress: string | undefined,\n toChain: ChainRef | undefined,\n isAddressForChain: IsAddressForChain\n): boolean => {\n if (!toAddress) {\n return true\n }\n return toChain ? isAddressForChain(toAddress, toChain) : false\n}\n"],"mappings":";;AAIA,MAAa,+BACX,eACA,gBACY,kBAAkB,UAAU,OAAO,gBAAgB,UAAU;AAU3E,MAAa,2BAA2B,EACtC,eACA,aACA,WACA,eACA,uBACwC;CACxC,IAAI,CAAC,4BAA4B,eAAe,WAAW,GACzD,OAAO;CAET,IAAI,CAAC,WACH,OAAO,QAAQ,gBAAgB;CAEjC,OAAO,UAAU,YAAY,MAAM,eAAe,YAAY;AAChE;AAIA,MAAa,2BAA2B,EACtC,eACA,WACA,WACA,SACA,wBAQA,QACE,iBACE,CAAC,aACD,aACA,WACA,UAAU,cAAc,QAAQ,aAChC,CAAC,kBAAkB,eAAe,OAAO,CAC7C;AAEF,MAAa,yBACX,WACA,SACA,sBACY;CACZ,IAAI,CAAC,WACH,OAAO;CAET,OAAO,UAAU,kBAAkB,WAAW,OAAO,IAAI;AAC3D"}