@lifi/widget 4.5.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 (522) 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/AppDrawer.js +2 -1
  7. package/dist/esm/AppDrawer.js.map +1 -1
  8. package/dist/esm/components/ActionRow/ActionRow.d.ts +1 -2
  9. package/dist/esm/components/ActionRow/ActionRow.d.ts.map +1 -1
  10. package/dist/esm/components/AmountInput/AmountInput.js +13 -7
  11. package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
  12. package/dist/esm/components/AmountInput/AmountInput.style.d.ts +2 -2
  13. package/dist/esm/components/AmountInput/AmountInput.style.d.ts.map +1 -1
  14. package/dist/esm/components/AmountInput/AmountInputEndAdornment.d.ts +1 -2
  15. package/dist/esm/components/AmountInput/AmountInputEndAdornment.d.ts.map +1 -1
  16. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +2 -13
  17. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
  18. package/dist/esm/components/AmountInput/PriceFormHelperText.style.d.ts +1 -2
  19. package/dist/esm/components/AmountInput/PriceFormHelperText.style.d.ts.map +1 -1
  20. package/dist/esm/components/AmountInputCard/PercentageChips.js +2 -13
  21. package/dist/esm/components/AmountInputCard/PercentageChips.js.map +1 -1
  22. package/dist/esm/components/AmountInputCard/PercentageChips.style.js +1 -1
  23. package/dist/esm/components/AmountInputCard/PercentageChips.style.js.map +1 -1
  24. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js +6 -2
  25. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -1
  26. package/dist/esm/components/AmountInputCard/SendAmountCard.js +13 -6
  27. package/dist/esm/components/AmountInputCard/SendAmountCard.js.map +1 -1
  28. package/dist/esm/components/Avatar/Avatar.d.ts +1 -2
  29. package/dist/esm/components/Avatar/Avatar.d.ts.map +1 -1
  30. package/dist/esm/components/Avatar/TokenAvatar.d.ts +1 -2
  31. package/dist/esm/components/Avatar/TokenAvatar.d.ts.map +1 -1
  32. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.d.ts +1 -2
  33. package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.d.ts.map +1 -1
  34. package/dist/esm/components/BaseTransactionButton/types.d.ts +1 -2
  35. package/dist/esm/components/BaseTransactionButton/types.d.ts.map +1 -1
  36. package/dist/esm/components/BottomSheet/BottomSheet.js +1 -0
  37. package/dist/esm/components/BottomSheet/BottomSheet.js.map +1 -1
  38. package/dist/esm/components/BottomSheet/types.d.ts +1 -2
  39. package/dist/esm/components/BottomSheet/types.d.ts.map +1 -1
  40. package/dist/esm/components/ButtonTertiary.d.ts +1 -2
  41. package/dist/esm/components/ButtonTertiary.d.ts.map +1 -1
  42. package/dist/esm/components/Card/CardIconButton.d.ts +1 -2
  43. package/dist/esm/components/Card/CardIconButton.d.ts.map +1 -1
  44. package/dist/esm/components/Card/CardTitle.d.ts +1 -2
  45. package/dist/esm/components/Card/CardTitle.d.ts.map +1 -1
  46. package/dist/esm/components/Card/InputCard.d.ts +1 -2
  47. package/dist/esm/components/Card/InputCard.d.ts.map +1 -1
  48. package/dist/esm/components/ChainSelect/ChainSelect.d.ts +1 -2
  49. package/dist/esm/components/ChainSelect/ChainSelect.d.ts.map +1 -1
  50. package/dist/esm/components/ChainSelect/ChainSelect.style.d.ts +1 -2
  51. package/dist/esm/components/ChainSelect/ChainSelect.style.d.ts.map +1 -1
  52. package/dist/esm/components/Chains/AllChainsAvatar.js +7 -1
  53. package/dist/esm/components/Chains/AllChainsAvatar.js.map +1 -1
  54. package/dist/esm/components/ContractComponent/ContractComponent.d.ts +1 -2
  55. package/dist/esm/components/ContractComponent/ContractComponent.d.ts.map +1 -1
  56. package/dist/esm/components/ContractComponent/ItemPrice.d.ts +2 -3
  57. package/dist/esm/components/ContractComponent/ItemPrice.d.ts.map +1 -1
  58. package/dist/esm/components/ContractComponent/NFT/NFT.d.ts +1 -2
  59. package/dist/esm/components/ContractComponent/NFT/NFT.d.ts.map +1 -1
  60. package/dist/esm/components/ContractComponent/NFT/NFTBase.d.ts +1 -2
  61. package/dist/esm/components/ContractComponent/NFT/NFTBase.d.ts.map +1 -1
  62. package/dist/esm/components/ContractComponent/NFT/types.d.ts +3 -4
  63. package/dist/esm/components/ContractComponent/NFT/types.d.ts.map +1 -1
  64. package/dist/esm/components/Dialog/Dialog.js +2 -1
  65. package/dist/esm/components/Dialog/Dialog.js.map +1 -1
  66. package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.d.ts +1 -2
  67. package/dist/esm/components/ExecutionStatusCard/ExecutionStatusCard.d.ts.map +1 -1
  68. package/dist/esm/components/ExecutionStatusCard/StatusIcon.d.ts +1 -2
  69. package/dist/esm/components/ExecutionStatusCard/StatusIcon.d.ts.map +1 -1
  70. package/dist/esm/components/Expansion/Expansion.js +4 -3
  71. package/dist/esm/components/Expansion/Expansion.js.map +1 -1
  72. package/dist/esm/components/FeeBreakdownTooltip.d.ts +1 -2
  73. package/dist/esm/components/FeeBreakdownTooltip.d.ts.map +1 -1
  74. package/dist/esm/components/Header/SettingsButton.js +2 -1
  75. package/dist/esm/components/Header/SettingsButton.js.map +1 -1
  76. package/dist/esm/components/IconCircle/IconCircle.d.ts +1 -2
  77. package/dist/esm/components/IconCircle/IconCircle.d.ts.map +1 -1
  78. package/dist/esm/components/IconCircle/IconCircle.js +2 -1
  79. package/dist/esm/components/IconCircle/IconCircle.js.map +1 -1
  80. package/dist/esm/components/IconCircle/statusIcons.d.ts +1 -2
  81. package/dist/esm/components/IconCircle/statusIcons.d.ts.map +1 -1
  82. package/dist/esm/components/IconTypography.d.ts +1 -2
  83. package/dist/esm/components/IconTypography.d.ts.map +1 -1
  84. package/dist/esm/components/ListItem/ListItemButton.d.ts +1 -2
  85. package/dist/esm/components/ListItem/ListItemButton.d.ts.map +1 -1
  86. package/dist/esm/components/Messages/UnsupportedToAddressMessage.js +27 -0
  87. package/dist/esm/components/Messages/UnsupportedToAddressMessage.js.map +1 -0
  88. package/dist/esm/components/Messages/WarningMessages.d.ts +1 -2
  89. package/dist/esm/components/Messages/WarningMessages.d.ts.map +1 -1
  90. package/dist/esm/components/Messages/WarningMessages.js +2 -0
  91. package/dist/esm/components/Messages/WarningMessages.js.map +1 -1
  92. package/dist/esm/components/Messages/useMessageQueue.js +6 -1
  93. package/dist/esm/components/Messages/useMessageQueue.js.map +1 -1
  94. package/dist/esm/components/PageContainer.d.ts +2 -3
  95. package/dist/esm/components/PageContainer.d.ts.map +1 -1
  96. package/dist/esm/components/PoweredBy/PoweredBy.d.ts +1 -2
  97. package/dist/esm/components/PoweredBy/PoweredBy.d.ts.map +1 -1
  98. package/dist/esm/components/ProgressToNextUpdate.d.ts +1 -2
  99. package/dist/esm/components/ProgressToNextUpdate.d.ts.map +1 -1
  100. package/dist/esm/components/RouteCard/RouteCard.d.ts +1 -2
  101. package/dist/esm/components/RouteCard/RouteCard.d.ts.map +1 -1
  102. package/dist/esm/components/RouteCard/RouteCardSkeleton.d.ts +1 -2
  103. package/dist/esm/components/RouteCard/RouteCardSkeleton.d.ts.map +1 -1
  104. package/dist/esm/components/RouteCard/RouteDetails.d.ts +1 -2
  105. package/dist/esm/components/RouteCard/RouteDetails.d.ts.map +1 -1
  106. package/dist/esm/components/RouteCard/RouteDetails.js +2 -1
  107. package/dist/esm/components/RouteCard/RouteDetails.js.map +1 -1
  108. package/dist/esm/components/RouteCard/RouteDetails.style.d.ts +5 -6
  109. package/dist/esm/components/RouteCard/RouteDetails.style.d.ts.map +1 -1
  110. package/dist/esm/components/RouteCard/RouteNotFoundCard.d.ts +1 -2
  111. package/dist/esm/components/RouteCard/RouteNotFoundCard.d.ts.map +1 -1
  112. package/dist/esm/components/RouteCard/RouteTokens.d.ts +1 -2
  113. package/dist/esm/components/RouteCard/RouteTokens.d.ts.map +1 -1
  114. package/dist/esm/components/RouteCard/types.d.ts +2 -3
  115. package/dist/esm/components/RouteCard/types.d.ts.map +1 -1
  116. package/dist/esm/components/Routes/LimitOrderRoutes.js +2 -2
  117. package/dist/esm/components/Routes/LimitOrderRoutes.js.map +1 -1
  118. package/dist/esm/components/Routes/RoutesContent.js +2 -2
  119. package/dist/esm/components/Routes/RoutesContent.js.map +1 -1
  120. package/dist/esm/components/Search/SearchInput.d.ts +1 -2
  121. package/dist/esm/components/Search/SearchInput.d.ts.map +1 -1
  122. package/dist/esm/components/SendToWallet/SendToWalletButton.d.ts +1 -2
  123. package/dist/esm/components/SendToWallet/SendToWalletButton.d.ts.map +1 -1
  124. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js +2 -2
  125. package/dist/esm/components/SendToWallet/SendToWalletExpandButton.js.map +1 -1
  126. package/dist/esm/components/Skeleton/WidgetSkeleton.d.ts +1 -2
  127. package/dist/esm/components/Skeleton/WidgetSkeleton.d.ts.map +1 -1
  128. package/dist/esm/components/Skeleton/WidgetSkeleton.js +2 -1
  129. package/dist/esm/components/Skeleton/WidgetSkeleton.js.map +1 -1
  130. package/dist/esm/components/Step/StepActions.js +18 -16
  131. package/dist/esm/components/Step/StepActions.js.map +1 -1
  132. package/dist/esm/components/StepActions/SentToWalletRow.d.ts +1 -2
  133. package/dist/esm/components/StepActions/SentToWalletRow.d.ts.map +1 -1
  134. package/dist/esm/components/StepActions/StepActionRow.js +2 -1
  135. package/dist/esm/components/StepActions/StepActionRow.js.map +1 -1
  136. package/dist/esm/components/StepActions/StepActionRow.style.d.ts +1 -2
  137. package/dist/esm/components/StepActions/StepActionRow.style.d.ts.map +1 -1
  138. package/dist/esm/components/StepActions/StepActionsList.d.ts +1 -2
  139. package/dist/esm/components/StepActions/StepActionsList.d.ts.map +1 -1
  140. package/dist/esm/components/StepActions/executionRows.d.ts +2 -3
  141. package/dist/esm/components/StepActions/executionRows.d.ts.map +1 -1
  142. package/dist/esm/components/Switch.js +1 -1
  143. package/dist/esm/components/Switch.js.map +1 -1
  144. package/dist/esm/components/Tabs/Tabs.style.js +4 -2
  145. package/dist/esm/components/Tabs/Tabs.style.js.map +1 -1
  146. package/dist/esm/components/Token/Token.d.ts.map +1 -1
  147. package/dist/esm/components/Token/Token.js +2 -4
  148. package/dist/esm/components/Token/Token.js.map +1 -1
  149. package/dist/esm/components/TokenList/RecentTokensHeader.js +44 -0
  150. package/dist/esm/components/TokenList/RecentTokensHeader.js.map +1 -0
  151. package/dist/esm/components/TokenList/RecentTokensToggle.js +36 -0
  152. package/dist/esm/components/TokenList/RecentTokensToggle.js.map +1 -0
  153. package/dist/esm/components/TokenList/RemoveRecentTokenButton.js +32 -0
  154. package/dist/esm/components/TokenList/RemoveRecentTokenButton.js.map +1 -0
  155. package/dist/esm/components/TokenList/TokenList.js +55 -5
  156. package/dist/esm/components/TokenList/TokenList.js.map +1 -1
  157. package/dist/esm/components/TokenList/TokenListItem.js +81 -27
  158. package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
  159. package/dist/esm/components/TokenList/TokenNotFound.d.ts +1 -2
  160. package/dist/esm/components/TokenList/TokenNotFound.d.ts.map +1 -1
  161. package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts +1 -2
  162. package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts.map +1 -1
  163. package/dist/esm/components/TokenList/VirtualizedTokenList.js +63 -37
  164. package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
  165. package/dist/esm/components/TokenList/types.d.ts +9 -2
  166. package/dist/esm/components/TokenList/types.d.ts.map +1 -1
  167. package/dist/esm/components/TokenList/useTokenSelect.d.ts +1 -2
  168. package/dist/esm/components/TokenList/useTokenSelect.d.ts.map +1 -1
  169. package/dist/esm/components/TokenRate/TokenRate.d.ts +1 -2
  170. package/dist/esm/components/TokenRate/TokenRate.d.ts.map +1 -1
  171. package/dist/esm/components/TokenRate/TokenRate.js +2 -1
  172. package/dist/esm/components/TokenRate/TokenRate.js.map +1 -1
  173. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js +22 -21
  174. package/dist/esm/components/TransactionCard/ActiveTransactionCard.js.map +1 -1
  175. package/dist/esm/components/TransactionCard/TransactionCard.style.d.ts +2 -3
  176. package/dist/esm/components/TransactionCard/TransactionCard.style.d.ts.map +1 -1
  177. package/dist/esm/config/constants.d.ts +1 -2
  178. package/dist/esm/config/constants.d.ts.map +1 -1
  179. package/dist/esm/config/version.d.ts +2 -3
  180. package/dist/esm/config/version.d.ts.map +1 -1
  181. package/dist/esm/config/version.js +1 -1
  182. package/dist/esm/config/version.js.map +1 -1
  183. package/dist/esm/hooks/timer/time.js +2 -2
  184. package/dist/esm/hooks/timer/time.js.map +1 -1
  185. package/dist/esm/hooks/useAddressActivity.d.ts +1 -2
  186. package/dist/esm/hooks/useAddressActivity.d.ts.map +1 -1
  187. package/dist/esm/hooks/useAddressValidation.d.ts +2 -3
  188. package/dist/esm/hooks/useAddressValidation.d.ts.map +1 -1
  189. package/dist/esm/hooks/useAvailableChains.d.ts +1 -2
  190. package/dist/esm/hooks/useAvailableChains.d.ts.map +1 -1
  191. package/dist/esm/hooks/useAvailableChains.js +2 -1
  192. package/dist/esm/hooks/useAvailableChains.js.map +1 -1
  193. package/dist/esm/hooks/useChain.d.ts +1 -2
  194. package/dist/esm/hooks/useChain.d.ts.map +1 -1
  195. package/dist/esm/hooks/useContactSupport.d.ts +1 -2
  196. package/dist/esm/hooks/useContactSupport.d.ts.map +1 -1
  197. package/dist/esm/hooks/useDebouncedWatch.d.ts +1 -2
  198. package/dist/esm/hooks/useDebouncedWatch.d.ts.map +1 -1
  199. package/dist/esm/hooks/useDisplayedTokens.js +6 -4
  200. package/dist/esm/hooks/useDisplayedTokens.js.map +1 -1
  201. package/dist/esm/hooks/useExplorer.d.ts +1 -2
  202. package/dist/esm/hooks/useExplorer.d.ts.map +1 -1
  203. package/dist/esm/hooks/useExplorer.js +4 -0
  204. package/dist/esm/hooks/useExplorer.js.map +1 -1
  205. package/dist/esm/hooks/useFlaggedTokenGuard.js +28 -0
  206. package/dist/esm/hooks/useFlaggedTokenGuard.js.map +1 -0
  207. package/dist/esm/hooks/useGasSufficiency.js +3 -1
  208. package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
  209. package/dist/esm/hooks/useHeader.d.ts +1 -2
  210. package/dist/esm/hooks/useHeader.d.ts.map +1 -1
  211. package/dist/esm/hooks/useListHeight.d.ts +1 -2
  212. package/dist/esm/hooks/useListHeight.d.ts.map +1 -1
  213. package/dist/esm/hooks/useMaxSendAmount.js +15 -0
  214. package/dist/esm/hooks/useMaxSendAmount.js.map +1 -0
  215. package/dist/esm/hooks/useNavigateBack.d.ts +1 -2
  216. package/dist/esm/hooks/useNavigateBack.d.ts.map +1 -1
  217. package/dist/esm/hooks/usePacedRouteExecution.js +3 -2
  218. package/dist/esm/hooks/usePacedRouteExecution.js.map +1 -1
  219. package/dist/esm/hooks/useRecentTokens.js +46 -0
  220. package/dist/esm/hooks/useRecentTokens.js.map +1 -0
  221. package/dist/esm/hooks/useRouteExecution.d.ts +1 -2
  222. package/dist/esm/hooks/useRouteExecution.d.ts.map +1 -1
  223. package/dist/esm/hooks/useRouteExecutionMessage.d.ts +1 -2
  224. package/dist/esm/hooks/useRouteExecutionMessage.d.ts.map +1 -1
  225. package/dist/esm/hooks/useRouteExecutionMessage.js +3 -2
  226. package/dist/esm/hooks/useRouteExecutionMessage.js.map +1 -1
  227. package/dist/esm/hooks/useRoutes.d.ts +1 -2
  228. package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
  229. package/dist/esm/hooks/useRoutes.js +8 -1
  230. package/dist/esm/hooks/useRoutes.js.map +1 -1
  231. package/dist/esm/hooks/useToAddressRequirements.d.ts +3 -2
  232. package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
  233. package/dist/esm/hooks/useToAddressRequirements.js +13 -1
  234. package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
  235. package/dist/esm/hooks/useToken.d.ts +1 -2
  236. package/dist/esm/hooks/useToken.d.ts.map +1 -1
  237. package/dist/esm/hooks/useTokenAddressBalance.d.ts +1 -2
  238. package/dist/esm/hooks/useTokenAddressBalance.d.ts.map +1 -1
  239. package/dist/esm/hooks/useTokenBalances.d.ts +3 -2
  240. package/dist/esm/hooks/useTokenBalances.d.ts.map +1 -1
  241. package/dist/esm/hooks/useTokenBalances.js +19 -8
  242. package/dist/esm/hooks/useTokenBalances.js.map +1 -1
  243. package/dist/esm/hooks/useTokenBalancesQueries.js +29 -28
  244. package/dist/esm/hooks/useTokenBalancesQueries.js.map +1 -1
  245. package/dist/esm/hooks/useTokenList.d.ts +1 -2
  246. package/dist/esm/hooks/useTokenList.d.ts.map +1 -1
  247. package/dist/esm/hooks/useTokenSearch.js +5 -6
  248. package/dist/esm/hooks/useTokenSearch.js.map +1 -1
  249. package/dist/esm/hooks/useTokens.js +40 -25
  250. package/dist/esm/hooks/useTokens.js.map +1 -1
  251. package/dist/esm/hooks/useTools.d.ts +1 -2
  252. package/dist/esm/hooks/useTools.d.ts.map +1 -1
  253. package/dist/esm/hooks/useWideVariant.js +2 -1
  254. package/dist/esm/hooks/useWideVariant.js.map +1 -1
  255. package/dist/esm/hooks/useWidgetChains.d.ts +1 -2
  256. package/dist/esm/hooks/useWidgetChains.d.ts.map +1 -1
  257. package/dist/esm/hooks/useWidgetEvents.d.ts +3 -4
  258. package/dist/esm/hooks/useWidgetEvents.d.ts.map +1 -1
  259. package/dist/esm/i18n/bn.json +7 -1
  260. package/dist/esm/i18n/de.json +7 -1
  261. package/dist/esm/i18n/en.json +16 -3
  262. package/dist/esm/i18n/es.json +7 -1
  263. package/dist/esm/i18n/fr.json +7 -1
  264. package/dist/esm/i18n/hi.json +7 -1
  265. package/dist/esm/i18n/id.json +7 -1
  266. package/dist/esm/i18n/it.json +7 -1
  267. package/dist/esm/i18n/ja.json +7 -1
  268. package/dist/esm/i18n/ko.json +7 -1
  269. package/dist/esm/i18n/pl.json +7 -1
  270. package/dist/esm/i18n/pt.json +7 -1
  271. package/dist/esm/i18n/th.json +7 -1
  272. package/dist/esm/i18n/tr.json +7 -1
  273. package/dist/esm/i18n/uk.json +7 -1
  274. package/dist/esm/i18n/vi.json +7 -1
  275. package/dist/esm/i18n/zh.json +7 -1
  276. package/dist/esm/pages/MainPage/MainPage.js +2 -1
  277. package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
  278. package/dist/esm/pages/MainPage/MainWarningMessages.d.ts +1 -2
  279. package/dist/esm/pages/MainPage/MainWarningMessages.d.ts.map +1 -1
  280. package/dist/esm/pages/MainPage/ReviewButton.js +2 -2
  281. package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
  282. package/dist/esm/pages/RoutesPage/RoutesPage.js +2 -2
  283. package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
  284. package/dist/esm/pages/SelectChainPage/SelectChainPage.d.ts +1 -2
  285. package/dist/esm/pages/SelectChainPage/SelectChainPage.d.ts.map +1 -1
  286. package/dist/esm/pages/SelectChainPage/SelectChainPage.js +13 -12
  287. package/dist/esm/pages/SelectChainPage/SelectChainPage.js.map +1 -1
  288. package/dist/esm/pages/SelectChainPage/types.d.ts +1 -2
  289. package/dist/esm/pages/SelectChainPage/types.d.ts.map +1 -1
  290. package/dist/esm/pages/SelectEnabledToolsPage.js +8 -5
  291. package/dist/esm/pages/SelectEnabledToolsPage.js.map +1 -1
  292. package/dist/esm/pages/SelectTokenPage/SearchTokenInput.d.ts +1 -2
  293. package/dist/esm/pages/SelectTokenPage/SearchTokenInput.d.ts.map +1 -1
  294. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js +2 -1
  295. package/dist/esm/pages/SelectTokenPage/SelectTokenPage.js.map +1 -1
  296. package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js +2 -1
  297. package/dist/esm/pages/SettingsPage/SmallBalanceFilterSettings.js.map +1 -1
  298. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.d.ts +1 -2
  299. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.d.ts.map +1 -1
  300. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js +2 -1
  301. package/dist/esm/pages/TransactionDetailsPage/ContactSupportButton.js.map +1 -1
  302. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js +2 -1
  303. package/dist/esm/pages/TransactionDetailsPage/TransactionDetailsPage.js.map +1 -1
  304. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.d.ts +1 -2
  305. package/dist/esm/pages/TransactionPage/ConfirmToAddressSheet.d.ts.map +1 -1
  306. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.d.ts +2 -3
  307. package/dist/esm/pages/TransactionPage/ExchangeRateBottomSheet.d.ts.map +1 -1
  308. package/dist/esm/pages/TransactionPage/ExecutionDoneCard.d.ts +1 -2
  309. package/dist/esm/pages/TransactionPage/ExecutionDoneCard.d.ts.map +1 -1
  310. package/dist/esm/pages/TransactionPage/RouteTracker.d.ts +1 -2
  311. package/dist/esm/pages/TransactionPage/RouteTracker.d.ts.map +1 -1
  312. package/dist/esm/pages/TransactionPage/StartTransactionButton.d.ts +1 -2
  313. package/dist/esm/pages/TransactionPage/StartTransactionButton.d.ts.map +1 -1
  314. package/dist/esm/pages/TransactionPage/StartTransactionButton.js +4 -3
  315. package/dist/esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
  316. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.d.ts +1 -2
  317. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.d.ts.map +1 -1
  318. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js +0 -1
  319. package/dist/esm/pages/TransactionPage/TokenValueBottomSheet.js.map +1 -1
  320. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js +63 -0
  321. package/dist/esm/pages/TransactionPage/TokenVerificationBottomSheet.js.map +1 -0
  322. package/dist/esm/pages/TransactionPage/TransactionDoneButtons.d.ts +1 -2
  323. package/dist/esm/pages/TransactionPage/TransactionDoneButtons.d.ts.map +1 -1
  324. package/dist/esm/pages/TransactionPage/TransactionExecutionContent.js +19 -16
  325. package/dist/esm/pages/TransactionPage/TransactionExecutionContent.js.map +1 -1
  326. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js +38 -10
  327. package/dist/esm/pages/TransactionPage/TransactionFailedButtons.js.map +1 -1
  328. package/dist/esm/pages/TransactionPage/TransactionReview.js +32 -9
  329. package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
  330. package/dist/esm/pages/TransactionPage/types.d.ts +1 -2
  331. package/dist/esm/pages/TransactionPage/types.d.ts.map +1 -1
  332. package/dist/esm/pages/TransactionPage/utils.d.ts +2 -3
  333. package/dist/esm/pages/TransactionPage/utils.d.ts.map +1 -1
  334. package/dist/esm/pages/TransactionPage/utils.js +23 -1
  335. package/dist/esm/pages/TransactionPage/utils.js.map +1 -1
  336. package/dist/esm/providers/I18nProvider/I18nProvider.d.ts +1 -2
  337. package/dist/esm/providers/I18nProvider/I18nProvider.d.ts.map +1 -1
  338. package/dist/esm/providers/I18nProvider/I18nProvider.js +37 -36
  339. package/dist/esm/providers/I18nProvider/I18nProvider.js.map +1 -1
  340. package/dist/esm/providers/I18nProvider/types.d.ts +4 -5
  341. package/dist/esm/providers/I18nProvider/types.d.ts.map +1 -1
  342. package/dist/esm/providers/QueryClientProvider.d.ts +1 -2
  343. package/dist/esm/providers/QueryClientProvider.d.ts.map +1 -1
  344. package/dist/esm/providers/SDKClientProvider.d.ts +2 -3
  345. package/dist/esm/providers/SDKClientProvider.d.ts.map +1 -1
  346. package/dist/esm/providers/ThemeProvider/ThemeProvider.js +2 -1
  347. package/dist/esm/providers/ThemeProvider/ThemeProvider.js.map +1 -1
  348. package/dist/esm/providers/WalletProvider/WalletProvider.d.ts +1 -2
  349. package/dist/esm/providers/WalletProvider/WalletProvider.d.ts.map +1 -1
  350. package/dist/esm/providers/WalletProvider/WalletProvider.js +10 -9
  351. package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
  352. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js +7 -3
  353. package/dist/esm/providers/WalletProvider/useExternalWalletProvider.js.map +1 -1
  354. package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts +2 -3
  355. package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
  356. package/dist/esm/providers/WidgetProvider/types.d.ts +2 -3
  357. package/dist/esm/providers/WidgetProvider/types.d.ts.map +1 -1
  358. package/dist/esm/stores/StoreProvider.d.ts +1 -2
  359. package/dist/esm/stores/StoreProvider.d.ts.map +1 -1
  360. package/dist/esm/stores/StoreProvider.js +10 -6
  361. package/dist/esm/stores/StoreProvider.js.map +1 -1
  362. package/dist/esm/stores/bookmarks/BookmarkStore.d.ts +1 -2
  363. package/dist/esm/stores/bookmarks/BookmarkStore.d.ts.map +1 -1
  364. package/dist/esm/stores/bookmarks/types.d.ts +5 -6
  365. package/dist/esm/stores/bookmarks/types.d.ts.map +1 -1
  366. package/dist/esm/stores/chains/ChainOrderStore.d.ts +1 -2
  367. package/dist/esm/stores/chains/ChainOrderStore.d.ts.map +1 -1
  368. package/dist/esm/stores/chains/ChainOrderStore.js +11 -5
  369. package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
  370. package/dist/esm/stores/chains/types.d.ts +1 -2
  371. package/dist/esm/stores/chains/types.d.ts.map +1 -1
  372. package/dist/esm/stores/form/types.d.ts +20 -21
  373. package/dist/esm/stores/form/types.d.ts.map +1 -1
  374. package/dist/esm/stores/form/useFieldActions.d.ts +1 -2
  375. package/dist/esm/stores/form/useFieldActions.d.ts.map +1 -1
  376. package/dist/esm/stores/form/useFieldValues.d.ts +1 -2
  377. package/dist/esm/stores/form/useFieldValues.d.ts.map +1 -1
  378. package/dist/esm/stores/header/types.d.ts +1 -2
  379. package/dist/esm/stores/header/types.d.ts.map +1 -1
  380. package/dist/esm/stores/header/useHeaderStore.d.ts +2 -3
  381. package/dist/esm/stores/header/useHeaderStore.d.ts.map +1 -1
  382. package/dist/esm/stores/inputMode/useInputModeStore.d.ts +1 -2
  383. package/dist/esm/stores/inputMode/useInputModeStore.d.ts.map +1 -1
  384. package/dist/esm/stores/recentTokens/RecentTokensStore.js +23 -0
  385. package/dist/esm/stores/recentTokens/RecentTokensStore.js.map +1 -0
  386. package/dist/esm/stores/recentTokens/createRecentTokensStore.js +54 -0
  387. package/dist/esm/stores/recentTokens/createRecentTokensStore.js.map +1 -0
  388. package/dist/esm/stores/recentTokens/utils.js +15 -0
  389. package/dist/esm/stores/recentTokens/utils.js.map +1 -0
  390. package/dist/esm/stores/routes/RouteExecutionStore.d.ts +2 -3
  391. package/dist/esm/stores/routes/RouteExecutionStore.d.ts.map +1 -1
  392. package/dist/esm/stores/routes/types.d.ts +3 -4
  393. package/dist/esm/stores/routes/types.d.ts.map +1 -1
  394. package/dist/esm/stores/routes/useRouteExecutionIndicator.js +4 -3
  395. package/dist/esm/stores/routes/useRouteExecutionIndicator.js.map +1 -1
  396. package/dist/esm/stores/routes/utils.d.ts +4 -5
  397. package/dist/esm/stores/routes/utils.d.ts.map +1 -1
  398. package/dist/esm/stores/settings/SettingsStore.d.ts +2 -3
  399. package/dist/esm/stores/settings/SettingsStore.d.ts.map +1 -1
  400. package/dist/esm/stores/settings/types.d.ts +2 -3
  401. package/dist/esm/stores/settings/types.d.ts.map +1 -1
  402. package/dist/esm/stores/types.d.ts +2 -3
  403. package/dist/esm/stores/types.d.ts.map +1 -1
  404. package/dist/esm/themes/azureLight.d.ts +1 -2
  405. package/dist/esm/themes/azureLight.d.ts.map +1 -1
  406. package/dist/esm/themes/jumper.d.ts +1 -2
  407. package/dist/esm/themes/jumper.d.ts.map +1 -1
  408. package/dist/esm/themes/palettes.d.ts +3 -4
  409. package/dist/esm/themes/palettes.d.ts.map +1 -1
  410. package/dist/esm/themes/types.d.ts +1 -0
  411. package/dist/esm/themes/watermelonLight.d.ts +1 -2
  412. package/dist/esm/themes/watermelonLight.d.ts.map +1 -1
  413. package/dist/esm/themes/windows95.d.ts +1 -2
  414. package/dist/esm/themes/windows95.d.ts.map +1 -1
  415. package/dist/esm/types/events.d.ts +13 -14
  416. package/dist/esm/types/events.d.ts.map +1 -1
  417. package/dist/esm/types/token.d.ts +6 -1
  418. package/dist/esm/types/token.d.ts.map +1 -1
  419. package/dist/esm/types/widget.d.ts +55 -51
  420. package/dist/esm/types/widget.d.ts.map +1 -1
  421. package/dist/esm/types/widget.js.map +1 -1
  422. package/dist/esm/utils/address.js +19 -0
  423. package/dist/esm/utils/address.js.map +1 -0
  424. package/dist/esm/utils/compactNumberFormatter.d.ts +1 -2
  425. package/dist/esm/utils/compactNumberFormatter.d.ts.map +1 -1
  426. package/dist/esm/utils/compactNumberFormatter.js +1 -3
  427. package/dist/esm/utils/compactNumberFormatter.js.map +1 -1
  428. package/dist/esm/utils/converters.d.ts +1 -2
  429. package/dist/esm/utils/converters.d.ts.map +1 -1
  430. package/dist/esm/utils/currencyExtendedFormatter.d.ts +1 -2
  431. package/dist/esm/utils/currencyExtendedFormatter.d.ts.map +1 -1
  432. package/dist/esm/utils/customReceiver.js +12 -0
  433. package/dist/esm/utils/customReceiver.js.map +1 -0
  434. package/dist/esm/utils/elements.d.ts +2 -3
  435. package/dist/esm/utils/elements.d.ts.map +1 -1
  436. package/dist/esm/utils/enum.d.ts +1 -2
  437. package/dist/esm/utils/enum.d.ts.map +1 -1
  438. package/dist/esm/utils/fees.d.ts +2 -3
  439. package/dist/esm/utils/fees.d.ts.map +1 -1
  440. package/dist/esm/utils/format.d.ts +8 -9
  441. package/dist/esm/utils/format.d.ts.map +1 -1
  442. package/dist/esm/utils/gas.js +24 -0
  443. package/dist/esm/utils/gas.js.map +1 -0
  444. package/dist/esm/utils/getErrorMessage.js +0 -1
  445. package/dist/esm/utils/getErrorMessage.js.map +1 -1
  446. package/dist/esm/utils/getPriceImpact.d.ts +1 -2
  447. package/dist/esm/utils/getPriceImpact.d.ts.map +1 -1
  448. package/dist/esm/utils/input.d.ts +1 -2
  449. package/dist/esm/utils/input.d.ts.map +1 -1
  450. package/dist/esm/utils/limitOrder.js +1 -1
  451. package/dist/esm/utils/limitOrder.js.map +1 -1
  452. package/dist/esm/utils/navigationRoutes.d.ts +2 -3
  453. package/dist/esm/utils/navigationRoutes.d.ts.map +1 -1
  454. package/dist/esm/utils/percentFormatter.d.ts +1 -2
  455. package/dist/esm/utils/percentFormatter.d.ts.map +1 -1
  456. package/dist/esm/utils/recentTokens.js +97 -0
  457. package/dist/esm/utils/recentTokens.js.map +1 -0
  458. package/dist/esm/utils/token.js +50 -7
  459. package/dist/esm/utils/token.js.map +1 -1
  460. package/dist/esm/utils/tokenList.js +54 -25
  461. package/dist/esm/utils/tokenList.js.map +1 -1
  462. package/dist/esm/utils/tokenListBands.js +85 -0
  463. package/dist/esm/utils/tokenListBands.js.map +1 -0
  464. package/dist/esm/utils/wallet.d.ts +1 -2
  465. package/dist/esm/utils/wallet.d.ts.map +1 -1
  466. package/package.json +15 -15
  467. package/src/components/AmountInput/AmountInputEndAdornment.tsx +2 -21
  468. package/src/components/AmountInputCard/PercentageChips.tsx +2 -18
  469. package/src/components/AmountInputCard/ReceiveAmountCard.tsx +16 -3
  470. package/src/components/BottomSheet/BottomSheet.tsx +3 -0
  471. package/src/components/Chains/AllChainsAvatar.tsx +7 -1
  472. package/src/components/Messages/UnsupportedToAddressMessage.tsx +24 -0
  473. package/src/components/Messages/WarningMessages.tsx +3 -0
  474. package/src/components/Messages/useMessageQueue.ts +9 -0
  475. package/src/components/Routes/LimitOrderRoutes.tsx +5 -2
  476. package/src/components/Routes/RoutesContent.tsx +5 -2
  477. package/src/components/SendToWallet/SendToWalletExpandButton.tsx +2 -1
  478. package/src/components/Token/Token.tsx +2 -1
  479. package/src/components/TokenList/RecentTokensHeader.tsx +52 -0
  480. package/src/components/TokenList/RecentTokensToggle.tsx +45 -0
  481. package/src/components/TokenList/RemoveRecentTokenButton.tsx +38 -0
  482. package/src/components/TokenList/TokenList.tsx +92 -3
  483. package/src/components/TokenList/TokenListItem.tsx +83 -9
  484. package/src/components/TokenList/VirtualizedTokenList.tsx +86 -103
  485. package/src/components/TokenList/types.ts +13 -0
  486. package/src/config/version.ts +1 -1
  487. package/src/hooks/useAvailableChains.ts +1 -0
  488. package/src/hooks/useDisplayedTokens.ts +17 -3
  489. package/src/hooks/useExplorer.ts +2 -0
  490. package/src/hooks/useFlaggedTokenGuard.ts +33 -0
  491. package/src/hooks/useGasSufficiency.ts +9 -1
  492. package/src/hooks/useMaxSendAmount.ts +21 -0
  493. package/src/hooks/useRecentTokens.ts +88 -0
  494. package/src/hooks/useRoutes.ts +10 -0
  495. package/src/hooks/useToAddressRequirements.ts +23 -1
  496. package/src/hooks/useTokenBalances.ts +38 -19
  497. package/src/hooks/useTokenSearch.ts +6 -19
  498. package/src/hooks/useTokens.ts +97 -40
  499. package/src/pages/MainPage/ReviewButton.tsx +6 -2
  500. package/src/pages/RoutesPage/RoutesPage.tsx +5 -2
  501. package/src/pages/TransactionPage/TokenValueBottomSheet.tsx +1 -1
  502. package/src/pages/TransactionPage/TokenVerificationBottomSheet.tsx +93 -0
  503. package/src/pages/TransactionPage/TransactionFailedButtons.tsx +62 -26
  504. package/src/pages/TransactionPage/TransactionReview.tsx +51 -25
  505. package/src/pages/TransactionPage/utils.ts +78 -0
  506. package/src/providers/WalletProvider/useExternalWalletProvider.ts +9 -1
  507. package/src/stores/StoreProvider.tsx +10 -7
  508. package/src/stores/chains/ChainOrderStore.test.tsx +298 -0
  509. package/src/stores/chains/ChainOrderStore.tsx +25 -6
  510. package/src/stores/recentTokens/RecentTokensStore.tsx +39 -0
  511. package/src/stores/recentTokens/createRecentTokensStore.ts +107 -0
  512. package/src/stores/recentTokens/types.ts +37 -0
  513. package/src/stores/recentTokens/utils.ts +18 -0
  514. package/src/types/token.ts +8 -3
  515. package/src/types/widget.ts +5 -0
  516. package/src/utils/address.ts +21 -0
  517. package/src/utils/customReceiver.ts +31 -0
  518. package/src/utils/gas.ts +41 -0
  519. package/src/utils/recentTokens.ts +187 -0
  520. package/src/utils/token.ts +122 -19
  521. package/src/utils/tokenList.ts +60 -14
  522. package/src/utils/tokenListBands.ts +181 -0
