@lifi/widget 4.6.0 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -3
- package/dist/esm/App.d.ts +1 -2
- package/dist/esm/App.d.ts.map +1 -1
- package/dist/esm/AppDrawer.d.ts +1 -2
- package/dist/esm/AppDrawer.d.ts.map +1 -1
- package/dist/esm/components/ActionRow/ActionRow.d.ts +1 -2
- package/dist/esm/components/ActionRow/ActionRow.d.ts.map +1 -1
- package/dist/esm/components/AmountInput/AmountInput.style.d.ts +2 -2
- package/dist/esm/components/AmountInput/AmountInput.style.d.ts.map +1 -1
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.d.ts +1 -2
- package/dist/esm/components/AmountInput/AmountInputEndAdornment.d.ts.map +1 -1
- package/dist/esm/components/AmountInput/PriceFormHelperText.style.d.ts +1 -2
- package/dist/esm/components/AmountInput/PriceFormHelperText.style.d.ts.map +1 -1
- package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js +6 -2
- package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -1
- package/dist/esm/components/Avatar/Avatar.d.ts +1 -2
- package/dist/esm/components/Avatar/Avatar.d.ts.map +1 -1
- package/dist/esm/components/Avatar/TokenAvatar.d.ts +1 -2
- package/dist/esm/components/Avatar/TokenAvatar.d.ts.map +1 -1
- package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.d.ts +1 -2
- package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.d.ts.map +1 -1
- package/dist/esm/components/BaseTransactionButton/types.d.ts +1 -2
- package/dist/esm/components/BaseTransactionButton/types.d.ts.map +1 -1
- package/dist/esm/components/BottomSheet/BottomSheet.js +1 -0
- package/dist/esm/components/BottomSheet/BottomSheet.js.map +1 -1
- package/dist/esm/components/BottomSheet/types.d.ts +1 -2
- package/dist/esm/components/BottomSheet/types.d.ts.map +1 -1
- package/dist/esm/components/ButtonTertiary.d.ts +1 -2
- package/dist/esm/components/ButtonTertiary.d.ts.map +1 -1
- package/dist/esm/components/Card/CardIconButton.d.ts +1 -2
- package/dist/esm/components/Card/CardIconButton.d.ts.map +1 -1
- package/dist/esm/components/Card/CardTitle.d.ts +1 -2
- package/dist/esm/components/Card/CardTitle.d.ts.map +1 -1
- package/dist/esm/components/Card/InputCard.d.ts +1 -2
- package/dist/esm/components/Card/InputCard.d.ts.map +1 -1
- package/dist/esm/components/ChainSelect/ChainSelect.d.ts +1 -2
- package/dist/esm/components/ChainSelect/ChainSelect.d.ts.map +1 -1
- package/dist/esm/components/ChainSelect/ChainSelect.style.d.ts +1 -2
- package/dist/esm/components/ChainSelect/ChainSelect.style.d.ts.map +1 -1
- package/dist/esm/components/ContractComponent/ContractComponent.d.ts +1 -2
- package/dist/esm/components/ContractComponent/ContractComponent.d.ts.map +1 -1
- package/dist/esm/components/ContractComponent/ItemPrice.d.ts +2 -3
- package/dist/esm/components/ContractComponent/ItemPrice.d.ts.map +1 -1
- package/dist/esm/components/ContractComponent/NFT/NFT.d.ts +1 -2
- package/dist/esm/components/ContractComponent/NFT/NFT.d.ts.map +1 -1
- package/dist/esm/components/ContractComponent/NFT/NFTBase.d.ts +1 -2
- package/dist/esm/components/ContractComponent/NFT/NFTBase.d.ts.map +1 -1
- package/dist/esm/components/ContractComponent/NFT/types.d.ts +3 -4
- package/dist/esm/components/ContractComponent/NFT/types.d.ts.map +1 -1
- package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.d.ts +1 -2
- package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.d.ts.map +1 -1
- package/dist/esm/components/ExecutionStatusCard/StatusIcon.d.ts +1 -2
- package/dist/esm/components/ExecutionStatusCard/StatusIcon.d.ts.map +1 -1
- package/dist/esm/components/FeeBreakdownTooltip.d.ts +1 -2
- package/dist/esm/components/FeeBreakdownTooltip.d.ts.map +1 -1
- package/dist/esm/components/IconCircle/IconCircle.d.ts +1 -2
- package/dist/esm/components/IconCircle/IconCircle.d.ts.map +1 -1
- package/dist/esm/components/IconCircle/statusIcons.d.ts +1 -2
- package/dist/esm/components/IconCircle/statusIcons.d.ts.map +1 -1
- package/dist/esm/components/IconTypography.d.ts +1 -2
- package/dist/esm/components/IconTypography.d.ts.map +1 -1
- package/dist/esm/components/ListItem/ListItemButton.d.ts +1 -2
- package/dist/esm/components/ListItem/ListItemButton.d.ts.map +1 -1
- package/dist/esm/components/Messages/WarningMessages.d.ts +1 -2
- package/dist/esm/components/Messages/WarningMessages.d.ts.map +1 -1
- package/dist/esm/components/PageContainer.d.ts +2 -3
- package/dist/esm/components/PageContainer.d.ts.map +1 -1
- package/dist/esm/components/PoweredBy/PoweredBy.d.ts +1 -2
- package/dist/esm/components/PoweredBy/PoweredBy.d.ts.map +1 -1
- package/dist/esm/components/ProgressToNextUpdate.d.ts +1 -2
- package/dist/esm/components/ProgressToNextUpdate.d.ts.map +1 -1
- package/dist/esm/components/RouteCard/RouteCard.d.ts +1 -2
- package/dist/esm/components/RouteCard/RouteCard.d.ts.map +1 -1
- package/dist/esm/components/RouteCard/RouteCardSkeleton.d.ts +1 -2
- package/dist/esm/components/RouteCard/RouteCardSkeleton.d.ts.map +1 -1
- package/dist/esm/components/RouteCard/RouteDetails.d.ts +1 -2
- package/dist/esm/components/RouteCard/RouteDetails.d.ts.map +1 -1
- package/dist/esm/components/RouteCard/RouteDetails.style.d.ts +5 -6
- package/dist/esm/components/RouteCard/RouteDetails.style.d.ts.map +1 -1
- package/dist/esm/components/RouteCard/RouteNotFoundCard.d.ts +1 -2
- package/dist/esm/components/RouteCard/RouteNotFoundCard.d.ts.map +1 -1
- package/dist/esm/components/RouteCard/RouteTokens.d.ts +1 -2
- package/dist/esm/components/RouteCard/RouteTokens.d.ts.map +1 -1
- package/dist/esm/components/RouteCard/types.d.ts +2 -3
- package/dist/esm/components/RouteCard/types.d.ts.map +1 -1
- package/dist/esm/components/Search/SearchInput.d.ts +1 -2
- package/dist/esm/components/Search/SearchInput.d.ts.map +1 -1
- package/dist/esm/components/SendToWallet/SendToWalletButton.d.ts +1 -2
- package/dist/esm/components/SendToWallet/SendToWalletButton.d.ts.map +1 -1
- package/dist/esm/components/Skeleton/WidgetSkeleton.d.ts +1 -2
- package/dist/esm/components/Skeleton/WidgetSkeleton.d.ts.map +1 -1
- package/dist/esm/components/StepActions/SentToWalletRow.d.ts +1 -2
- package/dist/esm/components/StepActions/SentToWalletRow.d.ts.map +1 -1
- package/dist/esm/components/StepActions/StepActionRow.style.d.ts +1 -2
- package/dist/esm/components/StepActions/StepActionRow.style.d.ts.map +1 -1
- package/dist/esm/components/StepActions/StepActionsList.d.ts +1 -2
- package/dist/esm/components/StepActions/StepActionsList.d.ts.map +1 -1
- package/dist/esm/components/StepActions/executionRows.d.ts +2 -3
- package/dist/esm/components/StepActions/executionRows.d.ts.map +1 -1
- package/dist/esm/components/Token/Token.d.ts.map +1 -1
- package/dist/esm/components/Token/Token.js +2 -4
- package/dist/esm/components/Token/Token.js.map +1 -1
- package/dist/esm/components/TokenList/RecentTokensHeader.js +44 -0
- package/dist/esm/components/TokenList/RecentTokensHeader.js.map +1 -0
- package/dist/esm/components/TokenList/RecentTokensToggle.js +36 -0
- package/dist/esm/components/TokenList/RecentTokensToggle.js.map +1 -0
- package/dist/esm/components/TokenList/RemoveRecentTokenButton.js +32 -0
- package/dist/esm/components/TokenList/RemoveRecentTokenButton.js.map +1 -0
- package/dist/esm/components/TokenList/TokenList.js +55 -5
- package/dist/esm/components/TokenList/TokenList.js.map +1 -1
- package/dist/esm/components/TokenList/TokenListItem.js +35 -19
- package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
- package/dist/esm/components/TokenList/TokenNotFound.d.ts +1 -2
- package/dist/esm/components/TokenList/TokenNotFound.d.ts.map +1 -1
- package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts +1 -2
- package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts.map +1 -1
- package/dist/esm/components/TokenList/VirtualizedTokenList.js +55 -42
- package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
- package/dist/esm/components/TokenList/types.d.ts +9 -2
- package/dist/esm/components/TokenList/types.d.ts.map +1 -1
- package/dist/esm/components/TokenList/useTokenSelect.d.ts +1 -2
- package/dist/esm/components/TokenList/useTokenSelect.d.ts.map +1 -1
- package/dist/esm/components/TokenRate/TokenRate.d.ts +1 -2
- package/dist/esm/components/TokenRate/TokenRate.d.ts.map +1 -1
- package/dist/esm/components/TransactionCard/TransactionCard.style.d.ts +2 -3
- package/dist/esm/components/TransactionCard/TransactionCard.style.d.ts.map +1 -1
- package/dist/esm/config/constants.d.ts +1 -2
- package/dist/esm/config/constants.d.ts.map +1 -1
- package/dist/esm/config/version.d.ts +2 -3
- package/dist/esm/config/version.d.ts.map +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/config/version.js.map +1 -1
- package/dist/esm/hooks/useAddressActivity.d.ts +1 -2
- package/dist/esm/hooks/useAddressActivity.d.ts.map +1 -1
- package/dist/esm/hooks/useAddressValidation.d.ts +2 -3
- package/dist/esm/hooks/useAddressValidation.d.ts.map +1 -1
- package/dist/esm/hooks/useAvailableChains.d.ts +1 -2
- package/dist/esm/hooks/useAvailableChains.d.ts.map +1 -1
- package/dist/esm/hooks/useChain.d.ts +1 -2
- package/dist/esm/hooks/useChain.d.ts.map +1 -1
- package/dist/esm/hooks/useContactSupport.d.ts +1 -2
- package/dist/esm/hooks/useContactSupport.d.ts.map +1 -1
- package/dist/esm/hooks/useDebouncedWatch.d.ts +1 -2
- package/dist/esm/hooks/useDebouncedWatch.d.ts.map +1 -1
- package/dist/esm/hooks/useDisplayedTokens.js +6 -4
- package/dist/esm/hooks/useDisplayedTokens.js.map +1 -1
- package/dist/esm/hooks/useExplorer.d.ts +1 -2
- package/dist/esm/hooks/useExplorer.d.ts.map +1 -1
- package/dist/esm/hooks/useHeader.d.ts +1 -2
- package/dist/esm/hooks/useHeader.d.ts.map +1 -1
- package/dist/esm/hooks/useListHeight.d.ts +1 -2
- package/dist/esm/hooks/useListHeight.d.ts.map +1 -1
- package/dist/esm/hooks/useNavigateBack.d.ts +1 -2
- package/dist/esm/hooks/useNavigateBack.d.ts.map +1 -1
- package/dist/esm/hooks/useRecentTokens.js +46 -0
- package/dist/esm/hooks/useRecentTokens.js.map +1 -0
- package/dist/esm/hooks/useRouteExecution.d.ts +1 -2
- package/dist/esm/hooks/useRouteExecution.d.ts.map +1 -1
- package/dist/esm/hooks/useRouteExecutionMessage.d.ts +1 -2
- package/dist/esm/hooks/useRouteExecutionMessage.d.ts.map +1 -1
- package/dist/esm/hooks/useRoutes.d.ts +1 -2
- package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
- package/dist/esm/hooks/useRoutes.js +7 -2
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.d.ts +1 -2
- package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.js +8 -2
- package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
- package/dist/esm/hooks/useToken.d.ts +1 -2
- package/dist/esm/hooks/useToken.d.ts.map +1 -1
- package/dist/esm/hooks/useTokenAddressBalance.d.ts +1 -2
- package/dist/esm/hooks/useTokenAddressBalance.d.ts.map +1 -1
- package/dist/esm/hooks/useTokenBalances.d.ts +3 -2
- package/dist/esm/hooks/useTokenBalances.d.ts.map +1 -1
- package/dist/esm/hooks/useTokenBalances.js +15 -9
- package/dist/esm/hooks/useTokenBalances.js.map +1 -1
- package/dist/esm/hooks/useTokenList.d.ts +1 -2
- package/dist/esm/hooks/useTokenList.d.ts.map +1 -1
- package/dist/esm/hooks/useTokenSearch.js +3 -2
- package/dist/esm/hooks/useTokenSearch.js.map +1 -1
- package/dist/esm/hooks/useTokens.js +26 -15
- package/dist/esm/hooks/useTokens.js.map +1 -1
- package/dist/esm/hooks/useTools.d.ts +1 -2
- package/dist/esm/hooks/useTools.d.ts.map +1 -1
- package/dist/esm/hooks/useWidgetChains.d.ts +1 -2
- package/dist/esm/hooks/useWidgetChains.d.ts.map +1 -1
- package/dist/esm/hooks/useWidgetEvents.d.ts +3 -4
- package/dist/esm/hooks/useWidgetEvents.d.ts.map +1 -1
- package/dist/esm/i18n/bn.json +4 -0
- package/dist/esm/i18n/de.json +4 -0
- package/dist/esm/i18n/en.json +4 -0
- package/dist/esm/i18n/es.json +4 -0
- package/dist/esm/i18n/fr.json +4 -0
- package/dist/esm/i18n/hi.json +4 -0
- package/dist/esm/i18n/id.json +4 -0
- package/dist/esm/i18n/it.json +4 -0
- package/dist/esm/i18n/ja.json +4 -0
- package/dist/esm/i18n/ko.json +4 -0
- package/dist/esm/i18n/pl.json +4 -0
- package/dist/esm/i18n/pt.json +4 -0
- package/dist/esm/i18n/th.json +4 -0
- package/dist/esm/i18n/tr.json +4 -0
- package/dist/esm/i18n/uk.json +4 -0
- package/dist/esm/i18n/vi.json +4 -0
- package/dist/esm/i18n/zh.json +4 -0
- package/dist/esm/pages/MainPage/MainWarningMessages.d.ts +1 -2
- package/dist/esm/pages/MainPage/MainWarningMessages.d.ts.map +1 -1
- package/dist/esm/pages/SelectChainPage/SelectChainPage.d.ts +1 -2
- package/dist/esm/pages/SelectChainPage/SelectChainPage.d.ts.map +1 -1
- package/dist/esm/pages/SelectChainPage/types.d.ts +1 -2
- package/dist/esm/pages/SelectChainPage/types.d.ts.map +1 -1
- package/dist/esm/pages/SelectTokenPage/SearchTokenInput.d.ts +1 -2
- package/dist/esm/pages/SelectTokenPage/SearchTokenInput.d.ts.map +1 -1
- package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.d.ts +1 -2
- package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.d.ts +1 -2
- package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.d.ts +2 -3
- package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/ExecutionDoneCard.d.ts +1 -2
- package/dist/esm/pages/TransactionPage/ExecutionDoneCard.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/RouteTracker.d.ts +1 -2
- package/dist/esm/pages/TransactionPage/RouteTracker.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/StartTransactionButton.d.ts +1 -2
- package/dist/esm/pages/TransactionPage/StartTransactionButton.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.d.ts +1 -2
- package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js +0 -1
- package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js +0 -1
- package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/TransactionDoneButtons.d.ts +1 -2
- package/dist/esm/pages/TransactionPage/TransactionDoneButtons.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js +38 -12
- package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js.map +1 -1
- package/dist/esm/pages/TransactionPage/TransactionReview.js +22 -21
- package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
- package/dist/esm/pages/TransactionPage/types.d.ts +1 -2
- package/dist/esm/pages/TransactionPage/types.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/utils.d.ts +2 -3
- package/dist/esm/pages/TransactionPage/utils.d.ts.map +1 -1
- package/dist/esm/pages/TransactionPage/utils.js +23 -1
- package/dist/esm/pages/TransactionPage/utils.js.map +1 -1
- package/dist/esm/providers/I18nProvider/I18nProvider.d.ts +1 -2
- package/dist/esm/providers/I18nProvider/I18nProvider.d.ts.map +1 -1
- package/dist/esm/providers/I18nProvider/types.d.ts +4 -5
- package/dist/esm/providers/I18nProvider/types.d.ts.map +1 -1
- package/dist/esm/providers/QueryClientProvider.d.ts +1 -2
- package/dist/esm/providers/QueryClientProvider.d.ts.map +1 -1
- package/dist/esm/providers/SDKClientProvider.d.ts +2 -3
- package/dist/esm/providers/SDKClientProvider.d.ts.map +1 -1
- package/dist/esm/providers/WalletProvider/WalletProvider.d.ts +1 -2
- package/dist/esm/providers/WalletProvider/WalletProvider.d.ts.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts +2 -3
- package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
- package/dist/esm/providers/WidgetProvider/types.d.ts +2 -3
- package/dist/esm/providers/WidgetProvider/types.d.ts.map +1 -1
- package/dist/esm/stores/StoreProvider.d.ts +1 -2
- package/dist/esm/stores/StoreProvider.d.ts.map +1 -1
- package/dist/esm/stores/StoreProvider.js +10 -6
- package/dist/esm/stores/StoreProvider.js.map +1 -1
- package/dist/esm/stores/bookmarks/BookmarkStore.d.ts +1 -2
- package/dist/esm/stores/bookmarks/BookmarkStore.d.ts.map +1 -1
- package/dist/esm/stores/bookmarks/types.d.ts +5 -6
- package/dist/esm/stores/bookmarks/types.d.ts.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.d.ts +1 -2
- package/dist/esm/stores/chains/ChainOrderStore.d.ts.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.js +11 -5
- package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
- package/dist/esm/stores/chains/types.d.ts +1 -2
- package/dist/esm/stores/chains/types.d.ts.map +1 -1
- package/dist/esm/stores/form/types.d.ts +20 -21
- package/dist/esm/stores/form/types.d.ts.map +1 -1
- package/dist/esm/stores/form/useFieldActions.d.ts +1 -2
- package/dist/esm/stores/form/useFieldActions.d.ts.map +1 -1
- package/dist/esm/stores/form/useFieldValues.d.ts +1 -2
- package/dist/esm/stores/form/useFieldValues.d.ts.map +1 -1
- package/dist/esm/stores/header/types.d.ts +1 -2
- package/dist/esm/stores/header/types.d.ts.map +1 -1
- package/dist/esm/stores/header/useHeaderStore.d.ts +2 -3
- package/dist/esm/stores/header/useHeaderStore.d.ts.map +1 -1
- package/dist/esm/stores/inputMode/useInputModeStore.d.ts +1 -2
- package/dist/esm/stores/inputMode/useInputModeStore.d.ts.map +1 -1
- package/dist/esm/stores/recentTokens/RecentTokensStore.js +23 -0
- package/dist/esm/stores/recentTokens/RecentTokensStore.js.map +1 -0
- package/dist/esm/stores/recentTokens/createRecentTokensStore.js +54 -0
- package/dist/esm/stores/recentTokens/createRecentTokensStore.js.map +1 -0
- package/dist/esm/stores/recentTokens/utils.js +15 -0
- package/dist/esm/stores/recentTokens/utils.js.map +1 -0
- package/dist/esm/stores/routes/RouteExecutionStore.d.ts +2 -3
- package/dist/esm/stores/routes/RouteExecutionStore.d.ts.map +1 -1
- package/dist/esm/stores/routes/types.d.ts +3 -4
- package/dist/esm/stores/routes/types.d.ts.map +1 -1
- package/dist/esm/stores/routes/utils.d.ts +4 -5
- package/dist/esm/stores/routes/utils.d.ts.map +1 -1
- package/dist/esm/stores/settings/SettingsStore.d.ts +2 -3
- package/dist/esm/stores/settings/SettingsStore.d.ts.map +1 -1
- package/dist/esm/stores/settings/types.d.ts +2 -3
- package/dist/esm/stores/settings/types.d.ts.map +1 -1
- package/dist/esm/stores/types.d.ts +2 -3
- package/dist/esm/stores/types.d.ts.map +1 -1
- package/dist/esm/themes/azureLight.d.ts +1 -2
- package/dist/esm/themes/azureLight.d.ts.map +1 -1
- package/dist/esm/themes/jumper.d.ts +1 -2
- package/dist/esm/themes/jumper.d.ts.map +1 -1
- package/dist/esm/themes/palettes.d.ts +3 -4
- package/dist/esm/themes/palettes.d.ts.map +1 -1
- package/dist/esm/themes/types.d.ts +1 -0
- package/dist/esm/themes/watermelonLight.d.ts +1 -2
- package/dist/esm/themes/watermelonLight.d.ts.map +1 -1
- package/dist/esm/themes/windows95.d.ts +1 -2
- package/dist/esm/themes/windows95.d.ts.map +1 -1
- package/dist/esm/types/events.d.ts +13 -14
- package/dist/esm/types/events.d.ts.map +1 -1
- package/dist/esm/types/token.d.ts +4 -2
- package/dist/esm/types/token.d.ts.map +1 -1
- package/dist/esm/types/widget.d.ts +55 -51
- package/dist/esm/types/widget.d.ts.map +1 -1
- package/dist/esm/types/widget.js.map +1 -1
- package/dist/esm/utils/address.js +19 -0
- package/dist/esm/utils/address.js.map +1 -0
- package/dist/esm/utils/compactNumberFormatter.d.ts +1 -2
- package/dist/esm/utils/compactNumberFormatter.d.ts.map +1 -1
- package/dist/esm/utils/converters.d.ts +1 -2
- package/dist/esm/utils/converters.d.ts.map +1 -1
- package/dist/esm/utils/currencyExtendedFormatter.d.ts +1 -2
- package/dist/esm/utils/currencyExtendedFormatter.d.ts.map +1 -1
- package/dist/esm/utils/customReceiver.js +6 -1
- package/dist/esm/utils/customReceiver.js.map +1 -1
- package/dist/esm/utils/elements.d.ts +2 -3
- package/dist/esm/utils/elements.d.ts.map +1 -1
- package/dist/esm/utils/enum.d.ts +1 -2
- package/dist/esm/utils/enum.d.ts.map +1 -1
- package/dist/esm/utils/fees.d.ts +2 -3
- package/dist/esm/utils/fees.d.ts.map +1 -1
- package/dist/esm/utils/format.d.ts +8 -9
- package/dist/esm/utils/format.d.ts.map +1 -1
- package/dist/esm/utils/getPriceImpact.d.ts +1 -2
- package/dist/esm/utils/getPriceImpact.d.ts.map +1 -1
- package/dist/esm/utils/input.d.ts +1 -2
- package/dist/esm/utils/input.d.ts.map +1 -1
- package/dist/esm/utils/navigationRoutes.d.ts +2 -3
- package/dist/esm/utils/navigationRoutes.d.ts.map +1 -1
- package/dist/esm/utils/percentFormatter.d.ts +1 -2
- package/dist/esm/utils/percentFormatter.d.ts.map +1 -1
- package/dist/esm/utils/recentTokens.js +97 -0
- package/dist/esm/utils/recentTokens.js.map +1 -0
- package/dist/esm/utils/token.js +30 -4
- package/dist/esm/utils/token.js.map +1 -1
- package/dist/esm/utils/tokenList.js +18 -6
- package/dist/esm/utils/tokenList.js.map +1 -1
- package/dist/esm/utils/tokenListBands.js +85 -0
- package/dist/esm/utils/tokenListBands.js.map +1 -0
- package/dist/esm/utils/wallet.d.ts +1 -2
- package/dist/esm/utils/wallet.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/components/AmountInputCard/ReceiveAmountCard.tsx +16 -3
- package/src/components/BottomSheet/BottomSheet.tsx +3 -0
- package/src/components/Token/Token.tsx +2 -1
- package/src/components/TokenList/RecentTokensHeader.tsx +52 -0
- package/src/components/TokenList/RecentTokensToggle.tsx +45 -0
- package/src/components/TokenList/RemoveRecentTokenButton.tsx +38 -0
- package/src/components/TokenList/TokenList.tsx +92 -3
- package/src/components/TokenList/TokenListItem.tsx +15 -0
- package/src/components/TokenList/VirtualizedTokenList.tsx +84 -125
- package/src/components/TokenList/types.ts +9 -0
- package/src/config/version.ts +1 -1
- package/src/hooks/useDisplayedTokens.ts +17 -3
- package/src/hooks/useRecentTokens.ts +88 -0
- package/src/hooks/useRoutes.ts +8 -5
- package/src/hooks/useToAddressRequirements.ts +11 -5
- package/src/hooks/useTokenBalances.ts +34 -31
- package/src/hooks/useTokenSearch.ts +5 -14
- package/src/hooks/useTokens.ts +69 -27
- package/src/pages/TransactionPage/TokenValueBottomSheet.tsx +1 -1
- package/src/pages/TransactionPage/TokenVerificationBottomSheet.tsx +1 -1
- package/src/pages/TransactionPage/TransactionFailedButtons.tsx +62 -26
- package/src/pages/TransactionPage/TransactionReview.tsx +36 -37
- package/src/pages/TransactionPage/utils.ts +78 -0
- package/src/stores/StoreProvider.tsx +10 -7
- package/src/stores/chains/ChainOrderStore.test.tsx +298 -0
- package/src/stores/chains/ChainOrderStore.tsx +25 -6
- package/src/stores/recentTokens/RecentTokensStore.tsx +39 -0
- package/src/stores/recentTokens/createRecentTokensStore.ts +107 -0
- package/src/stores/recentTokens/types.ts +37 -0
- package/src/stores/recentTokens/utils.ts +18 -0
- package/src/types/token.ts +2 -0
- package/src/types/widget.ts +5 -0
- package/src/utils/address.ts +21 -0
- package/src/utils/customReceiver.ts +24 -0
- package/src/utils/recentTokens.ts +187 -0
- package/src/utils/token.ts +69 -10
- package/src/utils/tokenList.ts +41 -23
- package/src/utils/tokenListBands.ts +181 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import type { FormType } from '../stores/form/types.js'
|
|
2
|
+
import type {
|
|
3
|
+
RecentToken,
|
|
4
|
+
RecentTokenId,
|
|
5
|
+
} from '../stores/recentTokens/types.js'
|
|
6
|
+
import { getTokenKey } from '../stores/recentTokens/utils.js'
|
|
7
|
+
import type { TokenAmount } from '../types/token.js'
|
|
8
|
+
import type { AllowDenySets, WidgetTokens } from '../types/widget.js'
|
|
9
|
+
import { isFormItemAllowed } from './item.js'
|
|
10
|
+
import { getChainTokenAllowSets } from './token.js'
|
|
11
|
+
|
|
12
|
+
export const collapsedRecentCount = 4
|
|
13
|
+
|
|
14
|
+
export interface ResolveRecentRowsParams {
|
|
15
|
+
recentTokens: RecentToken[]
|
|
16
|
+
availableChainIds: Set<number>
|
|
17
|
+
configTokens: WidgetTokens | undefined
|
|
18
|
+
formType: FormType
|
|
19
|
+
selectedChainId?: number
|
|
20
|
+
isAllNetworks?: boolean
|
|
21
|
+
nativeHoisted: boolean
|
|
22
|
+
disabled: boolean
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface RecentRows {
|
|
26
|
+
/** Unsliced; empty when the band is inactive. */
|
|
27
|
+
rows: TokenAmount[]
|
|
28
|
+
/** Everything Clear removes, including toggled-away and displaced rows. */
|
|
29
|
+
bandEntries: RecentTokenId[]
|
|
30
|
+
recentStartIndex: number
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface RecentTokensResult {
|
|
34
|
+
tokens: TokenAmount[]
|
|
35
|
+
recentCount: number
|
|
36
|
+
totalRecentCount: number
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Whitelisted fields; a flag is the one verdict kept, as stale it only over-warns.
|
|
40
|
+
const toSnapshotRow = (recent: RecentToken): TokenAmount =>
|
|
41
|
+
({
|
|
42
|
+
chainId: recent.chainId,
|
|
43
|
+
address: recent.address,
|
|
44
|
+
symbol: recent.symbol,
|
|
45
|
+
name: recent.name,
|
|
46
|
+
decimals: recent.decimals,
|
|
47
|
+
logoURI: recent.logoURI,
|
|
48
|
+
priceUSD: '',
|
|
49
|
+
verificationStatus: recent.flagged ? 'flagged' : undefined,
|
|
50
|
+
}) as TokenAmount
|
|
51
|
+
|
|
52
|
+
const isFeaturedCopy = (token: TokenAmount): boolean =>
|
|
53
|
+
!!token.featured && !token.amount
|
|
54
|
+
|
|
55
|
+
export const resolveRecentRows = (
|
|
56
|
+
tokens: TokenAmount[],
|
|
57
|
+
{
|
|
58
|
+
recentTokens,
|
|
59
|
+
availableChainIds,
|
|
60
|
+
configTokens,
|
|
61
|
+
formType,
|
|
62
|
+
selectedChainId,
|
|
63
|
+
isAllNetworks,
|
|
64
|
+
nativeHoisted,
|
|
65
|
+
disabled,
|
|
66
|
+
}: ResolveRecentRowsParams
|
|
67
|
+
): RecentRows => {
|
|
68
|
+
let recentStartIndex = nativeHoisted ? 1 : 0
|
|
69
|
+
while (tokens[recentStartIndex]?.pinned) {
|
|
70
|
+
recentStartIndex++
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const inactive: RecentRows = { rows: [], bandEntries: [], recentStartIndex }
|
|
74
|
+
|
|
75
|
+
if (disabled || !recentTokens.length || !tokens.length) {
|
|
76
|
+
return inactive
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const candidates = recentTokens.filter(
|
|
80
|
+
(recent) =>
|
|
81
|
+
(isAllNetworks || recent.chainId === selectedChainId) &&
|
|
82
|
+
availableChainIds.has(recent.chainId)
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
if (!candidates.length) {
|
|
86
|
+
return inactive
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const wanted = new Set(
|
|
90
|
+
candidates.map((recent) => getTokenKey(recent.chainId, recent.address))
|
|
91
|
+
)
|
|
92
|
+
// All-networks holds tens of thousands of rows: test the chain before the key.
|
|
93
|
+
const wantedChains = new Set(candidates.map((recent) => recent.chainId))
|
|
94
|
+
const fresh = new Map<string, TokenAmount>()
|
|
95
|
+
// A featured config copy has no balance and sits above the row with one.
|
|
96
|
+
let awaitingBalance = 0
|
|
97
|
+
for (const token of tokens) {
|
|
98
|
+
if (!wantedChains.has(token.chainId)) {
|
|
99
|
+
continue
|
|
100
|
+
}
|
|
101
|
+
const key = getTokenKey(token.chainId, token.address)
|
|
102
|
+
if (!wanted.has(key)) {
|
|
103
|
+
continue
|
|
104
|
+
}
|
|
105
|
+
const found = fresh.get(key)
|
|
106
|
+
if (!found) {
|
|
107
|
+
fresh.set(key, token)
|
|
108
|
+
if (isFeaturedCopy(token)) {
|
|
109
|
+
awaitingBalance++
|
|
110
|
+
}
|
|
111
|
+
} else if (token.amount && isFeaturedCopy(found)) {
|
|
112
|
+
fresh.set(key, {
|
|
113
|
+
...found,
|
|
114
|
+
amount: token.amount,
|
|
115
|
+
priceUSD: token.priceUSD || found.priceUSD,
|
|
116
|
+
})
|
|
117
|
+
awaitingBalance--
|
|
118
|
+
}
|
|
119
|
+
if (fresh.size === wanted.size && !awaitingBalance) {
|
|
120
|
+
break
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const allowedByChain = new Map<number, AllowDenySets | undefined>()
|
|
125
|
+
const allowedFor = (chainId: number) => {
|
|
126
|
+
if (!allowedByChain.has(chainId)) {
|
|
127
|
+
allowedByChain.set(
|
|
128
|
+
chainId,
|
|
129
|
+
getChainTokenAllowSets(configTokens, chainId, formType)
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
return allowedByChain.get(chainId)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const hoistedKey = nativeHoisted
|
|
136
|
+
? getTokenKey(tokens[0].chainId, tokens[0].address)
|
|
137
|
+
: undefined
|
|
138
|
+
|
|
139
|
+
const rows: TokenAmount[] = []
|
|
140
|
+
const bandEntries: RecentTokenId[] = []
|
|
141
|
+
for (const recent of candidates) {
|
|
142
|
+
const key = getTokenKey(recent.chainId, recent.address)
|
|
143
|
+
const resolved = fresh.get(key) ?? toSnapshotRow(recent)
|
|
144
|
+
if (
|
|
145
|
+
!isFormItemAllowed(resolved, allowedFor(recent.chainId), formType, (t) =>
|
|
146
|
+
t.address.toLowerCase()
|
|
147
|
+
)
|
|
148
|
+
) {
|
|
149
|
+
// Denied on this side only, so Clear must leave it for the other side.
|
|
150
|
+
continue
|
|
151
|
+
}
|
|
152
|
+
// Clear owns displaced entries too, or they reappear once unpinned.
|
|
153
|
+
bandEntries.push({ chainId: recent.chainId, address: recent.address })
|
|
154
|
+
if (key === hoistedKey || resolved.pinned) {
|
|
155
|
+
continue
|
|
156
|
+
}
|
|
157
|
+
rows.push({ ...resolved, recent: true })
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!rows.length) {
|
|
161
|
+
return inactive
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return { rows, bandEntries, recentStartIndex }
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export const spliceRecentRows = (
|
|
168
|
+
tokens: TokenAmount[],
|
|
169
|
+
{ rows, recentStartIndex }: RecentRows,
|
|
170
|
+
expanded: boolean
|
|
171
|
+
): RecentTokensResult => {
|
|
172
|
+
if (!rows.length) {
|
|
173
|
+
return { tokens, recentCount: 0, totalRecentCount: 0 }
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const visible = expanded ? rows : rows.slice(0, collapsedRecentCount)
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
tokens: [
|
|
180
|
+
...tokens.slice(0, recentStartIndex),
|
|
181
|
+
...visible,
|
|
182
|
+
...tokens.slice(recentStartIndex),
|
|
183
|
+
],
|
|
184
|
+
recentCount: visible.length,
|
|
185
|
+
totalRecentCount: rows.length,
|
|
186
|
+
}
|
|
187
|
+
}
|
package/src/utils/token.ts
CHANGED
|
@@ -5,13 +5,35 @@ import type {
|
|
|
5
5
|
StaticToken,
|
|
6
6
|
Token,
|
|
7
7
|
TokenAmount,
|
|
8
|
+
TokenExtended,
|
|
8
9
|
} from '@lifi/sdk'
|
|
9
10
|
import { ChainId } from '@lifi/sdk'
|
|
10
11
|
import type { FormType } from '../stores/form/types.js'
|
|
11
12
|
import type { TokensByChain, TokenWithFlags } from '../types/token.js'
|
|
12
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
AllowDenySets,
|
|
15
|
+
WidgetChains,
|
|
16
|
+
WidgetTokens,
|
|
17
|
+
} from '../types/widget.js'
|
|
13
18
|
import { getConfigItemSets, isFormItemAllowed } from './item.js'
|
|
14
19
|
|
|
20
|
+
// Number(): plain-JS integrators may pass chainId as a string.
|
|
21
|
+
export const getChainTokenAllowSets = (
|
|
22
|
+
configTokens: WidgetTokens | undefined,
|
|
23
|
+
chainId: number,
|
|
24
|
+
formType?: FormType
|
|
25
|
+
): AllowDenySets | undefined =>
|
|
26
|
+
getConfigItemSets(
|
|
27
|
+
configTokens,
|
|
28
|
+
(tokens: BaseToken[]) =>
|
|
29
|
+
new Set(
|
|
30
|
+
tokens
|
|
31
|
+
.filter((t) => Number(t.chainId) === chainId)
|
|
32
|
+
.map((t) => t.address.toLowerCase())
|
|
33
|
+
),
|
|
34
|
+
formType
|
|
35
|
+
)
|
|
36
|
+
|
|
15
37
|
/**
|
|
16
38
|
* Builds per-chain sets of lowercase token addresses from the
|
|
17
39
|
* `tokens.verified` config allowlist.
|
|
@@ -71,9 +93,39 @@ export const mergeVerifiedWithSearchTokens = (
|
|
|
71
93
|
return result
|
|
72
94
|
}
|
|
73
95
|
|
|
96
|
+
/**
|
|
97
|
+
* `priceUSD` is a required string, so an unknown price arrives as `'0'` or `''`
|
|
98
|
+
* rather than as an absent key — the same reading as in `useLimitMarketRate`. A
|
|
99
|
+
* known price must never lose to one, or a route that cannot price its output
|
|
100
|
+
* blanks a value the cache already knew.
|
|
101
|
+
*/
|
|
102
|
+
export const knownPriceUSD = (fresher: string, cached: string): string =>
|
|
103
|
+
Number(fresher) ? fresher : cached
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Merges a cached token into a route token for display. The route wins on every
|
|
107
|
+
* field it carries; the cache only fills gaps. Letting the cache win instead
|
|
108
|
+
* swaps the quoted price for a stale feed price.
|
|
109
|
+
*/
|
|
110
|
+
export const mergeFallbackToken = (
|
|
111
|
+
routeToken: TokenAmount,
|
|
112
|
+
cachedToken: TokenExtended | undefined
|
|
113
|
+
): TokenAmount =>
|
|
114
|
+
cachedToken
|
|
115
|
+
? {
|
|
116
|
+
...cachedToken,
|
|
117
|
+
...routeToken,
|
|
118
|
+
priceUSD: knownPriceUSD(routeToken.priceUSD, cachedToken.priceUSD),
|
|
119
|
+
logoURI: routeToken.logoURI || cachedToken.logoURI,
|
|
120
|
+
}
|
|
121
|
+
: routeToken
|
|
122
|
+
|
|
74
123
|
/**
|
|
75
124
|
* Updates a token in the cache by chainId and address.
|
|
76
125
|
* Returns a new cache object with the token updated, or the original if not found.
|
|
126
|
+
* Addresses are compared case-insensitively: the token list and the route can
|
|
127
|
+
* spell the same address differently. The incoming token only overwrites what it
|
|
128
|
+
* actually knows, so an unpriced or logo-less route cannot blank the cache.
|
|
77
129
|
*/
|
|
78
130
|
export const updateTokenInCache = (
|
|
79
131
|
data: TokensByChain | undefined,
|
|
@@ -86,14 +138,26 @@ export const updateTokenInCache = (
|
|
|
86
138
|
if (!chainTokens) {
|
|
87
139
|
return data
|
|
88
140
|
}
|
|
89
|
-
const
|
|
141
|
+
const address = token.address.toLowerCase()
|
|
142
|
+
const index = chainTokens.findIndex(
|
|
143
|
+
(t) => t.address.toLowerCase() === address
|
|
144
|
+
)
|
|
90
145
|
if (index < 0) {
|
|
91
146
|
return data
|
|
92
147
|
}
|
|
93
148
|
return {
|
|
94
149
|
...data,
|
|
95
150
|
[token.chainId]: chainTokens.map((t, i) =>
|
|
96
|
-
i === index
|
|
151
|
+
i === index
|
|
152
|
+
? {
|
|
153
|
+
...t,
|
|
154
|
+
...token,
|
|
155
|
+
// Keep the cached address: other readers hold it as the identity.
|
|
156
|
+
address: t.address,
|
|
157
|
+
priceUSD: knownPriceUSD(token.priceUSD, t.priceUSD),
|
|
158
|
+
logoURI: token.logoURI || t.logoURI,
|
|
159
|
+
}
|
|
160
|
+
: t
|
|
97
161
|
),
|
|
98
162
|
}
|
|
99
163
|
}
|
|
@@ -140,14 +204,9 @@ export const filterAllowedTokens = (
|
|
|
140
204
|
chainIncludedTokens.map((t) => t.address.toLowerCase())
|
|
141
205
|
)
|
|
142
206
|
|
|
143
|
-
const allowedAddresses =
|
|
207
|
+
const allowedAddresses = getChainTokenAllowSets(
|
|
144
208
|
configTokens,
|
|
145
|
-
|
|
146
|
-
new Set(
|
|
147
|
-
tokens
|
|
148
|
-
.filter((t) => Number(t.chainId) === chainId)
|
|
149
|
-
.map((t) => t.address.toLowerCase())
|
|
150
|
-
),
|
|
209
|
+
chainId,
|
|
151
210
|
formType
|
|
152
211
|
)
|
|
153
212
|
|
package/src/utils/tokenList.ts
CHANGED
|
@@ -256,25 +256,49 @@ const processedTypedTokens = (
|
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Builds the filter for one search, so the query is normalized once instead of
|
|
261
|
+
* once per token: an all-networks list holds tens of thousands of rows, where
|
|
262
|
+
* normalizing per row costs more than the matching itself. Binding the mode
|
|
263
|
+
* here also keeps every call site of one search on the same rule.
|
|
264
|
+
*
|
|
265
|
+
* An address search matches the token at that address only. Impersonators
|
|
266
|
+
* embed a real address in their name or symbol, so a substring match on
|
|
267
|
+
* those fields would surface them for the very query meant to avoid them.
|
|
268
|
+
*/
|
|
269
|
+
export const createSearchMatcher = (
|
|
270
|
+
search: string | undefined,
|
|
271
|
+
isAddressSearch: boolean
|
|
272
|
+
): ((token: TokenExtended | TokenAmountExtended) => boolean) => {
|
|
273
|
+
const searchTerm = search?.trim().toLowerCase()
|
|
274
|
+
|
|
275
|
+
if (!searchTerm) {
|
|
276
|
+
return () => true
|
|
265
277
|
}
|
|
266
278
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
.includes(
|
|
274
|
-
|
|
275
|
-
|
|
279
|
+
if (isAddressSearch) {
|
|
280
|
+
return (token) => token.address?.toLowerCase() === searchTerm
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return (token) =>
|
|
284
|
+
Boolean(
|
|
285
|
+
token.name?.toLowerCase().includes(searchTerm) ||
|
|
286
|
+
token.symbol?.replaceAll('₮', 'T').toLowerCase().includes(searchTerm) ||
|
|
287
|
+
token.address?.toLowerCase().includes(searchTerm)
|
|
288
|
+
)
|
|
276
289
|
}
|
|
277
290
|
|
|
291
|
+
export const isHoistableNative = (
|
|
292
|
+
token: TokenAmount | undefined,
|
|
293
|
+
selectedChainId?: number
|
|
294
|
+
): boolean =>
|
|
295
|
+
!!token?.native &&
|
|
296
|
+
!token.pinned &&
|
|
297
|
+
!token.featured &&
|
|
298
|
+
!token.popular &&
|
|
299
|
+
!token.verified &&
|
|
300
|
+
(selectedChainId === undefined || token.chainId === selectedChainId)
|
|
301
|
+
|
|
278
302
|
/**
|
|
279
303
|
* Moves the chain's native token to the top of its own chain's list, unless an
|
|
280
304
|
* external list already places it. Returns the array unchanged when nothing
|
|
@@ -287,14 +311,8 @@ export const hoistNativeToken = (
|
|
|
287
311
|
if (!selectedChainId) {
|
|
288
312
|
return tokens
|
|
289
313
|
}
|
|
290
|
-
const index = tokens.findIndex(
|
|
291
|
-
(token)
|
|
292
|
-
token.native &&
|
|
293
|
-
token.chainId === selectedChainId &&
|
|
294
|
-
!token.featured &&
|
|
295
|
-
!token.popular &&
|
|
296
|
-
!token.pinned &&
|
|
297
|
-
!token.verified
|
|
314
|
+
const index = tokens.findIndex((token) =>
|
|
315
|
+
isHoistableNative(token, selectedChainId)
|
|
298
316
|
)
|
|
299
317
|
// -1 is no native token, 0 is already first
|
|
300
318
|
if (index < 1) {
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type { TokenAmount } from '../types/token.js'
|
|
2
|
+
|
|
3
|
+
const bandHeaderAtListStart = 24
|
|
4
|
+
const bandHeaderAfterBand = 32
|
|
5
|
+
const toggleRowHeight = 26
|
|
6
|
+
|
|
7
|
+
type BandLabelKey =
|
|
8
|
+
| 'main.pinnedTokens'
|
|
9
|
+
| 'main.featuredTokens'
|
|
10
|
+
| 'main.myTokens'
|
|
11
|
+
| 'main.popularTokens'
|
|
12
|
+
| 'main.allTokens'
|
|
13
|
+
|
|
14
|
+
export type BandLabel =
|
|
15
|
+
| { kind: 'text'; key: BandLabelKey; atListStart: boolean }
|
|
16
|
+
| { kind: 'recent'; atListStart: boolean }
|
|
17
|
+
|
|
18
|
+
export interface BandResolverOptions {
|
|
19
|
+
showCategories: boolean
|
|
20
|
+
showPinnedTokens: boolean
|
|
21
|
+
nativeHoisted: boolean
|
|
22
|
+
/** Ignored while `recentCount` is 0. */
|
|
23
|
+
recentStartIndex: number
|
|
24
|
+
recentCount: number
|
|
25
|
+
showRecentToggle: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface BandResolver {
|
|
29
|
+
/** Called for every index by the virtualizer, so it allocates nothing. */
|
|
30
|
+
getRowExtraHeight: (index: number) => number
|
|
31
|
+
/** Called for visible rows only, so the label may be resolved lazily. */
|
|
32
|
+
getRowBandLabel: (index: number) => BandLabel | undefined
|
|
33
|
+
/** The row the toggle hangs below. Shares one definition with the height. */
|
|
34
|
+
isToggleRow: (index: number) => boolean
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Pinned and recent rows sit above the categories; transitions ignore both.
|
|
38
|
+
const isPromoted = (token: TokenAmount | undefined): boolean =>
|
|
39
|
+
!!token?.pinned || !!token?.recent
|
|
40
|
+
|
|
41
|
+
export const createBandResolver = (
|
|
42
|
+
tokens: TokenAmount[],
|
|
43
|
+
{
|
|
44
|
+
showCategories,
|
|
45
|
+
showPinnedTokens,
|
|
46
|
+
nativeHoisted,
|
|
47
|
+
recentStartIndex,
|
|
48
|
+
recentCount,
|
|
49
|
+
showRecentToggle,
|
|
50
|
+
}: BandResolverOptions
|
|
51
|
+
): BandResolver => {
|
|
52
|
+
const listStartIndex = nativeHoisted ? 1 : 0
|
|
53
|
+
const recentEndIndex = recentStartIndex + recentCount - 1
|
|
54
|
+
|
|
55
|
+
const isFirstPinned = (index: number) =>
|
|
56
|
+
!!tokens[index]?.pinned && index === listStartIndex
|
|
57
|
+
const isFirstRecent = (index: number) =>
|
|
58
|
+
recentCount > 0 && index === recentStartIndex && !!tokens[index]?.recent
|
|
59
|
+
const isLastRecent = (index: number) =>
|
|
60
|
+
recentCount > 0 && index === recentEndIndex && !!tokens[index]?.recent
|
|
61
|
+
// The hoisted native sits above every band, so the list-start row follows none.
|
|
62
|
+
const previousOf = (index: number) =>
|
|
63
|
+
index === listStartIndex ? undefined : tokens[index - 1]
|
|
64
|
+
const isTransitionFromPromoted = (index: number) =>
|
|
65
|
+
isPromoted(tokens[index - 1]) && !isPromoted(tokens[index])
|
|
66
|
+
// Only the top row has no card above it; below the hoisted native one does.
|
|
67
|
+
const isTopRow = (index: number) => index === 0
|
|
68
|
+
const headerHeight = (index: number) =>
|
|
69
|
+
isTopRow(index) ? bandHeaderAtListStart : bandHeaderAfterBand
|
|
70
|
+
|
|
71
|
+
const getRowExtraHeight = (index: number): number => {
|
|
72
|
+
const current = tokens[index]
|
|
73
|
+
const previous = previousOf(index)
|
|
74
|
+
let extra = 0
|
|
75
|
+
|
|
76
|
+
if (showPinnedTokens && isFirstPinned(index)) {
|
|
77
|
+
extra += headerHeight(index)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (isFirstRecent(index)) {
|
|
81
|
+
extra += headerHeight(index)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (showRecentToggle && isLastRecent(index)) {
|
|
85
|
+
extra += toggleRowHeight
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// The recent band needs its own term: all-networks has no categories.
|
|
89
|
+
if (
|
|
90
|
+
(showPinnedTokens || showCategories || recentCount > 0) &&
|
|
91
|
+
isTransitionFromPromoted(index)
|
|
92
|
+
) {
|
|
93
|
+
extra += bandHeaderAfterBand
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!showCategories) {
|
|
97
|
+
return extra
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (current?.featured && !isPromoted(current) && index === listStartIndex) {
|
|
101
|
+
extra += headerHeight(index)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const isNotPromoted = !isPromoted(current) && !isPromoted(previous)
|
|
105
|
+
if (
|
|
106
|
+
index !== listStartIndex &&
|
|
107
|
+
isNotPromoted &&
|
|
108
|
+
((previous?.amount && !current?.amount) ||
|
|
109
|
+
(previous?.featured && !current?.featured) ||
|
|
110
|
+
(previous?.popular && !current?.popular))
|
|
111
|
+
) {
|
|
112
|
+
extra += bandHeaderAfterBand
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return extra
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const getRowBandLabel = (index: number): BandLabel | undefined => {
|
|
119
|
+
const current = tokens[index]
|
|
120
|
+
const previous = previousOf(index)
|
|
121
|
+
const isListStart = index === listStartIndex
|
|
122
|
+
const notPromoted = !isPromoted(current)
|
|
123
|
+
const fromPromoted = isPromoted(previous) && notPromoted
|
|
124
|
+
|
|
125
|
+
if (showPinnedTokens && isFirstPinned(index)) {
|
|
126
|
+
return {
|
|
127
|
+
kind: 'text',
|
|
128
|
+
key: 'main.pinnedTokens',
|
|
129
|
+
atListStart: isTopRow(index),
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (isFirstRecent(index)) {
|
|
133
|
+
return { kind: 'recent', atListStart: isTopRow(index) }
|
|
134
|
+
}
|
|
135
|
+
if (
|
|
136
|
+
(showPinnedTokens || recentCount > 0) &&
|
|
137
|
+
!showCategories &&
|
|
138
|
+
fromPromoted
|
|
139
|
+
) {
|
|
140
|
+
return { kind: 'text', key: 'main.allTokens', atListStart: false }
|
|
141
|
+
}
|
|
142
|
+
if (!showCategories) {
|
|
143
|
+
return undefined
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const fromFeatured =
|
|
147
|
+
!!previous?.featured && !current?.featured && notPromoted
|
|
148
|
+
const fromMyTokens = !!previous?.amount && !current?.amount && notPromoted
|
|
149
|
+
const fromPopular = !!previous?.popular && !current?.popular && notPromoted
|
|
150
|
+
|
|
151
|
+
if (
|
|
152
|
+
(fromPromoted && current?.featured) ||
|
|
153
|
+
(current?.featured && notPromoted && isListStart)
|
|
154
|
+
) {
|
|
155
|
+
return {
|
|
156
|
+
kind: 'text',
|
|
157
|
+
key: 'main.featuredTokens',
|
|
158
|
+
atListStart: isTopRow(index),
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if ((fromFeatured || fromPromoted) && current?.amount && notPromoted) {
|
|
162
|
+
return { kind: 'text', key: 'main.myTokens', atListStart: false }
|
|
163
|
+
}
|
|
164
|
+
if (
|
|
165
|
+
(fromFeatured || fromMyTokens || fromPromoted) &&
|
|
166
|
+
current?.popular &&
|
|
167
|
+
notPromoted
|
|
168
|
+
) {
|
|
169
|
+
return { kind: 'text', key: 'main.popularTokens', atListStart: false }
|
|
170
|
+
}
|
|
171
|
+
if (fromMyTokens || fromFeatured || fromPromoted || fromPopular) {
|
|
172
|
+
return { kind: 'text', key: 'main.allTokens', atListStart: false }
|
|
173
|
+
}
|
|
174
|
+
return undefined
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const isToggleRow = (index: number): boolean =>
|
|
178
|
+
showRecentToggle && isLastRecent(index)
|
|
179
|
+
|
|
180
|
+
return { getRowExtraHeight, getRowBandLabel, isToggleRow }
|
|
181
|
+
}
|