@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.
Files changed (394) hide show
  1. package/README.md +26 -3
  2. package/dist/esm/App.d.ts +1 -2
  3. package/dist/esm/App.d.ts.map +1 -1
  4. package/dist/esm/AppDrawer.d.ts +1 -2
  5. package/dist/esm/AppDrawer.d.ts.map +1 -1
  6. package/dist/esm/components/ActionRow/ActionRow.d.ts +1 -2
  7. package/dist/esm/components/ActionRow/ActionRow.d.ts.map +1 -1
  8. package/dist/esm/components/AmountInput/AmountInput.style.d.ts +2 -2
  9. package/dist/esm/components/AmountInput/AmountInput.style.d.ts.map +1 -1
  10. package/dist/esm/components/AmountInput/AmountInputEndAdornment.d.ts +1 -2
  11. package/dist/esm/components/AmountInput/AmountInputEndAdornment.d.ts.map +1 -1
  12. package/dist/esm/components/AmountInput/PriceFormHelperText.style.d.ts +1 -2
  13. package/dist/esm/components/AmountInput/PriceFormHelperText.style.d.ts.map +1 -1
  14. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js +6 -2
  15. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -1
  16. package/dist/esm/components/Avatar/Avatar.d.ts +1 -2
  17. package/dist/esm/components/Avatar/Avatar.d.ts.map +1 -1
  18. package/dist/esm/components/Avatar/TokenAvatar.d.ts +1 -2
  19. package/dist/esm/components/Avatar/TokenAvatar.d.ts.map +1 -1
  20. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.d.ts +1 -2
  21. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.d.ts.map +1 -1
  22. package/dist/esm/components/BaseTransactionButton/types.d.ts +1 -2
  23. package/dist/esm/components/BaseTransactionButton/types.d.ts.map +1 -1
  24. package/dist/esm/components/BottomSheet/BottomSheet.js +1 -0
  25. package/dist/esm/components/BottomSheet/BottomSheet.js.map +1 -1
  26. package/dist/esm/components/BottomSheet/types.d.ts +1 -2
  27. package/dist/esm/components/BottomSheet/types.d.ts.map +1 -1
  28. package/dist/esm/components/ButtonTertiary.d.ts +1 -2
  29. package/dist/esm/components/ButtonTertiary.d.ts.map +1 -1
  30. package/dist/esm/components/Card/CardIconButton.d.ts +1 -2
  31. package/dist/esm/components/Card/CardIconButton.d.ts.map +1 -1
  32. package/dist/esm/components/Card/CardTitle.d.ts +1 -2
  33. package/dist/esm/components/Card/CardTitle.d.ts.map +1 -1
  34. package/dist/esm/components/Card/InputCard.d.ts +1 -2
  35. package/dist/esm/components/Card/InputCard.d.ts.map +1 -1
  36. package/dist/esm/components/ChainSelect/ChainSelect.d.ts +1 -2
  37. package/dist/esm/components/ChainSelect/ChainSelect.d.ts.map +1 -1
  38. package/dist/esm/components/ChainSelect/ChainSelect.style.d.ts +1 -2
  39. package/dist/esm/components/ChainSelect/ChainSelect.style.d.ts.map +1 -1
  40. package/dist/esm/components/ContractComponent/ContractComponent.d.ts +1 -2
  41. package/dist/esm/components/ContractComponent/ContractComponent.d.ts.map +1 -1
  42. package/dist/esm/components/ContractComponent/ItemPrice.d.ts +2 -3
  43. package/dist/esm/components/ContractComponent/ItemPrice.d.ts.map +1 -1
  44. package/dist/esm/components/ContractComponent/NFT/NFT.d.ts +1 -2
  45. package/dist/esm/components/ContractComponent/NFT/NFT.d.ts.map +1 -1
  46. package/dist/esm/components/ContractComponent/NFT/NFTBase.d.ts +1 -2
  47. package/dist/esm/components/ContractComponent/NFT/NFTBase.d.ts.map +1 -1
  48. package/dist/esm/components/ContractComponent/NFT/types.d.ts +3 -4
  49. package/dist/esm/components/ContractComponent/NFT/types.d.ts.map +1 -1
  50. package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.d.ts +1 -2
  51. package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.d.ts.map +1 -1
  52. package/dist/esm/components/ExecutionStatusCard/StatusIcon.d.ts +1 -2
  53. package/dist/esm/components/ExecutionStatusCard/StatusIcon.d.ts.map +1 -1
  54. package/dist/esm/components/FeeBreakdownTooltip.d.ts +1 -2
  55. package/dist/esm/components/FeeBreakdownTooltip.d.ts.map +1 -1
  56. package/dist/esm/components/IconCircle/IconCircle.d.ts +1 -2
  57. package/dist/esm/components/IconCircle/IconCircle.d.ts.map +1 -1
  58. package/dist/esm/components/IconCircle/statusIcons.d.ts +1 -2
  59. package/dist/esm/components/IconCircle/statusIcons.d.ts.map +1 -1
  60. package/dist/esm/components/IconTypography.d.ts +1 -2
  61. package/dist/esm/components/IconTypography.d.ts.map +1 -1
  62. package/dist/esm/components/ListItem/ListItemButton.d.ts +1 -2
  63. package/dist/esm/components/ListItem/ListItemButton.d.ts.map +1 -1
  64. package/dist/esm/components/Messages/WarningMessages.d.ts +1 -2
  65. package/dist/esm/components/Messages/WarningMessages.d.ts.map +1 -1
  66. package/dist/esm/components/PageContainer.d.ts +2 -3
  67. package/dist/esm/components/PageContainer.d.ts.map +1 -1
  68. package/dist/esm/components/PoweredBy/PoweredBy.d.ts +1 -2
  69. package/dist/esm/components/PoweredBy/PoweredBy.d.ts.map +1 -1
  70. package/dist/esm/components/ProgressToNextUpdate.d.ts +1 -2
  71. package/dist/esm/components/ProgressToNextUpdate.d.ts.map +1 -1
  72. package/dist/esm/components/RouteCard/RouteCard.d.ts +1 -2
  73. package/dist/esm/components/RouteCard/RouteCard.d.ts.map +1 -1
  74. package/dist/esm/components/RouteCard/RouteCardSkeleton.d.ts +1 -2
  75. package/dist/esm/components/RouteCard/RouteCardSkeleton.d.ts.map +1 -1
  76. package/dist/esm/components/RouteCard/RouteDetails.d.ts +1 -2
  77. package/dist/esm/components/RouteCard/RouteDetails.d.ts.map +1 -1
  78. package/dist/esm/components/RouteCard/RouteDetails.style.d.ts +5 -6
  79. package/dist/esm/components/RouteCard/RouteDetails.style.d.ts.map +1 -1
  80. package/dist/esm/components/RouteCard/RouteNotFoundCard.d.ts +1 -2
  81. package/dist/esm/components/RouteCard/RouteNotFoundCard.d.ts.map +1 -1
  82. package/dist/esm/components/RouteCard/RouteTokens.d.ts +1 -2
  83. package/dist/esm/components/RouteCard/RouteTokens.d.ts.map +1 -1
  84. package/dist/esm/components/RouteCard/types.d.ts +2 -3
  85. package/dist/esm/components/RouteCard/types.d.ts.map +1 -1
  86. package/dist/esm/components/Search/SearchInput.d.ts +1 -2
  87. package/dist/esm/components/Search/SearchInput.d.ts.map +1 -1
  88. package/dist/esm/components/SendToWallet/SendToWalletButton.d.ts +1 -2
  89. package/dist/esm/components/SendToWallet/SendToWalletButton.d.ts.map +1 -1
  90. package/dist/esm/components/Skeleton/WidgetSkeleton.d.ts +1 -2
  91. package/dist/esm/components/Skeleton/WidgetSkeleton.d.ts.map +1 -1
  92. package/dist/esm/components/StepActions/SentToWalletRow.d.ts +1 -2
  93. package/dist/esm/components/StepActions/SentToWalletRow.d.ts.map +1 -1
  94. package/dist/esm/components/StepActions/StepActionRow.style.d.ts +1 -2
  95. package/dist/esm/components/StepActions/StepActionRow.style.d.ts.map +1 -1
  96. package/dist/esm/components/StepActions/StepActionsList.d.ts +1 -2
  97. package/dist/esm/components/StepActions/StepActionsList.d.ts.map +1 -1
  98. package/dist/esm/components/StepActions/executionRows.d.ts +2 -3
  99. package/dist/esm/components/StepActions/executionRows.d.ts.map +1 -1
  100. package/dist/esm/components/Token/Token.d.ts.map +1 -1
  101. package/dist/esm/components/Token/Token.js +2 -4
  102. package/dist/esm/components/Token/Token.js.map +1 -1
  103. package/dist/esm/components/TokenList/RecentTokensHeader.js +44 -0
  104. package/dist/esm/components/TokenList/RecentTokensHeader.js.map +1 -0
  105. package/dist/esm/components/TokenList/RecentTokensToggle.js +36 -0
  106. package/dist/esm/components/TokenList/RecentTokensToggle.js.map +1 -0
  107. package/dist/esm/components/TokenList/RemoveRecentTokenButton.js +32 -0
  108. package/dist/esm/components/TokenList/RemoveRecentTokenButton.js.map +1 -0
  109. package/dist/esm/components/TokenList/TokenList.js +55 -5
  110. package/dist/esm/components/TokenList/TokenList.js.map +1 -1
  111. package/dist/esm/components/TokenList/TokenListItem.js +35 -19
  112. package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
  113. package/dist/esm/components/TokenList/TokenNotFound.d.ts +1 -2
  114. package/dist/esm/components/TokenList/TokenNotFound.d.ts.map +1 -1
  115. package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts +1 -2
  116. package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts.map +1 -1
  117. package/dist/esm/components/TokenList/VirtualizedTokenList.js +55 -42
  118. package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
  119. package/dist/esm/components/TokenList/types.d.ts +9 -2
  120. package/dist/esm/components/TokenList/types.d.ts.map +1 -1
  121. package/dist/esm/components/TokenList/useTokenSelect.d.ts +1 -2
  122. package/dist/esm/components/TokenList/useTokenSelect.d.ts.map +1 -1
  123. package/dist/esm/components/TokenRate/TokenRate.d.ts +1 -2
  124. package/dist/esm/components/TokenRate/TokenRate.d.ts.map +1 -1
  125. package/dist/esm/components/TransactionCard/TransactionCard.style.d.ts +2 -3
  126. package/dist/esm/components/TransactionCard/TransactionCard.style.d.ts.map +1 -1
  127. package/dist/esm/config/constants.d.ts +1 -2
  128. package/dist/esm/config/constants.d.ts.map +1 -1
  129. package/dist/esm/config/version.d.ts +2 -3
  130. package/dist/esm/config/version.d.ts.map +1 -1
  131. package/dist/esm/config/version.js +1 -1
  132. package/dist/esm/config/version.js.map +1 -1
  133. package/dist/esm/hooks/useAddressActivity.d.ts +1 -2
  134. package/dist/esm/hooks/useAddressActivity.d.ts.map +1 -1
  135. package/dist/esm/hooks/useAddressValidation.d.ts +2 -3
  136. package/dist/esm/hooks/useAddressValidation.d.ts.map +1 -1
  137. package/dist/esm/hooks/useAvailableChains.d.ts +1 -2
  138. package/dist/esm/hooks/useAvailableChains.d.ts.map +1 -1
  139. package/dist/esm/hooks/useChain.d.ts +1 -2
  140. package/dist/esm/hooks/useChain.d.ts.map +1 -1
  141. package/dist/esm/hooks/useContactSupport.d.ts +1 -2
  142. package/dist/esm/hooks/useContactSupport.d.ts.map +1 -1
  143. package/dist/esm/hooks/useDebouncedWatch.d.ts +1 -2
  144. package/dist/esm/hooks/useDebouncedWatch.d.ts.map +1 -1
  145. package/dist/esm/hooks/useDisplayedTokens.js +6 -4
  146. package/dist/esm/hooks/useDisplayedTokens.js.map +1 -1
  147. package/dist/esm/hooks/useExplorer.d.ts +1 -2
  148. package/dist/esm/hooks/useExplorer.d.ts.map +1 -1
  149. package/dist/esm/hooks/useHeader.d.ts +1 -2
  150. package/dist/esm/hooks/useHeader.d.ts.map +1 -1
  151. package/dist/esm/hooks/useListHeight.d.ts +1 -2
  152. package/dist/esm/hooks/useListHeight.d.ts.map +1 -1
  153. package/dist/esm/hooks/useNavigateBack.d.ts +1 -2
  154. package/dist/esm/hooks/useNavigateBack.d.ts.map +1 -1
  155. package/dist/esm/hooks/useRecentTokens.js +46 -0
  156. package/dist/esm/hooks/useRecentTokens.js.map +1 -0
  157. package/dist/esm/hooks/useRouteExecution.d.ts +1 -2
  158. package/dist/esm/hooks/useRouteExecution.d.ts.map +1 -1
  159. package/dist/esm/hooks/useRouteExecutionMessage.d.ts +1 -2
  160. package/dist/esm/hooks/useRouteExecutionMessage.d.ts.map +1 -1
  161. package/dist/esm/hooks/useRoutes.d.ts +1 -2
  162. package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
  163. package/dist/esm/hooks/useRoutes.js +7 -2
  164. package/dist/esm/hooks/useRoutes.js.map +1 -1
  165. package/dist/esm/hooks/useToAddressRequirements.d.ts +1 -2
  166. package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
  167. package/dist/esm/hooks/useToAddressRequirements.js +8 -2
  168. package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
  169. package/dist/esm/hooks/useToken.d.ts +1 -2
  170. package/dist/esm/hooks/useToken.d.ts.map +1 -1
  171. package/dist/esm/hooks/useTokenAddressBalance.d.ts +1 -2
  172. package/dist/esm/hooks/useTokenAddressBalance.d.ts.map +1 -1
  173. package/dist/esm/hooks/useTokenBalances.d.ts +3 -2
  174. package/dist/esm/hooks/useTokenBalances.d.ts.map +1 -1
  175. package/dist/esm/hooks/useTokenBalances.js +15 -9
  176. package/dist/esm/hooks/useTokenBalances.js.map +1 -1
  177. package/dist/esm/hooks/useTokenList.d.ts +1 -2
  178. package/dist/esm/hooks/useTokenList.d.ts.map +1 -1
  179. package/dist/esm/hooks/useTokenSearch.js +3 -2
  180. package/dist/esm/hooks/useTokenSearch.js.map +1 -1
  181. package/dist/esm/hooks/useTokens.js +26 -15
  182. package/dist/esm/hooks/useTokens.js.map +1 -1
  183. package/dist/esm/hooks/useTools.d.ts +1 -2
  184. package/dist/esm/hooks/useTools.d.ts.map +1 -1
  185. package/dist/esm/hooks/useWidgetChains.d.ts +1 -2
  186. package/dist/esm/hooks/useWidgetChains.d.ts.map +1 -1
  187. package/dist/esm/hooks/useWidgetEvents.d.ts +3 -4
  188. package/dist/esm/hooks/useWidgetEvents.d.ts.map +1 -1
  189. package/dist/esm/i18n/bn.json +4 -0
  190. package/dist/esm/i18n/de.json +4 -0
  191. package/dist/esm/i18n/en.json +4 -0
  192. package/dist/esm/i18n/es.json +4 -0
  193. package/dist/esm/i18n/fr.json +4 -0
  194. package/dist/esm/i18n/hi.json +4 -0
  195. package/dist/esm/i18n/id.json +4 -0
  196. package/dist/esm/i18n/it.json +4 -0
  197. package/dist/esm/i18n/ja.json +4 -0
  198. package/dist/esm/i18n/ko.json +4 -0
  199. package/dist/esm/i18n/pl.json +4 -0
  200. package/dist/esm/i18n/pt.json +4 -0
  201. package/dist/esm/i18n/th.json +4 -0
  202. package/dist/esm/i18n/tr.json +4 -0
  203. package/dist/esm/i18n/uk.json +4 -0
  204. package/dist/esm/i18n/vi.json +4 -0
  205. package/dist/esm/i18n/zh.json +4 -0
  206. package/dist/esm/pages/MainPage/MainWarningMessages.d.ts +1 -2
  207. package/dist/esm/pages/MainPage/MainWarningMessages.d.ts.map +1 -1
  208. package/dist/esm/pages/SelectChainPage/SelectChainPage.d.ts +1 -2
  209. package/dist/esm/pages/SelectChainPage/SelectChainPage.d.ts.map +1 -1
  210. package/dist/esm/pages/SelectChainPage/types.d.ts +1 -2
  211. package/dist/esm/pages/SelectChainPage/types.d.ts.map +1 -1
  212. package/dist/esm/pages/SelectTokenPage/SearchTokenInput.d.ts +1 -2
  213. package/dist/esm/pages/SelectTokenPage/SearchTokenInput.d.ts.map +1 -1
  214. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.d.ts +1 -2
  215. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.d.ts.map +1 -1
  216. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.d.ts +1 -2
  217. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.d.ts.map +1 -1
  218. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.d.ts +2 -3
  219. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.d.ts.map +1 -1
  220. package/dist/esm/pages/TransactionPage/ExecutionDoneCard.d.ts +1 -2
  221. package/dist/esm/pages/TransactionPage/ExecutionDoneCard.d.ts.map +1 -1
  222. package/dist/esm/pages/TransactionPage/RouteTracker.d.ts +1 -2
  223. package/dist/esm/pages/TransactionPage/RouteTracker.d.ts.map +1 -1
  224. package/dist/esm/pages/TransactionPage/StartTransactionButton.d.ts +1 -2
  225. package/dist/esm/pages/TransactionPage/StartTransactionButton.d.ts.map +1 -1
  226. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.d.ts +1 -2
  227. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.d.ts.map +1 -1
  228. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js +0 -1
  229. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
  230. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js +0 -1
  231. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js.map +1 -1
  232. package/dist/esm/pages/TransactionPage/TransactionDoneButtons.d.ts +1 -2
  233. package/dist/esm/pages/TransactionPage/TransactionDoneButtons.d.ts.map +1 -1
  234. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js +38 -12
  235. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js.map +1 -1
  236. package/dist/esm/pages/TransactionPage/TransactionReview.js +22 -21
  237. package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
  238. package/dist/esm/pages/TransactionPage/types.d.ts +1 -2
  239. package/dist/esm/pages/TransactionPage/types.d.ts.map +1 -1
  240. package/dist/esm/pages/TransactionPage/utils.d.ts +2 -3
  241. package/dist/esm/pages/TransactionPage/utils.d.ts.map +1 -1
  242. package/dist/esm/pages/TransactionPage/utils.js +23 -1
  243. package/dist/esm/pages/TransactionPage/utils.js.map +1 -1
  244. package/dist/esm/providers/I18nProvider/I18nProvider.d.ts +1 -2
  245. package/dist/esm/providers/I18nProvider/I18nProvider.d.ts.map +1 -1
  246. package/dist/esm/providers/I18nProvider/types.d.ts +4 -5
  247. package/dist/esm/providers/I18nProvider/types.d.ts.map +1 -1
  248. package/dist/esm/providers/QueryClientProvider.d.ts +1 -2
  249. package/dist/esm/providers/QueryClientProvider.d.ts.map +1 -1
  250. package/dist/esm/providers/SDKClientProvider.d.ts +2 -3
  251. package/dist/esm/providers/SDKClientProvider.d.ts.map +1 -1
  252. package/dist/esm/providers/WalletProvider/WalletProvider.d.ts +1 -2
  253. package/dist/esm/providers/WalletProvider/WalletProvider.d.ts.map +1 -1
  254. package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts +2 -3
  255. package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
  256. package/dist/esm/providers/WidgetProvider/types.d.ts +2 -3
  257. package/dist/esm/providers/WidgetProvider/types.d.ts.map +1 -1
  258. package/dist/esm/stores/StoreProvider.d.ts +1 -2
  259. package/dist/esm/stores/StoreProvider.d.ts.map +1 -1
  260. package/dist/esm/stores/StoreProvider.js +10 -6
  261. package/dist/esm/stores/StoreProvider.js.map +1 -1
  262. package/dist/esm/stores/bookmarks/BookmarkStore.d.ts +1 -2
  263. package/dist/esm/stores/bookmarks/BookmarkStore.d.ts.map +1 -1
  264. package/dist/esm/stores/bookmarks/types.d.ts +5 -6
  265. package/dist/esm/stores/bookmarks/types.d.ts.map +1 -1
  266. package/dist/esm/stores/chains/ChainOrderStore.d.ts +1 -2
  267. package/dist/esm/stores/chains/ChainOrderStore.d.ts.map +1 -1
  268. package/dist/esm/stores/chains/ChainOrderStore.js +11 -5
  269. package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
  270. package/dist/esm/stores/chains/types.d.ts +1 -2
  271. package/dist/esm/stores/chains/types.d.ts.map +1 -1
  272. package/dist/esm/stores/form/types.d.ts +20 -21
  273. package/dist/esm/stores/form/types.d.ts.map +1 -1
  274. package/dist/esm/stores/form/useFieldActions.d.ts +1 -2
  275. package/dist/esm/stores/form/useFieldActions.d.ts.map +1 -1
  276. package/dist/esm/stores/form/useFieldValues.d.ts +1 -2
  277. package/dist/esm/stores/form/useFieldValues.d.ts.map +1 -1
  278. package/dist/esm/stores/header/types.d.ts +1 -2
  279. package/dist/esm/stores/header/types.d.ts.map +1 -1
  280. package/dist/esm/stores/header/useHeaderStore.d.ts +2 -3
  281. package/dist/esm/stores/header/useHeaderStore.d.ts.map +1 -1
  282. package/dist/esm/stores/inputMode/useInputModeStore.d.ts +1 -2
  283. package/dist/esm/stores/inputMode/useInputModeStore.d.ts.map +1 -1
  284. package/dist/esm/stores/recentTokens/RecentTokensStore.js +23 -0
  285. package/dist/esm/stores/recentTokens/RecentTokensStore.js.map +1 -0
  286. package/dist/esm/stores/recentTokens/createRecentTokensStore.js +54 -0
  287. package/dist/esm/stores/recentTokens/createRecentTokensStore.js.map +1 -0
  288. package/dist/esm/stores/recentTokens/utils.js +15 -0
  289. package/dist/esm/stores/recentTokens/utils.js.map +1 -0
  290. package/dist/esm/stores/routes/RouteExecutionStore.d.ts +2 -3
  291. package/dist/esm/stores/routes/RouteExecutionStore.d.ts.map +1 -1
  292. package/dist/esm/stores/routes/types.d.ts +3 -4
  293. package/dist/esm/stores/routes/types.d.ts.map +1 -1
  294. package/dist/esm/stores/routes/utils.d.ts +4 -5
  295. package/dist/esm/stores/routes/utils.d.ts.map +1 -1
  296. package/dist/esm/stores/settings/SettingsStore.d.ts +2 -3
  297. package/dist/esm/stores/settings/SettingsStore.d.ts.map +1 -1
  298. package/dist/esm/stores/settings/types.d.ts +2 -3
  299. package/dist/esm/stores/settings/types.d.ts.map +1 -1
  300. package/dist/esm/stores/types.d.ts +2 -3
  301. package/dist/esm/stores/types.d.ts.map +1 -1
  302. package/dist/esm/themes/azureLight.d.ts +1 -2
  303. package/dist/esm/themes/azureLight.d.ts.map +1 -1
  304. package/dist/esm/themes/jumper.d.ts +1 -2
  305. package/dist/esm/themes/jumper.d.ts.map +1 -1
  306. package/dist/esm/themes/palettes.d.ts +3 -4
  307. package/dist/esm/themes/palettes.d.ts.map +1 -1
  308. package/dist/esm/themes/types.d.ts +1 -0
  309. package/dist/esm/themes/watermelonLight.d.ts +1 -2
  310. package/dist/esm/themes/watermelonLight.d.ts.map +1 -1
  311. package/dist/esm/themes/windows95.d.ts +1 -2
  312. package/dist/esm/themes/windows95.d.ts.map +1 -1
  313. package/dist/esm/types/events.d.ts +13 -14
  314. package/dist/esm/types/events.d.ts.map +1 -1
  315. package/dist/esm/types/token.d.ts +4 -2
  316. package/dist/esm/types/token.d.ts.map +1 -1
  317. package/dist/esm/types/widget.d.ts +55 -51
  318. package/dist/esm/types/widget.d.ts.map +1 -1
  319. package/dist/esm/types/widget.js.map +1 -1
  320. package/dist/esm/utils/address.js +19 -0
  321. package/dist/esm/utils/address.js.map +1 -0
  322. package/dist/esm/utils/compactNumberFormatter.d.ts +1 -2
  323. package/dist/esm/utils/compactNumberFormatter.d.ts.map +1 -1
  324. package/dist/esm/utils/converters.d.ts +1 -2
  325. package/dist/esm/utils/converters.d.ts.map +1 -1
  326. package/dist/esm/utils/currencyExtendedFormatter.d.ts +1 -2
  327. package/dist/esm/utils/currencyExtendedFormatter.d.ts.map +1 -1
  328. package/dist/esm/utils/customReceiver.js +6 -1
  329. package/dist/esm/utils/customReceiver.js.map +1 -1
  330. package/dist/esm/utils/elements.d.ts +2 -3
  331. package/dist/esm/utils/elements.d.ts.map +1 -1
  332. package/dist/esm/utils/enum.d.ts +1 -2
  333. package/dist/esm/utils/enum.d.ts.map +1 -1
  334. package/dist/esm/utils/fees.d.ts +2 -3
  335. package/dist/esm/utils/fees.d.ts.map +1 -1
  336. package/dist/esm/utils/format.d.ts +8 -9
  337. package/dist/esm/utils/format.d.ts.map +1 -1
  338. package/dist/esm/utils/getPriceImpact.d.ts +1 -2
  339. package/dist/esm/utils/getPriceImpact.d.ts.map +1 -1
  340. package/dist/esm/utils/input.d.ts +1 -2
  341. package/dist/esm/utils/input.d.ts.map +1 -1
  342. package/dist/esm/utils/navigationRoutes.d.ts +2 -3
  343. package/dist/esm/utils/navigationRoutes.d.ts.map +1 -1
  344. package/dist/esm/utils/percentFormatter.d.ts +1 -2
  345. package/dist/esm/utils/percentFormatter.d.ts.map +1 -1
  346. package/dist/esm/utils/recentTokens.js +97 -0
  347. package/dist/esm/utils/recentTokens.js.map +1 -0
  348. package/dist/esm/utils/token.js +30 -4
  349. package/dist/esm/utils/token.js.map +1 -1
  350. package/dist/esm/utils/tokenList.js +18 -6
  351. package/dist/esm/utils/tokenList.js.map +1 -1
  352. package/dist/esm/utils/tokenListBands.js +85 -0
  353. package/dist/esm/utils/tokenListBands.js.map +1 -0
  354. package/dist/esm/utils/wallet.d.ts +1 -2
  355. package/dist/esm/utils/wallet.d.ts.map +1 -1
  356. package/package.json +9 -9
  357. package/src/components/AmountInputCard/ReceiveAmountCard.tsx +16 -3
  358. package/src/components/BottomSheet/BottomSheet.tsx +3 -0
  359. package/src/components/Token/Token.tsx +2 -1
  360. package/src/components/TokenList/RecentTokensHeader.tsx +52 -0
  361. package/src/components/TokenList/RecentTokensToggle.tsx +45 -0
  362. package/src/components/TokenList/RemoveRecentTokenButton.tsx +38 -0
  363. package/src/components/TokenList/TokenList.tsx +92 -3
  364. package/src/components/TokenList/TokenListItem.tsx +15 -0
  365. package/src/components/TokenList/VirtualizedTokenList.tsx +84 -125
  366. package/src/components/TokenList/types.ts +9 -0
  367. package/src/config/version.ts +1 -1
  368. package/src/hooks/useDisplayedTokens.ts +17 -3
  369. package/src/hooks/useRecentTokens.ts +88 -0
  370. package/src/hooks/useRoutes.ts +8 -5
  371. package/src/hooks/useToAddressRequirements.ts +11 -5
  372. package/src/hooks/useTokenBalances.ts +34 -31
  373. package/src/hooks/useTokenSearch.ts +5 -14
  374. package/src/hooks/useTokens.ts +69 -27
  375. package/src/pages/TransactionPage/TokenValueBottomSheet.tsx +1 -1
  376. package/src/pages/TransactionPage/TokenVerificationBottomSheet.tsx +1 -1
  377. package/src/pages/TransactionPage/TransactionFailedButtons.tsx +62 -26
  378. package/src/pages/TransactionPage/TransactionReview.tsx +36 -37
  379. package/src/pages/TransactionPage/utils.ts +78 -0
  380. package/src/stores/StoreProvider.tsx +10 -7
  381. package/src/stores/chains/ChainOrderStore.test.tsx +298 -0
  382. package/src/stores/chains/ChainOrderStore.tsx +25 -6
  383. package/src/stores/recentTokens/RecentTokensStore.tsx +39 -0
  384. package/src/stores/recentTokens/createRecentTokensStore.ts +107 -0
  385. package/src/stores/recentTokens/types.ts +37 -0
  386. package/src/stores/recentTokens/utils.ts +18 -0
  387. package/src/types/token.ts +2 -0
  388. package/src/types/widget.ts +5 -0
  389. package/src/utils/address.ts +21 -0
  390. package/src/utils/customReceiver.ts +24 -0
  391. package/src/utils/recentTokens.ts +187 -0
  392. package/src/utils/token.ts +69 -10
  393. package/src/utils/tokenList.ts +41 -23
  394. package/src/utils/tokenListBands.ts +181 -0