package/README.md CHANGED
@@ -16,12 +16,12 @@
16
16
 
17
17
  [**LI.FI Widget**](https://docs.li.fi/widget/overview) features include:
18
18
 
19
- - **Provider-based architecture** - Modular blockchain support with separate packages for Ethereum, Bitcoin, Solana, Sui, and Tron
19
+ - **Provider-based architecture** - Modular blockchain support with separate packages for Ethereum, Bitcoin, Solana, Sui, Tron, and Stellar
20
20
  - All ecosystems, chains, bridges, exchanges, and solvers that [LI.FI](https://docs.li.fi/introduction/chains) supports
21
21
  - Embeddable variants - compact, wide, and drawer
22
22
  - Options to allow or deny certain chains, tokens, bridges, and exchanges
23
23
  - Pre-configured themes and lots of customization options with dark mode support so you can match the look and feel of your web app
24
- - Built-in wallet management UI with support for external wallet providers ([Wagmi](https://wagmi.sh/), [Bigmi](https://github.com/lifinance/bigmi), [Wallet Standard](https://github.com/wallet-standard/wallet-standard), [@mysten/dapp-kit-react](https://sdk.mystenlabs.com/dapp-kit), and [TronWallet Adapters](https://github.com/tronweb3/tronwallet-adapter))
24
+ - Built-in wallet management UI with support for external wallet providers ([Wagmi](https://wagmi.sh/), [Bigmi](https://github.com/lifinance/bigmi), [Wallet Standard](https://github.com/wallet-standard/wallet-standard), [@mysten/dapp-kit-react](https://sdk.mystenlabs.com/dapp-kit), [TronWallet Adapters](https://github.com/tronweb3/tronwallet-adapter), and [Stellar Wallets Kit](https://github.com/Creit-Tech/Stellar-Wallets-Kit))
25
25
  - Supports widely adopted industry standards, including [EIP-5792](https://eips.ethereum.org/EIPS/eip-5792), [ERC-2612](https://eips.ethereum.org/EIPS/eip-2612), [EIP-712](https://eips.ethereum.org/EIPS/eip-712), [EIP-6963](https://eips.ethereum.org/EIPS/eip-6963), and [Permit2](https://github.com/Uniswap/permit2)
26
26
  - View of transactions in progress and transaction history
27
27
  - Curated wallet lists and wallet bookmarks
@@ -159,6 +159,26 @@ npm install @lifi/widget-provider-tron @tronweb3/tronwallet-adapter-react-hooks
159
159
  yarn add @lifi/widget-provider-tron @tronweb3/tronwallet-adapter-react-hooks
160
160
  ```
161
161
 
162
+ **Stellar:**
163
+
164
+ **pnpm:**
165
+
166
+ ```sh
167
+ pnpm add @lifi/widget-provider-stellar
168
+ ```
169
+
170
+ **npm:**
171
+
172
+ ```sh
173
+ npm install @lifi/widget-provider-stellar
174
+ ```
175
+
176
+ **yarn:**
177
+
178
+ ```sh
179
+ yarn add @lifi/widget-provider-stellar
180
+ ```
181
+
162
182
  **Note:** You only need to install the provider packages for the blockchains you want to support. Each provider package includes its required peer dependencies.
163
183
 
164
184
  ### LI.FI Wallet Management
@@ -218,6 +238,7 @@ The LI.FI Widget uses a **provider-based architecture** that allows you to selec
218
238
  - **`@lifi/widget-provider-solana`** - Solana support (requires [bs58](https://www.npmjs.com/package/bs58))
219
239
  - **`@lifi/widget-provider-sui`** - Sui support (requires [@mysten/dapp-kit-react](https://sdk.mystenlabs.com/dapp-kit))
220
240
  - **`@lifi/widget-provider-tron`** - Tron support (requires [@tronweb3/tronwallet-adapter-react-hooks](https://github.com/tronweb3/tronwallet-adapter))
241
+ - **`@lifi/widget-provider-stellar`** - Stellar support (bundles [Stellar Wallets Kit](https://github.com/Creit-Tech/Stellar-Wallets-Kit); no extra install)
221
242
  - **`@lifi/wallet-management`** - Wallet management UI components
222
243
  - **`@lifi/widget-light`** - Lightweight iframe-based integration ([docs](https://docs.li.fi/widget/widget-light-overview))
223
244
 
@@ -254,13 +275,14 @@ export const WidgetPage = () => {
254
275
  };
255
276
  ```
256
277
 
257
- **Multi-chain example** (Ethereum, Solana, Bitcoin, Sui, and Tron):
278
+ **Multi-chain example** (Ethereum, Solana, Bitcoin, Sui, Tron, and Stellar):
258
279
 
259
280
  ```tsx
260
281
  import { LiFiWidget, WidgetConfig } from '@lifi/widget';
261
282
  import { BitcoinProvider } from '@lifi/widget-provider-bitcoin';
262
283
  import { EthereumProvider } from '@lifi/widget-provider-ethereum';
263
284
  import { SolanaProvider } from '@lifi/widget-provider-solana';
285
+ import { StellarProvider } from '@lifi/widget-provider-stellar';
264
286
  import { SuiProvider } from '@lifi/widget-provider-sui';
265
287
  import { TronProvider } from '@lifi/widget-provider-tron';
266
288
 
@@ -271,6 +293,7 @@ const widgetConfig: WidgetConfig = {
271
293
  BitcoinProvider(),
272
294
  SuiProvider(),
273
295
  TronProvider(),
296
+ StellarProvider(),
274
297
  ],
275
298
  theme: {
276
299
  container: {
package/dist/esm/App.d.ts CHANGED
@@ -2,9 +2,8 @@ import { WidgetProps } from "./types/widget.js";
2
2
  import { WidgetDrawer } from "./AppDrawer.js";
3
3
  import { JSX, Ref } from "react";
4
4
  //#region src/App.d.ts
5
- declare const App: (props: WidgetProps & {
5
+ export declare const App: (props: WidgetProps & {
6
6
  ref?: Ref<WidgetDrawer>;
7
7
  }) => JSX.Element;
8
8
  //#endregion
9
- export { App };
10
9
  //# sourceMappingURL=App.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","names":[],"sources":["../../src/App.tsx"],"mappings":";;;;cASa,MACX,OAAO;EAAgB,MAAM,IAAI;MAChC,IAAI"}
1
+ {"version":3,"file":"App.d.ts","names":[],"sources":["../../src/App.tsx"],"mappings":";;;;qBASa,MACX,OAAO;EAAgB,MAAM,IAAI;MAChC,IAAI"}
@@ -1,12 +1,11 @@
1
1
  import "./types/widget.js";
2
2
  import { JSX, PropsWithChildren, Ref } from "react";
3
3
  //#region src/AppDrawer.d.ts
4
- interface WidgetDrawer {
4
+ export interface WidgetDrawer {
5
5
  isOpen(): void;
6
6
  toggleDrawer(): void;
7
7
  openDrawer(): void;
8
8
  closeDrawer(): void;
9
9
  }
10
10
  //#endregion
11
- export { WidgetDrawer };
12
11
  //# sourceMappingURL=AppDrawer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AppDrawer.d.ts","names":[],"sources":["../../src/AppDrawer.tsx"],"mappings":";;;UAaiB;EACf;EACA;EACA;EACA"}
1
+ {"version":3,"file":"AppDrawer.d.ts","names":[],"sources":["../../src/AppDrawer.tsx"],"mappings":";;;iBAaiB;EACf;EACA;EACA;EACA"}
@@ -32,8 +32,9 @@ const AppDrawer = ({ elementRef, open, onClose, children, ref }) => {
32
32
  openDrawer,
33
33
  toggleDrawer
34
34
  ]);
35
+ const drawerContext = useMemo(() => ({ closeDrawer }), [closeDrawer]);
35
36
  return /* @__PURE__ */ jsx(DrawerContext, {
36
- value: useMemo(() => ({ closeDrawer }), [closeDrawer]),
37
+ value: drawerContext,
37
38
  children: /* @__PURE__ */ jsx(Drawer, {
38
39
  ref: elementRef,
39
40
  anchor: "right",
@@ -1 +1 @@
1
- {"version":3,"file":"AppDrawer.js","names":[],"sources":["../../src/AppDrawer.tsx"],"sourcesContent":["import { Drawer } from '@mui/material'\nimport type { JSX, PropsWithChildren, Ref } from 'react'\nimport {\n useCallback,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport type { WidgetDrawerContext } from './AppDrawerContext.js'\nimport { DrawerContext } from './AppDrawerContext.js'\nimport type { WidgetDrawerProps } from './types/widget.js'\n\nexport interface WidgetDrawer {\n isOpen(): void\n toggleDrawer(): void\n openDrawer(): void\n closeDrawer(): void\n}\n\nexport const AppDrawer = ({\n elementRef,\n open,\n onClose,\n children,\n ref,\n}: PropsWithChildren<WidgetDrawerProps> & {\n ref?: Ref<WidgetDrawer>\n}): JSX.Element => {\n const openRef = useRef(Boolean(open))\n const [drawerOpen, setDrawerOpen] = useState(Boolean(open))\n\n const toggleDrawer = useCallback(() => {\n setDrawerOpen((open) => {\n openRef.current = !open\n return openRef.current\n })\n if (!openRef.current) {\n onClose?.()\n }\n }, [onClose])\n\n const openDrawer = useCallback(() => {\n setDrawerOpen(true)\n openRef.current = true\n }, [])\n\n const closeDrawer = useCallback(() => {\n setDrawerOpen(false)\n openRef.current = false\n onClose?.()\n }, [onClose])\n\n useImperativeHandle(\n ref,\n () => ({\n isOpen: () => openRef.current,\n toggleDrawer,\n openDrawer,\n closeDrawer,\n }),\n [closeDrawer, openDrawer, toggleDrawer]\n )\n\n const drawerContext: WidgetDrawerContext = useMemo(\n () => ({\n closeDrawer,\n }),\n [closeDrawer]\n )\n\n return (\n <DrawerContext value={drawerContext}>\n <Drawer\n ref={elementRef}\n anchor=\"right\"\n open={drawerOpen}\n onClose={closeDrawer}\n slotProps={{\n paper: {\n sx: (theme) => ({\n background: theme.vars.palette.background.default,\n width: theme?.container?.width ?? '100%',\n minWidth:\n theme?.container?.minWidth ?? theme.breakpoints.values.xs,\n maxWidth:\n theme?.container?.maxWidth ?? theme.breakpoints.values.sm,\n }),\n },\n backdrop: {\n sx: {\n backgroundColor: 'rgb(0 0 0 / 48%)',\n backdropFilter: 'blur(3px)',\n },\n },\n }}\n keepMounted\n >\n {children}\n </Drawer>\n </DrawerContext>\n )\n}\n"],"mappings":";;;;;AAoBA,MAAa,aAAa,EACxB,YACA,MACA,SACA,UACA,UAGiB;CACjB,MAAM,UAAU,OAAO,QAAQ,IAAI,CAAC;CACpC,MAAM,CAAC,YAAY,iBAAiB,SAAS,QAAQ,IAAI,CAAC;CAE1D,MAAM,eAAe,kBAAkB;EACrC,eAAe,SAAS;GACtB,QAAQ,UAAU,CAAC;GACnB,OAAO,QAAQ;EACjB,CAAC;EACD,IAAI,CAAC,QAAQ,SACX,UAAU;CAEd,GAAG,CAAC,OAAO,CAAC;CAEZ,MAAM,aAAa,kBAAkB;EACnC,cAAc,IAAI;EAClB,QAAQ,UAAU;CACpB,GAAG,CAAC,CAAC;CAEL,MAAM,cAAc,kBAAkB;EACpC,cAAc,KAAK;EACnB,QAAQ,UAAU;EAClB,UAAU;CACZ,GAAG,CAAC,OAAO,CAAC;CAEZ,oBACE,YACO;EACL,cAAc,QAAQ;EACtB;EACA;EACA;CACF,IACA;EAAC;EAAa;EAAY;CAAY,CACxC;CASA,OACE,oBAAC,eAAD;EAAe,OAR0B,eAClC,EACL,YACF,IACA,CAAC,WAAW,CAIsB;EAChC,UAAA,oBAAC,QAAD;GACE,KAAK;GACL,QAAO;GACP,MAAM;GACN,SAAS;GACT,WAAW;IACT,OAAO,EACL,KAAK,WAAW;KACd,YAAY,MAAM,KAAK,QAAQ,WAAW;KAC1C,OAAO,OAAO,WAAW,SAAS;KAClC,UACE,OAAO,WAAW,YAAY,MAAM,YAAY,OAAO;KACzD,UACE,OAAO,WAAW,YAAY,MAAM,YAAY,OAAO;IAC3D,GACF;IACA,UAAU,EACR,IAAI;KACF,iBAAiB;KACjB,gBAAgB;IAClB,EACF;GACF;GACA,aAAA;GAEC;EACK,CAAA;CACK,CAAA;AAEnB"}
1
+ {"version":3,"file":"AppDrawer.js","names":[],"sources":["../../src/AppDrawer.tsx"],"sourcesContent":["import { Drawer } from '@mui/material'\nimport type { JSX, PropsWithChildren, Ref } from 'react'\nimport {\n useCallback,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport type { WidgetDrawerContext } from './AppDrawerContext.js'\nimport { DrawerContext } from './AppDrawerContext.js'\nimport type { WidgetDrawerProps } from './types/widget.js'\n\nexport interface WidgetDrawer {\n isOpen(): void\n toggleDrawer(): void\n openDrawer(): void\n closeDrawer(): void\n}\n\nexport const AppDrawer = ({\n elementRef,\n open,\n onClose,\n children,\n ref,\n}: PropsWithChildren<WidgetDrawerProps> & {\n ref?: Ref<WidgetDrawer>\n}): JSX.Element => {\n const openRef = useRef(Boolean(open))\n const [drawerOpen, setDrawerOpen] = useState(Boolean(open))\n\n const toggleDrawer = useCallback(() => {\n setDrawerOpen((open) => {\n openRef.current = !open\n return openRef.current\n })\n if (!openRef.current) {\n onClose?.()\n }\n }, [onClose])\n\n const openDrawer = useCallback(() => {\n setDrawerOpen(true)\n openRef.current = true\n }, [])\n\n const closeDrawer = useCallback(() => {\n setDrawerOpen(false)\n openRef.current = false\n onClose?.()\n }, [onClose])\n\n useImperativeHandle(\n ref,\n () => ({\n isOpen: () => openRef.current,\n toggleDrawer,\n openDrawer,\n closeDrawer,\n }),\n [closeDrawer, openDrawer, toggleDrawer]\n )\n\n const drawerContext: WidgetDrawerContext = useMemo(\n () => ({\n closeDrawer,\n }),\n [closeDrawer]\n )\n\n return (\n <DrawerContext value={drawerContext}>\n <Drawer\n ref={elementRef}\n anchor=\"right\"\n open={drawerOpen}\n onClose={closeDrawer}\n slotProps={{\n paper: {\n sx: (theme) => ({\n background: theme.vars.palette.background.default,\n width: theme?.container?.width ?? '100%',\n minWidth:\n theme?.container?.minWidth ?? theme.breakpoints.values.xs,\n maxWidth:\n theme?.container?.maxWidth ?? theme.breakpoints.values.sm,\n }),\n },\n backdrop: {\n sx: {\n backgroundColor: 'rgb(0 0 0 / 48%)',\n backdropFilter: 'blur(3px)',\n },\n },\n }}\n keepMounted\n >\n {children}\n </Drawer>\n </DrawerContext>\n )\n}\n"],"mappings":";;;;;AAoBA,MAAa,aAAa,EACxB,YACA,MACA,SACA,UACA,UAGiB;CACjB,MAAM,UAAU,OAAO,QAAQ,IAAI,CAAC;CACpC,MAAM,CAAC,YAAY,iBAAiB,SAAS,QAAQ,IAAI,CAAC;CAE1D,MAAM,eAAe,kBAAkB;EACrC,eAAe,SAAS;GACtB,QAAQ,UAAU,CAAC;GACnB,OAAO,QAAQ;EACjB,CAAC;EACD,IAAI,CAAC,QAAQ,SACX,UAAU;CAEd,GAAG,CAAC,OAAO,CAAC;CAEZ,MAAM,aAAa,kBAAkB;EACnC,cAAc,IAAI;EAClB,QAAQ,UAAU;CACpB,GAAG,CAAC,CAAC;CAEL,MAAM,cAAc,kBAAkB;EACpC,cAAc,KAAK;EACnB,QAAQ,UAAU;EAClB,UAAU;CACZ,GAAG,CAAC,OAAO,CAAC;CAEZ,oBACE,YACO;EACL,cAAc,QAAQ;EACtB;EACA;EACA;CACF,IACA;EAAC;EAAa;EAAY;CAAY,CACxC;CAEA,MAAM,gBAAqC,eAClC,EACL,YACF,IACA,CAAC,WAAW,CACd;CAEA,OACE,oBAAC,eAAD;EAAe,OAAO;EACpB,UAAA,oBAAC,QAAD;GACE,KAAK;GACL,QAAO;GACP,MAAM;GACN,SAAS;GACT,WAAW;IACT,OAAO,EACL,KAAK,WAAW;KACd,YAAY,MAAM,KAAK,QAAQ,WAAW;KAC1C,OAAO,OAAO,WAAW,SAAS;KAClC,UACE,OAAO,WAAW,YAAY,MAAM,YAAY,OAAO;KACzD,UACE,OAAO,WAAW,YAAY,MAAM,YAAY,OAAO;IAC3D,GACF;IACA,UAAU,EACR,IAAI;KACF,iBAAiB;KACjB,gBAAgB;IAClB,EACF;GACF;GACA,aAAA;GAEC;EACK,CAAA;CACK,CAAA;AAEnB"}
@@ -7,7 +7,6 @@ interface ActionRowProps {
7
7
  endAdornment?: ReactNode;
8
8
  sx?: SxProps<Theme>;
9
9
  }
10
- declare const ActionRow: FC<ActionRowProps>;
10
+ export declare const ActionRow: FC<ActionRowProps>;
11
11
  //#endregion
12
- export { ActionRow };
13
12
  //# sourceMappingURL=ActionRow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ActionRow.d.ts","names":[],"sources":["../../../../src/components/ActionRow/ActionRow.tsx"],"mappings":";;;UAIU;EACR;EACA,gBAAgB;EAChB,eAAe;EACf,KAAK,QAAQ;;cAGF,WAAW,GAAG"}
1
+ {"version":3,"file":"ActionRow.d.ts","names":[],"sources":["../../../../src/components/ActionRow/ActionRow.tsx"],"mappings":";;;UAIU;EACR;EACA,gBAAgB;EAChB,eAAe;EACf,KAAK,QAAQ;;qBAGF,WAAW,GAAG"}
@@ -40,16 +40,20 @@ const AmountInputBase = ({ formType, token, startAdornment, bottomAdornment, dis
40
40
  const { inputMode } = useInputModeStore();
41
41
  const currentInputMode = inputMode[formType];
42
42
  let displayValue;
43
- if (isEditingRef.current) if (currentInputMode === "price") displayValue = formattedPriceInput;
44
- else displayValue = value;
45
- else if (currentInputMode === "price") displayValue = formatInputAmount(formatTokenPrice(value, token?.priceUSD).toFixed(2), 2);
46
- else displayValue = value;
43
+ if (isEditingRef.current) {
44
+ if (currentInputMode === "price") displayValue = formattedPriceInput;
45
+ else displayValue = value;
46
+ } else if (currentInputMode === "price") {
47
+ const priceValue = formatTokenPrice(value, token?.priceUSD);
48
+ displayValue = formatInputAmount(priceValue.toFixed(2), 2);
49
+ } else displayValue = value;
47
50
  const handleChange = (event) => {
48
51
  const { value: inputValue } = event.target;
49
52
  isEditingRef.current = true;
50
53
  let formattedValue;
51
54
  if (currentInputMode === "price") {
52
- formattedValue = formatInputAmount(inputValue.replace("$", ""), 2, true);
55
+ const cleanInputValue = inputValue.replace("$", "");
56
+ formattedValue = formatInputAmount(cleanInputValue, 2, true);
53
57
  const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD);
54
58
  setFormattedPriceInput(formattedValue);
55
59
  setFieldValue(amountKey, tokenValue, {
@@ -69,8 +73,10 @@ const AmountInputBase = ({ formType, token, startAdornment, bottomAdornment, dis
69
73
  isEditingRef.current = false;
70
74
  let formattedValue;
71
75
  if (currentInputMode === "price") {
72
- formattedValue = formatInputAmount(inputValue.replace("$", ""), 2);
73
- const formattedAmount = formatInputAmount(priceToTokenAmount(formattedValue, token?.priceUSD), token?.decimals);
76
+ const cleanInputValue = inputValue.replace("$", "");
77
+ formattedValue = formatInputAmount(cleanInputValue, 2);
78
+ const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD);
79
+ const formattedAmount = formatInputAmount(tokenValue, token?.decimals);
74
80
  setFieldValue(amountKey, formattedAmount, {
75
81
  isDirty: true,
76
82
  isTouched: true
@@ -1 +1 @@
1
- {"version":3,"file":"AmountInput.js","names":[],"sources":["../../../../src/components/AmountInput/AmountInput.tsx"],"sourcesContent":["import type { Token } from '@lifi/sdk'\nimport type { CardProps } from '@mui/material'\nimport type { ChangeEvent, ReactNode } from 'react'\nimport { useLayoutEffect, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useToken } from '../../hooks/useToken.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { FormKeyHelper, type FormTypeProps } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport { useInputModeStore } from '../../stores/inputMode/useInputModeStore.js'\nimport {\n formatInputAmount,\n formatTokenPrice,\n priceToTokenAmount,\n usdDecimals,\n} from '../../utils/format.js'\nimport { fitInputText } from '../../utils/input.js'\nimport { InputCard } from '../Card/InputCard.js'\nimport {\n AmountInputCardHeader,\n AmountInputCardTitle,\n FormContainer,\n FormControl,\n Input,\n maxInputFontSize,\n minInputFontSize,\n} from './AmountInput.style.js'\nimport { AmountInputEndAdornment } from './AmountInputEndAdornment.js'\nimport { AmountInputStartAdornment } from './AmountInputStartAdornment.js'\nimport { PriceFormHelperText } from './PriceFormHelperText.js'\n\nexport const AmountInput: React.FC<FormTypeProps & CardProps> = ({\n formType,\n ...props\n}) => {\n const { disabledUI } = useWidgetConfig()\n\n const [chainId, tokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n FormKeyHelper.getTokenKey(formType)\n )\n\n const { token } = useToken(chainId, tokenAddress)\n\n const disabled = disabledUI?.fromAmount\n return (\n <AmountInputBase\n formType={formType}\n token={token}\n bottomAdornment={<PriceFormHelperText formType={formType} />}\n disabled={disabled}\n {...props}\n />\n )\n}\n\nconst AmountInputBase: React.FC<\n FormTypeProps &\n CardProps & {\n token?: Token\n startAdornment?: ReactNode\n bottomAdornment?: ReactNode\n disabled?: boolean\n }\n> = ({\n formType,\n token,\n startAdornment,\n bottomAdornment,\n disabled,\n ...props\n}) => {\n const { t } = useTranslation()\n const { mode, modeOptions } = useWidgetConfig()\n const ref = useRef<HTMLInputElement>(null)\n\n const isEditingRef = useRef(false)\n const [formattedPriceInput, setFormattedPriceInput] = useState('')\n\n const amountKey = FormKeyHelper.getAmountKey(formType)\n const [value] = useFieldValues(amountKey)\n const { setFieldValue } = useFieldActions()\n const { inputMode } = useInputModeStore()\n\n const currentInputMode = inputMode[formType]\n let displayValue: string\n if (isEditingRef.current) {\n if (currentInputMode === 'price') {\n displayValue = formattedPriceInput\n } else {\n displayValue = value as string\n }\n } else {\n if (currentInputMode === 'price') {\n const priceValue = formatTokenPrice(value as string, token?.priceUSD)\n displayValue = formatInputAmount(\n priceValue.toFixed(usdDecimals),\n usdDecimals\n )\n } else {\n displayValue = value as string\n }\n }\n\n const handleChange = (\n event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>\n ) => {\n const { value: inputValue } = event.target\n isEditingRef.current = true\n\n let formattedValue: string\n if (currentInputMode === 'price') {\n const cleanInputValue = inputValue.replace('$', '')\n formattedValue = formatInputAmount(cleanInputValue, usdDecimals, true)\n const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD)\n setFormattedPriceInput(formattedValue)\n setFieldValue(amountKey, tokenValue, { isDirty: true, isTouched: true })\n } else {\n formattedValue = formatInputAmount(inputValue, token?.decimals, true)\n setFieldValue(amountKey, formattedValue, {\n isDirty: true,\n isTouched: true,\n })\n }\n }\n\n const handleBlur = (\n event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>\n ) => {\n const { value: inputValue } = event.target\n isEditingRef.current = false\n\n let formattedValue: string\n if (currentInputMode === 'price') {\n const cleanInputValue = inputValue.replace('$', '')\n formattedValue = formatInputAmount(cleanInputValue, usdDecimals)\n const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD)\n const formattedAmount = formatInputAmount(tokenValue, token?.decimals)\n setFieldValue(amountKey, formattedAmount, {\n isDirty: true,\n isTouched: true,\n })\n } else {\n formattedValue = formatInputAmount(inputValue, token?.decimals)\n setFieldValue(amountKey, formattedValue, {\n isDirty: true,\n isTouched: true,\n })\n }\n }\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: we need run effect on value change\n useLayoutEffect(() => {\n if (ref.current) {\n fitInputText(maxInputFontSize, minInputFontSize, ref.current)\n }\n }, [displayValue])\n\n const title =\n mode === 'custom'\n ? modeOptions?.custom?.type === 'deposit'\n ? t('header.amount')\n : t('header.youPay')\n : t('header.send')\n\n return (\n <InputCard {...props}>\n <AmountInputCardHeader>\n <AmountInputCardTitle>{title}</AmountInputCardTitle>\n </AmountInputCardHeader>\n <FormContainer>\n <AmountInputStartAdornment formType={formType} />\n <FormControl fullWidth>\n <Input\n inputRef={ref}\n size=\"small\"\n autoComplete=\"off\"\n placeholder={currentInputMode === 'price' ? '$0' : '0'}\n startAdornment={startAdornment}\n inputProps={{\n inputMode: 'decimal',\n }}\n onChange={handleChange}\n onBlur={handleBlur}\n value={\n currentInputMode === 'price'\n ? displayValue\n ? `$${displayValue}`\n : ''\n : displayValue\n }\n name={amountKey}\n disabled={disabled}\n required\n />\n {bottomAdornment}\n </FormControl>\n </FormContainer>\n {!disabled && <AmountInputEndAdornment formType={formType} />}\n </InputCard>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AmountInput.js","names":[],"sources":["../../../../src/components/AmountInput/AmountInput.tsx"],"sourcesContent":["import type { Token } from '@lifi/sdk'\nimport type { CardProps } from '@mui/material'\nimport type { ChangeEvent, ReactNode } from 'react'\nimport { useLayoutEffect, useRef, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useToken } from '../../hooks/useToken.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { FormKeyHelper, type FormTypeProps } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport { useInputModeStore } from '../../stores/inputMode/useInputModeStore.js'\nimport {\n formatInputAmount,\n formatTokenPrice,\n priceToTokenAmount,\n usdDecimals,\n} from '../../utils/format.js'\nimport { fitInputText } from '../../utils/input.js'\nimport { InputCard } from '../Card/InputCard.js'\nimport {\n AmountInputCardHeader,\n AmountInputCardTitle,\n FormContainer,\n FormControl,\n Input,\n maxInputFontSize,\n minInputFontSize,\n} from './AmountInput.style.js'\nimport { AmountInputEndAdornment } from './AmountInputEndAdornment.js'\nimport { AmountInputStartAdornment } from './AmountInputStartAdornment.js'\nimport { PriceFormHelperText } from './PriceFormHelperText.js'\n\nexport const AmountInput: React.FC<FormTypeProps & CardProps> = ({\n formType,\n ...props\n}) => {\n const { disabledUI } = useWidgetConfig()\n\n const [chainId, tokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n FormKeyHelper.getTokenKey(formType)\n )\n\n const { token } = useToken(chainId, tokenAddress)\n\n const disabled = disabledUI?.fromAmount\n return (\n <AmountInputBase\n formType={formType}\n token={token}\n bottomAdornment={<PriceFormHelperText formType={formType} />}\n disabled={disabled}\n {...props}\n />\n )\n}\n\nconst AmountInputBase: React.FC<\n FormTypeProps &\n CardProps & {\n token?: Token\n startAdornment?: ReactNode\n bottomAdornment?: ReactNode\n disabled?: boolean\n }\n> = ({\n formType,\n token,\n startAdornment,\n bottomAdornment,\n disabled,\n ...props\n}) => {\n const { t } = useTranslation()\n const { mode, modeOptions } = useWidgetConfig()\n const ref = useRef<HTMLInputElement>(null)\n\n const isEditingRef = useRef(false)\n const [formattedPriceInput, setFormattedPriceInput] = useState('')\n\n const amountKey = FormKeyHelper.getAmountKey(formType)\n const [value] = useFieldValues(amountKey)\n const { setFieldValue } = useFieldActions()\n const { inputMode } = useInputModeStore()\n\n const currentInputMode = inputMode[formType]\n let displayValue: string\n if (isEditingRef.current) {\n if (currentInputMode === 'price') {\n displayValue = formattedPriceInput\n } else {\n displayValue = value as string\n }\n } else {\n if (currentInputMode === 'price') {\n const priceValue = formatTokenPrice(value as string, token?.priceUSD)\n displayValue = formatInputAmount(\n priceValue.toFixed(usdDecimals),\n usdDecimals\n )\n } else {\n displayValue = value as string\n }\n }\n\n const handleChange = (\n event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>\n ) => {\n const { value: inputValue } = event.target\n isEditingRef.current = true\n\n let formattedValue: string\n if (currentInputMode === 'price') {\n const cleanInputValue = inputValue.replace('$', '')\n formattedValue = formatInputAmount(cleanInputValue, usdDecimals, true)\n const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD)\n setFormattedPriceInput(formattedValue)\n setFieldValue(amountKey, tokenValue, { isDirty: true, isTouched: true })\n } else {\n formattedValue = formatInputAmount(inputValue, token?.decimals, true)\n setFieldValue(amountKey, formattedValue, {\n isDirty: true,\n isTouched: true,\n })\n }\n }\n\n const handleBlur = (\n event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>\n ) => {\n const { value: inputValue } = event.target\n isEditingRef.current = false\n\n let formattedValue: string\n if (currentInputMode === 'price') {\n const cleanInputValue = inputValue.replace('$', '')\n formattedValue = formatInputAmount(cleanInputValue, usdDecimals)\n const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD)\n const formattedAmount = formatInputAmount(tokenValue, token?.decimals)\n setFieldValue(amountKey, formattedAmount, {\n isDirty: true,\n isTouched: true,\n })\n } else {\n formattedValue = formatInputAmount(inputValue, token?.decimals)\n setFieldValue(amountKey, formattedValue, {\n isDirty: true,\n isTouched: true,\n })\n }\n }\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: we need run effect on value change\n useLayoutEffect(() => {\n if (ref.current) {\n fitInputText(maxInputFontSize, minInputFontSize, ref.current)\n }\n }, [displayValue])\n\n const title =\n mode === 'custom'\n ? modeOptions?.custom?.type === 'deposit'\n ? t('header.amount')\n : t('header.youPay')\n : t('header.send')\n\n return (\n <InputCard {...props}>\n <AmountInputCardHeader>\n <AmountInputCardTitle>{title}</AmountInputCardTitle>\n </AmountInputCardHeader>\n <FormContainer>\n <AmountInputStartAdornment formType={formType} />\n <FormControl fullWidth>\n <Input\n inputRef={ref}\n size=\"small\"\n autoComplete=\"off\"\n placeholder={currentInputMode === 'price' ? '$0' : '0'}\n startAdornment={startAdornment}\n inputProps={{\n inputMode: 'decimal',\n }}\n onChange={handleChange}\n onBlur={handleBlur}\n value={\n currentInputMode === 'price'\n ? displayValue\n ? `$${displayValue}`\n : ''\n : displayValue\n }\n name={amountKey}\n disabled={disabled}\n required\n />\n {bottomAdornment}\n </FormControl>\n </FormContainer>\n {!disabled && <AmountInputEndAdornment formType={formType} />}\n </InputCard>\n )\n}\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ import React from "react";
3
3
  import { Box, FormControl, InputBase } from "@mui/material";
4
4
  //#region src/components/AmountInput/AmountInput.style.d.ts
5
5
  declare const FormControl$1: React.FC<React.ComponentProps<typeof FormControl>>;
6
- declare const Input: React.FC<React.ComponentProps<typeof InputBase>>;
6
+ export declare const Input: React.FC<React.ComponentProps<typeof InputBase>>;
7
7
  //#endregion
8
- export { FormControl$1 as FormControl, Input };
8
+ export { FormControl$1 as FormControl };
9
9
  //# sourceMappingURL=AmountInput.style.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AmountInput.style.d.ts","names":[],"sources":["../../../../src/components/AmountInput/AmountInput.style.tsx"],"mappings":";;;;cAqBa,eAAa,MAAM,GAC9B,MAAM,sBAAsB;cAKjB,OAAO,MAAM,GAAG,MAAM,sBAAsB"}
1
+ {"version":3,"file":"AmountInput.style.d.ts","names":[],"sources":["../../../../src/components/AmountInput/AmountInput.style.tsx"],"mappings":";;;;cAqBa,eAAa,MAAM,GAC9B,MAAM,sBAAsB;qBAKjB,OAAO,MAAM,GAAG,MAAM,sBAAsB"}
@@ -1,7 +1,6 @@
1
1
  import { FormTypeProps } from "../../stores/form/types.js";
2
2
  import React from "react";
3
3
  //#region src/components/AmountInput/AmountInputEndAdornment.d.ts
4
- declare const AmountInputEndAdornment: React.NamedExoticComponent<FormTypeProps>;
4
+ export declare const AmountInputEndAdornment: React.NamedExoticComponent<FormTypeProps>;
5
5
  //#endregion
6
- export { AmountInputEndAdornment };
7
6
  //# sourceMappingURL=AmountInputEndAdornment.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AmountInputEndAdornment.d.ts","names":[],"sources":["../../../../src/components/AmountInput/AmountInputEndAdornment.tsx"],"mappings":";;;cAiBa,yBAAyB,MAAM,qBAAqB"}
1
+ {"version":3,"file":"AmountInputEndAdornment.d.ts","names":[],"sources":["../../../../src/components/AmountInput/AmountInputEndAdornment.tsx"],"mappings":";;;qBAiBa,yBAAyB,MAAM,qBAAqB"}
@@ -2,8 +2,8 @@ import { useAvailableChains } from "../../hooks/useAvailableChains.js";
2
2
  import { useFieldActions } from "../../stores/form/useFieldActions.js";
3
3
  import { FormKeyHelper } from "../../stores/form/types.js";
4
4
  import { useFieldValues } from "../../stores/form/useFieldValues.js";
5
- import { useGasRecommendation } from "../../hooks/useGasRecommendation.js";
6
5
  import { useTokenAddressBalance } from "../../hooks/useTokenAddressBalance.js";
6
+ import { useMaxSendAmount } from "../../hooks/useMaxSendAmount.js";
7
7
  import { AmountInputButton, ButtonContainer } from "./AmountInputEndAdornment.style.js";
8
8
  import { formatUnits } from "@lifi/sdk";
9
9
  import { memo } from "react";
@@ -18,26 +18,15 @@ const AmountInputEndAdornment = memo(({ formType }) => {
18
18
  const [chainId, tokenAddress] = useFieldValues(FormKeyHelper.getChainKey(formType), FormKeyHelper.getTokenKey(formType));
19
19
  const chain = getChainById(chainId);
20
20
  const { account } = useAccount({ chainType: chain?.chainType });
21
- const { data } = useGasRecommendation(chainId);
22
21
  const { token } = useTokenAddressBalance(chainId, tokenAddress);
23
- const getMaxAmount = () => {
24
- if (!token?.amount) return 0n;
25
- let maxAmount = token.amount;
26
- if (chain?.nativeToken.address === tokenAddress && data?.recommended) {
27
- const recommendedAmount = BigInt(data.recommended.amount);
28
- if (token.amount > recommendedAmount) maxAmount = token.amount - recommendedAmount;
29
- }
30
- return maxAmount;
31
- };
22
+ const maxAmount = useMaxSendAmount(chainId, tokenAddress);
32
23
  const handlePercentage = (percentage) => {
33
- const maxAmount = getMaxAmount();
34
24
  if (maxAmount && token?.decimals) {
35
25
  const percentageAmount = maxAmount * BigInt(percentage) / 100n;
36
26
  setFieldValue(FormKeyHelper.getAmountKey(formType), formatUnits(percentageAmount, token.decimals), { isTouched: true });
37
27
  }
38
28
  };
39
29
  const handleMax = () => {
40
- const maxAmount = getMaxAmount();
41
30
  if (maxAmount && token?.decimals) setFieldValue(FormKeyHelper.getAmountKey(formType), formatUnits(maxAmount, token.decimals), { isTouched: true });
42
31
  };
43
32
  if (formType !== "from" || !token || !account?.isConnected) return null;
@@ -1 +1 @@
1
- {"version":3,"file":"AmountInputEndAdornment.js","names":[],"sources":["../../../../src/components/AmountInput/AmountInputEndAdornment.tsx"],"sourcesContent":["import { formatUnits } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport type React from 'react'\nimport { type JSX, memo } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useGasRecommendation } from '../../hooks/useGasRecommendation.js'\nimport { useTokenAddressBalance } from '../../hooks/useTokenAddressBalance.js'\nimport type { FormTypeProps } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport {\n AmountInputButton,\n ButtonContainer,\n} from './AmountInputEndAdornment.style.js'\n\nexport const AmountInputEndAdornment: React.NamedExoticComponent<FormTypeProps> =\n memo(({ formType }: FormTypeProps): JSX.Element | null => {\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n const { setFieldValue } = useFieldActions()\n\n const [chainId, tokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n FormKeyHelper.getTokenKey(formType)\n )\n\n const chain = getChainById(chainId)\n const { account } = useAccount({ chainType: chain?.chainType })\n\n // We get gas recommendations for the source chain to make sure that after pressing the Max button\n // the user will have enough funds remaining to cover gas costs\n const { data } = useGasRecommendation(chainId)\n\n const { token } = useTokenAddressBalance(chainId, tokenAddress)\n\n const getMaxAmount = () => {\n if (!token?.amount) {\n return 0n\n }\n let maxAmount = token.amount\n if (chain?.nativeToken.address === tokenAddress && data?.recommended) {\n const recommendedAmount = BigInt(data.recommended.amount)\n if (token.amount > recommendedAmount) {\n maxAmount = token.amount - recommendedAmount\n }\n }\n return maxAmount\n }\n\n const handlePercentage = (percentage: number) => {\n const maxAmount = getMaxAmount()\n if (maxAmount && token?.decimals) {\n const percentageAmount = (maxAmount * BigInt(percentage)) / 100n\n setFieldValue(\n FormKeyHelper.getAmountKey(formType),\n formatUnits(percentageAmount, token.decimals),\n {\n isTouched: true,\n }\n )\n }\n }\n\n const handleMax = () => {\n const maxAmount = getMaxAmount()\n if (maxAmount && token?.decimals) {\n setFieldValue(\n FormKeyHelper.getAmountKey(formType),\n formatUnits(maxAmount, token.decimals),\n {\n isTouched: true,\n }\n )\n }\n }\n\n if (formType !== 'from' || !token || !account?.isConnected) {\n return null\n }\n\n return (\n <ButtonContainer>\n <AmountInputButton onClick={() => handlePercentage(25)}>\n 25%\n </AmountInputButton>\n <AmountInputButton onClick={() => handlePercentage(50)}>\n 50%\n </AmountInputButton>\n <AmountInputButton onClick={() => handlePercentage(75)}>\n 75%\n </AmountInputButton>\n <AmountInputButton onClick={handleMax}>\n {t('button.max')}\n </AmountInputButton>\n </ButtonContainer>\n )\n })\n"],"mappings":";;;;;;;;;;;;;AAiBA,MAAa,0BACX,MAAM,EAAE,eAAkD;CACxD,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,iBAAiB,mBAAmB;CAC5C,MAAM,EAAE,kBAAkB,gBAAgB;CAE1C,MAAM,CAAC,SAAS,gBAAgB,eAC9B,cAAc,YAAY,QAAQ,GAClC,cAAc,YAAY,QAAQ,CACpC;CAEA,MAAM,QAAQ,aAAa,OAAO;CAClC,MAAM,EAAE,YAAY,WAAW,EAAE,WAAW,OAAO,UAAU,CAAC;CAI9D,MAAM,EAAE,SAAS,qBAAqB,OAAO;CAE7C,MAAM,EAAE,UAAU,uBAAuB,SAAS,YAAY;CAE9D,MAAM,qBAAqB;EACzB,IAAI,CAAC,OAAO,QACV,OAAO;EAET,IAAI,YAAY,MAAM;EACtB,IAAI,OAAO,YAAY,YAAY,gBAAgB,MAAM,aAAa;GACpE,MAAM,oBAAoB,OAAO,KAAK,YAAY,MAAM;GACxD,IAAI,MAAM,SAAS,mBACjB,YAAY,MAAM,SAAS;EAE/B;EACA,OAAO;CACT;CAEA,MAAM,oBAAoB,eAAuB;EAC/C,MAAM,YAAY,aAAa;EAC/B,IAAI,aAAa,OAAO,UAAU;GAChC,MAAM,mBAAoB,YAAY,OAAO,UAAU,IAAK;GAC5D,cACE,cAAc,aAAa,QAAQ,GACnC,YAAY,kBAAkB,MAAM,QAAQ,GAC5C,EACE,WAAW,KACb,CACF;EACF;CACF;CAEA,MAAM,kBAAkB;EACtB,MAAM,YAAY,aAAa;EAC/B,IAAI,aAAa,OAAO,UACtB,cACE,cAAc,aAAa,QAAQ,GACnC,YAAY,WAAW,MAAM,QAAQ,GACrC,EACE,WAAW,KACb,CACF;CAEJ;CAEA,IAAI,aAAa,UAAU,CAAC,SAAS,CAAC,SAAS,aAC7C,OAAO;CAGT,OACE,qBAAC,iBAAD,EAAA,UAAA;EACE,oBAAC,mBAAD;GAAmB,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAErC,CAAA;EACnB,oBAAC,mBAAD;GAAmB,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAErC,CAAA;EACnB,oBAAC,mBAAD;GAAmB,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAErC,CAAA;EACnB,oBAAC,mBAAD;GAAmB,SAAS;GACzB,UAAA,EAAE,YAAY;EACE,CAAA;CACJ,EAAA,CAAA;AAErB,CAAC"}
1
+ {"version":3,"file":"AmountInputEndAdornment.js","names":[],"sources":["../../../../src/components/AmountInput/AmountInputEndAdornment.tsx"],"sourcesContent":["import { formatUnits } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport type React from 'react'\nimport { type JSX, memo } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useMaxSendAmount } from '../../hooks/useMaxSendAmount.js'\nimport { useTokenAddressBalance } from '../../hooks/useTokenAddressBalance.js'\nimport type { FormTypeProps } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport {\n AmountInputButton,\n ButtonContainer,\n} from './AmountInputEndAdornment.style.js'\n\nexport const AmountInputEndAdornment: React.NamedExoticComponent<FormTypeProps> =\n memo(({ formType }: FormTypeProps): JSX.Element | null => {\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n const { setFieldValue } = useFieldActions()\n\n const [chainId, tokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n FormKeyHelper.getTokenKey(formType)\n )\n\n const chain = getChainById(chainId)\n const { account } = useAccount({ chainType: chain?.chainType })\n\n const { token } = useTokenAddressBalance(chainId, tokenAddress)\n const maxAmount = useMaxSendAmount(chainId, tokenAddress)\n\n const handlePercentage = (percentage: number) => {\n if (maxAmount && token?.decimals) {\n const percentageAmount = (maxAmount * BigInt(percentage)) / 100n\n setFieldValue(\n FormKeyHelper.getAmountKey(formType),\n formatUnits(percentageAmount, token.decimals),\n {\n isTouched: true,\n }\n )\n }\n }\n\n const handleMax = () => {\n if (maxAmount && token?.decimals) {\n setFieldValue(\n FormKeyHelper.getAmountKey(formType),\n formatUnits(maxAmount, token.decimals),\n {\n isTouched: true,\n }\n )\n }\n }\n\n if (formType !== 'from' || !token || !account?.isConnected) {\n return null\n }\n\n return (\n <ButtonContainer>\n <AmountInputButton onClick={() => handlePercentage(25)}>\n 25%\n </AmountInputButton>\n <AmountInputButton onClick={() => handlePercentage(50)}>\n 50%\n </AmountInputButton>\n <AmountInputButton onClick={() => handlePercentage(75)}>\n 75%\n </AmountInputButton>\n <AmountInputButton onClick={handleMax}>\n {t('button.max')}\n </AmountInputButton>\n </ButtonContainer>\n )\n })\n"],"mappings":";;;;;;;;;;;;;AAiBA,MAAa,0BACX,MAAM,EAAE,eAAkD;CACxD,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,iBAAiB,mBAAmB;CAC5C,MAAM,EAAE,kBAAkB,gBAAgB;CAE1C,MAAM,CAAC,SAAS,gBAAgB,eAC9B,cAAc,YAAY,QAAQ,GAClC,cAAc,YAAY,QAAQ,CACpC;CAEA,MAAM,QAAQ,aAAa,OAAO;CAClC,MAAM,EAAE,YAAY,WAAW,EAAE,WAAW,OAAO,UAAU,CAAC;CAE9D,MAAM,EAAE,UAAU,uBAAuB,SAAS,YAAY;CAC9D,MAAM,YAAY,iBAAiB,SAAS,YAAY;CAExD,MAAM,oBAAoB,eAAuB;EAC/C,IAAI,aAAa,OAAO,UAAU;GAChC,MAAM,mBAAoB,YAAY,OAAO,UAAU,IAAK;GAC5D,cACE,cAAc,aAAa,QAAQ,GACnC,YAAY,kBAAkB,MAAM,QAAQ,GAC5C,EACE,WAAW,KACb,CACF;EACF;CACF;CAEA,MAAM,kBAAkB;EACtB,IAAI,aAAa,OAAO,UACtB,cACE,cAAc,aAAa,QAAQ,GACnC,YAAY,WAAW,MAAM,QAAQ,GACrC,EACE,WAAW,KACb,CACF;CAEJ;CAEA,IAAI,aAAa,UAAU,CAAC,SAAS,CAAC,SAAS,aAC7C,OAAO;CAGT,OACE,qBAAC,iBAAD,EAAA,UAAA;EACE,oBAAC,mBAAD;GAAmB,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAErC,CAAA;EACnB,oBAAC,mBAAD;GAAmB,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAErC,CAAA;EACnB,oBAAC,mBAAD;GAAmB,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAErC,CAAA;EACnB,oBAAC,mBAAD;GAAmB,SAAS;GACzB,UAAA,EAAE,YAAY;EACE,CAAA;CACJ,EAAA,CAAA;AAErB,CAAC"}
@@ -1,7 +1,6 @@
1
1
  import React from "react";
2
2
  import { Button } from "@mui/material";
3
3
  //#region src/components/AmountInput/PriceFormHelperText.style.d.ts
4
- declare const InputPriceButton: React.FC<React.ComponentProps<typeof Button>>;
4
+ export declare const InputPriceButton: React.FC<React.ComponentProps<typeof Button>>;
5
5
  //#endregion
6
- export { InputPriceButton };
7
6
  //# sourceMappingURL=PriceFormHelperText.style.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PriceFormHelperText.style.d.ts","names":[],"sources":["../../../../src/components/AmountInput/PriceFormHelperText.style.tsx"],"mappings":";;;cAGa,kBAAkB,MAAM,GAAG,MAAM,sBAAsB"}
1
+ {"version":3,"file":"PriceFormHelperText.style.d.ts","names":[],"sources":["../../../../src/components/AmountInput/PriceFormHelperText.style.tsx"],"mappings":";;;qBAGa,kBAAkB,MAAM,GAAG,MAAM,sBAAsB"}
@@ -3,8 +3,8 @@ import { useAvailableChains } from "../../hooks/useAvailableChains.js";
3
3
  import { useFieldActions } from "../../stores/form/useFieldActions.js";
4
4
  import { FormKeyHelper } from "../../stores/form/types.js";
5
5
  import { useFieldValues } from "../../stores/form/useFieldValues.js";
6
- import { useGasRecommendation } from "../../hooks/useGasRecommendation.js";
7
6
  import { useTokenAddressBalance } from "../../hooks/useTokenAddressBalance.js";
7
+ import { useMaxSendAmount } from "../../hooks/useMaxSendAmount.js";
8
8
  import { useLinkedLimitFields } from "../../hooks/useLinkedLimitFields.js";
9
9
  import { Chip, ChipContainer } from "./PercentageChips.style.js";
10
10
  import { formatUnits } from "@lifi/sdk";
@@ -24,30 +24,19 @@ const PercentageChips = memo(({ formType }) => {
24
24
  const [chainId, tokenAddress] = useFieldValues(FormKeyHelper.getChainKey(formType), FormKeyHelper.getTokenKey(formType));
25
25
  const chain = getChainById(chainId);
26
26
  const { account } = useAccount({ chainType: chain?.chainType });
27
- const { data } = useGasRecommendation(chainId);
28
27
  const { token } = useTokenAddressBalance(chainId, tokenAddress);
29
- const getMaxAmount = () => {
30
- if (!token?.amount) return 0n;
31
- let maxAmount = token.amount;
32
- if (chain?.nativeToken.address === tokenAddress && data?.recommended) {
33
- const recommendedAmount = BigInt(data.recommended.amount);
34
- if (token.amount > recommendedAmount) maxAmount = token.amount - recommendedAmount;
35
- }
36
- return maxAmount;
37
- };
28
+ const maxAmount = useMaxSendAmount(chainId, tokenAddress);
38
29
  const applyAmount = (value) => {
39
30
  if (mode === "limit") setSendAmount(value);
40
31
  else setFieldValue(amountKey, value, { isTouched: true });
41
32
  };
42
33
  const handlePercentage = (percentage) => {
43
- const maxAmount = getMaxAmount();
44
34
  if (maxAmount && token?.decimals) {
45
35
  const percentageAmount = maxAmount * BigInt(percentage) / 100n;
46
36
  applyAmount(formatUnits(percentageAmount, token.decimals));
47
37
  }
48
38
  };
49
39
  const handleMax = () => {
50
- const maxAmount = getMaxAmount();
51
40
  if (maxAmount && token?.decimals) applyAmount(formatUnits(maxAmount, token.decimals));
52
41
  };
53
42
  if (formType !== "from" || isDisabled || !token || !account?.isConnected) return null;
@@ -1 +1 @@
1
- {"version":3,"file":"PercentageChips.js","names":[],"sources":["../../../../src/components/AmountInputCard/PercentageChips.tsx"],"sourcesContent":["import { formatUnits } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { type JSX, memo } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useGasRecommendation } from '../../hooks/useGasRecommendation.js'\nimport { useLinkedLimitFields } from '../../hooks/useLinkedLimitFields.js'\nimport { useTokenAddressBalance } from '../../hooks/useTokenAddressBalance.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormTypeProps } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport type { DisabledUIConfig } from '../../types/widget.js'\nimport { Chip, ChipContainer } from './PercentageChips.style.js'\n\nexport const PercentageChips: React.NamedExoticComponent<FormTypeProps> = memo(\n ({ formType }: FormTypeProps): JSX.Element | null => {\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n const { setFieldValue } = useFieldActions()\n const { disabledUI, mode } = useWidgetConfig()\n const { setSendAmount } = useLinkedLimitFields()\n\n const amountKey = FormKeyHelper.getAmountKey(formType)\n const isDisabled = !!disabledUI?.[amountKey as keyof DisabledUIConfig]\n\n const [chainId, tokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n FormKeyHelper.getTokenKey(formType)\n )\n\n const chain = getChainById(chainId)\n const { account } = useAccount({ chainType: chain?.chainType })\n\n const { data } = useGasRecommendation(chainId)\n const { token } = useTokenAddressBalance(chainId, tokenAddress)\n\n const getMaxAmount = (): bigint => {\n if (!token?.amount) {\n return 0n\n }\n let maxAmount = token.amount\n if (chain?.nativeToken.address === tokenAddress && data?.recommended) {\n const recommendedAmount = BigInt(data.recommended.amount)\n if (token.amount > recommendedAmount) {\n maxAmount = token.amount - recommendedAmount\n }\n }\n return maxAmount\n }\n\n // In limit mode the send amount must flow through the linked-field\n // derivation so the receive amount recomputes; otherwise it is a plain\n // form-field write.\n const applyAmount = (value: string): void => {\n if (mode === 'limit') {\n setSendAmount(value)\n } else {\n setFieldValue(amountKey, value, { isTouched: true })\n }\n }\n\n const handlePercentage = (percentage: number): void => {\n const maxAmount = getMaxAmount()\n if (maxAmount && token?.decimals) {\n const percentageAmount = (maxAmount * BigInt(percentage)) / 100n\n applyAmount(formatUnits(percentageAmount, token.decimals))\n }\n }\n\n const handleMax = (): void => {\n const maxAmount = getMaxAmount()\n if (maxAmount && token?.decimals) {\n applyAmount(formatUnits(maxAmount, token.decimals))\n }\n }\n\n if (formType !== 'from' || isDisabled || !token || !account?.isConnected) {\n return null\n }\n\n return (\n <ChipContainer>\n <Chip data-delay=\"0\" onClick={() => handlePercentage(25)}>\n 25%\n </Chip>\n <Chip data-delay=\"1\" onClick={() => handlePercentage(50)}>\n 50%\n </Chip>\n <Chip data-delay=\"2\" onClick={() => handlePercentage(75)}>\n 75%\n </Chip>\n <Chip data-delay=\"3\" onClick={handleMax}>\n {t('button.max')}\n </Chip>\n </ChipContainer>\n )\n }\n)\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAa,kBAA6D,MACvE,EAAE,eAAkD;CACnD,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,iBAAiB,mBAAmB;CAC5C,MAAM,EAAE,kBAAkB,gBAAgB;CAC1C,MAAM,EAAE,YAAY,SAAS,gBAAgB;CAC7C,MAAM,EAAE,kBAAkB,qBAAqB;CAE/C,MAAM,YAAY,cAAc,aAAa,QAAQ;CACrD,MAAM,aAAa,CAAC,CAAC,aAAa;CAElC,MAAM,CAAC,SAAS,gBAAgB,eAC9B,cAAc,YAAY,QAAQ,GAClC,cAAc,YAAY,QAAQ,CACpC;CAEA,MAAM,QAAQ,aAAa,OAAO;CAClC,MAAM,EAAE,YAAY,WAAW,EAAE,WAAW,OAAO,UAAU,CAAC;CAE9D,MAAM,EAAE,SAAS,qBAAqB,OAAO;CAC7C,MAAM,EAAE,UAAU,uBAAuB,SAAS,YAAY;CAE9D,MAAM,qBAA6B;EACjC,IAAI,CAAC,OAAO,QACV,OAAO;EAET,IAAI,YAAY,MAAM;EACtB,IAAI,OAAO,YAAY,YAAY,gBAAgB,MAAM,aAAa;GACpE,MAAM,oBAAoB,OAAO,KAAK,YAAY,MAAM;GACxD,IAAI,MAAM,SAAS,mBACjB,YAAY,MAAM,SAAS;EAE/B;EACA,OAAO;CACT;CAKA,MAAM,eAAe,UAAwB;EAC3C,IAAI,SAAS,SACX,cAAc,KAAK;OAEnB,cAAc,WAAW,OAAO,EAAE,WAAW,KAAK,CAAC;CAEvD;CAEA,MAAM,oBAAoB,eAA6B;EACrD,MAAM,YAAY,aAAa;EAC/B,IAAI,aAAa,OAAO,UAAU;GAChC,MAAM,mBAAoB,YAAY,OAAO,UAAU,IAAK;GAC5D,YAAY,YAAY,kBAAkB,MAAM,QAAQ,CAAC;EAC3D;CACF;CAEA,MAAM,kBAAwB;EAC5B,MAAM,YAAY,aAAa;EAC/B,IAAI,aAAa,OAAO,UACtB,YAAY,YAAY,WAAW,MAAM,QAAQ,CAAC;CAEtD;CAEA,IAAI,aAAa,UAAU,cAAc,CAAC,SAAS,CAAC,SAAS,aAC3D,OAAO;CAGT,OACE,qBAAC,eAAD,EAAA,UAAA;EACE,oBAAC,MAAD;GAAM,cAAW;GAAI,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAEpD,CAAA;EACN,oBAAC,MAAD;GAAM,cAAW;GAAI,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAEpD,CAAA;EACN,oBAAC,MAAD;GAAM,cAAW;GAAI,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAEpD,CAAA;EACN,oBAAC,MAAD;GAAM,cAAW;GAAI,SAAS;GAC3B,UAAA,EAAE,YAAY;EACX,CAAA;CACO,EAAA,CAAA;AAEnB,CACF"}
1
+ {"version":3,"file":"PercentageChips.js","names":[],"sources":["../../../../src/components/AmountInputCard/PercentageChips.tsx"],"sourcesContent":["import { formatUnits } from '@lifi/sdk'\nimport { useAccount } from '@lifi/wallet-management'\nimport { type JSX, memo } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useLinkedLimitFields } from '../../hooks/useLinkedLimitFields.js'\nimport { useMaxSendAmount } from '../../hooks/useMaxSendAmount.js'\nimport { useTokenAddressBalance } from '../../hooks/useTokenAddressBalance.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormTypeProps } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport type { DisabledUIConfig } from '../../types/widget.js'\nimport { Chip, ChipContainer } from './PercentageChips.style.js'\n\nexport const PercentageChips: React.NamedExoticComponent<FormTypeProps> = memo(\n ({ formType }: FormTypeProps): JSX.Element | null => {\n const { t } = useTranslation()\n const { getChainById } = useAvailableChains()\n const { setFieldValue } = useFieldActions()\n const { disabledUI, mode } = useWidgetConfig()\n const { setSendAmount } = useLinkedLimitFields()\n\n const amountKey = FormKeyHelper.getAmountKey(formType)\n const isDisabled = !!disabledUI?.[amountKey as keyof DisabledUIConfig]\n\n const [chainId, tokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n FormKeyHelper.getTokenKey(formType)\n )\n\n const chain = getChainById(chainId)\n const { account } = useAccount({ chainType: chain?.chainType })\n\n const { token } = useTokenAddressBalance(chainId, tokenAddress)\n const maxAmount = useMaxSendAmount(chainId, tokenAddress)\n\n // In limit mode the send amount must flow through the linked-field\n // derivation so the receive amount recomputes; otherwise it is a plain\n // form-field write.\n const applyAmount = (value: string): void => {\n if (mode === 'limit') {\n setSendAmount(value)\n } else {\n setFieldValue(amountKey, value, { isTouched: true })\n }\n }\n\n const handlePercentage = (percentage: number): void => {\n if (maxAmount && token?.decimals) {\n const percentageAmount = (maxAmount * BigInt(percentage)) / 100n\n applyAmount(formatUnits(percentageAmount, token.decimals))\n }\n }\n\n const handleMax = (): void => {\n if (maxAmount && token?.decimals) {\n applyAmount(formatUnits(maxAmount, token.decimals))\n }\n }\n\n if (formType !== 'from' || isDisabled || !token || !account?.isConnected) {\n return null\n }\n\n return (\n <ChipContainer>\n <Chip data-delay=\"0\" onClick={() => handlePercentage(25)}>\n 25%\n </Chip>\n <Chip data-delay=\"1\" onClick={() => handlePercentage(50)}>\n 50%\n </Chip>\n <Chip data-delay=\"2\" onClick={() => handlePercentage(75)}>\n 75%\n </Chip>\n <Chip data-delay=\"3\" onClick={handleMax}>\n {t('button.max')}\n </Chip>\n </ChipContainer>\n )\n }\n)\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAa,kBAA6D,MACvE,EAAE,eAAkD;CACnD,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,iBAAiB,mBAAmB;CAC5C,MAAM,EAAE,kBAAkB,gBAAgB;CAC1C,MAAM,EAAE,YAAY,SAAS,gBAAgB;CAC7C,MAAM,EAAE,kBAAkB,qBAAqB;CAE/C,MAAM,YAAY,cAAc,aAAa,QAAQ;CACrD,MAAM,aAAa,CAAC,CAAC,aAAa;CAElC,MAAM,CAAC,SAAS,gBAAgB,eAC9B,cAAc,YAAY,QAAQ,GAClC,cAAc,YAAY,QAAQ,CACpC;CAEA,MAAM,QAAQ,aAAa,OAAO;CAClC,MAAM,EAAE,YAAY,WAAW,EAAE,WAAW,OAAO,UAAU,CAAC;CAE9D,MAAM,EAAE,UAAU,uBAAuB,SAAS,YAAY;CAC9D,MAAM,YAAY,iBAAiB,SAAS,YAAY;CAKxD,MAAM,eAAe,UAAwB;EAC3C,IAAI,SAAS,SACX,cAAc,KAAK;OAEnB,cAAc,WAAW,OAAO,EAAE,WAAW,KAAK,CAAC;CAEvD;CAEA,MAAM,oBAAoB,eAA6B;EACrD,IAAI,aAAa,OAAO,UAAU;GAChC,MAAM,mBAAoB,YAAY,OAAO,UAAU,IAAK;GAC5D,YAAY,YAAY,kBAAkB,MAAM,QAAQ,CAAC;EAC3D;CACF;CAEA,MAAM,kBAAwB;EAC5B,IAAI,aAAa,OAAO,UACtB,YAAY,YAAY,WAAW,MAAM,QAAQ,CAAC;CAEtD;CAEA,IAAI,aAAa,UAAU,cAAc,CAAC,SAAS,CAAC,SAAS,aAC3D,OAAO;CAGT,OACE,qBAAC,eAAD,EAAA,UAAA;EACE,oBAAC,MAAD;GAAM,cAAW;GAAI,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAEpD,CAAA;EACN,oBAAC,MAAD;GAAM,cAAW;GAAI,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAEpD,CAAA;EACN,oBAAC,MAAD;GAAM,cAAW;GAAI,eAAe,iBAAiB,EAAE;GAAG,UAAA;EAEpD,CAAA;EACN,oBAAC,MAAD;GAAM,cAAW;GAAI,SAAS;GAC3B,UAAA,EAAE,YAAY;EACX,CAAA;CACO,EAAA,CAAA;AAEnB,CACF"}
@@ -8,7 +8,7 @@ const revealStagger = Object.fromEntries(Array.from({ length: chipCount }, (_, i
8
8
  opacity: 1,
9
9
  transform: "scale(1) translateX(0)",
10
10
  pointerEvents: "auto",
11
- transitionDelay: `${(chipCount - 1 - index) * staggerStepMs}ms`
11
+ transitionDelay: `${(3 - index) * staggerStepMs}ms`
12
12
  },
13
13
  [`.${cardClasses.root}:not(:hover) &`]: { transitionDelay: `${index * staggerStepMs}ms` }
14
14
  }]));
@@ -1 +1 @@
1
- {"version":3,"file":"PercentageChips.style.js","names":[],"sources":["../../../../src/components/AmountInputCard/PercentageChips.style.tsx"],"sourcesContent":["import { Box, Button, styled } from '@mui/material'\nimport { cardClasses } from '@mui/material/Card'\nimport type React from 'react'\n\nconst chipCount = 4\nconst staggerStepMs = 25\n\nconst revealStagger = Object.fromEntries(\n Array.from({ length: chipCount }, (_, index) => [\n `&[data-delay=\"${index}\"]`,\n {\n [`.${cardClasses.root}:hover &`]: {\n opacity: 1,\n transform: 'scale(1) translateX(0)',\n pointerEvents: 'auto',\n transitionDelay: `${(chipCount - 1 - index) * staggerStepMs}ms`,\n },\n [`.${cardClasses.root}:not(:hover) &`]: {\n transitionDelay: `${index * staggerStepMs}ms`,\n },\n },\n ])\n)\n\nexport const ChipContainer: React.FC<React.ComponentProps<typeof Box>> = styled(\n Box\n)(({ theme }) => ({\n display: 'flex',\n gap: theme.spacing(0.5),\n}))\n\nexport const Chip: React.FC<React.ComponentProps<typeof Button>> = styled(\n Button\n)(({ theme }) => ({\n minWidth: 0,\n padding: theme.spacing(0.5, 1.5),\n fontSize: 12,\n fontWeight: 700,\n lineHeight: 1.3334,\n backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 4%, transparent)`,\n color: theme.vars.palette.text.primary,\n transition:\n 'opacity 200ms cubic-bezier(0.4, 0, 0.2, 1), transform 200ms cubic-bezier(0.4, 0, 0.2, 1), background-color 200ms ease',\n '&:hover': {\n backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 8%, transparent)`,\n },\n // Reveal-on-hover — only on devices that support hover. On touch there is no\n // hover, so the chips stay permanently visible (the default above) instead of\n // becoming an unreachable dead row.\n '@media (hover: hover)': {\n opacity: 0,\n transform: 'scale(0.85) translateX(10px)',\n pointerEvents: 'none',\n ...revealStagger,\n '@media (prefers-reduced-motion: reduce)': {\n transform: 'none !important',\n transitionDelay: '0ms !important',\n },\n },\n}))\n"],"mappings":";;;AAIA,MAAM,YAAY;AAClB,MAAM,gBAAgB;AAEtB,MAAM,gBAAgB,OAAO,YAC3B,MAAM,KAAK,EAAE,QAAQ,UAAU,IAAI,GAAG,UAAU,CAC9C,iBAAiB,MAAM,KACvB;EACG,IAAI,YAAY,KAAK,YAAY;EAChC,SAAS;EACT,WAAW;EACX,eAAe;EACf,iBAAiB,IAAI,YAAY,IAAI,SAAS,cAAc;CAC9D;EACC,IAAI,YAAY,KAAK,kBAAkB,EACtC,iBAAiB,GAAG,QAAQ,cAAc,IAC5C;AACF,CACF,CAAC,CACH;AAEA,MAAa,gBAA4D,OACvE,GACF,CAAC,EAAE,EAAE,aAAa;CAChB,SAAS;CACT,KAAK,MAAM,QAAQ,EAAG;AACxB,EAAE;AAEF,MAAa,OAAsD,OACjE,MACF,CAAC,EAAE,EAAE,aAAa;CAChB,UAAU;CACV,SAAS,MAAM,QAAQ,IAAK,GAAG;CAC/B,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,iBAAiB,sBAAsB,MAAM,KAAK,QAAQ,OAAO,aAAa;CAC9E,OAAO,MAAM,KAAK,QAAQ,KAAK;CAC/B,YACE;CACF,WAAW,EACT,iBAAiB,sBAAsB,MAAM,KAAK,QAAQ,OAAO,aAAa,mBAChF;CAIA,yBAAyB;EACvB,SAAS;EACT,WAAW;EACX,eAAe;EACf,GAAG;EACH,2CAA2C;GACzC,WAAW;GACX,iBAAiB;EACnB;CACF;AACF,EAAE"}
1
+ {"version":3,"file":"PercentageChips.style.js","names":[],"sources":["../../../../src/components/AmountInputCard/PercentageChips.style.tsx"],"sourcesContent":["import { Box, Button, styled } from '@mui/material'\nimport { cardClasses } from '@mui/material/Card'\nimport type React from 'react'\n\nconst chipCount = 4\nconst staggerStepMs = 25\n\nconst revealStagger = Object.fromEntries(\n Array.from({ length: chipCount }, (_, index) => [\n `&[data-delay=\"${index}\"]`,\n {\n [`.${cardClasses.root}:hover &`]: {\n opacity: 1,\n transform: 'scale(1) translateX(0)',\n pointerEvents: 'auto',\n transitionDelay: `${(chipCount - 1 - index) * staggerStepMs}ms`,\n },\n [`.${cardClasses.root}:not(:hover) &`]: {\n transitionDelay: `${index * staggerStepMs}ms`,\n },\n },\n ])\n)\n\nexport const ChipContainer: React.FC<React.ComponentProps<typeof Box>> = styled(\n Box\n)(({ theme }) => ({\n display: 'flex',\n gap: theme.spacing(0.5),\n}))\n\nexport const Chip: React.FC<React.ComponentProps<typeof Button>> = styled(\n Button\n)(({ theme }) => ({\n minWidth: 0,\n padding: theme.spacing(0.5, 1.5),\n fontSize: 12,\n fontWeight: 700,\n lineHeight: 1.3334,\n backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 4%, transparent)`,\n color: theme.vars.palette.text.primary,\n transition:\n 'opacity 200ms cubic-bezier(0.4, 0, 0.2, 1), transform 200ms cubic-bezier(0.4, 0, 0.2, 1), background-color 200ms ease',\n '&:hover': {\n backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 8%, transparent)`,\n },\n // Reveal-on-hover — only on devices that support hover. On touch there is no\n // hover, so the chips stay permanently visible (the default above) instead of\n // becoming an unreachable dead row.\n '@media (hover: hover)': {\n opacity: 0,\n transform: 'scale(0.85) translateX(10px)',\n pointerEvents: 'none',\n ...revealStagger,\n '@media (prefers-reduced-motion: reduce)': {\n transform: 'none !important',\n transitionDelay: '0ms !important',\n },\n },\n}))\n"],"mappings":";;;AAIA,MAAM,YAAY;AAClB,MAAM,gBAAgB;AAEtB,MAAM,gBAAgB,OAAO,YAC3B,MAAM,KAAK,EAAE,QAAQ,UAAU,IAAI,GAAG,UAAU,CAC9C,iBAAiB,MAAM,KACvB;EACG,IAAI,YAAY,KAAK,YAAY;EAChC,SAAS;EACT,WAAW;EACX,eAAe;EACf,iBAAiB,IAAI,IAAgB,SAAS,cAAc;CAC9D;EACC,IAAI,YAAY,KAAK,kBAAkB,EACtC,iBAAiB,GAAG,QAAQ,cAAc,IAC5C;AACF,CACF,CAAC,CACH;AAEA,MAAa,gBAA4D,OACvE,GACF,CAAC,EAAE,EAAE,aAAa;CAChB,SAAS;CACT,KAAK,MAAM,QAAQ,EAAG;AACxB,EAAE;AAEF,MAAa,OAAsD,OACjE,MACF,CAAC,EAAE,EAAE,aAAa;CAChB,UAAU;CACV,SAAS,MAAM,QAAQ,IAAK,GAAG;CAC/B,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,iBAAiB,sBAAsB,MAAM,KAAK,QAAQ,OAAO,aAAa;CAC9E,OAAO,MAAM,KAAK,QAAQ,KAAK;CAC/B,YACE;CACF,WAAW,EACT,iBAAiB,sBAAsB,MAAM,KAAK,QAAQ,OAAO,aAAa,mBAChF;CAIA,yBAAyB;EACvB,SAAS;EACT,WAAW;EACX,eAAe;EACf,GAAG;EACH,2CAA2C;GACzC,WAAW;GACX,iBAAiB;EACnB;CACF;AACF,EAAE"}
@@ -1,6 +1,8 @@
1
1
  import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
2
2
  import { formatTokenAmount, formatTokenPrice } from "../../utils/format.js";
3
3
  import { useFieldValues } from "../../stores/form/useFieldValues.js";
4
+ import { mergeFallbackToken } from "../../utils/token.js";
5
+ import { useToken } from "../../hooks/useToken.js";
4
6
  import { useRoutes } from "../../hooks/useRoutes.js";
5
7
  import { ProgressToNextUpdate } from "../ProgressToNextUpdate.js";
6
8
  import { getPriceImpact } from "../../utils/getPriceImpact.js";
@@ -80,10 +82,12 @@ const ReceiveAmountCard = (props) => {
80
82
  const route = routes?.find((r) => r.id === selectedRouteId) ?? routes?.[0];
81
83
  const priceImpact = useReceivePriceImpact(route);
82
84
  const showPriceImpact = !hiddenUI?.routeCardPriceImpact;
85
+ const { token: cachedToken } = useToken(route?.toToken.chainId, route?.toToken.address);
86
+ const pricedToken = route ? mergeFallbackToken(route.toToken, cachedToken) : void 0;
83
87
  const receiveAmount = route?.toAmount ? formatTokenAmount(BigInt(route.toAmount), route.toToken.decimals) : void 0;
84
88
  const showSkeleton = isFetching && !receiveAmount;
85
- const fiatValue = receiveAmount && route?.toToken.priceUSD ? formatTokenPrice(receiveAmount, route.toToken.priceUSD) : 0;
86
- const canToggle = !!receiveAmount && !!route?.toToken.priceUSD;
89
+ const fiatValue = receiveAmount && pricedToken?.priceUSD ? formatTokenPrice(receiveAmount, pricedToken.priceUSD) : 0;
90
+ const canToggle = !!receiveAmount && !!pricedToken?.priceUSD;
87
91
  const mainDisplay = showFiat ? t("format.currency", { value: fiatValue }) : t("format.tokenAmount", { value: receiveAmount || "0" });
88
92
  const footerDisplay = showFiat ? t("format.tokenAmount", { value: receiveAmount || "0" }) : t("format.currency", { value: fiatValue });
89
93
  useLayoutEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"ReceiveAmountCard.js","names":["InfoOutlinedIcon"],"sources":["../../../../src/components/AmountInputCard/ReceiveAmountCard.tsx"],"sourcesContent":["import type { Route } from '@lifi/sdk'\nimport InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'\nimport SwapVertIcon from '@mui/icons-material/SwapVert'\nimport type { CardProps } from '@mui/material'\nimport { Box, Skeleton, Tooltip } from '@mui/material'\nimport { type JSX, type ReactNode, useLayoutEffect, useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useRoutes } from '../../hooks/useRoutes.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport { useInputModeStore } from '../../stores/inputMode/useInputModeStore.js'\nimport { formatTokenAmount, formatTokenPrice } from '../../utils/format.js'\nimport { getPriceImpact } from '../../utils/getPriceImpact.js'\nimport { fitInputText } from '../../utils/input.js'\nimport { CardTitle } from '../Card/CardTitle.js'\nimport { ProgressToNextUpdate } from '../ProgressToNextUpdate.js'\nimport { TokenPillButton } from '../TokenPillButton/TokenPillButton.js'\nimport {\n AmountCard,\n AmountDisplay,\n amountHeight,\n CardBodyRow,\n CardFooterRow,\n CardHeaderRow,\n FooterText,\n footerFontSize,\n maxInputFontSize,\n minInputFontSize,\n ToggleButton,\n} from './AmountInputCard.style.js'\n\nconst formType = 'to' as const\n\ntype ReceiveCardProps = CardProps & { mask?: boolean }\n\nconst ReceiveAmountCardLayout = ({\n cardProps,\n title,\n headerEnd,\n amount,\n footerStart,\n footerEnd,\n}: {\n cardProps: ReceiveCardProps\n title: string\n headerEnd?: ReactNode\n amount: ReactNode\n footerStart: ReactNode\n footerEnd?: ReactNode\n}): JSX.Element => (\n <AmountCard {...cardProps} formType={formType}>\n <CardHeaderRow>\n <CardTitle sx={{ padding: 0 }}>{title}</CardTitle>\n {headerEnd}\n </CardHeaderRow>\n <CardBodyRow>\n {amount}\n <TokenPillButton formType={formType} />\n </CardBodyRow>\n <CardFooterRow>\n {footerStart}\n {footerEnd}\n </CardFooterRow>\n </AmountCard>\n)\n\nconst PriceImpactBadge = ({\n priceImpact,\n}: {\n priceImpact: number | undefined\n}): JSX.Element | null => {\n const { t } = useTranslation()\n if (priceImpact === undefined) {\n return null\n }\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <FooterText>\n {t('format.percent', { value: priceImpact, usePlusSign: true })}\n </FooterText>\n <Tooltip title={t('tooltip.priceImpact')}>\n <InfoOutlinedIcon\n sx={{ fontSize: 16, color: 'text.secondary', cursor: 'help' }}\n />\n </Tooltip>\n </Box>\n )\n}\n\nconst useReceivePriceImpact = (\n route: Route | undefined\n): number | undefined => {\n const { hiddenUI } = useWidgetConfig()\n if (!route || hiddenUI?.routeCardPriceImpact) {\n return undefined\n }\n return getPriceImpact({\n fromAmount: BigInt(route.fromAmount),\n toAmount: BigInt(route.toAmount),\n fromToken: route.fromToken,\n toToken: route.toToken,\n })\n}\n\n/**\n * The receive amount is a read-only quote derived from the best route, with a\n * fiat/token toggle and price impact in the footer. In limit mode the amount is\n * still the quote for the current limit (the limit price drives it via the\n * dedicated price card); it is never edited here, and the header shows the\n * refetch progress indicator with a \"Buy\" title.\n */\nexport const ReceiveAmountCard: React.FC<ReceiveCardProps> = (\n props\n): JSX.Element => {\n const { t } = useTranslation()\n const amountRef = useRef<HTMLSpanElement>(null)\n const { inputMode, toggleInputMode } = useInputModeStore()\n const showFiat = inputMode[formType] === 'price'\n const { hiddenUI, mode } = useWidgetConfig()\n const isLimit = mode === 'limit'\n\n const [selectedRouteId] = useFieldValues('selectedRouteId')\n const { routes, isFetching, dataUpdatedAt, refetchTime, refetch } =\n useRoutes()\n // Reflect the route the user selected in the routes list (falling back to the\n // best route), so the buy amount matches the highlighted provider card.\n const route = routes?.find((r) => r.id === selectedRouteId) ?? routes?.[0]\n const priceImpact = useReceivePriceImpact(route)\n const showPriceImpact = !hiddenUI?.routeCardPriceImpact\n\n const receiveAmount = route?.toAmount\n ? formatTokenAmount(BigInt(route.toAmount), route.toToken.decimals)\n : undefined\n // Only show skeletons on the initial fetch.\n const showSkeleton = isFetching && !receiveAmount\n\n const fiatValue =\n receiveAmount && route?.toToken.priceUSD\n ? formatTokenPrice(receiveAmount, route.toToken.priceUSD)\n : 0\n const canToggle = !!receiveAmount && !!route?.toToken.priceUSD\n\n const mainDisplay = showFiat\n ? t('format.currency', { value: fiatValue })\n : t('format.tokenAmount', { value: receiveAmount || '0' })\n const footerDisplay = showFiat\n ? t('format.tokenAmount', { value: receiveAmount || '0' })\n : t('format.currency', { value: fiatValue })\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: effect must run on value change\n useLayoutEffect(() => {\n if (amountRef.current) {\n fitInputText(maxInputFontSize, minInputFontSize, amountRef.current)\n }\n }, [mainDisplay])\n\n return (\n <ReceiveAmountCardLayout\n cardProps={props}\n title={isLimit ? t('header.buy') : t('header.receive')}\n headerEnd={\n isLimit && (isFetching || routes?.length) ? (\n <ProgressToNextUpdate\n updatedAt={dataUpdatedAt || Date.now()}\n timeToUpdate={refetchTime}\n isLoading={isFetching}\n onClick={() => refetch()}\n sx={{ padding: 0 }}\n />\n ) : undefined\n }\n amount={\n showSkeleton ? (\n <Skeleton variant=\"rounded\" height={amountHeight} sx={{ flex: 1 }} />\n ) : (\n <AmountDisplay\n ref={amountRef}\n sx={{ color: 'text.primary', opacity: receiveAmount ? 1 : 0.5 }}\n >\n {mainDisplay}\n </AmountDisplay>\n )\n }\n footerStart={\n showSkeleton ? (\n <Skeleton\n variant=\"text\"\n width={72}\n sx={{ fontSize: footerFontSize }}\n />\n ) : (\n <ToggleButton\n clickable={canToggle}\n onClick={canToggle ? () => toggleInputMode(formType) : undefined}\n aria-label={canToggle ? 'Toggle fiat value' : undefined}\n >\n <FooterText>{footerDisplay}</FooterText>\n {canToggle ? (\n <SwapVertIcon sx={{ fontSize: 14, color: 'text.secondary' }} />\n ) : null}\n </ToggleButton>\n )\n }\n footerEnd={\n showSkeleton ? (\n showPriceImpact ? (\n <Skeleton\n variant=\"text\"\n width={56}\n sx={{ fontSize: footerFontSize }}\n />\n ) : null\n ) : (\n <PriceImpactBadge priceImpact={priceImpact} />\n )\n }\n />\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReceiveAmountCard.js","names":["InfoOutlinedIcon"],"sources":["../../../../src/components/AmountInputCard/ReceiveAmountCard.tsx"],"sourcesContent":["import type { Route } from '@lifi/sdk'\nimport InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'\nimport SwapVertIcon from '@mui/icons-material/SwapVert'\nimport type { CardProps } from '@mui/material'\nimport { Box, Skeleton, Tooltip } from '@mui/material'\nimport { type JSX, type ReactNode, useLayoutEffect, useRef } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useRoutes } from '../../hooks/useRoutes.js'\nimport { useToken } from '../../hooks/useToken.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport { useInputModeStore } from '../../stores/inputMode/useInputModeStore.js'\nimport { formatTokenAmount, formatTokenPrice } from '../../utils/format.js'\nimport { getPriceImpact } from '../../utils/getPriceImpact.js'\nimport { fitInputText } from '../../utils/input.js'\nimport { mergeFallbackToken } from '../../utils/token.js'\nimport { CardTitle } from '../Card/CardTitle.js'\nimport { ProgressToNextUpdate } from '../ProgressToNextUpdate.js'\nimport { TokenPillButton } from '../TokenPillButton/TokenPillButton.js'\nimport {\n AmountCard,\n AmountDisplay,\n amountHeight,\n CardBodyRow,\n CardFooterRow,\n CardHeaderRow,\n FooterText,\n footerFontSize,\n maxInputFontSize,\n minInputFontSize,\n ToggleButton,\n} from './AmountInputCard.style.js'\n\nconst formType = 'to' as const\n\ntype ReceiveCardProps = CardProps & { mask?: boolean }\n\nconst ReceiveAmountCardLayout = ({\n cardProps,\n title,\n headerEnd,\n amount,\n footerStart,\n footerEnd,\n}: {\n cardProps: ReceiveCardProps\n title: string\n headerEnd?: ReactNode\n amount: ReactNode\n footerStart: ReactNode\n footerEnd?: ReactNode\n}): JSX.Element => (\n <AmountCard {...cardProps} formType={formType}>\n <CardHeaderRow>\n <CardTitle sx={{ padding: 0 }}>{title}</CardTitle>\n {headerEnd}\n </CardHeaderRow>\n <CardBodyRow>\n {amount}\n <TokenPillButton formType={formType} />\n </CardBodyRow>\n <CardFooterRow>\n {footerStart}\n {footerEnd}\n </CardFooterRow>\n </AmountCard>\n)\n\nconst PriceImpactBadge = ({\n priceImpact,\n}: {\n priceImpact: number | undefined\n}): JSX.Element | null => {\n const { t } = useTranslation()\n if (priceImpact === undefined) {\n return null\n }\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>\n <FooterText>\n {t('format.percent', { value: priceImpact, usePlusSign: true })}\n </FooterText>\n <Tooltip title={t('tooltip.priceImpact')}>\n <InfoOutlinedIcon\n sx={{ fontSize: 16, color: 'text.secondary', cursor: 'help' }}\n />\n </Tooltip>\n </Box>\n )\n}\n\nconst useReceivePriceImpact = (\n route: Route | undefined\n): number | undefined => {\n const { hiddenUI } = useWidgetConfig()\n if (!route || hiddenUI?.routeCardPriceImpact) {\n return undefined\n }\n return getPriceImpact({\n fromAmount: BigInt(route.fromAmount),\n toAmount: BigInt(route.toAmount),\n fromToken: route.fromToken,\n toToken: route.toToken,\n })\n}\n\n/**\n * The receive amount is a read-only quote derived from the best route, with a\n * fiat/token toggle and price impact in the footer. In limit mode the amount is\n * still the quote for the current limit (the limit price drives it via the\n * dedicated price card); it is never edited here, and the header shows the\n * refetch progress indicator with a \"Buy\" title.\n */\nexport const ReceiveAmountCard: React.FC<ReceiveCardProps> = (\n props\n): JSX.Element => {\n const { t } = useTranslation()\n const amountRef = useRef<HTMLSpanElement>(null)\n const { inputMode, toggleInputMode } = useInputModeStore()\n const showFiat = inputMode[formType] === 'price'\n const { hiddenUI, mode } = useWidgetConfig()\n const isLimit = mode === 'limit'\n\n const [selectedRouteId] = useFieldValues('selectedRouteId')\n const { routes, isFetching, dataUpdatedAt, refetchTime, refetch } =\n useRoutes()\n // Reflect the route the user selected in the routes list (falling back to the\n // best route), so the buy amount matches the highlighted provider card.\n const route = routes?.find((r) => r.id === selectedRouteId) ?? routes?.[0]\n const priceImpact = useReceivePriceImpact(route)\n const showPriceImpact = !hiddenUI?.routeCardPriceImpact\n\n // Value the amount the way a quote card does, so the two sides of the screen\n // cannot disagree: the route's own price wins, and the cache fills only a gap\n // the route leaves — a token it could not price arrives as '0' or ''.\n const { token: cachedToken } = useToken(\n route?.toToken.chainId,\n route?.toToken.address\n )\n const pricedToken = route\n ? mergeFallbackToken(route.toToken, cachedToken)\n : undefined\n\n const receiveAmount = route?.toAmount\n ? formatTokenAmount(BigInt(route.toAmount), route.toToken.decimals)\n : undefined\n // Only show skeletons on the initial fetch.\n const showSkeleton = isFetching && !receiveAmount\n\n const fiatValue =\n receiveAmount && pricedToken?.priceUSD\n ? formatTokenPrice(receiveAmount, pricedToken.priceUSD)\n : 0\n const canToggle = !!receiveAmount && !!pricedToken?.priceUSD\n\n const mainDisplay = showFiat\n ? t('format.currency', { value: fiatValue })\n : t('format.tokenAmount', { value: receiveAmount || '0' })\n const footerDisplay = showFiat\n ? t('format.tokenAmount', { value: receiveAmount || '0' })\n : t('format.currency', { value: fiatValue })\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: effect must run on value change\n useLayoutEffect(() => {\n if (amountRef.current) {\n fitInputText(maxInputFontSize, minInputFontSize, amountRef.current)\n }\n }, [mainDisplay])\n\n return (\n <ReceiveAmountCardLayout\n cardProps={props}\n title={isLimit ? t('header.buy') : t('header.receive')}\n headerEnd={\n isLimit && (isFetching || routes?.length) ? (\n <ProgressToNextUpdate\n updatedAt={dataUpdatedAt || Date.now()}\n timeToUpdate={refetchTime}\n isLoading={isFetching}\n onClick={() => refetch()}\n sx={{ padding: 0 }}\n />\n ) : undefined\n }\n amount={\n showSkeleton ? (\n <Skeleton variant=\"rounded\" height={amountHeight} sx={{ flex: 1 }} />\n ) : (\n <AmountDisplay\n ref={amountRef}\n sx={{ color: 'text.primary', opacity: receiveAmount ? 1 : 0.5 }}\n >\n {mainDisplay}\n </AmountDisplay>\n )\n }\n footerStart={\n showSkeleton ? (\n <Skeleton\n variant=\"text\"\n width={72}\n sx={{ fontSize: footerFontSize }}\n />\n ) : (\n <ToggleButton\n clickable={canToggle}\n onClick={canToggle ? () => toggleInputMode(formType) : undefined}\n aria-label={canToggle ? 'Toggle fiat value' : undefined}\n >\n <FooterText>{footerDisplay}</FooterText>\n {canToggle ? (\n <SwapVertIcon sx={{ fontSize: 14, color: 'text.secondary' }} />\n ) : null}\n </ToggleButton>\n )\n }\n footerEnd={\n showSkeleton ? (\n showPriceImpact ? (\n <Skeleton\n variant=\"text\"\n width={56}\n sx={{ fontSize: footerFontSize }}\n />\n ) : null\n ) : (\n <PriceImpactBadge priceImpact={priceImpact} />\n )\n }\n />\n )\n}\n"],"mappings":"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"}
@@ -40,15 +40,19 @@ const SendAmountCard = (props) => {
40
40
  };
41
41
  const title = mode === "limit" ? t("header.sell") : mode === "custom" && modeOptions?.custom?.type === "deposit" ? t("header.deposit") : t("header.send");
42
42
  let displayValue;
43
- if (isEditingRef.current) if (currentInputMode === "price") displayValue = formattedPriceInput;
44
- else displayValue = value;
45
- else if (currentInputMode === "price") displayValue = formatInputAmount(formatTokenPrice(value, token?.priceUSD).toFixed(2), 2);
46
- else displayValue = value;
43
+ if (isEditingRef.current) {
44
+ if (currentInputMode === "price") displayValue = formattedPriceInput;
45
+ else displayValue = value;
46
+ } else if (currentInputMode === "price") {
47
+ const priceValue = formatTokenPrice(value, token?.priceUSD);
48
+ displayValue = formatInputAmount(priceValue.toFixed(2), 2);
49
+ } else displayValue = value;
47
50
  const handleChange = (event) => {
48
51
  const { value: inputValue } = event.target;
49
52
  isEditingRef.current = true;
50
53
  if (currentInputMode === "price") {
51
- const formattedValue = formatInputAmount(inputValue.replace("$", ""), 2, true);
54
+ const cleanInputValue = inputValue.replace("$", "");
55
+ const formattedValue = formatInputAmount(cleanInputValue, 2, true);
52
56
  const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD);
53
57
  setFormattedPriceInput(formattedValue);
54
58
  applyFromAmount(tokenValue);
@@ -61,7 +65,10 @@ const SendAmountCard = (props) => {
61
65
  const { value: inputValue } = event.target;
62
66
  isEditingRef.current = false;
63
67
  if (currentInputMode === "price") {
64
- const formattedAmount = formatInputAmount(priceToTokenAmount(formatInputAmount(inputValue.replace("$", ""), 2), token?.priceUSD), token?.decimals);
68
+ const cleanInputValue = inputValue.replace("$", "");
69
+ const formattedValue = formatInputAmount(cleanInputValue, 2);
70
+ const tokenValue = priceToTokenAmount(formattedValue, token?.priceUSD);
71
+ const formattedAmount = formatInputAmount(tokenValue, token?.decimals);
65
72
  applyFromAmount(formattedAmount);
66
73
  } else {
67
74
  const formattedValue = formatInputAmount(inputValue, token?.decimals);