@lifi/widget 4.1.0 → 4.3.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 (210) hide show
  1. package/dist/esm/AppDefault.js +14 -0
  2. package/dist/esm/AppDefault.js.map +1 -1
  3. package/dist/esm/components/AmountInput/AmountInput.js +2 -1
  4. package/dist/esm/components/AmountInput/AmountInput.js.map +1 -1
  5. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js +4 -2
  6. package/dist/esm/components/AmountInput/AmountInputEndAdornment.js.map +1 -1
  7. package/dist/esm/components/AmountInput/AmountInputEndAdornment.style.js +1 -1
  8. package/dist/esm/components/AmountInput/AmountInputEndAdornment.style.js.map +1 -1
  9. package/dist/esm/components/AmountInput/PriceFormHelperText.js +4 -2
  10. package/dist/esm/components/AmountInput/PriceFormHelperText.js.map +1 -1
  11. package/dist/esm/components/AmountInputCard/AmountInputCard.style.js +98 -0
  12. package/dist/esm/components/AmountInputCard/AmountInputCard.style.js.map +1 -0
  13. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js +25 -0
  14. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -0
  15. package/dist/esm/components/AmountInputCard/BalanceDisplay.js +35 -0
  16. package/dist/esm/components/AmountInputCard/BalanceDisplay.js.map +1 -0
  17. package/dist/esm/components/AmountInputCard/BalanceDisplay.style.js +11 -0
  18. package/dist/esm/components/AmountInputCard/BalanceDisplay.style.js.map +1 -0
  19. package/dist/esm/components/AmountInputCard/FiatValueToggle.js +41 -0
  20. package/dist/esm/components/AmountInputCard/FiatValueToggle.js.map +1 -0
  21. package/dist/esm/components/AmountInputCard/PercentageChips.js +80 -0
  22. package/dist/esm/components/AmountInputCard/PercentageChips.js.map +1 -0
  23. package/dist/esm/components/AmountInputCard/PercentageChips.style.js +43 -0
  24. package/dist/esm/components/AmountInputCard/PercentageChips.style.js.map +1 -0
  25. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js +137 -0
  26. package/dist/esm/components/AmountInputCard/ReceiveAmountCard.js.map +1 -0
  27. package/dist/esm/components/AmountInputCard/SendAmountCard.js +102 -0
  28. package/dist/esm/components/AmountInputCard/SendAmountCard.js.map +1 -0
  29. package/dist/esm/components/Avatar/Avatar.js +12 -3
  30. package/dist/esm/components/Avatar/Avatar.js.map +1 -1
  31. package/dist/esm/components/Chains/VirtualizedChainList.js +2 -1
  32. package/dist/esm/components/Chains/VirtualizedChainList.js.map +1 -1
  33. package/dist/esm/components/Header/HeaderNavigationTabs.js +14 -1
  34. package/dist/esm/components/Header/HeaderNavigationTabs.js.map +1 -1
  35. package/dist/esm/components/IconCircle/IconCircle.style.js +1 -1
  36. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js +99 -0
  37. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.js.map +1 -0
  38. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.style.js +52 -0
  39. package/dist/esm/components/LimitOrderSettings/LimitOrderSettings.style.js.map +1 -0
  40. package/dist/esm/components/LimitPriceCard/LimitPriceCard.js +115 -0
  41. package/dist/esm/components/LimitPriceCard/LimitPriceCard.js.map +1 -0
  42. package/dist/esm/components/LimitPriceCard/LimitPriceCard.style.js +89 -0
  43. package/dist/esm/components/LimitPriceCard/LimitPriceCard.style.js.map +1 -0
  44. package/dist/esm/components/LimitPriceCard/LimitPricePresets.js +91 -0
  45. package/dist/esm/components/LimitPriceCard/LimitPricePresets.js.map +1 -0
  46. package/dist/esm/components/RouteCard/RouteProviderCard.js +118 -0
  47. package/dist/esm/components/RouteCard/RouteProviderCard.js.map +1 -0
  48. package/dist/esm/components/Routes/LimitOrderRoutes.js +34 -0
  49. package/dist/esm/components/Routes/LimitOrderRoutes.js.map +1 -0
  50. package/dist/esm/components/Routes/Routes.js +2 -2
  51. package/dist/esm/components/Routes/Routes.js.map +1 -1
  52. package/dist/esm/components/SettingsPanel/SettingsPanel.js +51 -0
  53. package/dist/esm/components/SettingsPanel/SettingsPanel.js.map +1 -0
  54. package/dist/esm/components/SettingsPanel/SettingsPanel.style.js +33 -0
  55. package/dist/esm/components/SettingsPanel/SettingsPanel.style.js.map +1 -0
  56. package/dist/esm/components/SettingsPanel/utils.js +14 -0
  57. package/dist/esm/components/SettingsPanel/utils.js.map +1 -0
  58. package/dist/esm/components/SwapButton/SwapButton.js +50 -0
  59. package/dist/esm/components/SwapButton/SwapButton.js.map +1 -0
  60. package/dist/esm/components/SwapButton/SwapButton.style.js +24 -0
  61. package/dist/esm/components/SwapButton/SwapButton.style.js.map +1 -0
  62. package/dist/esm/components/TokenPillButton/TokenPillButton.js +52 -0
  63. package/dist/esm/components/TokenPillButton/TokenPillButton.js.map +1 -0
  64. package/dist/esm/components/TokenPillButton/TokenPillButton.style.js +39 -0
  65. package/dist/esm/components/TokenPillButton/TokenPillButton.style.js.map +1 -0
  66. package/dist/esm/config/version.d.ts +1 -1
  67. package/dist/esm/config/version.js +1 -1
  68. package/dist/esm/config/version.js.map +1 -1
  69. package/dist/esm/hooks/useChainSearch.js +2 -1
  70. package/dist/esm/hooks/useChainSearch.js.map +1 -1
  71. package/dist/esm/hooks/useFilteredByTokenBalances.js +4 -1
  72. package/dist/esm/hooks/useFilteredByTokenBalances.js.map +1 -1
  73. package/dist/esm/hooks/useLimitMarketRate.js +24 -0
  74. package/dist/esm/hooks/useLimitMarketRate.js.map +1 -0
  75. package/dist/esm/hooks/useLinkedLimitFields.js +49 -0
  76. package/dist/esm/hooks/useLinkedLimitFields.js.map +1 -0
  77. package/dist/esm/hooks/useRoutes.js +23 -6
  78. package/dist/esm/hooks/useRoutes.js.map +1 -1
  79. package/dist/esm/hooks/useTokens.js +16 -14
  80. package/dist/esm/hooks/useTokens.js.map +1 -1
  81. package/dist/esm/hooks/useWideVariant.js +5 -2
  82. package/dist/esm/hooks/useWideVariant.js.map +1 -1
  83. package/dist/esm/i18n/en.json +22 -0
  84. package/dist/esm/index.d.ts +2 -2
  85. package/dist/esm/pages/MainPage/LimitPageContent.js +23 -0
  86. package/dist/esm/pages/MainPage/LimitPageContent.js.map +1 -0
  87. package/dist/esm/pages/MainPage/MainPage.js +19 -22
  88. package/dist/esm/pages/MainPage/MainPage.js.map +1 -1
  89. package/dist/esm/pages/MainPage/MainPageActions.js +28 -0
  90. package/dist/esm/pages/MainPage/MainPageActions.js.map +1 -0
  91. package/dist/esm/pages/MainPage/ReviewButton.js +9 -2
  92. package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
  93. package/dist/esm/pages/RoutePriorityPage.js +48 -0
  94. package/dist/esm/pages/RoutePriorityPage.js.map +1 -0
  95. package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js +2 -2
  96. package/dist/esm/pages/SettingsPage/BridgeAndExchangeSettings.js.map +1 -1
  97. package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js +12 -27
  98. package/dist/esm/pages/SettingsPage/RoutePrioritySettings.js.map +1 -1
  99. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js +133 -0
  100. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippagePage.js.map +1 -0
  101. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js +14 -72
  102. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.js.map +1 -1
  103. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js +26 -14
  104. package/dist/esm/pages/SettingsPage/SlippageSettings/SlippageSettings.style.js.map +1 -1
  105. package/dist/esm/pages/SettingsPage/ThemeSettings.js +4 -0
  106. package/dist/esm/pages/SettingsPage/ThemeSettings.js.map +1 -1
  107. package/dist/esm/pages/TransactionPage/TransactionReview.js +4 -1
  108. package/dist/esm/pages/TransactionPage/TransactionReview.js.map +1 -1
  109. package/dist/esm/providers/I18nProvider/I18nProvider.js +1 -1
  110. package/dist/esm/providers/I18nProvider/enResource.d.ts +1 -1
  111. package/dist/esm/providers/I18nProvider/enResource.js +1 -1
  112. package/dist/esm/providers/I18nProvider/types.d.ts +2 -2
  113. package/dist/esm/providers/SDKClientProvider.js +25 -24
  114. package/dist/esm/providers/SDKClientProvider.js.map +1 -1
  115. package/dist/esm/providers/WidgetProvider/WidgetProvider.js +22 -21
  116. package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
  117. package/dist/esm/stores/form/URLSearchParamsBuilder.js +14 -3
  118. package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
  119. package/dist/esm/stores/form/createFormStore.js +6 -2
  120. package/dist/esm/stores/form/createFormStore.js.map +1 -1
  121. package/dist/esm/stores/form/getDefaultValuesFromQueryString.js +3 -0
  122. package/dist/esm/stores/form/getDefaultValuesFromQueryString.js.map +1 -1
  123. package/dist/esm/stores/form/types.d.ts +9 -1
  124. package/dist/esm/stores/form/types.d.ts.map +1 -1
  125. package/dist/esm/stores/form/types.js.map +1 -1
  126. package/dist/esm/stores/form/useClearAmountFields.js +1 -0
  127. package/dist/esm/stores/form/useClearAmountFields.js.map +1 -1
  128. package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js +4 -2
  129. package/dist/esm/stores/navigationTabs/useNavigationTabsStore.js.map +1 -1
  130. package/dist/esm/stores/navigationTabs/utils.js +38 -8
  131. package/dist/esm/stores/navigationTabs/utils.js.map +1 -1
  132. package/dist/esm/types/events.d.ts +10 -1
  133. package/dist/esm/types/events.d.ts.map +1 -1
  134. package/dist/esm/types/events.js +2 -0
  135. package/dist/esm/types/events.js.map +1 -1
  136. package/dist/esm/types/widget.d.ts +10 -0
  137. package/dist/esm/types/widget.d.ts.map +1 -1
  138. package/dist/esm/types/widget.js.map +1 -1
  139. package/dist/esm/utils/format.d.ts +1 -1
  140. package/dist/esm/utils/format.d.ts.map +1 -1
  141. package/dist/esm/utils/format.js +2 -2
  142. package/dist/esm/utils/format.js.map +1 -1
  143. package/dist/esm/utils/limitOrder.js +61 -0
  144. package/dist/esm/utils/limitOrder.js.map +1 -0
  145. package/dist/esm/utils/navigationRoutes.d.ts +2 -0
  146. package/dist/esm/utils/navigationRoutes.d.ts.map +1 -1
  147. package/dist/esm/utils/navigationRoutes.js +6 -0
  148. package/dist/esm/utils/navigationRoutes.js.map +1 -1
  149. package/dist/esm/utils/token.js +38 -3
  150. package/dist/esm/utils/token.js.map +1 -1
  151. package/package.json +11 -11
  152. package/src/AppDefault.tsx +16 -0
  153. package/src/components/AmountInput/AmountInputEndAdornment.style.ts +1 -1
  154. package/src/components/AmountInput/AmountInputEndAdornment.tsx +5 -2
  155. package/src/components/AmountInputCard/AmountInputCard.style.tsx +157 -0
  156. package/src/components/AmountInputCard/AmountInputCardPair.tsx +25 -0
  157. package/src/components/AmountInputCard/BalanceDisplay.style.tsx +9 -0
  158. package/src/components/AmountInputCard/BalanceDisplay.tsx +46 -0
  159. package/src/components/AmountInputCard/FiatValueToggle.tsx +55 -0
  160. package/src/components/AmountInputCard/PercentageChips.style.tsx +60 -0
  161. package/src/components/AmountInputCard/PercentageChips.tsx +100 -0
  162. package/src/components/AmountInputCard/ReceiveAmountCard.tsx +219 -0
  163. package/src/components/AmountInputCard/SendAmountCard.tsx +179 -0
  164. package/src/components/Avatar/Avatar.tsx +8 -3
  165. package/src/components/Header/HeaderNavigationTabs.tsx +19 -2
  166. package/src/components/LimitOrderSettings/LimitOrderSettings.style.tsx +69 -0
  167. package/src/components/LimitOrderSettings/LimitOrderSettings.tsx +124 -0
  168. package/src/components/LimitPriceCard/LimitPriceCard.style.tsx +103 -0
  169. package/src/components/LimitPriceCard/LimitPriceCard.tsx +153 -0
  170. package/src/components/LimitPriceCard/LimitPricePresets.tsx +139 -0
  171. package/src/components/RouteCard/RouteProviderCard.tsx +113 -0
  172. package/src/components/Routes/LimitOrderRoutes.tsx +64 -0
  173. package/src/components/Routes/Routes.tsx +3 -2
  174. package/src/components/SettingsPanel/SettingsPanel.style.tsx +41 -0
  175. package/src/components/SettingsPanel/SettingsPanel.tsx +73 -0
  176. package/src/components/SettingsPanel/utils.ts +27 -0
  177. package/src/components/SwapButton/SwapButton.style.tsx +28 -0
  178. package/src/components/SwapButton/SwapButton.tsx +71 -0
  179. package/src/components/TokenPillButton/TokenPillButton.style.tsx +50 -0
  180. package/src/components/TokenPillButton/TokenPillButton.tsx +81 -0
  181. package/src/config/version.ts +1 -1
  182. package/src/hooks/useFilteredByTokenBalances.ts +7 -2
  183. package/src/hooks/useLimitMarketRate.ts +39 -0
  184. package/src/hooks/useLinkedLimitFields.ts +74 -0
  185. package/src/hooks/useRoutes.ts +45 -4
  186. package/src/hooks/useWideVariant.ts +8 -2
  187. package/src/pages/MainPage/LimitPageContent.tsx +18 -0
  188. package/src/pages/MainPage/MainPage.tsx +43 -30
  189. package/src/pages/MainPage/MainPageActions.tsx +35 -0
  190. package/src/pages/MainPage/ReviewButton.tsx +13 -1
  191. package/src/pages/RoutePriorityPage.tsx +55 -0
  192. package/src/pages/SettingsPage/RoutePrioritySettings.tsx +14 -38
  193. package/src/pages/SettingsPage/SlippageSettings/SlippagePage.tsx +176 -0
  194. package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.style.tsx +32 -25
  195. package/src/pages/SettingsPage/SlippageSettings/SlippageSettings.tsx +14 -128
  196. package/src/pages/SettingsPage/ThemeSettings.tsx +4 -0
  197. package/src/stores/form/URLSearchParamsBuilder.tsx +25 -3
  198. package/src/stores/form/createFormStore.ts +7 -3
  199. package/src/stores/form/getDefaultValuesFromQueryString.ts +11 -0
  200. package/src/stores/form/types.ts +14 -1
  201. package/src/stores/form/useClearAmountFields.ts +1 -0
  202. package/src/stores/navigationTabs/types.ts +6 -0
  203. package/src/stores/navigationTabs/useNavigationTabsStore.tsx +8 -3
  204. package/src/stores/navigationTabs/utils.ts +67 -5
  205. package/src/types/events.ts +12 -0
  206. package/src/types/widget.ts +10 -0
  207. package/src/utils/format.ts +6 -2
  208. package/src/utils/limitOrder.ts +88 -0
  209. package/src/utils/navigationRoutes.ts +6 -0
  210. package/src/utils/token.ts +71 -20