@@ -12,6 +12,7 @@ import { useSDKClient } from '../providers/SDKClientProvider.js'
12
12
  import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
13
13
  import type { FormType } from '../stores/form/types.js'
14
14
  import type { TokensByChain } from '../types/token.js'
15
+ import { isAddressQuery } from '../utils/address.js'
15
16
  import { defaultChainIdsByType } from '../utils/chainType.js'
16
17
  import { isItemAllowed } from '../utils/item.js'
17
18
  import { getQueryKey } from '../utils/queries.js'
@@ -32,6 +33,8 @@ export const useTokens = (
32
33
  allTokens: Record<number, TokenExtended[]> | undefined
33
34
  isLoading: boolean
34
35
  isSearchLoading: boolean
36
+ /** The search is a contract address, so only the token at that address matches. */
37
+ isAddressSearch: boolean
35
38
  } => {
36
39
  const {
37
40
  tokens: configTokens,
@@ -39,7 +42,16 @@ export const useTokens = (
39
42
  keyPrefix,
40
43
  } = useWidgetConfig()
41
44
  const sdkClient = useSDKClient()
42
- const { getChainTypeFromAddress } = useChainTypeFromAddress()
45
+ const { getChainTypeFromTokenAddress } = useChainTypeFromAddress()
46
+ // A pasted address often carries a trailing space or newline, which the
47
+ // API rejects. Trim once so the key, the requests and the checks agree.
48
+ const trimmedSearch = search?.trim()
49
+ // Keep this memoized, and out of any per-token loop: a provider validates by
50
+ // parsing, which costs microseconds per call rather than nanoseconds.
51
+ const isAddressSearch = useMemo(
52
+ () => isAddressQuery(trimmedSearch, getChainTypeFromTokenAddress),
53
+ [trimmedSearch, getChainTypeFromTokenAddress]
54
+ )
43
55
 
44
56
  // Main tokens cache - verified tokens from API
45
57
  const { data: verifiedTokens, isLoading } = useQuery({
@@ -82,13 +94,14 @@ export const useTokens = (
82
94
 
83
95
  // Search tokens cache - unverified tokens from search
84
96
  const { data: searchTokens, isLoading: isSearchLoading } = useQuery({
85
- queryKey: [getQueryKey('tokens-search', keyPrefix), search, chainId],
97
+ queryKey: [
98
+ getQueryKey('tokens-search', keyPrefix),
99
+ trimmedSearch,
100
+ chainId,
101
+ isAddressSearch,
102
+ ] as const,
86
103
  queryFn: async ({ queryKey, signal }) => {
87
- const [, searchQuery, searchChainId] = queryKey as [
88
- string,
89
- string,
90
- number,
91
- ]
104
+ const [, searchQuery, searchChainId, addressSearch] = queryKey
92
105
  const chainTypes = [
93
106
  ChainType.EVM,
94
107
  ChainType.SVM,
@@ -111,32 +124,60 @@ export const useTokens = (
111
124
  { signal }
112
125
  )
113
126
 
114
- // If the chainId is not provided, try to get it from the search query
115
- let _chainId = searchChainId
116
- if (!_chainId) {
117
- const chainType = getChainTypeFromAddress(searchQuery)
118
- if (chainType && chainType in defaultChainIdsByType) {
119
- _chainId = defaultChainIdsByType[chainType]
120
- }
121
- }
122
-
123
- // Fallback: If the main search returned no tokens for the specific chainId,
124
- // fetch a single token using the /token endpoint
125
- if (_chainId && searchQuery) {
126
- const existingTokens = tokensResponse.tokens[_chainId] || []
127
- if (!existingTokens.length) {
128
- const token = await getToken(sdkClient, _chainId, searchQuery, {
129
- signal,
130
- })
131
- if (token) {
132
- tokensResponse.tokens[_chainId] = [token]
127
+ // Fallback: fetch a single token from the /token endpoint when the
128
+ // search did not deliver one. Look it up on the selected chain, or
129
+ // without one on the default chain of the address format.
130
+ if (searchQuery) {
131
+ const chainType = getChainTypeFromTokenAddress(searchQuery)
132
+ const lookupChainId =
133
+ searchChainId ??
134
+ (chainType ? defaultChainIdsByType[chainType] : undefined)
135
+ if (lookupChainId) {
136
+ const existingTokens = tokensResponse.tokens[lookupChainId] ?? []
137
+ // The search index also matches names, so for an address query
138
+ // impersonators that embed the address can fill the list while the
139
+ // token at that address is missing. Without a selected chain the
140
+ // token can sit on any chain of the response.
141
+ const hasTokenAtAddress = () => {
142
+ const address = searchQuery.toLowerCase()
143
+ const candidates = searchChainId
144
+ ? [existingTokens]
145
+ : Object.values(tokensResponse.tokens)
146
+ return candidates.some((tokens) =>
147
+ tokens.some((token) => token.address?.toLowerCase() === address)
148
+ )
149
+ }
150
+ const isTokenMissing = addressSearch
151
+ ? !hasTokenAtAddress()
152
+ : !existingTokens.length
153
+ if (isTokenMissing) {
154
+ try {
155
+ const token = await getToken(
156
+ sdkClient,
157
+ lookupChainId,
158
+ searchQuery,
159
+ { signal }
160
+ )
161
+ if (token) {
162
+ tokensResponse.tokens[lookupChainId] = [
163
+ ...existingTokens,
164
+ token,
165
+ ]
166
+ }
167
+ } catch (error) {
168
+ // A guessed chain may not hold the token (HTTP 400). Keep the
169
+ // search results instead of failing the whole query.
170
+ if (signal.aborted) {
171
+ throw error
172
+ }
173
+ }
133
174
  }
134
175
  }
135
176
  }
136
177
 
137
178
  return tokensResponse.tokens as TokensByChain
138
179
  },
139
- enabled: !!search,
180
+ enabled: !!trimmedSearch,
140
181
  refetchInterval,
141
182
  staleTime: refetchInterval,
142
183
  })
@@ -170,5 +211,6 @@ export const useTokens = (
170
211
  allTokens,
171
212
  isLoading,
172
213
  isSearchLoading,
214
+ isAddressSearch,
173
215
  }
174
216
  }
@@ -36,8 +36,8 @@ export const TokenValueBottomSheet = ({
36
36
  ref?: Ref<BottomSheetBase>
37
37
  }): JSX.Element => {
38
38
  const handleCancel = () => {
39
+ // close() reaches onClose, which is onCancel
39
40
  ;(ref as RefObject<BottomSheetBase>).current?.close()
40
- onCancel?.()
41
41
  }
42
42
 
43
43
  return (
@@ -31,8 +31,8 @@ export const TokenVerificationBottomSheet = ({
31
31
  ref?: Ref<BottomSheetBase>
32
32
  }): JSX.Element => {
33
33
  const handleCancel = () => {
34
+ // close() reaches onClose, which is onCancel
34
35
  ;(ref as RefObject<BottomSheetBase>).current?.close()
35
- onCancel?.()
36
36
  }
37
37
 
38
38
  return (
@@ -5,12 +5,20 @@ import { useTranslation } from 'react-i18next'
5
5
  import type { BottomSheetBase } from '../../components/BottomSheet/types.js'
6
6
  import { useAddressActivity } from '../../hooks/useAddressActivity.js'
7
7
  import { useNavigateBack } from '../../hooks/useNavigateBack.js'
8
+ import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
8
9
  import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
10
+ import { WidgetEvent } from '../../types/events.js'
9
11
  import { getAccumulatedFeeCostsBreakdown } from '../../utils/fees.js'
10
12
  import { ConfirmToAddressSheet } from './ConfirmToAddressSheet.js'
11
13
  import { StartTransactionButton } from './StartTransactionButton.js'
12
14
  import { TokenValueBottomSheet } from './TokenValueBottomSheet.js'
13
- import { getTokenValueLossThreshold } from './utils.js'
15
+ import type { RetryGate } from './utils.js'
16
+ import {
17
+ calculateValueLossPercentage,
18
+ getRetryGates,
19
+ getTokenValueLossThreshold,
20
+ openNextGate,
21
+ } from './utils.js'
14
22
 
15
23
  interface TransactionFailedButtonsProps {
16
24
  route: RouteExtended
@@ -22,6 +30,7 @@ export const TransactionFailedButtons: React.FC<
22
30
  TransactionFailedButtonsProps
23
31
  > = ({ route, restartRoute, deleteRoute }) => {
24
32
  const { t } = useTranslation()
33
+ const emitter = useWidgetEvents()
25
34
  const navigateBack = useNavigateBack()
26
35
  const { mode, hiddenUI } = useWidgetConfig()
27
36
 
@@ -40,34 +49,61 @@ export const TransactionFailedButtons: React.FC<
40
49
  deleteRoute()
41
50
  }
42
51
 
43
- const handleRetryClick = () => {
44
- if (
45
- toAddress &&
46
- !hasActivity &&
47
- !isLoadingAddressActivity &&
48
- isActivityAddressFetched &&
49
- !hiddenUI?.lowAddressActivityConfirmation
50
- ) {
51
- confirmToAddressSheetRef.current?.open()
52
- return
53
- }
54
-
52
+ const retryGates = (() => {
55
53
  const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route)
56
- const fromAmountUSD = Number.parseFloat(route.fromAmountUSD)
57
- const toAmountUSD = Number.parseFloat(route.toAmountUSD)
58
- const tokenValueLossThresholdExceeded = getTokenValueLossThreshold(
59
- fromAmountUSD,
60
- toAmountUSD,
61
- gasCostUSD,
62
- feeCostUSD
54
+ return getRetryGates({
55
+ toAddress,
56
+ hasActivity,
57
+ isLoadingAddressActivity,
58
+ isActivityAddressFetched,
59
+ confirmationHidden: Boolean(hiddenUI?.lowAddressActivityConfirmation),
60
+ valueLossExceeded: getTokenValueLossThreshold(
61
+ Number.parseFloat(route.fromAmountUSD),
62
+ Number.parseFloat(route.toAmountUSD),
63
+ gasCostUSD,
64
+ feeCostUSD
65
+ ),
66
+ isCustomMode: mode === 'custom',
67
+ })
68
+ })()
69
+
70
+ const openGate = (after?: RetryGate) =>
71
+ openNextGate(
72
+ retryGates,
73
+ {
74
+ address: () => confirmToAddressSheetRef.current?.open(),
75
+ value: () => tokenValueBottomSheetRef.current?.open(),
76
+ },
77
+ handleRestartRoute,
78
+ after
63
79
  )
64
- if (tokenValueLossThresholdExceeded && mode !== 'custom') {
65
- tokenValueBottomSheetRef.current?.open()
66
- } else {
67
- restartRoute()
80
+
81
+ const handleRestartRoute = () => {
82
+ if (tokenValueBottomSheetRef.current?.isOpen()) {
83
+ const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route)
84
+ const fromAmountUSD = Number.parseFloat(route.fromAmountUSD)
85
+ const toAmountUSD = Number.parseFloat(route.toAmountUSD)
86
+ emitter.emit(WidgetEvent.RouteHighValueLoss, {
87
+ fromAmountUSD,
88
+ toAmountUSD,
89
+ gasCostUSD,
90
+ feeCostUSD,
91
+ valueLoss: calculateValueLossPercentage(
92
+ fromAmountUSD,
93
+ toAmountUSD,
94
+ gasCostUSD,
95
+ feeCostUSD
96
+ ),
97
+ })
68
98
  }
99
+ tokenValueBottomSheetRef.current?.close()
100
+ restartRoute()
69
101
  }
70
102
 
103
+ const handleRetryClick = () => openGate()
104
+
105
+ const handleConfirmToAddressContinue = () => openGate('address')
106
+
71
107
  return (
72
108
  <Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
73
109
  <Box sx={{ display: 'flex', gap: 1.5 }}>
@@ -89,13 +125,13 @@ export const TransactionFailedButtons: React.FC<
89
125
  <TokenValueBottomSheet
90
126
  route={route}
91
127
  ref={tokenValueBottomSheetRef}
92
- onContinue={restartRoute}
128
+ onContinue={handleRestartRoute}
93
129
  />
94
130
  ) : null}
95
131
  {!hiddenUI?.lowAddressActivityConfirmation ? (
96
132
  <ConfirmToAddressSheet
97
133
  ref={confirmToAddressSheetRef}
98
- onContinue={restartRoute}
134
+ onContinue={handleConfirmToAddressContinue}
99
135
  toAddress={toAddress!}
100
136
  toChainId={route.toChainId!}
101
137
  />
@@ -20,9 +20,12 @@ import { ConfirmToAddressSheet } from './ConfirmToAddressSheet.js'
20
20
  import { StartTransactionButton } from './StartTransactionButton.js'
21
21
  import { TokenValueBottomSheet } from './TokenValueBottomSheet.js'
22
22
  import { TokenVerificationBottomSheet } from './TokenVerificationBottomSheet.js'
23
+ import type { StartGate } from './utils.js'
23
24
  import {
24
25
  calculateValueLossPercentage,
26
+ getStartGates,
25
27
  getTokenValueLossThreshold,
28
+ openNextGate,
26
29
  } from './utils.js'
27
30
 
28
31
  interface TransactionReviewProps {
@@ -74,7 +77,6 @@ export const TransactionReview: React.FC<TransactionReviewProps> = ({
74
77
  })
75
78
  }
76
79
  tokenValueBottomSheetRef.current?.close()
77
- flaggedTokenSheetRef.current?.close()
78
80
  executeRoute()
79
81
  setFieldValue('fromAmount', '')
80
82
  if (mode === 'custom') {
@@ -86,49 +88,46 @@ export const TransactionReview: React.FC<TransactionReviewProps> = ({
86
88
  })
87
89
  }
88
90
 
89
- // Runs the remaining gates. The flagged-token sheet continues into this
90
- // rather than executing, so accepting it does not skip the others.
91
- const handleStartAfterTokenCheck = () => {
92
- if (
93
- toAddress &&
94
- !hasActivity &&
95
- !isLoadingAddressActivity &&
96
- isActivityAddressFetched &&
97
- !hiddenUI?.lowAddressActivityConfirmation
98
- ) {
99
- confirmToAddressSheetRef.current?.open()
100
- return
101
- }
102
-
91
+ const startGates = (() => {
103
92
  const { gasCostUSD, feeCostUSD } = getAccumulatedFeeCostsBreakdown(route)
104
- const fromAmountUSD = Number.parseFloat(route.fromAmountUSD)
105
- const toAmountUSD = Number.parseFloat(route.toAmountUSD)
106
- const tokenValueLossThresholdExceeded = getTokenValueLossThreshold(
107
- fromAmountUSD,
108
- toAmountUSD,
109
- gasCostUSD,
110
- feeCostUSD
93
+ return getStartGates({
94
+ flaggedTokenCount: flaggedTokens.length,
95
+ toAddress,
96
+ hasActivity,
97
+ isLoadingAddressActivity,
98
+ isActivityAddressFetched,
99
+ confirmationHidden: Boolean(hiddenUI?.lowAddressActivityConfirmation),
100
+ valueLossExceeded: getTokenValueLossThreshold(
101
+ Number.parseFloat(route.fromAmountUSD),
102
+ Number.parseFloat(route.toAmountUSD),
103
+ gasCostUSD,
104
+ feeCostUSD
105
+ ),
106
+ isCustomMode: mode === 'custom',
107
+ })
108
+ })()
109
+
110
+ const openGate = (after?: StartGate) =>
111
+ openNextGate(
112
+ startGates,
113
+ {
114
+ flagged: () => flaggedTokenSheetRef.current?.open(),
115
+ address: () => confirmToAddressSheetRef.current?.open(),
116
+ value: () => tokenValueBottomSheetRef.current?.open(),
117
+ },
118
+ handleExecuteRoute,
119
+ after
111
120
  )
112
- if (tokenValueLossThresholdExceeded && mode !== 'custom') {
113
- tokenValueBottomSheetRef.current?.open()
114
- } else {
115
- handleExecuteRoute()
116
- }
117
- }
118
121
 
119
- const handleStartClick = () => {
120
- if (flaggedTokens.length) {
121
- flaggedTokenSheetRef.current?.open()
122
- return
123
- }
124
- handleStartAfterTokenCheck()
125
- }
122
+ const handleStartClick = () => openGate()
126
123
 
127
124
  const handleFlaggedTokensContinue = () => {
128
125
  flaggedTokenSheetRef.current?.close()
129
- handleStartAfterTokenCheck()
126
+ openGate('flagged')
130
127
  }
131
128
 
129
+ const handleConfirmToAddressContinue = () => openGate('address')
130
+
132
131
  const getButtonText = (): string => {
133
132
  switch (mode) {
134
133
  case 'custom':
@@ -180,7 +179,7 @@ export const TransactionReview: React.FC<TransactionReviewProps> = ({
180
179
  {!hiddenUI?.lowAddressActivityConfirmation ? (
181
180
  <ConfirmToAddressSheet
182
181
  ref={confirmToAddressSheetRef}
183
- onContinue={handleExecuteRoute}
182
+ onContinue={handleConfirmToAddressContinue}
184
183
  toAddress={toAddress!}
185
184
  toChainId={route.toChainId!}
186
185
  />
@@ -23,3 +23,81 @@ export const getTokenValueLossThreshold = (
23
23
  }
24
24
  return toAmountUSD / (fromAmountUSD + gasCostUSD + feeCostUSD) < 0.9
25
25
  }
26
+
27
+ interface AddressGateInput {
28
+ toAddress: string | undefined
29
+ hasActivity: boolean | undefined
30
+ isLoadingAddressActivity: boolean
31
+ isActivityAddressFetched: boolean
32
+ confirmationHidden: boolean
33
+ }
34
+
35
+ const needsAddressConfirmation = ({
36
+ toAddress,
37
+ hasActivity,
38
+ isLoadingAddressActivity,
39
+ isActivityAddressFetched,
40
+ confirmationHidden,
41
+ }: AddressGateInput): boolean =>
42
+ Boolean(
43
+ toAddress &&
44
+ !hasActivity &&
45
+ !isLoadingAddressActivity &&
46
+ isActivityAddressFetched &&
47
+ !confirmationHidden
48
+ )
49
+
50
+ export type RetryGate = 'address' | 'value'
51
+
52
+ export const getRetryGates = (
53
+ input: AddressGateInput & {
54
+ valueLossExceeded: boolean
55
+ isCustomMode: boolean
56
+ }
57
+ ): readonly (readonly [gate: RetryGate, needed: boolean])[] => [
58
+ ['address', needsAddressConfirmation(input)],
59
+ ['value', input.valueLossExceeded && !input.isCustomMode],
60
+ ]
61
+
62
+ /** Ordering lives here so no sheet decides what follows it — that is how gates came to be skipped. */
63
+ export const nextGate = <T extends string>(
64
+ gates: readonly (readonly [gate: T, needed: boolean])[],
65
+ after?: T
66
+ ): T | undefined => {
67
+ if (!after) {
68
+ return gates.find(([, needed]) => needed)?.[0]
69
+ }
70
+ const index = gates.findIndex(([gate]) => gate === after)
71
+ if (index < 0) {
72
+ return undefined
73
+ }
74
+ return gates.slice(index + 1).find(([, needed]) => needed)?.[0]
75
+ }
76
+
77
+ export const openNextGate = <T extends string>(
78
+ gates: readonly (readonly [gate: T, needed: boolean])[],
79
+ open: Record<T, () => void>,
80
+ done: () => void,
81
+ after?: T
82
+ ): void => {
83
+ const gate = nextGate(gates, after)
84
+ if (gate) {
85
+ open[gate]()
86
+ return
87
+ }
88
+ done()
89
+ }
90
+
91
+ export type StartGate = 'flagged' | 'address' | 'value'
92
+
93
+ export const getStartGates = (
94
+ input: AddressGateInput & {
95
+ flaggedTokenCount: number
96
+ valueLossExceeded: boolean
97
+ isCustomMode: boolean
98
+ }
99
+ ): readonly (readonly [gate: StartGate, needed: boolean])[] => [
100
+ ['flagged', input.flaggedTokenCount > 0],
101
+ ['address', needsAddressConfirmation(input)],
102
+ ['value', input.valueLossExceeded && !input.isCustomMode],
103
+ ]
@@ -6,6 +6,7 @@ import { FormStoreProvider } from './form/FormStore.js'
6
6
  import { HeaderStoreProvider } from './header/useHeaderStore.js'
7
7
  import { NavigationTabsStoreProvider } from './navigationTabs/useNavigationTabsStore.js'
8
8
  import { PinnedTokensStoreProvider } from './pinnedTokens/PinnedTokensStore.js'
9
+ import { RecentTokensStoreProvider } from './recentTokens/RecentTokensStore.js'
9
10
  import { RouteExecutionStoreProvider } from './routes/RouteExecutionStore.js'
10
11
 
11
12
  export const StoreProvider: React.FC<PropsWithChildren<WidgetConfigProps>> = ({
@@ -18,13 +19,15 @@ export const StoreProvider: React.FC<PropsWithChildren<WidgetConfigProps>> = ({
18
19
  <HeaderStoreProvider namePrefix={config?.keyPrefix}>
19
20
  <BookmarkStoreProvider namePrefix={config?.keyPrefix}>
20
21
  <PinnedTokensStoreProvider namePrefix={config?.keyPrefix}>
21
- <FormStoreProvider formRef={formRef}>
22
- <ChainOrderStoreProvider namePrefix={config?.keyPrefix}>
23
- <RouteExecutionStoreProvider namePrefix={config?.keyPrefix}>
24
- {children}
25
- </RouteExecutionStoreProvider>
26
- </ChainOrderStoreProvider>
27
- </FormStoreProvider>
22
+ <RecentTokensStoreProvider namePrefix={config?.keyPrefix}>
23
+ <FormStoreProvider formRef={formRef}>
24
+ <ChainOrderStoreProvider namePrefix={config?.keyPrefix}>
25
+ <RouteExecutionStoreProvider namePrefix={config?.keyPrefix}>
26
+ {children}
27
+ </RouteExecutionStoreProvider>
28
+ </ChainOrderStoreProvider>
29
+ </FormStoreProvider>
30
+ </RecentTokensStoreProvider>
28
31
  </PinnedTokensStoreProvider>
29
32
  </BookmarkStoreProvider>
30
33
  </HeaderStoreProvider>