@@ -0,0 +1,34 @@
1
+ import { useFieldActions } from "../../stores/form/useFieldActions.js";
2
+ import { useFieldValues } from "../../stores/form/useFieldValues.js";
3
+ import { useRoutes } from "../../hooks/useRoutes.js";
4
+ import { useToAddressRequirements } from "../../hooks/useToAddressRequirements.js";
5
+ import { RouteNotFoundCard } from "../RouteCard/RouteNotFoundCard.js";
6
+ import { RouteProviderCard, RouteProviderCardSkeleton } from "../RouteCard/RouteProviderCard.js";
7
+ import { Stack } from "@mui/material";
8
+ import { jsx } from "react/jsx-runtime";
9
+ //#region src/components/Routes/LimitOrderRoutes.tsx
10
+ const LimitOrderRoutes = (props) => {
11
+ const { routes, isLoading, isFetching, isFetched } = useRoutes();
12
+ const [toAddress, selectedRouteId] = useFieldValues("toAddress", "selectedRouteId");
13
+ const { setFieldValue } = useFieldActions();
14
+ const { requiredToAddress } = useToAddressRequirements();
15
+ const currentRoute = routes?.[0];
16
+ if (!currentRoute && !isLoading && !isFetching && !isFetched) return null;
17
+ const allowInteraction = !(currentRoute && requiredToAddress && !toAddress);
18
+ const activeRouteId = routes?.find((route) => route.id === selectedRouteId)?.id ?? currentRoute?.id;
19
+ return /* @__PURE__ */ jsx(Stack, {
20
+ direction: "column",
21
+ spacing: 1,
22
+ sx: props.sx,
23
+ className: props.className,
24
+ children: isLoading && !currentRoute ? Array.from({ length: 2 }).map((_, index) => /* @__PURE__ */ jsx(RouteProviderCardSkeleton, {}, index)) : !currentRoute ? /* @__PURE__ */ jsx(RouteNotFoundCard, {}) : routes?.map((route) => /* @__PURE__ */ jsx(RouteProviderCard, {
25
+ route,
26
+ active: route.id === activeRouteId,
27
+ onClick: allowInteraction ? () => setFieldValue("selectedRouteId", route.id) : void 0
28
+ }, route.id))
29
+ });
30
+ };
31
+ //#endregion
32
+ export { LimitOrderRoutes };
33
+
34
+ //# sourceMappingURL=LimitOrderRoutes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LimitOrderRoutes.js","names":[],"sources":["../../../../src/components/Routes/LimitOrderRoutes.tsx"],"sourcesContent":["import { Stack } from '@mui/material'\nimport { useRoutes } from '../../hooks/useRoutes.js'\nimport { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport type { CardProps } from '../Card/Card.js'\nimport { RouteNotFoundCard } from '../RouteCard/RouteNotFoundCard.js'\nimport {\n RouteProviderCard,\n RouteProviderCardSkeleton,\n} from '../RouteCard/RouteProviderCard.js'\n\nexport const LimitOrderRoutes: React.FC<CardProps> = (props) => {\n const { routes, isLoading, isFetching, isFetched } = useRoutes()\n const [toAddress, selectedRouteId] = useFieldValues(\n 'toAddress',\n 'selectedRouteId'\n )\n const { setFieldValue } = useFieldActions()\n const { requiredToAddress } = useToAddressRequirements()\n\n const currentRoute = routes?.[0]\n\n if (!currentRoute && !isLoading && !isFetching && !isFetched) {\n return null\n }\n\n const toAddressUnsatisfied = currentRoute && requiredToAddress && !toAddress\n const allowInteraction = !toAddressUnsatisfied\n\n const activeRouteId =\n routes?.find((route) => route.id === selectedRouteId)?.id ??\n currentRoute?.id\n\n return (\n <Stack\n direction=\"column\"\n spacing={1}\n sx={props.sx}\n className={props.className}\n >\n {isLoading && !currentRoute ? (\n Array.from({ length: 2 }).map((_, index) => (\n <RouteProviderCardSkeleton key={index} />\n ))\n ) : !currentRoute ? (\n <RouteNotFoundCard />\n ) : (\n routes?.map((route) => (\n <RouteProviderCard\n key={route.id}\n route={route}\n active={route.id === activeRouteId}\n onClick={\n allowInteraction\n ? () => setFieldValue('selectedRouteId', route.id)\n : undefined\n }\n />\n ))\n )}\n </Stack>\n )\n}\n"],"mappings":";;;;;;;;;AAYA,MAAa,oBAAyC,UAAU;CAC9D,MAAM,EAAE,QAAQ,WAAW,YAAY,cAAc,UAAU;CAC/D,MAAM,CAAC,WAAW,mBAAmB,eACnC,aACA,iBACF;CACA,MAAM,EAAE,kBAAkB,gBAAgB;CAC1C,MAAM,EAAE,sBAAsB,yBAAyB;CAEvD,MAAM,eAAe,SAAS;CAE9B,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,cAAc,CAAC,WACjD,OAAO;CAIT,MAAM,mBAAmB,EADI,gBAAgB,qBAAqB,CAAC;CAGnE,MAAM,gBACJ,QAAQ,MAAM,UAAU,MAAM,OAAO,eAAe,CAAC,EAAE,MACvD,cAAc;CAEhB,OACE,oBAAC,OAAD;EACE,WAAU;EACV,SAAS;EACT,IAAI,MAAM;EACV,WAAW,MAAM;YAEhB,aAAa,CAAC,eACb,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,UAChC,oBAAC,2BAAD,CAAwC,GAAR,KAAQ,CACzC,IACC,CAAC,eACH,oBAAC,mBAAD,CAAoB,CAAA,IAEpB,QAAQ,KAAK,UACX,oBAAC,mBAAD;GAES;GACP,QAAQ,MAAM,OAAO;GACrB,SACE,yBACU,cAAc,mBAAmB,MAAM,EAAE,IAC/C,KAAA;EAEP,GARM,MAAM,EAQZ,CACF;CAEE,CAAA;AAEX"}
@@ -16,7 +16,7 @@ import { useTranslation } from "react-i18next";
16
16
  const Routes = (props) => {
17
17
  const { t } = useTranslation();
18
18
  const navigate = useNavigate();
19
- const { mode, modeOptions, showSingleRoute } = useWidgetConfig();
19
+ const { mode, modeOptions, showSingleRoute, defaultUI } = useWidgetConfig();
20
20
  const { routes, isLoading, isFetching, isFetched, dataUpdatedAt, refetchTime, refetch } = useRoutes();
21
21
  const currentRoute = routes?.[0];
22
22
  if (!currentRoute && !isLoading && !isFetching && !isFetched) return null;
@@ -28,7 +28,7 @@ const Routes = (props) => {
28
28
  return /* @__PURE__ */ jsxs(Card$1, {
29
29
  ...props,
30
30
  children: [
31
- /* @__PURE__ */ jsx(CardTitle, { children: title }),
31
+ defaultUI?.layout === "cards" ? null : /* @__PURE__ */ jsx(CardTitle, { children: title }),
32
32
  /* @__PURE__ */ jsx(ProgressToNextUpdate, {
33
33
  updatedAt: dataUpdatedAt || Date.now(),
34
34
  timeToUpdate: refetchTime,
@@ -1 +1 @@
1
- {"version":3,"file":"Routes.js","names":["Card"],"sources":["../../../../src/components/Routes/Routes.tsx"],"sourcesContent":["import { Box, Collapse } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport { useTranslation } from 'react-i18next'\nimport { useRoutes } from '../../hooks/useRoutes.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { ButtonTertiary } from '../ButtonTertiary.js'\nimport type { CardProps } from '../Card/Card.js'\nimport { Card } from '../Card/Card.js'\nimport { CardTitle } from '../Card/CardTitle.js'\nimport { ProgressToNextUpdate } from '../ProgressToNextUpdate.js'\nimport { RouteCard } from '../RouteCard/RouteCard.js'\nimport { RouteCardSkeleton } from '../RouteCard/RouteCardSkeleton.js'\nimport { RouteNotFoundCard } from '../RouteCard/RouteNotFoundCard.js'\n\nexport const Routes: React.FC<CardProps> = (props) => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const { mode, modeOptions, showSingleRoute } = useWidgetConfig()\n const {\n routes,\n isLoading,\n isFetching,\n isFetched,\n dataUpdatedAt,\n refetchTime,\n refetch,\n } = useRoutes()\n\n const currentRoute = routes?.[0]\n\n if (!currentRoute && !isLoading && !isFetching && !isFetched) {\n return null\n }\n\n const handleCardClick = () => {\n navigate({ to: navigationRoutes.routes })\n }\n\n const routeNotFound = !currentRoute && !isLoading && !isFetching\n const onlySingleRoute = mode === 'refuel' || showSingleRoute\n const showAll =\n !onlySingleRoute && !routeNotFound && (routes?.length ?? 0) > 1\n\n const title =\n mode === 'custom'\n ? modeOptions?.custom?.type === 'deposit'\n ? t('header.receive')\n : t('header.youPay')\n : t('header.receive')\n\n return (\n <Card {...props}>\n <CardTitle>{title}</CardTitle>\n <ProgressToNextUpdate\n updatedAt={dataUpdatedAt || Date.now()}\n timeToUpdate={refetchTime}\n isLoading={isFetching}\n onClick={() => refetch()}\n sx={{\n position: 'absolute',\n top: 8,\n right: 8,\n }}\n />\n <Box\n sx={{\n p: 2,\n }}\n >\n {isLoading && !currentRoute ? (\n <RouteCardSkeleton variant=\"cardless\" />\n ) : !currentRoute ? (\n <RouteNotFoundCard />\n ) : (\n <RouteCard route={currentRoute} variant=\"cardless\" active />\n )}\n\n <Collapse timeout={225} in={showAll} unmountOnExit mountOnEnter>\n <Box\n sx={{\n mt: 2,\n }}\n >\n <ButtonTertiary onClick={handleCardClick} fullWidth>\n {t('button.showAll')}\n </ButtonTertiary>\n </Box>\n </Collapse>\n </Box>\n </Card>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAa,UAA+B,UAAU;CACpD,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,EAAE,MAAM,aAAa,oBAAoB,gBAAgB;CAC/D,MAAM,EACJ,QACA,WACA,YACA,WACA,eACA,aACA,YACE,UAAU;CAEd,MAAM,eAAe,SAAS;CAE9B,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,cAAc,CAAC,WACjD,OAAO;CAGT,MAAM,wBAAwB;EAC5B,SAAS,EAAE,IAAI,iBAAiB,OAAO,CAAC;CAC1C;CAIA,MAAM,UACJ,EAFsB,SAAS,YAAY,oBAEvB,EAHA,CAAC,gBAAgB,CAAC,aAAa,CAAC,gBAGb,QAAQ,UAAU,KAAK;CAEhE,MAAM,QACJ,SAAS,WACL,aAAa,QAAQ,SAAS,YAC5B,EAAE,gBAAgB,IAClB,EAAE,eAAe,IACnB,EAAE,gBAAgB;CAExB,OACE,qBAACA,QAAD;EAAM,GAAI;YAAV;GACE,oBAAC,WAAD,EAAA,UAAY,MAAiB,CAAA;GAC7B,oBAAC,sBAAD;IACE,WAAW,iBAAiB,KAAK,IAAI;IACrC,cAAc;IACd,WAAW;IACX,eAAe,QAAQ;IACvB,IAAI;KACF,UAAU;KACV,KAAK;KACL,OAAO;IACT;GACD,CAAA;GACD,qBAAC,KAAD;IACE,IAAI,EACF,GAAG,EACL;cAHF,CAKG,aAAa,CAAC,eACb,oBAAC,mBAAD,EAAmB,SAAQ,WAAY,CAAA,IACrC,CAAC,eACH,oBAAC,mBAAD,CAAoB,CAAA,IAEpB,oBAAC,WAAD;KAAW,OAAO;KAAc,SAAQ;KAAW,QAAA;IAAQ,CAAA,GAG7D,oBAAC,UAAD;KAAU,SAAS;KAAK,IAAI;KAAS,eAAA;KAAc,cAAA;eACjD,oBAAC,KAAD;MACE,IAAI,EACF,IAAI,EACN;gBAEA,oBAAC,gBAAD;OAAgB,SAAS;OAAiB,WAAA;iBACvC,EAAE,gBAAgB;MACL,CAAA;KACb,CAAA;IACG,CAAA,CACP;;EACD;;AAEV"}
1
+ {"version":3,"file":"Routes.js","names":["Card"],"sources":["../../../../src/components/Routes/Routes.tsx"],"sourcesContent":["import { Box, Collapse } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport { useTranslation } from 'react-i18next'\nimport { useRoutes } from '../../hooks/useRoutes.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { ButtonTertiary } from '../ButtonTertiary.js'\nimport type { CardProps } from '../Card/Card.js'\nimport { Card } from '../Card/Card.js'\nimport { CardTitle } from '../Card/CardTitle.js'\nimport { ProgressToNextUpdate } from '../ProgressToNextUpdate.js'\nimport { RouteCard } from '../RouteCard/RouteCard.js'\nimport { RouteCardSkeleton } from '../RouteCard/RouteCardSkeleton.js'\nimport { RouteNotFoundCard } from '../RouteCard/RouteNotFoundCard.js'\n\nexport const Routes: React.FC<CardProps> = (props) => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const { mode, modeOptions, showSingleRoute, defaultUI } = useWidgetConfig()\n const {\n routes,\n isLoading,\n isFetching,\n isFetched,\n dataUpdatedAt,\n refetchTime,\n refetch,\n } = useRoutes()\n\n const currentRoute = routes?.[0]\n\n if (!currentRoute && !isLoading && !isFetching && !isFetched) {\n return null\n }\n\n const handleCardClick = () => {\n navigate({ to: navigationRoutes.routes })\n }\n\n const routeNotFound = !currentRoute && !isLoading && !isFetching\n const onlySingleRoute = mode === 'refuel' || showSingleRoute\n const showAll =\n !onlySingleRoute && !routeNotFound && (routes?.length ?? 0) > 1\n\n const title =\n mode === 'custom'\n ? modeOptions?.custom?.type === 'deposit'\n ? t('header.receive')\n : t('header.youPay')\n : t('header.receive')\n\n return (\n <Card {...props}>\n {/* The cards layout's Receive card already carries this header. */}\n {defaultUI?.layout === 'cards' ? null : <CardTitle>{title}</CardTitle>}\n <ProgressToNextUpdate\n updatedAt={dataUpdatedAt || Date.now()}\n timeToUpdate={refetchTime}\n isLoading={isFetching}\n onClick={() => refetch()}\n sx={{\n position: 'absolute',\n top: 8,\n right: 8,\n }}\n />\n <Box\n sx={{\n p: 2,\n }}\n >\n {isLoading && !currentRoute ? (\n <RouteCardSkeleton variant=\"cardless\" />\n ) : !currentRoute ? (\n <RouteNotFoundCard />\n ) : (\n <RouteCard route={currentRoute} variant=\"cardless\" active />\n )}\n\n <Collapse timeout={225} in={showAll} unmountOnExit mountOnEnter>\n <Box\n sx={{\n mt: 2,\n }}\n >\n <ButtonTertiary onClick={handleCardClick} fullWidth>\n {t('button.showAll')}\n </ButtonTertiary>\n </Box>\n </Collapse>\n </Box>\n </Card>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;AAeA,MAAa,UAA+B,UAAU;CACpD,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,EAAE,MAAM,aAAa,iBAAiB,cAAc,gBAAgB;CAC1E,MAAM,EACJ,QACA,WACA,YACA,WACA,eACA,aACA,YACE,UAAU;CAEd,MAAM,eAAe,SAAS;CAE9B,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,cAAc,CAAC,WACjD,OAAO;CAGT,MAAM,wBAAwB;EAC5B,SAAS,EAAE,IAAI,iBAAiB,OAAO,CAAC;CAC1C;CAIA,MAAM,UACJ,EAFsB,SAAS,YAAY,oBAEvB,EAHA,CAAC,gBAAgB,CAAC,aAAa,CAAC,gBAGb,QAAQ,UAAU,KAAK;CAEhE,MAAM,QACJ,SAAS,WACL,aAAa,QAAQ,SAAS,YAC5B,EAAE,gBAAgB,IAClB,EAAE,eAAe,IACnB,EAAE,gBAAgB;CAExB,OACE,qBAACA,QAAD;EAAM,GAAI;YAAV;GAEG,WAAW,WAAW,UAAU,OAAO,oBAAC,WAAD,EAAA,UAAY,MAAiB,CAAA;GACrE,oBAAC,sBAAD;IACE,WAAW,iBAAiB,KAAK,IAAI;IACrC,cAAc;IACd,WAAW;IACX,eAAe,QAAQ;IACvB,IAAI;KACF,UAAU;KACV,KAAK;KACL,OAAO;IACT;GACD,CAAA;GACD,qBAAC,KAAD;IACE,IAAI,EACF,GAAG,EACL;cAHF,CAKG,aAAa,CAAC,eACb,oBAAC,mBAAD,EAAmB,SAAQ,WAAY,CAAA,IACrC,CAAC,eACH,oBAAC,mBAAD,CAAoB,CAAA,IAEpB,oBAAC,WAAD;KAAW,OAAO;KAAc,SAAQ;KAAW,QAAA;IAAQ,CAAA,GAG7D,oBAAC,UAAD;KAAU,SAAS;KAAK,IAAI;KAAS,eAAA;KAAc,cAAA;eACjD,oBAAC,KAAD;MACE,IAAI,EACF,IAAI,EACN;gBAEA,oBAAC,gBAAD;OAAgB,SAAS;OAAiB,WAAA;iBACvC,EAAE,gBAAgB;MACL,CAAA;KACb,CAAA;IACG,CAAA,CACP;;EACD;;AAEV"}
@@ -0,0 +1,51 @@
1
+ import { useSettingsStore } from "../../stores/settings/SettingsStore.js";
2
+ import { navigationRoutes } from "../../utils/navigationRoutes.js";
3
+ import { useSplitMode } from "../../stores/navigationTabs/useNavigationTabsStore.js";
4
+ import { Card } from "../Card/Card.js";
5
+ import { useSettings } from "../../stores/settings/useSettings.js";
6
+ import { SettingsPanelButton, SettingsPanelContainer, SettingsPanelTitle, SettingsPanelValue } from "./SettingsPanel.style.js";
7
+ import { bridgeSettingsPanelKeys, swapSettingsPanelKeys } from "./utils.js";
8
+ import { useNavigate } from "@tanstack/react-router";
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ import { useTranslation } from "react-i18next";
11
+ //#region src/components/SettingsPanel/SettingsPanel.tsx
12
+ const SettingsPanel = (props) => {
13
+ const { t } = useTranslation();
14
+ const navigate = useNavigate();
15
+ const splitMode = useSplitMode();
16
+ const { slippage, routePriority } = useSettings(["slippage", "routePriority"]);
17
+ const [enabledBridges, totalBridges, enabledExchanges, totalExchanges] = useSettingsStore((state) => [
18
+ Object.values(state._enabledBridges).filter(Boolean).length,
19
+ Object.values(state._enabledBridges).length,
20
+ Object.values(state._enabledExchanges).filter(Boolean).length,
21
+ Object.values(state._enabledExchanges).length
22
+ ]);
23
+ const rows = splitMode === "bridge" ? bridgeSettingsPanelKeys : swapSettingsPanelKeys;
24
+ const labelByKey = {
25
+ routePriority: t("settings.routePriority"),
26
+ exchanges: t("settings.enabledExchanges"),
27
+ bridges: t("settings.enabledBridges"),
28
+ slippage: t("settings.slippage")
29
+ };
30
+ const valueByKey = {
31
+ routePriority: routePriority === "FASTEST" ? t("settings.routePriorityOptions.fastest.title") : t("settings.routePriorityOptions.cheapest.title"),
32
+ exchanges: `${enabledExchanges}/${totalExchanges}`,
33
+ bridges: `${enabledBridges}/${totalBridges}`,
34
+ slippage: slippage ? `${slippage}%` : t("button.auto")
35
+ };
36
+ const handleClick = (key) => {
37
+ navigate({ to: `/${navigationRoutes.settings}/${navigationRoutes[key]}` });
38
+ };
39
+ return /* @__PURE__ */ jsx(SettingsPanelContainer, {
40
+ ...props,
41
+ children: rows.map((key) => /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(SettingsPanelButton, {
42
+ onClick: () => handleClick(key),
43
+ disableRipple: true,
44
+ children: [/* @__PURE__ */ jsx(SettingsPanelTitle, { children: labelByKey[key] }), /* @__PURE__ */ jsx(SettingsPanelValue, { children: valueByKey[key] })]
45
+ }) }, key))
46
+ });
47
+ };
48
+ //#endregion
49
+ export { SettingsPanel };
50
+
51
+ //# sourceMappingURL=SettingsPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsPanel.js","names":[],"sources":["../../../../src/components/SettingsPanel/SettingsPanel.tsx"],"sourcesContent":["import type { BoxProps } from '@mui/material'\nimport { useNavigate } from '@tanstack/react-router'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useSplitMode } from '../../stores/navigationTabs/useNavigationTabsStore.js'\nimport { useSettingsStore } from '../../stores/settings/SettingsStore.js'\nimport { useSettings } from '../../stores/settings/useSettings.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { Card } from '../Card/Card.js'\nimport {\n SettingsPanelButton,\n SettingsPanelContainer,\n SettingsPanelTitle,\n SettingsPanelValue,\n} from './SettingsPanel.style.js'\nimport {\n bridgeSettingsPanelKeys,\n type SettingsPanelKey,\n swapSettingsPanelKeys,\n} from './utils.js'\n\nexport const SettingsPanel: React.FC<BoxProps> = (props): JSX.Element => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const splitMode = useSplitMode()\n const { slippage, routePriority } = useSettings(['slippage', 'routePriority'])\n const [enabledBridges, totalBridges, enabledExchanges, totalExchanges] =\n useSettingsStore((state) => [\n Object.values(state._enabledBridges).filter(Boolean).length,\n Object.values(state._enabledBridges).length,\n Object.values(state._enabledExchanges).filter(Boolean).length,\n Object.values(state._enabledExchanges).length,\n ])\n\n const rows =\n splitMode === 'bridge' ? bridgeSettingsPanelKeys : swapSettingsPanelKeys\n\n const labelByKey: Record<SettingsPanelKey, string> = {\n routePriority: t('settings.routePriority'),\n exchanges: t('settings.enabledExchanges'),\n bridges: t('settings.enabledBridges'),\n slippage: t('settings.slippage'),\n }\n\n const valueByKey: Record<SettingsPanelKey, string> = {\n routePriority:\n routePriority === 'FASTEST'\n ? t('settings.routePriorityOptions.fastest.title')\n : t('settings.routePriorityOptions.cheapest.title'),\n exchanges: `${enabledExchanges}/${totalExchanges}`,\n bridges: `${enabledBridges}/${totalBridges}`,\n slippage: slippage ? `${slippage}%` : t('button.auto'),\n }\n\n const handleClick = (key: SettingsPanelKey) => {\n navigate({\n to: `/${navigationRoutes.settings}/${navigationRoutes[key]}`,\n })\n }\n\n return (\n <SettingsPanelContainer {...props}>\n {rows.map((key) => (\n <Card key={key}>\n <SettingsPanelButton onClick={() => handleClick(key)} disableRipple>\n <SettingsPanelTitle>{labelByKey[key]}</SettingsPanelTitle>\n <SettingsPanelValue>{valueByKey[key]}</SettingsPanelValue>\n </SettingsPanelButton>\n </Card>\n ))}\n </SettingsPanelContainer>\n )\n}\n"],"mappings":";;;;;;;;;;;AAqBA,MAAa,iBAAqC,UAAuB;CACvE,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,YAAY,aAAa;CAC/B,MAAM,EAAE,UAAU,kBAAkB,YAAY,CAAC,YAAY,eAAe,CAAC;CAC7E,MAAM,CAAC,gBAAgB,cAAc,kBAAkB,kBACrD,kBAAkB,UAAU;EAC1B,OAAO,OAAO,MAAM,eAAe,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC;EACrD,OAAO,OAAO,MAAM,eAAe,CAAC,CAAC;EACrC,OAAO,OAAO,MAAM,iBAAiB,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC;EACvD,OAAO,OAAO,MAAM,iBAAiB,CAAC,CAAC;CACzC,CAAC;CAEH,MAAM,OACJ,cAAc,WAAW,0BAA0B;CAErD,MAAM,aAA+C;EACnD,eAAe,EAAE,wBAAwB;EACzC,WAAW,EAAE,2BAA2B;EACxC,SAAS,EAAE,yBAAyB;EACpC,UAAU,EAAE,mBAAmB;CACjC;CAEA,MAAM,aAA+C;EACnD,eACE,kBAAkB,YACd,EAAE,6CAA6C,IAC/C,EAAE,8CAA8C;EACtD,WAAW,GAAG,iBAAiB,GAAG;EAClC,SAAS,GAAG,eAAe,GAAG;EAC9B,UAAU,WAAW,GAAG,SAAS,KAAK,EAAE,aAAa;CACvD;CAEA,MAAM,eAAe,QAA0B;EAC7C,SAAS,EACP,IAAI,IAAI,iBAAiB,SAAS,GAAG,iBAAiB,OACxD,CAAC;CACH;CAEA,OACE,oBAAC,wBAAD;EAAwB,GAAI;YACzB,KAAK,KAAK,QACT,oBAAC,MAAD,EAAA,UACE,qBAAC,qBAAD;GAAqB,eAAe,YAAY,GAAG;GAAG,eAAA;aAAtD,CACE,oBAAC,oBAAD,EAAA,UAAqB,WAAW,KAAyB,CAAA,GACzD,oBAAC,oBAAD,EAAA,UAAqB,WAAW,KAAyB,CAAA,CACtC;KACjB,GALK,GAKL,CACP;CACqB,CAAA;AAE5B"}
@@ -0,0 +1,33 @@
1
+ import { Box, ButtonBase, Typography, styled } from "@mui/material";
2
+ //#region src/components/SettingsPanel/SettingsPanel.style.tsx
3
+ const SettingsPanelContainer = styled(Box)(({ theme }) => ({
4
+ display: "flex",
5
+ flexDirection: "column",
6
+ gap: theme.spacing(1)
7
+ }));
8
+ const SettingsPanelButton = styled(ButtonBase)(({ theme }) => ({
9
+ display: "flex",
10
+ width: "100%",
11
+ justifyContent: "space-between",
12
+ alignItems: "center",
13
+ gap: theme.spacing(1),
14
+ padding: theme.spacing(2),
15
+ borderRadius: theme.vars.shape.borderRadius
16
+ }));
17
+ const SettingsPanelTitle = styled(Typography)(({ theme }) => ({
18
+ fontSize: 14,
19
+ lineHeight: 1,
20
+ fontWeight: 700,
21
+ color: theme.vars.palette.text.primary
22
+ }));
23
+ const SettingsPanelValue = styled(Typography)(({ theme }) => ({
24
+ fontSize: 14,
25
+ lineHeight: 1,
26
+ fontWeight: 500,
27
+ color: theme.vars.palette.text.secondary,
28
+ whiteSpace: "nowrap"
29
+ }));
30
+ //#endregion
31
+ export { SettingsPanelButton, SettingsPanelContainer, SettingsPanelTitle, SettingsPanelValue };
32
+
33
+ //# sourceMappingURL=SettingsPanel.style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SettingsPanel.style.js","names":[],"sources":["../../../../src/components/SettingsPanel/SettingsPanel.style.tsx"],"sourcesContent":["import { Box, ButtonBase, styled, Typography } from '@mui/material'\nimport type React from 'react'\n\nexport const SettingsPanelContainer: React.FC<\n React.ComponentProps<typeof Box>\n> = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1),\n}))\n\nexport const SettingsPanelButton: React.FC<\n React.ComponentProps<typeof ButtonBase>\n> = styled(ButtonBase)(({ theme }) => ({\n display: 'flex',\n width: '100%',\n justifyContent: 'space-between',\n alignItems: 'center',\n gap: theme.spacing(1),\n padding: theme.spacing(2),\n borderRadius: theme.vars.shape.borderRadius,\n}))\n\nexport const SettingsPanelTitle: React.FC<\n React.ComponentProps<typeof Typography>\n> = styled(Typography)(({ theme }) => ({\n fontSize: 14,\n lineHeight: 1,\n fontWeight: 700,\n color: theme.vars.palette.text.primary,\n}))\n\nexport const SettingsPanelValue: React.FC<\n React.ComponentProps<typeof Typography>\n> = styled(Typography)(({ theme }) => ({\n fontSize: 14,\n lineHeight: 1,\n fontWeight: 500,\n color: theme.vars.palette.text.secondary,\n whiteSpace: 'nowrap',\n}))\n"],"mappings":";;AAGA,MAAa,yBAET,OAAO,GAAG,CAAC,EAAE,EAAE,aAAa;CAC9B,SAAS;CACT,eAAe;CACf,KAAK,MAAM,QAAQ,CAAC;AACtB,EAAE;AAEF,MAAa,sBAET,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACrC,SAAS;CACT,OAAO;CACP,gBAAgB;CAChB,YAAY;CACZ,KAAK,MAAM,QAAQ,CAAC;CACpB,SAAS,MAAM,QAAQ,CAAC;CACxB,cAAc,MAAM,KAAK,MAAM;AACjC,EAAE;AAEF,MAAa,qBAET,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACrC,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,OAAO,MAAM,KAAK,QAAQ,KAAK;AACjC,EAAE;AAEF,MAAa,qBAET,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACrC,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,OAAO,MAAM,KAAK,QAAQ,KAAK;CAC/B,YAAY;AACd,EAAE"}
@@ -0,0 +1,14 @@
1
+ //#region src/components/SettingsPanel/utils.ts
2
+ /** Navigation tabs that surface the settings panel on the main page. */
3
+ const advancedNavigationTabKeys = ["swap-advanced", "bridge-advanced"];
4
+ const swapSettingsPanelKeys = ["slippage", "exchanges"];
5
+ const bridgeSettingsPanelKeys = [
6
+ "routePriority",
7
+ "slippage",
8
+ "bridges",
9
+ "exchanges"
10
+ ];
11
+ //#endregion
12
+ export { advancedNavigationTabKeys, bridgeSettingsPanelKeys, swapSettingsPanelKeys };
13
+
14
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../../src/components/SettingsPanel/utils.ts"],"sourcesContent":["import type { NavigationTabKey } from '../../types/widget.js'\n\nexport type SettingsPanelKey =\n | 'routePriority'\n | 'exchanges'\n | 'bridges'\n | 'slippage'\n\n/** Navigation tabs that surface the settings panel on the main page. */\nexport const advancedNavigationTabKeys: NavigationTabKey[] = [\n 'swap-advanced',\n 'bridge-advanced',\n]\n\n// Keys are ordered to match the settings page layout.\n// Swap is same-chain, so route priority and bridges are not relevant.\nexport const swapSettingsPanelKeys: SettingsPanelKey[] = [\n 'slippage',\n 'exchanges',\n]\n\nexport const bridgeSettingsPanelKeys: SettingsPanelKey[] = [\n 'routePriority',\n 'slippage',\n 'bridges',\n 'exchanges',\n]\n"],"mappings":";;AASA,MAAa,4BAAgD,CAC3D,iBACA,iBACF;AAIA,MAAa,wBAA4C,CACvD,YACA,WACF;AAEA,MAAa,0BAA8C;CACzD;CACA;CACA;CACA;AACF"}
@@ -0,0 +1,50 @@
1
+ import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
2
+ import { useAvailableChains } from "../../hooks/useAvailableChains.js";
3
+ import { useFieldActions } from "../../stores/form/useFieldActions.js";
4
+ import { useToAddressReset } from "../../hooks/useToAddressReset.js";
5
+ import { useToAddressAutoPopulate } from "../../hooks/useToAddressAutoPopulate.js";
6
+ import { SwapButtonContainer, SwapIconCard } from "./SwapButton.style.js";
7
+ import { jsx } from "react/jsx-runtime";
8
+ import { useTranslation } from "react-i18next";
9
+ import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
10
+ //#region src/components/SwapButton/SwapButton.tsx
11
+ const SwapButton = ({ sx, ...props }) => {
12
+ const { t } = useTranslation();
13
+ const { mode } = useWidgetConfig();
14
+ const { setFieldValue, getFieldValues } = useFieldActions();
15
+ const { getChainById } = useAvailableChains();
16
+ const { tryResetToAddress } = useToAddressReset();
17
+ const autoPopulateToAddress = useToAddressAutoPopulate();
18
+ const handleClick = () => {
19
+ const [fromChainId, fromToken, toChainId, toToken, toAddress, toAmount] = getFieldValues("fromChain", "fromToken", "toChain", "toToken", "toAddress", "toAmount");
20
+ setFieldValue("fromAmount", mode === "limit" && toAmount ? toAmount : "", { isTouched: true });
21
+ setFieldValue("fromChain", toChainId, { isTouched: true });
22
+ setFieldValue("fromToken", toToken, { isTouched: true });
23
+ setFieldValue("toChain", fromChainId, { isTouched: true });
24
+ setFieldValue("toToken", fromToken, { isTouched: true });
25
+ if (autoPopulateToAddress({
26
+ formType: "from",
27
+ selectedToAddress: toAddress,
28
+ selectedChainId: toChainId,
29
+ selectedOppositeChainId: fromChainId,
30
+ selectedOppositeTokenAddress: fromToken
31
+ })) return;
32
+ const toChain = getChainById(fromChainId);
33
+ if (toChain) tryResetToAddress(toChain);
34
+ };
35
+ return /* @__PURE__ */ jsx(SwapButtonContainer, {
36
+ sx,
37
+ ...props,
38
+ children: /* @__PURE__ */ jsx(SwapIconCard, {
39
+ component: "button",
40
+ onClick: handleClick,
41
+ "aria-label": t("button.swap"),
42
+ "data-testid": "widget-swap-tokens-button",
43
+ children: /* @__PURE__ */ jsx(ArrowDownwardIcon, { fontSize: "inherit" })
44
+ })
45
+ });
46
+ };
47
+ //#endregion
48
+ export { SwapButton };
49
+
50
+ //# sourceMappingURL=SwapButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwapButton.js","names":["ArrowDownward"],"sources":["../../../../src/components/SwapButton/SwapButton.tsx"],"sourcesContent":["import ArrowDownward from '@mui/icons-material/ArrowDownward'\nimport type { BoxProps } from '@mui/material'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useAvailableChains } from '../../hooks/useAvailableChains.js'\nimport { useToAddressAutoPopulate } from '../../hooks/useToAddressAutoPopulate.js'\nimport { useToAddressReset } from '../../hooks/useToAddressReset.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport { useFieldActions } from '../../stores/form/useFieldActions.js'\nimport { SwapButtonContainer, SwapIconCard } from './SwapButton.style.js'\n\nexport const SwapButton: React.FC<BoxProps> = ({\n sx,\n ...props\n}): JSX.Element => {\n const { t } = useTranslation()\n const { mode } = useWidgetConfig()\n const { setFieldValue, getFieldValues } = useFieldActions()\n const { getChainById } = useAvailableChains()\n const { tryResetToAddress } = useToAddressReset()\n const autoPopulateToAddress = useToAddressAutoPopulate()\n\n const handleClick = (): void => {\n const [fromChainId, fromToken, toChainId, toToken, toAddress, toAmount] =\n getFieldValues(\n 'fromChain',\n 'fromToken',\n 'toChain',\n 'toToken',\n 'toAddress',\n 'toAmount'\n )\n const newFromAmount =\n mode === 'limit' && toAmount ? (toAmount as string) : ''\n setFieldValue('fromAmount', newFromAmount, { isTouched: true })\n setFieldValue('fromChain', toChainId, { isTouched: true })\n setFieldValue('fromToken', toToken, { isTouched: true })\n setFieldValue('toChain', fromChainId, { isTouched: true })\n setFieldValue('toToken', fromToken, { isTouched: true })\n\n const autoPopulatedToAddress = autoPopulateToAddress({\n formType: 'from',\n selectedToAddress: toAddress,\n selectedChainId: toChainId,\n selectedOppositeChainId: fromChainId,\n selectedOppositeTokenAddress: fromToken,\n })\n\n if (autoPopulatedToAddress) {\n return\n }\n\n const toChain = getChainById(fromChainId)\n if (toChain) {\n tryResetToAddress(toChain)\n }\n }\n\n return (\n <SwapButtonContainer sx={sx} {...props}>\n <SwapIconCard\n component=\"button\"\n onClick={handleClick}\n aria-label={t('button.swap')}\n data-testid=\"widget-swap-tokens-button\"\n >\n <ArrowDownward fontSize=\"inherit\" />\n </SwapIconCard>\n </SwapButtonContainer>\n )\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAa,cAAkC,EAC7C,IACA,GAAG,YACc;CACjB,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,EAAE,SAAS,gBAAgB;CACjC,MAAM,EAAE,eAAe,mBAAmB,gBAAgB;CAC1D,MAAM,EAAE,iBAAiB,mBAAmB;CAC5C,MAAM,EAAE,sBAAsB,kBAAkB;CAChD,MAAM,wBAAwB,yBAAyB;CAEvD,MAAM,oBAA0B;EAC9B,MAAM,CAAC,aAAa,WAAW,WAAW,SAAS,WAAW,YAC5D,eACE,aACA,aACA,WACA,WACA,aACA,UACF;EAGF,cAAc,cADZ,SAAS,WAAW,WAAY,WAAsB,IACb,EAAE,WAAW,KAAK,CAAC;EAC9D,cAAc,aAAa,WAAW,EAAE,WAAW,KAAK,CAAC;EACzD,cAAc,aAAa,SAAS,EAAE,WAAW,KAAK,CAAC;EACvD,cAAc,WAAW,aAAa,EAAE,WAAW,KAAK,CAAC;EACzD,cAAc,WAAW,WAAW,EAAE,WAAW,KAAK,CAAC;EAUvD,IAR+B,sBAAsB;GACnD,UAAU;GACV,mBAAmB;GACnB,iBAAiB;GACjB,yBAAyB;GACzB,8BAA8B;EAChC,CAEyB,GACvB;EAGF,MAAM,UAAU,aAAa,WAAW;EACxC,IAAI,SACF,kBAAkB,OAAO;CAE7B;CAEA,OACE,oBAAC,qBAAD;EAAyB;EAAI,GAAI;YAC/B,oBAAC,cAAD;GACE,WAAU;GACV,SAAS;GACT,cAAY,EAAE,aAAa;GAC3B,eAAY;aAEZ,oBAACA,mBAAD,EAAe,UAAS,UAAW,CAAA;EACvB,CAAA;CACK,CAAA;AAEzB"}
@@ -0,0 +1,24 @@
1
+ import { Card as Card$1 } from "../Card/Card.js";
2
+ import { Box, styled } from "@mui/material";
3
+ //#region src/components/SwapButton/SwapButton.style.tsx
4
+ const swapButtonZIndex = 1110;
5
+ const SwapIconCard = styled(Card$1)(({ theme }) => ({
6
+ height: 32,
7
+ width: 32,
8
+ fontSize: 16,
9
+ display: "flex",
10
+ alignItems: "center",
11
+ justifyContent: "center",
12
+ borderRadius: theme.vars.shape.borderRadiusTertiary,
13
+ zIndex: swapButtonZIndex
14
+ }));
15
+ const SwapButtonContainer = styled(Box)(({ theme }) => ({
16
+ display: "flex",
17
+ justifyContent: "center",
18
+ alignItems: "center",
19
+ margin: theme.spacing(-1.5)
20
+ }));
21
+ //#endregion
22
+ export { SwapButtonContainer, SwapIconCard };
23
+
24
+ //# sourceMappingURL=SwapButton.style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwapButton.style.js","names":["Card"],"sources":["../../../../src/components/SwapButton/SwapButton.style.tsx"],"sourcesContent":["import { Box, styled } from '@mui/material'\nimport type React from 'react'\nimport { Card } from '../Card/Card.js'\n\n// Sits just above MUI's appBar layer (1100) so the swap icon stays on top of the\n// two overlapping amount cards it bridges.\nconst swapButtonZIndex = 1110\n\nexport const SwapIconCard: React.FC<React.ComponentProps<typeof Card>> = styled(\n Card\n)(({ theme }) => ({\n height: 32,\n width: 32,\n fontSize: 16,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: theme.vars.shape.borderRadiusTertiary,\n zIndex: swapButtonZIndex,\n}))\n\nexport const SwapButtonContainer: React.FC<React.ComponentProps<typeof Box>> =\n styled(Box)(({ theme }) => ({\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n margin: theme.spacing(-1.5),\n }))\n"],"mappings":";;;AAMA,MAAM,mBAAmB;AAEzB,MAAa,eAA4D,OACvEA,MACF,CAAC,EAAE,EAAE,aAAa;CAChB,QAAQ;CACR,OAAO;CACP,UAAU;CACV,SAAS;CACT,YAAY;CACZ,gBAAgB;CAChB,cAAc,MAAM,KAAK,MAAM;CAC/B,QAAQ;AACV,EAAE;AAEF,MAAa,sBACX,OAAO,GAAG,CAAC,EAAE,EAAE,aAAa;CAC1B,SAAS;CACT,gBAAgB;CAChB,YAAY;CACZ,QAAQ,MAAM,QAAQ,IAAI;AAC5B,EAAE"}
@@ -0,0 +1,52 @@
1
+ import { useWidgetConfig } from "../../providers/WidgetProvider/WidgetProvider.js";
2
+ import { navigationRoutes } from "../../utils/navigationRoutes.js";
3
+ import { FormKeyHelper } from "../../stores/form/types.js";
4
+ import { useFieldValues } from "../../stores/form/useFieldValues.js";
5
+ import { useChain } from "../../hooks/useChain.js";
6
+ import { useToken } from "../../hooks/useToken.js";
7
+ import { AvatarBadgedDefault } from "../Avatar/Avatar.js";
8
+ import { TokenAvatar } from "../Avatar/TokenAvatar.js";
9
+ import { TokenPill, TokenPillLabel, TokenPillSymbol, TokenSelectPill } from "./TokenPillButton.style.js";
10
+ import { useNavigate } from "@tanstack/react-router";
11
+ import { jsx, jsxs } from "react/jsx-runtime";
12
+ import { useTranslation } from "react-i18next";
13
+ //#region src/components/TokenPillButton/TokenPillButton.tsx
14
+ const TokenPillButton = ({ formType }) => {
15
+ const { t } = useTranslation();
16
+ const navigate = useNavigate();
17
+ const { disabledUI, mode } = useWidgetConfig();
18
+ const tokenKey = FormKeyHelper.getTokenKey(formType);
19
+ const [chainId, tokenAddress] = useFieldValues(FormKeyHelper.getChainKey(formType), tokenKey);
20
+ const { chain } = useChain(chainId);
21
+ const { token } = useToken(chainId, tokenAddress);
22
+ const isSelected = !!(chain && token);
23
+ const handleClick = () => {
24
+ navigate({ to: formType === "from" ? navigationRoutes.fromToken : mode === "refuel" ? navigationRoutes.toTokenNative : navigationRoutes.toToken });
25
+ };
26
+ const isDisabled = !!disabledUI?.[tokenKey];
27
+ const testId = `widget-${formType}-token-button`;
28
+ if (isSelected) return /* @__PURE__ */ jsxs(TokenPill, {
29
+ onClick: isDisabled ? void 0 : handleClick,
30
+ disabled: isDisabled,
31
+ "data-testid": testId,
32
+ children: [/* @__PURE__ */ jsx(TokenAvatar, {
33
+ token,
34
+ chain,
35
+ tokenAvatarSize: 24,
36
+ chainAvatarSize: 12
37
+ }), /* @__PURE__ */ jsx(TokenPillSymbol, { children: token.symbol })]
38
+ });
39
+ return /* @__PURE__ */ jsxs(TokenSelectPill, {
40
+ onClick: isDisabled ? void 0 : handleClick,
41
+ "data-testid": testId,
42
+ children: [/* @__PURE__ */ jsx(AvatarBadgedDefault, {
43
+ chain,
44
+ avatarSize: 24,
45
+ badgeSize: 12
46
+ }), /* @__PURE__ */ jsx(TokenPillLabel, { children: t("main.select") })]
47
+ });
48
+ };
49
+ //#endregion
50
+ export { TokenPillButton };
51
+
52
+ //# sourceMappingURL=TokenPillButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenPillButton.js","names":[],"sources":["../../../../src/components/TokenPillButton/TokenPillButton.tsx"],"sourcesContent":["import { useNavigate } from '@tanstack/react-router'\nimport type { JSX } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { useChain } from '../../hooks/useChain.js'\nimport { useToken } from '../../hooks/useToken.js'\nimport { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormTypeProps } from '../../stores/form/types.js'\nimport { FormKeyHelper } from '../../stores/form/types.js'\nimport { useFieldValues } from '../../stores/form/useFieldValues.js'\nimport type { DisabledUIConfig } from '../../types/widget.js'\nimport { navigationRoutes } from '../../utils/navigationRoutes.js'\nimport { AvatarBadgedDefault } from '../Avatar/Avatar.js'\nimport { TokenAvatar } from '../Avatar/TokenAvatar.js'\nimport {\n TokenPill,\n TokenPillLabel,\n TokenPillSymbol,\n TokenSelectPill,\n} from './TokenPillButton.style.js'\n\nexport const TokenPillButton: React.FC<FormTypeProps> = ({\n formType,\n}): JSX.Element => {\n const { t } = useTranslation()\n const navigate = useNavigate()\n const { disabledUI, mode } = useWidgetConfig()\n\n const tokenKey = FormKeyHelper.getTokenKey(formType)\n const [chainId, tokenAddress] = useFieldValues(\n FormKeyHelper.getChainKey(formType),\n tokenKey\n )\n\n const { chain } = useChain(chainId)\n const { token } = useToken(chainId, tokenAddress)\n\n const isSelected = !!(chain && token)\n\n const handleClick = (): void => {\n navigate({\n to:\n formType === 'from'\n ? navigationRoutes.fromToken\n : mode === 'refuel'\n ? navigationRoutes.toTokenNative\n : navigationRoutes.toToken,\n })\n }\n\n const isDisabled = !!disabledUI?.[tokenKey as keyof DisabledUIConfig]\n\n const testId = `widget-${formType}-token-button`\n\n if (isSelected) {\n return (\n <TokenPill\n onClick={isDisabled ? undefined : handleClick}\n disabled={isDisabled}\n data-testid={testId}\n >\n <TokenAvatar\n token={token}\n chain={chain}\n tokenAvatarSize={24}\n chainAvatarSize={12}\n />\n <TokenPillSymbol>{token.symbol}</TokenPillSymbol>\n </TokenPill>\n )\n }\n\n return (\n <TokenSelectPill\n onClick={isDisabled ? undefined : handleClick}\n data-testid={testId}\n >\n <AvatarBadgedDefault chain={chain} avatarSize={24} badgeSize={12} />\n <TokenPillLabel>{t('main.select')}</TokenPillLabel>\n </TokenSelectPill>\n )\n}\n"],"mappings":";;;;;;;;;;;;;AAoBA,MAAa,mBAA4C,EACvD,eACiB;CACjB,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,EAAE,YAAY,SAAS,gBAAgB;CAE7C,MAAM,WAAW,cAAc,YAAY,QAAQ;CACnD,MAAM,CAAC,SAAS,gBAAgB,eAC9B,cAAc,YAAY,QAAQ,GAClC,QACF;CAEA,MAAM,EAAE,UAAU,SAAS,OAAO;CAClC,MAAM,EAAE,UAAU,SAAS,SAAS,YAAY;CAEhD,MAAM,aAAa,CAAC,EAAE,SAAS;CAE/B,MAAM,oBAA0B;EAC9B,SAAS,EACP,IACE,aAAa,SACT,iBAAiB,YACjB,SAAS,WACP,iBAAiB,gBACjB,iBAAiB,QAC3B,CAAC;CACH;CAEA,MAAM,aAAa,CAAC,CAAC,aAAa;CAElC,MAAM,SAAS,UAAU,SAAS;CAElC,IAAI,YACF,OACE,qBAAC,WAAD;EACE,SAAS,aAAa,KAAA,IAAY;EAClC,UAAU;EACV,eAAa;YAHf,CAKE,oBAAC,aAAD;GACS;GACA;GACP,iBAAiB;GACjB,iBAAiB;EAClB,CAAA,GACD,oBAAC,iBAAD,EAAA,UAAkB,MAAM,OAAwB,CAAA,CACvC;;CAIf,OACE,qBAAC,iBAAD;EACE,SAAS,aAAa,KAAA,IAAY;EAClC,eAAa;YAFf,CAIE,oBAAC,qBAAD;GAA4B;GAAO,YAAY;GAAI,WAAW;EAAK,CAAA,GACnE,oBAAC,gBAAD,EAAA,UAAiB,EAAE,aAAa,EAAkB,CAAA,CACnC;;AAErB"}
@@ -0,0 +1,39 @@
1
+ import { Button, Typography, styled } from "@mui/material";
2
+ //#region src/components/TokenPillButton/TokenPillButton.style.tsx
3
+ const pillLayout = (theme) => ({
4
+ height: 36,
5
+ borderRadius: theme.vars.shape.borderRadiusSecondary,
6
+ padding: theme.spacing(.5, 1),
7
+ display: "flex",
8
+ alignItems: "center",
9
+ gap: theme.spacing(1),
10
+ whiteSpace: "nowrap",
11
+ flexShrink: 0
12
+ });
13
+ const TokenPill = styled(Button)(({ theme }) => ({
14
+ ...pillLayout(theme),
15
+ backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 4%, transparent)`,
16
+ border: "1px solid transparent",
17
+ transition: theme.transitions.create(["background-color"], { duration: theme.transitions.duration.short }),
18
+ "&:hover": { backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 8%, transparent)` }
19
+ }));
20
+ const TokenSelectPill = styled(TokenPill)({ minWidth: 0 });
21
+ const TokenPillSymbol = styled(Typography)(({ theme }) => ({
22
+ fontSize: 14,
23
+ fontWeight: 700,
24
+ lineHeight: "18px",
25
+ overflow: "hidden",
26
+ textOverflow: "ellipsis",
27
+ whiteSpace: "nowrap",
28
+ color: theme.vars.palette.text.primary
29
+ }));
30
+ const TokenPillLabel = styled(Typography)(({ theme }) => ({
31
+ fontSize: 16,
32
+ fontWeight: 700,
33
+ lineHeight: "20px",
34
+ color: theme.vars.palette.text.secondary
35
+ }));
36
+ //#endregion
37
+ export { TokenPill, TokenPillLabel, TokenPillSymbol, TokenSelectPill };
38
+
39
+ //# sourceMappingURL=TokenPillButton.style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenPillButton.style.js","names":[],"sources":["../../../../src/components/TokenPillButton/TokenPillButton.style.tsx"],"sourcesContent":["import { Button, styled, type Theme, Typography } from '@mui/material'\nimport type React from 'react'\n\nconst pillLayout = (theme: Theme) => ({\n height: 36,\n borderRadius: theme.vars.shape.borderRadiusSecondary,\n padding: theme.spacing(0.5, 1),\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n whiteSpace: 'nowrap',\n flexShrink: 0,\n})\n\nexport const TokenPill: React.FC<React.ComponentProps<typeof Button>> = styled(\n Button\n)(({ theme }) => ({\n ...pillLayout(theme),\n backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 4%, transparent)`,\n border: '1px solid transparent',\n transition: theme.transitions.create(['background-color'], {\n duration: theme.transitions.duration.short,\n }),\n '&:hover': {\n backgroundColor: `color-mix(in srgb, ${theme.vars.palette.common.onBackground} 8%, transparent)`,\n },\n}))\n\nexport const TokenSelectPill: React.FC<React.ComponentProps<typeof Button>> =\n styled(TokenPill)({ minWidth: 0 })\n\nexport const TokenPillSymbol: React.FC<\n React.ComponentProps<typeof Typography>\n> = styled(Typography)(({ theme }) => ({\n fontSize: 14,\n fontWeight: 700,\n lineHeight: '18px',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: theme.vars.palette.text.primary,\n}))\n\nexport const TokenPillLabel: React.FC<React.ComponentProps<typeof Typography>> =\n styled(Typography)(({ theme }) => ({\n fontSize: 16,\n fontWeight: 700,\n lineHeight: '20px',\n color: theme.vars.palette.text.secondary,\n }))\n"],"mappings":";;AAGA,MAAM,cAAc,WAAkB;CACpC,QAAQ;CACR,cAAc,MAAM,KAAK,MAAM;CAC/B,SAAS,MAAM,QAAQ,IAAK,CAAC;CAC7B,SAAS;CACT,YAAY;CACZ,KAAK,MAAM,QAAQ,CAAC;CACpB,YAAY;CACZ,YAAY;AACd;AAEA,MAAa,YAA2D,OACtE,MACF,CAAC,EAAE,EAAE,aAAa;CAChB,GAAG,WAAW,KAAK;CACnB,iBAAiB,sBAAsB,MAAM,KAAK,QAAQ,OAAO,aAAa;CAC9E,QAAQ;CACR,YAAY,MAAM,YAAY,OAAO,CAAC,kBAAkB,GAAG,EACzD,UAAU,MAAM,YAAY,SAAS,MACvC,CAAC;CACD,WAAW,EACT,iBAAiB,sBAAsB,MAAM,KAAK,QAAQ,OAAO,aAAa,mBAChF;AACF,EAAE;AAEF,MAAa,kBACX,OAAO,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;AAEnC,MAAa,kBAET,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACrC,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,UAAU;CACV,cAAc;CACd,YAAY;CACZ,OAAO,MAAM,KAAK,QAAQ,KAAK;AACjC,EAAE;AAEF,MAAa,iBACX,OAAO,UAAU,CAAC,EAAE,EAAE,aAAa;CACjC,UAAU;CACV,YAAY;CACZ,YAAY;CACZ,OAAO,MAAM,KAAK,QAAQ,KAAK;AACjC,EAAE"}
@@ -1,6 +1,6 @@
1
1
  //#region src/config/version.d.ts
2
2
  declare const name = "@lifi/widget";
3
- declare const version = "4.1.0";
3
+ declare const version = "4.3.0";
4
4
  //#endregion
5
5
  export { name, version };
6
6
  //# sourceMappingURL=version.d.ts.map
@@ -1,6 +1,6 @@
1
1
  //#region src/config/version.ts
2
2
  const name = "@lifi/widget";
3
- const version = "4.1.0";
3
+ const version = "4.3.0";
4
4
  //#endregion
5
5
  export { name, version };
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":[],"sources":["../../../src/config/version.ts"],"sourcesContent":["export const name = '@lifi/widget'\nexport const version = '4.1.0'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
1
+ {"version":3,"file":"version.js","names":[],"sources":["../../../src/config/version.ts"],"sourcesContent":["export const name = '@lifi/widget'\nexport const version = '4.3.0'\n"],"mappings":";AAAA,MAAa,OAAO;AACpB,MAAa,UAAU"}
@@ -24,7 +24,8 @@ function useChainSearch(formType, listRef, inputRef) {
24
24
  setCurrentChain(chain.id);
25
25
  }, [setCurrentChain]),
26
26
  onChange: useCallback(() => {
27
- debouncedFilterChains(inputRef.current?.value || "");
27
+ const value = inputRef.current?.value || "";
28
+ debouncedFilterChains(value);
28
29
  }, [debouncedFilterChains, inputRef]),
29
30
  onClear: useCallback(() => {
30
31
  if (inputRef.current) inputRef.current.value = "";
@@ -1 +1 @@
1
- {"version":3,"file":"useChainSearch.js","names":[],"sources":["../../../src/hooks/useChainSearch.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { debounce } from '@mui/material'\nimport type { RefObject } from 'react'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useChainSelect } from '../components/ChainSelect/useChainSelect.js'\nimport { FormKeyHelper, type FormType } from '../stores/form/types.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\n\nexport function useChainSearch(\n formType: FormType,\n listRef: RefObject<HTMLDivElement | null>,\n inputRef: RefObject<HTMLInputElement | null>\n): {\n filteredChains: ExtendedChain[]\n isLoading: boolean\n selectedChainId: number | undefined\n onSelectChainFallback: (chain: ExtendedChain) => void\n onChange: () => void\n onClear: () => void\n} {\n const { chains, isLoading, setCurrentChain } = useChainSelect(formType)\n const [selectedChainId] = useFieldValues(FormKeyHelper.getChainKey(formType))\n const [debouncedSearchValue, setDebouncedSearchValue] = useState('')\n\n const filteredChains = useMemo(() => {\n const value = debouncedSearchValue.toLowerCase()\n return value\n ? (chains?.filter((chain) => chain.name.toLowerCase().includes(value)) ??\n [])\n : (chains ?? [])\n }, [chains, debouncedSearchValue])\n\n const debouncedFilterChains = useMemo(\n () =>\n debounce((value: string) => {\n setDebouncedSearchValue(value)\n listRef.current?.scrollTo(0, 0)\n }, 250),\n [listRef]\n )\n\n const onSelectChainFallback = useCallback(\n (chain: ExtendedChain) => {\n setCurrentChain(chain.id)\n },\n [setCurrentChain]\n )\n\n const onChange = useCallback(() => {\n const value = inputRef.current?.value || ''\n debouncedFilterChains(value)\n }, [debouncedFilterChains, inputRef])\n\n const onClear = useCallback(() => {\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n setDebouncedSearchValue('')\n listRef.current?.scrollTo(0, 0)\n }, [inputRef, listRef])\n\n return {\n filteredChains,\n isLoading,\n selectedChainId,\n onSelectChainFallback,\n onChange,\n onClear,\n }\n}\n"],"mappings":";;;;;;AAQA,SAAgB,eACd,UACA,SACA,UAQA;CACA,MAAM,EAAE,QAAQ,WAAW,oBAAoB,eAAe,QAAQ;CACtE,MAAM,CAAC,mBAAmB,eAAe,cAAc,YAAY,QAAQ,CAAC;CAC5E,MAAM,CAAC,sBAAsB,2BAA2B,SAAS,EAAE;CAEnE,MAAM,iBAAiB,cAAc;EACnC,MAAM,QAAQ,qBAAqB,YAAY;EAC/C,OAAO,QACF,QAAQ,QAAQ,UAAU,MAAM,KAAK,YAAY,CAAC,CAAC,SAAS,KAAK,CAAC,KACjE,CAAC,IACF,UAAU,CAAC;CAClB,GAAG,CAAC,QAAQ,oBAAoB,CAAC;CAEjC,MAAM,wBAAwB,cAE1B,UAAU,UAAkB;EAC1B,wBAAwB,KAAK;EAC7B,QAAQ,SAAS,SAAS,GAAG,CAAC;CAChC,GAAG,GAAG,GACR,CAAC,OAAO,CACV;CAsBA,OAAO;EACL;EACA;EACA;EACA,uBAxB4B,aAC3B,UAAyB;GACxB,gBAAgB,MAAM,EAAE;EAC1B,GACA,CAAC,eAAe,CAoBI;EACpB,UAlBe,kBAAkB;GAEjC,sBADc,SAAS,SAAS,SAAS,EACd;EAC7B,GAAG,CAAC,uBAAuB,QAAQ,CAe1B;EACP,SAdc,kBAAkB;GAChC,IAAI,SAAS,SACX,SAAS,QAAQ,QAAQ;GAE3B,wBAAwB,EAAE;GAC1B,QAAQ,SAAS,SAAS,GAAG,CAAC;EAChC,GAAG,CAAC,UAAU,OAAO,CAQb;CACR;AACF"}
1
+ {"version":3,"file":"useChainSearch.js","names":[],"sources":["../../../src/hooks/useChainSearch.ts"],"sourcesContent":["import type { ExtendedChain } from '@lifi/sdk'\nimport { debounce } from '@mui/material'\nimport type { RefObject } from 'react'\nimport { useCallback, useMemo, useState } from 'react'\nimport { useChainSelect } from '../components/ChainSelect/useChainSelect.js'\nimport { FormKeyHelper, type FormType } from '../stores/form/types.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\n\nexport function useChainSearch(\n formType: FormType,\n listRef: RefObject<HTMLDivElement | null>,\n inputRef: RefObject<HTMLInputElement | null>\n): {\n filteredChains: ExtendedChain[]\n isLoading: boolean\n selectedChainId: number | undefined\n onSelectChainFallback: (chain: ExtendedChain) => void\n onChange: () => void\n onClear: () => void\n} {\n const { chains, isLoading, setCurrentChain } = useChainSelect(formType)\n const [selectedChainId] = useFieldValues(FormKeyHelper.getChainKey(formType))\n const [debouncedSearchValue, setDebouncedSearchValue] = useState('')\n\n const filteredChains = useMemo(() => {\n const value = debouncedSearchValue.toLowerCase()\n return value\n ? (chains?.filter((chain) => chain.name.toLowerCase().includes(value)) ??\n [])\n : (chains ?? [])\n }, [chains, debouncedSearchValue])\n\n const debouncedFilterChains = useMemo(\n () =>\n debounce((value: string) => {\n setDebouncedSearchValue(value)\n listRef.current?.scrollTo(0, 0)\n }, 250),\n [listRef]\n )\n\n const onSelectChainFallback = useCallback(\n (chain: ExtendedChain) => {\n setCurrentChain(chain.id)\n },\n [setCurrentChain]\n )\n\n const onChange = useCallback(() => {\n const value = inputRef.current?.value || ''\n debouncedFilterChains(value)\n }, [debouncedFilterChains, inputRef])\n\n const onClear = useCallback(() => {\n if (inputRef.current) {\n inputRef.current.value = ''\n }\n setDebouncedSearchValue('')\n listRef.current?.scrollTo(0, 0)\n }, [inputRef, listRef])\n\n return {\n filteredChains,\n isLoading,\n selectedChainId,\n onSelectChainFallback,\n onChange,\n onClear,\n }\n}\n"],"mappings":";;;;;;AAQA,SAAgB,eACd,UACA,SACA,UAQA;CACA,MAAM,EAAE,QAAQ,WAAW,oBAAoB,eAAe,QAAQ;CACtE,MAAM,CAAC,mBAAmB,eAAe,cAAc,YAAY,QAAQ,CAAC;CAC5E,MAAM,CAAC,sBAAsB,2BAA2B,SAAS,EAAE;CAEnE,MAAM,iBAAiB,cAAc;EACnC,MAAM,QAAQ,qBAAqB,YAAY;EAC/C,OAAO,QACF,QAAQ,QAAQ,UAAU,MAAM,KAAK,YAAY,CAAC,CAAC,SAAS,KAAK,CAAC,KACjE,CAAC,IACF,UAAU,CAAC;CAClB,GAAG,CAAC,QAAQ,oBAAoB,CAAC;CAEjC,MAAM,wBAAwB,cAE1B,UAAU,UAAkB;EAC1B,wBAAwB,KAAK;EAC7B,QAAQ,SAAS,SAAS,GAAG,CAAC;CAChC,GAAG,GAAG,GACR,CAAC,OAAO,CACV;CAsBA,OAAO;EACL;EACA;EACA;EACA,uBAxB4B,aAC3B,UAAyB;GACxB,gBAAgB,MAAM,EAAE;EAC1B,GACA,CAAC,eAAe,CAoBI;EACpB,UAlBe,kBAAkB;GACjC,MAAM,QAAQ,SAAS,SAAS,SAAS;GACzC,sBAAsB,KAAK;EAC7B,GAAG,CAAC,uBAAuB,QAAQ,CAe1B;EACP,SAdc,kBAAkB;GAChC,IAAI,SAAS,SACX,SAAS,QAAQ,QAAQ;GAE3B,wBAAwB,EAAE;GAC1B,QAAQ,SAAS,SAAS,GAAG,CAAC;EAChC,GAAG,CAAC,UAAU,OAAO,CAQb;CACR;AACF"}
@@ -1,6 +1,7 @@
1
1
  import { getConfigItemSets, isFormItemAllowed } from "../utils/item.js";
2
2
  import { useWidgetConfig } from "../providers/WidgetProvider/WidgetProvider.js";
3
3
  import { useSDKClient } from "../providers/SDKClientProvider.js";
4
+ import { getVerifiedTokensSets } from "../utils/token.js";
4
5
  import { isSupportedToken } from "../utils/tokenList.js";
5
6
  import { ChainType, getWalletBalances } from "@lifi/sdk";
6
7
  import { useMemo } from "react";
@@ -28,10 +29,12 @@ const useFilteredTokensByBalance = (accountsWithTokens, formType) => {
28
29
  for (const [address, { tokens }] of Object.entries(accountsWithTokens)) result[address] = tokens;
29
30
  return result;
30
31
  }
32
+ const verifiedTokensSets = getVerifiedTokensSets(configTokens);
31
33
  for (const [address, { tokens }] of Object.entries(accountsWithTokens)) {
32
34
  result[address] = {};
33
35
  for (const [chainIdStr, chainTokens] of Object.entries(tokens)) {
34
36
  const chainId = Number(chainIdStr);
37
+ const verifiedAddresses = verifiedTokensSets?.get(chainId);
35
38
  const balances = existingBalances?.[chainId];
36
39
  if (!balances?.length) {
37
40
  if (chainTokens.length) result[address][chainId] = chainTokens;
@@ -49,7 +52,7 @@ const useFilteredTokensByBalance = (accountsWithTokens, formType) => {
49
52
  return !chainTokenSet.has(balanceKey) && isSupportedToken(balance) && isFormItemAllowed(balance, allowedAddressesConfig, formType, (t) => t.address.toLowerCase());
50
53
  }).map((token) => ({
51
54
  ...token,
52
- verified: false
55
+ verified: verifiedAddresses?.has(token.address.toLowerCase()) ?? false
53
56
  }));
54
57
  const allTokens = [...filteredTokens, ...additionalTokens];
55
58
  if (allTokens.length) result[address][chainId] = allTokens;
@@ -1 +1 @@
1
- {"version":3,"file":"useFilteredByTokenBalances.js","names":[],"sources":["../../../src/hooks/useFilteredByTokenBalances.ts"],"sourcesContent":["import {\n type BaseToken,\n ChainType,\n getWalletBalances,\n type TokenExtended,\n type WalletTokenExtended,\n} from '@lifi/sdk'\nimport { useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormType } from '../stores/form/types.js'\nimport { getConfigItemSets, isFormItemAllowed } from '../utils/item.js'\nimport { isSupportedToken } from '../utils/tokenList.js'\n\nexport const useFilteredTokensByBalance = (\n accountsWithTokens?: Record<\n string,\n { chainType: ChainType; tokens: Record<number, TokenExtended[]> }\n >,\n formType?: FormType\n): {\n data: Record<string, Record<number, TokenExtended[]>> | undefined\n isLoading: boolean\n} => {\n const { tokens: configTokens } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const evmAddress = useMemo(() => {\n const evmAccount = Object.entries(accountsWithTokens ?? {}).find(\n ([_, { chainType }]) => chainType === ChainType.EVM\n )\n return evmAccount?.[0]\n }, [accountsWithTokens])\n\n const { data: existingBalances, isLoading } = useQuery({\n queryKey: ['existing-evm-balances', evmAddress],\n queryFn: () => getWalletBalances(sdkClient, evmAddress ?? ''),\n enabled: !!evmAddress,\n refetchInterval: 30_000, // 30 seconds\n staleTime: 30_000, // 30 seconds\n retry: false,\n })\n\n const accountsWithFilteredTokens = useMemo(() => {\n if (!accountsWithTokens) {\n return undefined\n }\n\n // Early return if no existing balances - return all tokens\n const result: Record<string, Record<number, TokenExtended[]>> = {}\n if (!existingBalances) {\n for (const [address, { tokens }] of Object.entries(accountsWithTokens)) {\n result[address] = tokens\n }\n return result\n }\n\n for (const [address, { tokens }] of Object.entries(accountsWithTokens)) {\n result[address] = {}\n\n for (const [chainIdStr, chainTokens] of Object.entries(tokens)) {\n const chainId = Number(chainIdStr)\n // Get balances for this specific chain\n const balances = existingBalances?.[chainId]\n // If no balances, RPC all tokens of the chain\n if (!balances?.length) {\n if (chainTokens.length) {\n result[address][chainId] = chainTokens\n }\n continue\n }\n\n // Optimize token matching with Set for O(1) lookup\n const balanceSet = new Set(\n balances.map((balance: WalletTokenExtended) =>\n balance.address.toLowerCase()\n )\n )\n\n // Get tokens that are in chainTokens and have balances\n const filteredTokens = chainTokens.filter((token) => {\n const tokenKey = token.address.toLowerCase()\n return balanceSet.has(tokenKey)\n })\n\n // Get tokens that are in balances but not in chainTokens\n const chainTokenSet = new Set(\n chainTokens.map((token) => token.address.toLowerCase())\n )\n\n // Get allowed addresses from config tokens\n const allowedAddressesConfig = getConfigItemSets(\n configTokens,\n (tokens: BaseToken[]) =>\n new Set(\n tokens\n .filter((t) => Number(t.chainId) === chainId)\n .map((t) => t.address.toLowerCase())\n ),\n formType\n )\n\n const additionalTokens = balances\n .filter((balance: WalletTokenExtended) => {\n const balanceKey = balance.address.toLowerCase()\n return (\n !chainTokenSet.has(balanceKey) &&\n isSupportedToken(balance) &&\n isFormItemAllowed(\n balance,\n allowedAddressesConfig,\n formType,\n (t) => t.address.toLowerCase()\n )\n )\n })\n // Mark tokens from wallet balances as unverified\n .map((token: WalletTokenExtended) => ({\n ...token,\n verified: false,\n })) as TokenExtended[]\n\n // Combine both sets of tokens - convert WalletTokenExtended to TokenAmount\n const allTokens = [\n ...filteredTokens,\n ...additionalTokens,\n ] as TokenExtended[]\n\n if (allTokens.length) {\n result[address][chainId] = allTokens\n }\n }\n }\n\n return result\n }, [accountsWithTokens, existingBalances, configTokens, formType])\n\n return { data: accountsWithFilteredTokens, isLoading }\n}\n"],"mappings":";;;;;;;;AAeA,MAAa,8BACX,oBAIA,aAIG;CACH,MAAM,EAAE,QAAQ,iBAAiB,gBAAgB;CACjD,MAAM,YAAY,aAAa;CAE/B,MAAM,aAAa,cAAc;EAI/B,OAHmB,OAAO,QAAQ,sBAAsB,CAAC,CAAC,CAAC,CAAC,MACzD,CAAC,GAAG,EAAE,iBAAiB,cAAc,UAAU,GAElC,CAAC,GAAG;CACtB,GAAG,CAAC,kBAAkB,CAAC;CAEvB,MAAM,EAAE,MAAM,kBAAkB,cAAc,SAAS;EACrD,UAAU,CAAC,yBAAyB,UAAU;EAC9C,eAAe,kBAAkB,WAAW,cAAc,EAAE;EAC5D,SAAS,CAAC,CAAC;EACX,iBAAiB;EACjB,WAAW;EACX,OAAO;CACT,CAAC;CAgGD,OAAO;EAAE,MA9F0B,cAAc;GAC/C,IAAI,CAAC,oBACH;GAIF,MAAM,SAA0D,CAAC;GACjE,IAAI,CAAC,kBAAkB;IACrB,KAAK,MAAM,CAAC,SAAS,EAAE,aAAa,OAAO,QAAQ,kBAAkB,GACnE,OAAO,WAAW;IAEpB,OAAO;GACT;GAEA,KAAK,MAAM,CAAC,SAAS,EAAE,aAAa,OAAO,QAAQ,kBAAkB,GAAG;IACtE,OAAO,WAAW,CAAC;IAEnB,KAAK,MAAM,CAAC,YAAY,gBAAgB,OAAO,QAAQ,MAAM,GAAG;KAC9D,MAAM,UAAU,OAAO,UAAU;KAEjC,MAAM,WAAW,mBAAmB;KAEpC,IAAI,CAAC,UAAU,QAAQ;MACrB,IAAI,YAAY,QACd,OAAO,QAAQ,CAAC,WAAW;MAE7B;KACF;KAGA,MAAM,aAAa,IAAI,IACrB,SAAS,KAAK,YACZ,QAAQ,QAAQ,YAAY,CAC9B,CACF;KAGA,MAAM,iBAAiB,YAAY,QAAQ,UAAU;MACnD,MAAM,WAAW,MAAM,QAAQ,YAAY;MAC3C,OAAO,WAAW,IAAI,QAAQ;KAChC,CAAC;KAGD,MAAM,gBAAgB,IAAI,IACxB,YAAY,KAAK,UAAU,MAAM,QAAQ,YAAY,CAAC,CACxD;KAGA,MAAM,yBAAyB,kBAC7B,eACC,WACC,IAAI,IACF,OACG,QAAQ,MAAM,OAAO,EAAE,OAAO,MAAM,OAAO,CAAC,CAC5C,KAAK,MAAM,EAAE,QAAQ,YAAY,CAAC,CACvC,GACF,QACF;KAEA,MAAM,mBAAmB,SACtB,QAAQ,YAAiC;MACxC,MAAM,aAAa,QAAQ,QAAQ,YAAY;MAC/C,OACE,CAAC,cAAc,IAAI,UAAU,KAC7B,iBAAiB,OAAO,KACxB,kBACE,SACA,wBACA,WACC,MAAM,EAAE,QAAQ,YAAY,CAC/B;KAEJ,CAAC,CAAC,CAED,KAAK,WAAgC;MACpC,GAAG;MACH,UAAU;KACZ,EAAE;KAGJ,MAAM,YAAY,CAChB,GAAG,gBACH,GAAG,gBACL;KAEA,IAAI,UAAU,QACZ,OAAO,QAAQ,CAAC,WAAW;IAE/B;GACF;GAEA,OAAO;EACT,GAAG;GAAC;GAAoB;GAAkB;GAAc;EAAQ,CAExB;EAAG;CAAU;AACvD"}
1
+ {"version":3,"file":"useFilteredByTokenBalances.js","names":[],"sources":["../../../src/hooks/useFilteredByTokenBalances.ts"],"sourcesContent":["import {\n type BaseToken,\n ChainType,\n getWalletBalances,\n type TokenExtended,\n type WalletTokenExtended,\n} from '@lifi/sdk'\nimport { useQuery } from '@tanstack/react-query'\nimport { useMemo } from 'react'\nimport { useSDKClient } from '../providers/SDKClientProvider.js'\nimport { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'\nimport type { FormType } from '../stores/form/types.js'\nimport { getConfigItemSets, isFormItemAllowed } from '../utils/item.js'\nimport { getVerifiedTokensSets } from '../utils/token.js'\nimport { isSupportedToken } from '../utils/tokenList.js'\n\nexport const useFilteredTokensByBalance = (\n accountsWithTokens?: Record<\n string,\n { chainType: ChainType; tokens: Record<number, TokenExtended[]> }\n >,\n formType?: FormType\n): {\n data: Record<string, Record<number, TokenExtended[]>> | undefined\n isLoading: boolean\n} => {\n const { tokens: configTokens } = useWidgetConfig()\n const sdkClient = useSDKClient()\n\n const evmAddress = useMemo(() => {\n const evmAccount = Object.entries(accountsWithTokens ?? {}).find(\n ([_, { chainType }]) => chainType === ChainType.EVM\n )\n return evmAccount?.[0]\n }, [accountsWithTokens])\n\n const { data: existingBalances, isLoading } = useQuery({\n queryKey: ['existing-evm-balances', evmAddress],\n queryFn: () => getWalletBalances(sdkClient, evmAddress ?? ''),\n enabled: !!evmAddress,\n refetchInterval: 30_000, // 30 seconds\n staleTime: 30_000, // 30 seconds\n retry: false,\n })\n\n const accountsWithFilteredTokens = useMemo(() => {\n if (!accountsWithTokens) {\n return undefined\n }\n\n // Early return if no existing balances - return all tokens\n const result: Record<string, Record<number, TokenExtended[]>> = {}\n if (!existingBalances) {\n for (const [address, { tokens }] of Object.entries(accountsWithTokens)) {\n result[address] = tokens\n }\n return result\n }\n\n const verifiedTokensSets = getVerifiedTokensSets(configTokens)\n\n for (const [address, { tokens }] of Object.entries(accountsWithTokens)) {\n result[address] = {}\n\n for (const [chainIdStr, chainTokens] of Object.entries(tokens)) {\n const chainId = Number(chainIdStr)\n const verifiedAddresses = verifiedTokensSets?.get(chainId)\n // Get balances for this specific chain\n const balances = existingBalances?.[chainId]\n // If no balances, RPC all tokens of the chain\n if (!balances?.length) {\n if (chainTokens.length) {\n result[address][chainId] = chainTokens\n }\n continue\n }\n\n // Optimize token matching with Set for O(1) lookup\n const balanceSet = new Set(\n balances.map((balance: WalletTokenExtended) =>\n balance.address.toLowerCase()\n )\n )\n\n // Get tokens that are in chainTokens and have balances\n const filteredTokens = chainTokens.filter((token) => {\n const tokenKey = token.address.toLowerCase()\n return balanceSet.has(tokenKey)\n })\n\n // Get tokens that are in balances but not in chainTokens\n const chainTokenSet = new Set(\n chainTokens.map((token) => token.address.toLowerCase())\n )\n\n // Get allowed addresses from config tokens\n const allowedAddressesConfig = getConfigItemSets(\n configTokens,\n (tokens: BaseToken[]) =>\n new Set(\n tokens\n .filter((t) => Number(t.chainId) === chainId)\n .map((t) => t.address.toLowerCase())\n ),\n formType\n )\n\n const additionalTokens = balances\n .filter((balance: WalletTokenExtended) => {\n const balanceKey = balance.address.toLowerCase()\n return (\n !chainTokenSet.has(balanceKey) &&\n isSupportedToken(balance) &&\n isFormItemAllowed(\n balance,\n allowedAddressesConfig,\n formType,\n (t) => t.address.toLowerCase()\n )\n )\n })\n // Mark tokens from wallet balances as unverified unless allowlisted\n .map((token: WalletTokenExtended) => ({\n ...token,\n verified:\n verifiedAddresses?.has(token.address.toLowerCase()) ?? false,\n })) as TokenExtended[]\n\n // Combine both sets of tokens - convert WalletTokenExtended to TokenAmount\n const allTokens = [\n ...filteredTokens,\n ...additionalTokens,\n ] as TokenExtended[]\n\n if (allTokens.length) {\n result[address][chainId] = allTokens\n }\n }\n }\n\n return result\n }, [accountsWithTokens, existingBalances, configTokens, formType])\n\n return { data: accountsWithFilteredTokens, isLoading }\n}\n"],"mappings":";;;;;;;;;AAgBA,MAAa,8BACX,oBAIA,aAIG;CACH,MAAM,EAAE,QAAQ,iBAAiB,gBAAgB;CACjD,MAAM,YAAY,aAAa;CAE/B,MAAM,aAAa,cAAc;EAI/B,OAHmB,OAAO,QAAQ,sBAAsB,CAAC,CAAC,CAAC,CAAC,MACzD,CAAC,GAAG,EAAE,iBAAiB,cAAc,UAAU,GAElC,CAAC,GAAG;CACtB,GAAG,CAAC,kBAAkB,CAAC;CAEvB,MAAM,EAAE,MAAM,kBAAkB,cAAc,SAAS;EACrD,UAAU,CAAC,yBAAyB,UAAU;EAC9C,eAAe,kBAAkB,WAAW,cAAc,EAAE;EAC5D,SAAS,CAAC,CAAC;EACX,iBAAiB;EACjB,WAAW;EACX,OAAO;CACT,CAAC;CAoGD,OAAO;EAAE,MAlG0B,cAAc;GAC/C,IAAI,CAAC,oBACH;GAIF,MAAM,SAA0D,CAAC;GACjE,IAAI,CAAC,kBAAkB;IACrB,KAAK,MAAM,CAAC,SAAS,EAAE,aAAa,OAAO,QAAQ,kBAAkB,GACnE,OAAO,WAAW;IAEpB,OAAO;GACT;GAEA,MAAM,qBAAqB,sBAAsB,YAAY;GAE7D,KAAK,MAAM,CAAC,SAAS,EAAE,aAAa,OAAO,QAAQ,kBAAkB,GAAG;IACtE,OAAO,WAAW,CAAC;IAEnB,KAAK,MAAM,CAAC,YAAY,gBAAgB,OAAO,QAAQ,MAAM,GAAG;KAC9D,MAAM,UAAU,OAAO,UAAU;KACjC,MAAM,oBAAoB,oBAAoB,IAAI,OAAO;KAEzD,MAAM,WAAW,mBAAmB;KAEpC,IAAI,CAAC,UAAU,QAAQ;MACrB,IAAI,YAAY,QACd,OAAO,QAAQ,CAAC,WAAW;MAE7B;KACF;KAGA,MAAM,aAAa,IAAI,IACrB,SAAS,KAAK,YACZ,QAAQ,QAAQ,YAAY,CAC9B,CACF;KAGA,MAAM,iBAAiB,YAAY,QAAQ,UAAU;MACnD,MAAM,WAAW,MAAM,QAAQ,YAAY;MAC3C,OAAO,WAAW,IAAI,QAAQ;KAChC,CAAC;KAGD,MAAM,gBAAgB,IAAI,IACxB,YAAY,KAAK,UAAU,MAAM,QAAQ,YAAY,CAAC,CACxD;KAGA,MAAM,yBAAyB,kBAC7B,eACC,WACC,IAAI,IACF,OACG,QAAQ,MAAM,OAAO,EAAE,OAAO,MAAM,OAAO,CAAC,CAC5C,KAAK,MAAM,EAAE,QAAQ,YAAY,CAAC,CACvC,GACF,QACF;KAEA,MAAM,mBAAmB,SACtB,QAAQ,YAAiC;MACxC,MAAM,aAAa,QAAQ,QAAQ,YAAY;MAC/C,OACE,CAAC,cAAc,IAAI,UAAU,KAC7B,iBAAiB,OAAO,KACxB,kBACE,SACA,wBACA,WACC,MAAM,EAAE,QAAQ,YAAY,CAC/B;KAEJ,CAAC,CAAC,CAED,KAAK,WAAgC;MACpC,GAAG;MACH,UACE,mBAAmB,IAAI,MAAM,QAAQ,YAAY,CAAC,KAAK;KAC3D,EAAE;KAGJ,MAAM,YAAY,CAChB,GAAG,gBACH,GAAG,gBACL;KAEA,IAAI,UAAU,QACZ,OAAO,QAAQ,CAAC,WAAW;IAE/B;GACF;GAEA,OAAO;EACT,GAAG;GAAC;GAAoB;GAAkB;GAAc;EAAQ,CAExB;EAAG;CAAU;AACvD"}
@@ -0,0 +1,24 @@
1
+ import { FormKeyHelper } from "../stores/form/types.js";
2
+ import { useFieldValues } from "../stores/form/useFieldValues.js";
3
+ import { useToken } from "./useToken.js";
4
+ //#region src/hooks/useLimitMarketRate.ts
5
+ /**
6
+ * Canonical limit-order market rate (receive token per send token), derived
7
+ * from the tokens' USD prices: 1 send token ≈ sendPrice / receivePrice receive
8
+ * tokens. This is the spot ratio — what the price card's "Market" reference and
9
+ * proximity indicator compare against. Returns `undefined` until both token
10
+ * prices are known.
11
+ */
12
+ const useLimitMarketRate = () => {
13
+ const [fromChainId, fromTokenAddress, toChainId, toTokenAddress] = useFieldValues(FormKeyHelper.getChainKey("from"), FormKeyHelper.getTokenKey("from"), FormKeyHelper.getChainKey("to"), FormKeyHelper.getTokenKey("to"));
14
+ const { token: fromToken } = useToken(fromChainId, fromTokenAddress);
15
+ const { token: toToken } = useToken(toChainId, toTokenAddress);
16
+ const fromPrice = Number(fromToken?.priceUSD);
17
+ const toPrice = Number(toToken?.priceUSD);
18
+ if (!fromPrice || !toPrice || Number.isNaN(fromPrice) || Number.isNaN(toPrice)) return;
19
+ return fromPrice / toPrice;
20
+ };
21
+ //#endregion
22
+ export { useLimitMarketRate };
23
+
24
+ //# sourceMappingURL=useLimitMarketRate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLimitMarketRate.js","names":[],"sources":["../../../src/hooks/useLimitMarketRate.ts"],"sourcesContent":["import { FormKeyHelper } from '../stores/form/types.js'\nimport { useFieldValues } from '../stores/form/useFieldValues.js'\nimport { useToken } from './useToken.js'\n\n/**\n * Canonical limit-order market rate (receive token per send token), derived\n * from the tokens' USD prices: 1 send token ≈ sendPrice / receivePrice receive\n * tokens. This is the spot ratio — what the price card's \"Market\" reference and\n * proximity indicator compare against. Returns `undefined` until both token\n * prices are known.\n */\nexport const useLimitMarketRate = (): number | undefined => {\n const [fromChainId, fromTokenAddress, toChainId, toTokenAddress] =\n useFieldValues(\n FormKeyHelper.getChainKey('from'),\n FormKeyHelper.getTokenKey('from'),\n FormKeyHelper.getChainKey('to'),\n FormKeyHelper.getTokenKey('to')\n )\n const { token: fromToken } = useToken(fromChainId, fromTokenAddress)\n const { token: toToken } = useToken(toChainId, toTokenAddress)\n\n const fromPrice = Number(fromToken?.priceUSD)\n const toPrice = Number(toToken?.priceUSD)\n\n // A `priceUSD` of `\"0\"` (or missing) means the price is unknown — there's no\n // meaningful spot ratio to derive, and dividing by a zero `toPrice` would be\n // `Infinity`, so the falsy guard intentionally suppresses the rate here.\n if (\n !fromPrice ||\n !toPrice ||\n Number.isNaN(fromPrice) ||\n Number.isNaN(toPrice)\n ) {\n return undefined\n }\n\n return fromPrice / toPrice\n}\n"],"mappings":";;;;;;;;;;;AAWA,MAAa,2BAA+C;CAC1D,MAAM,CAAC,aAAa,kBAAkB,WAAW,kBAC/C,eACE,cAAc,YAAY,MAAM,GAChC,cAAc,YAAY,MAAM,GAChC,cAAc,YAAY,IAAI,GAC9B,cAAc,YAAY,IAAI,CAChC;CACF,MAAM,EAAE,OAAO,cAAc,SAAS,aAAa,gBAAgB;CACnE,MAAM,EAAE,OAAO,YAAY,SAAS,WAAW,cAAc;CAE7D,MAAM,YAAY,OAAO,WAAW,QAAQ;CAC5C,MAAM,UAAU,OAAO,SAAS,QAAQ;CAKxC,IACE,CAAC,aACD,CAAC,WACD,OAAO,MAAM,SAAS,KACtB,OAAO,MAAM,OAAO,GAEpB;CAGF,OAAO,YAAY;AACrB"}