@lifi/widget 4.7.1 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. package/dist/esm/components/AmountInput/AmountInput.style.d.ts.map +1 -1
  2. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js +5 -2
  3. package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -1
  4. package/dist/esm/components/Card/Card.d.ts.map +1 -1
  5. package/dist/esm/components/Card/CardIconButton.d.ts.map +1 -1
  6. package/dist/esm/components/ContractComponent/ItemPrice.d.ts.map +1 -1
  7. package/dist/esm/components/ListItem/ListItemButton.d.ts.map +1 -1
  8. package/dist/esm/components/ListItemButton.d.ts.map +1 -1
  9. package/dist/esm/components/SelectChainAndToken.js +5 -2
  10. package/dist/esm/components/SelectChainAndToken.js.map +1 -1
  11. package/dist/esm/components/SendToWallet/SendToWalletButton.js +5 -4
  12. package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
  13. package/dist/esm/components/Token/Token.d.ts.map +1 -1
  14. package/dist/esm/components/TokenList/types.d.ts.map +1 -1
  15. package/dist/esm/components/TokenList/useTokenSelect.d.ts.map +1 -1
  16. package/dist/esm/components/TokenList/useTokenSelect.js +10 -0
  17. package/dist/esm/components/TokenList/useTokenSelect.js.map +1 -1
  18. package/dist/esm/config/constants.js.map +1 -1
  19. package/dist/esm/config/version.d.ts +1 -1
  20. package/dist/esm/config/version.js +1 -1
  21. package/dist/esm/config/version.js.map +1 -1
  22. package/dist/esm/hooks/useAccountsBalancesData.js +5 -2
  23. package/dist/esm/hooks/useAccountsBalancesData.js.map +1 -1
  24. package/dist/esm/hooks/useAddressValidation.d.ts +3 -2
  25. package/dist/esm/hooks/useAddressValidation.d.ts.map +1 -1
  26. package/dist/esm/hooks/useAddressValidation.js +48 -21
  27. package/dist/esm/hooks/useAddressValidation.js.map +1 -1
  28. package/dist/esm/hooks/useAvailableChains.d.ts.map +1 -1
  29. package/dist/esm/hooks/useAvailableChains.js +21 -38
  30. package/dist/esm/hooks/useAvailableChains.js.map +1 -1
  31. package/dist/esm/hooks/useFromTokenSufficiency.js +3 -3
  32. package/dist/esm/hooks/useFromTokenSufficiency.js.map +1 -1
  33. package/dist/esm/hooks/useGasRecommendation.js +3 -3
  34. package/dist/esm/hooks/useGasRecommendation.js.map +1 -1
  35. package/dist/esm/hooks/useGasRefuel.js +4 -1
  36. package/dist/esm/hooks/useGasRefuel.js.map +1 -1
  37. package/dist/esm/hooks/useGasSufficiency.js +3 -3
  38. package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
  39. package/dist/esm/hooks/useIsBatchingSupported.js +2 -2
  40. package/dist/esm/hooks/useIsBatchingSupported.js.map +1 -1
  41. package/dist/esm/hooks/useRouteExecution.js +6 -6
  42. package/dist/esm/hooks/useRouteExecution.js.map +1 -1
  43. package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
  44. package/dist/esm/hooks/useRoutes.js +18 -13
  45. package/dist/esm/hooks/useRoutes.js.map +1 -1
  46. package/dist/esm/hooks/useToAddressAutoPopulate.js +6 -8
  47. package/dist/esm/hooks/useToAddressAutoPopulate.js.map +1 -1
  48. package/dist/esm/hooks/useToAddressRequirements.d.ts +3 -2
  49. package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
  50. package/dist/esm/hooks/useToAddressRequirements.js +8 -7
  51. package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
  52. package/dist/esm/hooks/useToAddressReset.js +6 -3
  53. package/dist/esm/hooks/useToAddressReset.js.map +1 -1
  54. package/dist/esm/hooks/useTokenBalance.js +6 -5
  55. package/dist/esm/hooks/useTokenBalance.js.map +1 -1
  56. package/dist/esm/hooks/useTokenBalancesQueries.js +3 -3
  57. package/dist/esm/hooks/useTokenBalancesQueries.js.map +1 -1
  58. package/dist/esm/hooks/useTokenSearch.js +3 -3
  59. package/dist/esm/hooks/useTokenSearch.js.map +1 -1
  60. package/dist/esm/hooks/useTokens.js +15 -15
  61. package/dist/esm/hooks/useTokens.js.map +1 -1
  62. package/dist/esm/hooks/useTools.d.ts.map +1 -1
  63. package/dist/esm/hooks/useTools.js +26 -27
  64. package/dist/esm/hooks/useTools.js.map +1 -1
  65. package/dist/esm/hooks/useTransactionDetails.js +2 -2
  66. package/dist/esm/hooks/useTransactionDetails.js.map +1 -1
  67. package/dist/esm/hooks/useTransactionHistory.js +3 -3
  68. package/dist/esm/hooks/useTransactionHistory.js.map +1 -1
  69. package/dist/esm/i18n/bn.json +2 -1
  70. package/dist/esm/i18n/de.json +2 -1
  71. package/dist/esm/i18n/en.json +2 -1
  72. package/dist/esm/i18n/es.json +2 -1
  73. package/dist/esm/i18n/fr.json +2 -1
  74. package/dist/esm/i18n/hi.json +2 -1
  75. package/dist/esm/i18n/id.json +2 -1
  76. package/dist/esm/i18n/it.json +2 -1
  77. package/dist/esm/i18n/ja.json +2 -1
  78. package/dist/esm/i18n/ko.json +2 -1
  79. package/dist/esm/i18n/pl.json +2 -1
  80. package/dist/esm/i18n/pt.json +2 -1
  81. package/dist/esm/i18n/th.json +2 -1
  82. package/dist/esm/i18n/tr.json +2 -1
  83. package/dist/esm/i18n/uk.json +2 -1
  84. package/dist/esm/i18n/vi.json +2 -1
  85. package/dist/esm/i18n/zh.json +2 -1
  86. package/dist/esm/index.d.ts +5 -1
  87. package/dist/esm/index.js +3 -1
  88. package/dist/esm/pages/RoutesPage/RoutesPage.style.d.ts.map +1 -1
  89. package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js +7 -4
  90. package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js.map +1 -1
  91. package/dist/esm/pages/SendToWallet/BookmarksPage.js +35 -31
  92. package/dist/esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
  93. package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js +4 -3
  94. package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js.map +1 -1
  95. package/dist/esm/pages/SendToWallet/RecentWalletsPage.js +43 -39
  96. package/dist/esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
  97. package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js +32 -26
  98. package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js.map +1 -1
  99. package/dist/esm/pages/SendToWallet/SendToWalletPage.js +5 -10
  100. package/dist/esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
  101. package/dist/esm/providers/I18nProvider/types.d.ts.map +1 -1
  102. package/dist/esm/providers/WalletProvider/WalletProvider.d.ts.map +1 -1
  103. package/dist/esm/providers/WalletProvider/WalletProvider.js +14 -2
  104. package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
  105. package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
  106. package/dist/esm/providers/WidgetProvider/WidgetProvider.js +15 -11
  107. package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
  108. package/dist/esm/providers/WidgetProvider/types.d.ts +2 -0
  109. package/dist/esm/providers/WidgetProvider/types.d.ts.map +1 -1
  110. package/dist/esm/queries/getChains.d.ts +38 -0
  111. package/dist/esm/queries/getChains.d.ts.map +1 -0
  112. package/dist/esm/queries/getChains.js +51 -0
  113. package/dist/esm/queries/getChains.js.map +1 -0
  114. package/dist/esm/queries/getTools.d.ts +26 -0
  115. package/dist/esm/queries/getTools.d.ts.map +1 -0
  116. package/dist/esm/queries/getTools.js +30 -0
  117. package/dist/esm/queries/getTools.js.map +1 -0
  118. package/dist/esm/queries/index.d.ts +4 -0
  119. package/dist/esm/queries/index.js +3 -0
  120. package/dist/esm/queries/types.d.ts +25 -0
  121. package/dist/esm/queries/types.d.ts.map +1 -0
  122. package/dist/esm/shared.d.ts +2 -1
  123. package/dist/esm/shared.js +2 -1
  124. package/dist/esm/stores/StoreProvider.d.ts.map +1 -1
  125. package/dist/esm/stores/StoreProvider.js +16 -17
  126. package/dist/esm/stores/StoreProvider.js.map +1 -1
  127. package/dist/esm/stores/bookmarks/types.d.ts +3 -0
  128. package/dist/esm/stores/bookmarks/types.d.ts.map +1 -1
  129. package/dist/esm/stores/chains/ChainOrderStore.d.ts.map +1 -1
  130. package/dist/esm/stores/chains/ChainOrderStore.js +4 -1
  131. package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
  132. package/dist/esm/stores/form/FormStore.js +3 -2
  133. package/dist/esm/stores/form/FormStore.js.map +1 -1
  134. package/dist/esm/stores/form/URLSearchParamsBuilder.js +7 -3
  135. package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
  136. package/dist/esm/stores/form/getDefaultValuesFromQueryString.js +4 -1
  137. package/dist/esm/stores/form/getDefaultValuesFromQueryString.js.map +1 -1
  138. package/dist/esm/stores/header/useHeaderStore.d.ts +1 -1
  139. package/dist/esm/stores/header/useHeaderStore.d.ts.map +1 -1
  140. package/dist/esm/stores/header/useHeaderStore.js.map +1 -1
  141. package/dist/esm/themes/createTheme.d.ts.map +1 -1
  142. package/dist/esm/types/events.d.ts.map +1 -1
  143. package/dist/esm/types/token.d.ts.map +1 -1
  144. package/dist/esm/types/widget.d.ts +30 -0
  145. package/dist/esm/types/widget.d.ts.map +1 -1
  146. package/dist/esm/types/widget.js.map +1 -1
  147. package/dist/esm/utils/chainType.js +32 -1
  148. package/dist/esm/utils/chainType.js.map +1 -1
  149. package/dist/esm/utils/customReceiver.js +6 -1
  150. package/dist/esm/utils/customReceiver.js.map +1 -1
  151. package/dist/esm/utils/queries.js.map +1 -1
  152. package/dist/esm/utils/scopeKeys.d.ts +6 -0
  153. package/dist/esm/utils/scopeKeys.d.ts.map +1 -0
  154. package/dist/esm/utils/scopeKeys.js +8 -0
  155. package/dist/esm/utils/scopeKeys.js.map +1 -0
  156. package/package.json +15 -7
  157. package/src/components/AmountInputCard/AmountInputCardPair.tsx +6 -2
  158. package/src/components/SelectChainAndToken.tsx +5 -1
  159. package/src/components/SendToWallet/SendToWalletButton.tsx +13 -8
  160. package/src/components/TokenList/useTokenSelect.ts +15 -0
  161. package/src/config/constants.ts +3 -0
  162. package/src/config/version.ts +1 -1
  163. package/src/hooks/useAccountsBalancesData.ts +6 -2
  164. package/src/hooks/useAddressValidation.ts +87 -32
  165. package/src/hooks/useAvailableChains.test.tsx +170 -0
  166. package/src/hooks/useAvailableChains.ts +29 -47
  167. package/src/hooks/useFromTokenSufficiency.ts +2 -2
  168. package/src/hooks/useGasRecommendation.ts +2 -2
  169. package/src/hooks/useGasRefuel.ts +11 -1
  170. package/src/hooks/useGasSufficiency.ts +2 -2
  171. package/src/hooks/useIsBatchingSupported.ts +2 -2
  172. package/src/hooks/useRouteExecution.ts +5 -5
  173. package/src/hooks/useRoutes.ts +28 -23
  174. package/src/hooks/useToAddressAutoPopulate.ts +13 -17
  175. package/src/hooks/useToAddressRequirements.ts +19 -4
  176. package/src/hooks/useToAddressReset.ts +13 -4
  177. package/src/hooks/useTokenBalance.ts +10 -5
  178. package/src/hooks/useTokenBalancesQueries.ts +3 -3
  179. package/src/hooks/useTokenSearch.ts +7 -3
  180. package/src/hooks/useTokens.ts +13 -14
  181. package/src/hooks/useTools.sharedEntry.test.tsx +155 -0
  182. package/src/hooks/useTools.ts +42 -37
  183. package/src/hooks/useTransactionDetails.ts +3 -3
  184. package/src/hooks/useTransactionHistory.ts +2 -2
  185. package/src/index.ts +2 -1
  186. package/src/pages/SendToWallet/BookmarkAddressSheet.tsx +5 -1
  187. package/src/pages/SendToWallet/BookmarksPage.tsx +42 -52
  188. package/src/pages/SendToWallet/ConnectedWalletsPage.tsx +4 -14
  189. package/src/pages/SendToWallet/RecentWalletsPage.tsx +59 -66
  190. package/src/pages/SendToWallet/SendToConfiguredWalletPage.tsx +45 -50
  191. package/src/pages/SendToWallet/SendToWalletPage.tsx +4 -16
  192. package/src/providers/WalletProvider/WalletProvider.tsx +28 -3
  193. package/src/providers/WidgetProvider/WidgetProvider.test.tsx +73 -0
  194. package/src/providers/WidgetProvider/WidgetProvider.tsx +28 -14
  195. package/src/providers/WidgetProvider/types.ts +2 -0
  196. package/src/queries/getChains.ts +93 -0
  197. package/src/queries/getTools.ts +62 -0
  198. package/src/queries/index.ts +30 -0
  199. package/src/queries/sharedCache.test.tsx +223 -0
  200. package/src/queries/types.ts +38 -0
  201. package/src/shared.ts +1 -0
  202. package/src/stores/StoreProvider.test.tsx +107 -0
  203. package/src/stores/StoreProvider.tsx +8 -6
  204. package/src/stores/bookmarks/types.ts +3 -0
  205. package/src/stores/chains/ChainOrderStore.tsx +4 -1
  206. package/src/stores/form/FormStore.tsx +2 -0
  207. package/src/stores/form/URLSearchParamsBuilder.tsx +4 -2
  208. package/src/stores/form/getDefaultValuesFromQueryString.ts +19 -0
  209. package/src/stores/header/useHeaderStore.tsx +3 -4
  210. package/src/types/widget.ts +30 -0
  211. package/src/utils/chainType.ts +73 -1
  212. package/src/utils/customReceiver.ts +36 -0
  213. package/src/utils/queries.ts +1 -0
  214. package/src/utils/scopeKeys.ts +18 -0
@@ -1,56 +1,61 @@
1
- import { getTools, type ToolsResponse } from '@lifi/sdk'
1
+ import type { ToolsResponse } from '@lifi/sdk'
2
2
  import { useQuery } from '@tanstack/react-query'
3
+ import { useCallback, useEffect } from 'react'
3
4
  import { useSDKClient } from '../providers/SDKClientProvider.js'
4
5
  import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
6
+ import { getToolsQueryOptions } from '../queries/getTools.js'
5
7
  import { useSettingsStoreContext } from '../stores/settings/SettingsStore.js'
6
8
  import { getConfigItemSets, isItemAllowedForSets } from '../utils/item.js'
7
- import { getQueryKey } from '../utils/queries.js'
9
+
10
+ const refetchInterval = 180_000
8
11
 
9
12
  export const useTools = (): { tools: ToolsResponse | undefined } => {
10
- const { bridges, exchanges, keyPrefix } = useWidgetConfig()
13
+ const { bridges, exchanges, queryScopeKey } = useWidgetConfig()
11
14
  const settingsStore = useSettingsStoreContext()
12
15
  const sdkClient = useSDKClient()
13
16
 
14
- const { data } = useQuery({
15
- queryKey: [
16
- getQueryKey('tools', keyPrefix),
17
- bridges?.allow,
18
- bridges?.deny,
19
- exchanges?.allow,
20
- exchanges?.deny,
21
- ],
22
- queryFn: async (): Promise<ToolsResponse> => {
23
- const tools = await getTools(sdkClient)
24
- const bridgesConfigSets = getConfigItemSets(
25
- bridges,
26
- (bridges) => new Set(bridges)
27
- )
28
- const exchangesConfigSets = getConfigItemSets(
29
- exchanges,
30
- (exchanges) => new Set(exchanges)
31
- )
32
- const result = {
17
+ const selectAllowedTools = useCallback(
18
+ (tools: ToolsResponse): ToolsResponse => {
19
+ const bridgeSets = getConfigItemSets(bridges, (keys) => new Set(keys))
20
+ const exchangeSets = getConfigItemSets(exchanges, (keys) => new Set(keys))
21
+ return {
33
22
  bridges: tools.bridges.filter((bridge) =>
34
- isItemAllowedForSets(bridge.key, bridgesConfigSets)
23
+ isItemAllowedForSets(bridge.key, bridgeSets)
35
24
  ),
36
25
  exchanges: tools.exchanges.filter((exchange) =>
37
- isItemAllowedForSets(exchange.key, exchangesConfigSets)
26
+ isItemAllowedForSets(exchange.key, exchangeSets)
38
27
  ),
39
28
  }
40
- const { initializeTools } = settingsStore.getState()
41
- initializeTools(
42
- 'Bridges',
43
- result.bridges.map((bridge) => bridge.key)
44
- )
45
- initializeTools(
46
- 'Exchanges',
47
- result.exchanges.map((exchange) => exchange.key)
48
- )
49
- return result
50
29
  },
51
- refetchInterval: 180_000,
52
- staleTime: 180_000,
53
- })
30
+ [bridges, exchanges]
31
+ )
32
+
33
+ const { data } = useQuery(
34
+ getToolsQueryOptions(sdkClient, {
35
+ scopeKey: queryScopeKey,
36
+ query: {
37
+ refetchInterval,
38
+ staleTime: refetchInterval,
39
+ select: selectAllowedTools,
40
+ },
41
+ })
42
+ )
43
+
44
+ // A host may fill the shared entry, so seed from the data, not in a queryFn.
45
+ useEffect(() => {
46
+ if (!data) {
47
+ return
48
+ }
49
+ const { initializeTools } = settingsStore.getState()
50
+ initializeTools(
51
+ 'Bridges',
52
+ data.bridges.map((bridge) => bridge.key)
53
+ )
54
+ initializeTools(
55
+ 'Exchanges',
56
+ data.exchanges.map((exchange) => exchange.key)
57
+ )
58
+ }, [data, settingsStore])
54
59
 
55
60
  return { tools: data }
56
61
  }
@@ -19,12 +19,12 @@ export const useTransactionDetails = (
19
19
  } => {
20
20
  const { account, accounts } = useAccount()
21
21
  const queryClient = useQueryClient()
22
- const { keyPrefix } = useWidgetConfig()
22
+ const { storageScopeKey } = useWidgetConfig()
23
23
  const sdkClient = useSDKClient()
24
24
 
25
25
  const transactionHistoryQueryKey = useMemo(
26
- () => getQueryKey('transaction-history', keyPrefix),
27
- [keyPrefix]
26
+ () => getQueryKey('transaction-history', storageScopeKey),
27
+ [storageScopeKey]
28
28
  )
29
29
 
30
30
  const { data, isLoading } = useQuery({
@@ -22,14 +22,14 @@ export const useTransactionHistory = (): {
22
22
  } => {
23
23
  const store = useRouteExecutionStoreContext()
24
24
  const { accounts } = useAccount()
25
- const { keyPrefix } = useWidgetConfig()
25
+ const { storageScopeKey } = useWidgetConfig()
26
26
  const sdkClient = useSDKClient()
27
27
  const { tools } = useTools()
28
28
 
29
29
  const { data: routeExecutions, isLoading } = useQueries({
30
30
  queries: accounts.map((account) => ({
31
31
  queryKey: [
32
- getQueryKey('transaction-history', keyPrefix),
32
+ getQueryKey('transaction-history', storageScopeKey),
33
33
  account.address,
34
34
  ],
35
35
  queryFn: (async ({ queryKey: [, accountAddress], signal }) => {
package/src/index.ts CHANGED
@@ -8,13 +8,14 @@ export * from './components/ContractComponent/NFT/NFTBase.js'
8
8
  export * from './components/ContractComponent/NFT/types.js'
9
9
  export * from './components/Skeleton/WidgetSkeleton.js'
10
10
  export { defaultMaxHeight } from './config/constants.js'
11
- export * from './config/version.js'
11
+ export { name, version } from './config/version.js'
12
12
  export { useWidgetChains } from './hooks/useWidgetChains.js'
13
13
  export {
14
14
  useWidgetEvents,
15
15
  type WidgetEventEmitter,
16
16
  widgetEvents,
17
17
  } from './hooks/useWidgetEvents.js'
18
+ export * from './queries/index.js'
18
19
  export * from './stores/bookmarks/types.js'
19
20
  export * from './stores/form/types.js'
20
21
  export { useFieldActions } from './stores/form/useFieldActions.js'
@@ -9,6 +9,7 @@ import { BottomSheet } from '../../components/BottomSheet/BottomSheet.js'
9
9
  import type { BottomSheetBase } from '../../components/BottomSheet/types.js'
10
10
  import { Input } from '../../components/Input.js'
11
11
  import { AlertMessage } from '../../components/Messages/AlertMessage.js'
12
+ import { addressInputMaxLength } from '../../config/constants.js'
12
13
  import { useAddressValidation } from '../../hooks/useAddressValidation.js'
13
14
  import type { Bookmark } from '../../stores/bookmarks/types.js'
14
15
  import { useBookmarkActions } from '../../stores/bookmarks/useBookmarkActions.js'
@@ -63,6 +64,7 @@ export const BookmarkAddressSheet = ({
63
64
  name: nameValue,
64
65
  address: validationResult.address,
65
66
  chainType: validationResult.chainType,
67
+ chainId: validationResult.chainId,
66
68
  }
67
69
  }
68
70
 
@@ -74,6 +76,7 @@ export const BookmarkAddressSheet = ({
74
76
  name: nameValue,
75
77
  address: validatedWallet.address,
76
78
  chainType: validatedWallet.chainType,
79
+ chainId: validatedWallet.chainId,
77
80
  }
78
81
  }
79
82
 
@@ -119,6 +122,7 @@ export const BookmarkAddressSheet = ({
119
122
  name: validatedBookmark.name,
120
123
  address: validatedBookmark.address,
121
124
  chainType: validatedBookmark.chainType,
125
+ chainId: validatedBookmark.chainId,
122
126
  })
123
127
  }
124
128
  }
@@ -198,7 +202,7 @@ export const BookmarkAddressSheet = ({
198
202
  context: 'long',
199
203
  })}
200
204
  maxRows={2}
201
- inputProps={{ maxLength: 128 }}
205
+ inputProps={{ maxLength: addressInputMaxLength }}
202
206
  multiline
203
207
  />
204
208
  </SendToWalletCard>
@@ -34,7 +34,7 @@ export const BookmarksPage = (): JSX.Element => {
34
34
  const listParentRef = useRef<HTMLUListElement | null>(null)
35
35
  const buttonRef = useRef<HTMLDivElement | null>(null)
36
36
  const { bookmarks } = useBookmarks()
37
- const { requiredToChainType } = useToAddressRequirements()
37
+ const { isValidReceiver } = useToAddressRequirements()
38
38
  const { addBookmark, removeBookmark, setSelectedBookmark } =
39
39
  useBookmarkActions()
40
40
  const navigate = useNavigate()
@@ -70,59 +70,49 @@ export const BookmarksPage = (): JSX.Element => {
70
70
  disablePadding
71
71
  sx={{ paddingTop: 1.5 }}
72
72
  >
73
- {bookmarks.map((bookmark) => (
74
- <ListItem key={bookmark.address} sx={{ position: 'relative' }}>
75
- <ListItemButton
76
- onClick={() => handleBookmarkSelected(bookmark)}
77
- disabled={
78
- requiredToChainType &&
79
- requiredToChainType !== bookmark.chainType
80
- }
81
- >
82
- <ListItemAvatar>
83
- <AccountAvatar
84
- chainId={defaultChainIdsByType[bookmark.chainType]}
73
+ {bookmarks.map((bookmark) => {
74
+ const disabled = !isValidReceiver(bookmark.address)
75
+ const chainId =
76
+ bookmark.chainId ?? defaultChainIdsByType[bookmark.chainType]
77
+ return (
78
+ <ListItem key={bookmark.address} sx={{ position: 'relative' }}>
79
+ <ListItemButton
80
+ onClick={() => handleBookmarkSelected(bookmark)}
81
+ disabled={disabled}
82
+ >
83
+ <ListItemAvatar>
84
+ <AccountAvatar chainId={chainId} />
85
+ </ListItemAvatar>
86
+ <ListItemText
87
+ primary={bookmark.name}
88
+ secondary={shortenAddress(bookmark.address)}
85
89
  />
86
- </ListItemAvatar>
87
- <ListItemText
88
- primary={bookmark.name}
89
- secondary={shortenAddress(bookmark.address)}
90
+ </ListItemButton>
91
+ <ContextMenu
92
+ disabled={disabled}
93
+ items={[
94
+ {
95
+ icon: <ContentCopyRounded />,
96
+ label: t('button.copyAddress'),
97
+ onClick: () =>
98
+ navigator.clipboard.writeText(bookmark.address),
99
+ },
100
+ {
101
+ icon: <OpenInNewRounded />,
102
+ label: t('button.viewOnExplorer'),
103
+ onClick: () =>
104
+ openInNewTab(getAddressLink(bookmark.address, chainId)),
105
+ },
106
+ {
107
+ icon: <DeleteOutline />,
108
+ label: t('button.delete'),
109
+ onClick: () => removeBookmark(bookmark.address),
110
+ },
111
+ ]}
90
112
  />
91
- </ListItemButton>
92
- <ContextMenu
93
- disabled={
94
- !!(
95
- requiredToChainType &&
96
- requiredToChainType !== bookmark.chainType
97
- )
98
- }
99
- items={[
100
- {
101
- icon: <ContentCopyRounded />,
102
- label: t('button.copyAddress'),
103
- onClick: () =>
104
- navigator.clipboard.writeText(bookmark.address),
105
- },
106
- {
107
- icon: <OpenInNewRounded />,
108
- label: t('button.viewOnExplorer'),
109
- onClick: () =>
110
- openInNewTab(
111
- getAddressLink(
112
- bookmark.address,
113
- defaultChainIdsByType[bookmark.chainType]
114
- )
115
- ),
116
- },
117
- {
118
- icon: <DeleteOutline />,
119
- label: t('button.delete'),
120
- onClick: () => removeBookmark(bookmark.address),
121
- },
122
- ]}
123
- />
124
- </ListItem>
125
- ))}
113
+ </ListItem>
114
+ )
115
+ })}
126
116
  {!bookmarks.length && (
127
117
  <EmptyListIndicator
128
118
  icon={<TurnedIn />}
@@ -27,7 +27,7 @@ export const ConnectedWalletsPage = (): JSX.Element => {
27
27
  const { t } = useTranslation()
28
28
  const { accounts } = useAccount()
29
29
  const { setSelectedBookmark } = useBookmarkActions()
30
- const { requiredToChainType } = useToAddressRequirements()
30
+ const { isValidReceiver } = useToAddressRequirements()
31
31
  const navigate = useNavigate()
32
32
  const { setFieldValue } = useFieldActions()
33
33
  const { getAddressLink } = useExplorer()
@@ -91,15 +91,13 @@ export const ConnectedWalletsPage = (): JSX.Element => {
91
91
  ]
92
92
  : []),
93
93
  ]
94
+ const disabled = !isValidReceiver(account.address)
94
95
 
95
96
  return (
96
97
  <ListItem key={account.address} sx={{ position: 'relative' }}>
97
98
  <ListItemButton
98
99
  onClick={() => handleWalletSelected(account)}
99
- disabled={
100
- requiredToChainType &&
101
- requiredToChainType !== account.chainType
102
- }
100
+ disabled={disabled}
103
101
  >
104
102
  <ListItemAvatar>
105
103
  <AccountAvatar chainId={account.chainId} account={account} />
@@ -109,15 +107,7 @@ export const ConnectedWalletsPage = (): JSX.Element => {
109
107
  secondary={walletAddress}
110
108
  />
111
109
  </ListItemButton>
112
- <ContextMenu
113
- items={menuItems}
114
- disabled={
115
- !!(
116
- requiredToChainType &&
117
- requiredToChainType !== account.chainType
118
- )
119
- }
120
- />
110
+ <ContextMenu items={menuItems} disabled={disabled} />
121
111
  </ListItem>
122
112
  )
123
113
  })}
@@ -35,7 +35,7 @@ export const RecentWalletsPage = (): JSX.Element => {
35
35
  const bookmarkAddressSheetRef = useRef<BottomSheetBase>(null)
36
36
  const listParentRef = useRef<HTMLUListElement | null>(null)
37
37
  const { recentWallets } = useBookmarks()
38
- const { requiredToChainType } = useToAddressRequirements()
38
+ const { isValidReceiver } = useToAddressRequirements()
39
39
  const {
40
40
  removeRecentWallet,
41
41
  addBookmark,
@@ -76,73 +76,66 @@ export const RecentWalletsPage = (): JSX.Element => {
76
76
  disablePadding
77
77
  sx={{ paddingTop: 1.5 }}
78
78
  >
79
- {recentWallets.map((recentWallet) => (
80
- <ListItem key={recentWallet.address} sx={{ position: 'relative' }}>
81
- <ListItemButton
82
- disabled={
83
- requiredToChainType &&
84
- requiredToChainType !== recentWallet.chainType
85
- }
86
- onClick={() => handleRecentSelected(recentWallet)}
87
- >
88
- <ListItemAvatar>
89
- <AccountAvatar
90
- chainId={defaultChainIdsByType[recentWallet.chainType]}
79
+ {recentWallets.map((recentWallet) => {
80
+ const disabled = !isValidReceiver(recentWallet.address)
81
+ const chainId =
82
+ recentWallet.chainId ??
83
+ defaultChainIdsByType[recentWallet.chainType]
84
+ return (
85
+ <ListItem key={recentWallet.address} sx={{ position: 'relative' }}>
86
+ <ListItemButton
87
+ disabled={disabled}
88
+ onClick={() => handleRecentSelected(recentWallet)}
89
+ >
90
+ <ListItemAvatar>
91
+ <AccountAvatar chainId={chainId} />
92
+ </ListItemAvatar>
93
+ <ListItemText
94
+ primary={
95
+ recentWallet.name || shortenAddress(recentWallet.address)
96
+ }
97
+ secondary={
98
+ recentWallet.name
99
+ ? shortenAddress(recentWallet.address)
100
+ : undefined
101
+ }
91
102
  />
92
- </ListItemAvatar>
93
- <ListItemText
94
- primary={
95
- recentWallet.name || shortenAddress(recentWallet.address)
96
- }
97
- secondary={
98
- recentWallet.name
99
- ? shortenAddress(recentWallet.address)
100
- : undefined
101
- }
102
- />
103
- </ListItemButton>
104
- <ContextMenu
105
- disabled={
106
- !!(
107
- requiredToChainType &&
108
- requiredToChainType !== recentWallet.chainType
109
- )
110
- }
111
- items={[
112
- {
113
- icon: <ContentCopyRounded />,
114
- label: t('button.copyAddress'),
115
- onClick: () =>
116
- navigator.clipboard.writeText(recentWallet.address),
117
- },
118
- {
119
- icon: <OpenInNewRounded />,
120
- label: t('button.viewOnExplorer'),
121
- onClick: () =>
122
- openInNewTab(
123
- getAddressLink(
124
- recentWallet.address,
125
- defaultChainIdsByType[recentWallet.chainType]
126
- )
127
- ),
128
- },
129
- {
130
- icon: <TurnedInNot />,
131
- label: t('button.bookmark'),
132
- onClick: () => {
133
- setBookmarkTarget(recentWallet)
134
- bookmarkAddressSheetRef.current?.open()
103
+ </ListItemButton>
104
+ <ContextMenu
105
+ disabled={disabled}
106
+ items={[
107
+ {
108
+ icon: <ContentCopyRounded />,
109
+ label: t('button.copyAddress'),
110
+ onClick: () =>
111
+ navigator.clipboard.writeText(recentWallet.address),
112
+ },
113
+ {
114
+ icon: <OpenInNewRounded />,
115
+ label: t('button.viewOnExplorer'),
116
+ onClick: () =>
117
+ openInNewTab(
118
+ getAddressLink(recentWallet.address, chainId)
119
+ ),
120
+ },
121
+ {
122
+ icon: <TurnedInNot />,
123
+ label: t('button.bookmark'),
124
+ onClick: () => {
125
+ setBookmarkTarget(recentWallet)
126
+ bookmarkAddressSheetRef.current?.open()
127
+ },
135
128
  },
136
- },
137
- {
138
- icon: <DeleteOutline />,
139
- label: t('button.delete'),
140
- onClick: () => removeRecentWallet(recentWallet.address),
141
- },
142
- ]}
143
- />
144
- </ListItem>
145
- ))}
129
+ {
130
+ icon: <DeleteOutline />,
131
+ label: t('button.delete'),
132
+ onClick: () => removeRecentWallet(recentWallet.address),
133
+ },
134
+ ]}
135
+ />
136
+ </ListItem>
137
+ )
138
+ })}
146
139
  {!recentWallets.length && (
147
140
  <EmptyListIndicator
148
141
  icon={<AccountBalanceWalletIcon />}
@@ -1,3 +1,4 @@
1
+ import { useChainTypeFromAddress } from '@lifi/widget-provider'
1
2
  import ContentCopyRounded from '@mui/icons-material/ContentCopyRounded'
2
3
  import OpenInNewRounded from '@mui/icons-material/OpenInNewRounded'
3
4
  import { List, ListItemAvatar, ListItemText } from '@mui/material'
@@ -25,7 +26,8 @@ export const SendToConfiguredWalletPage = (): JSX.Element => {
25
26
  const { t } = useTranslation()
26
27
  const navigateBack = useNavigateBack()
27
28
  const { toAddresses } = useWidgetConfig()
28
- const { requiredToChainType } = useToAddressRequirements()
29
+ const { isValidReceiver } = useToAddressRequirements()
30
+ const { getChainFromAddress } = useChainTypeFromAddress()
29
31
  const { setSelectedBookmark } = useBookmarkActions()
30
32
  const { setFieldValue } = useFieldActions()
31
33
  const { getAddressLink } = useExplorer()
@@ -53,57 +55,50 @@ export const SendToConfiguredWalletPage = (): JSX.Element => {
53
55
  disablePadding
54
56
  sx={{ paddingTop: 1.5 }}
55
57
  >
56
- {toAddresses?.map((toAddress) => (
57
- <ListItem key={toAddress.address} sx={{ position: 'relative' }}>
58
- <ListItemButton
59
- disabled={
60
- requiredToChainType &&
61
- requiredToChainType !== toAddress.chainType
62
- }
63
- onClick={() => handleCuratedSelected(toAddress)}
64
- >
65
- <ListItemAvatar>
66
- <AccountAvatar
67
- chainId={defaultChainIdsByType[toAddress.chainType]}
68
- toAddress={toAddress}
58
+ {toAddresses?.map((toAddress) => {
59
+ const disabled = !isValidReceiver(toAddress.address)
60
+ // A configured receiver has no chainId; its provider knows the chain.
61
+ const chainId =
62
+ getChainFromAddress(toAddress.address)?.chainId ??
63
+ defaultChainIdsByType[toAddress.chainType]
64
+ return (
65
+ <ListItem key={toAddress.address} sx={{ position: 'relative' }}>
66
+ <ListItemButton
67
+ disabled={disabled}
68
+ onClick={() => handleCuratedSelected(toAddress)}
69
+ >
70
+ <ListItemAvatar>
71
+ <AccountAvatar chainId={chainId} toAddress={toAddress} />
72
+ </ListItemAvatar>
73
+ <ListItemText
74
+ primary={toAddress.name || shortenAddress(toAddress.address)}
75
+ secondary={
76
+ toAddress.name
77
+ ? shortenAddress(toAddress.address)
78
+ : undefined
79
+ }
69
80
  />
70
- </ListItemAvatar>
71
- <ListItemText
72
- primary={toAddress.name || shortenAddress(toAddress.address)}
73
- secondary={
74
- toAddress.name ? shortenAddress(toAddress.address) : undefined
75
- }
81
+ </ListItemButton>
82
+ <ContextMenu
83
+ disabled={disabled}
84
+ items={[
85
+ {
86
+ icon: <ContentCopyRounded />,
87
+ label: t('button.copyAddress'),
88
+ onClick: () =>
89
+ navigator.clipboard.writeText(toAddress.address),
90
+ },
91
+ {
92
+ icon: <OpenInNewRounded />,
93
+ label: t('button.viewOnExplorer'),
94
+ onClick: () =>
95
+ openInNewTab(getAddressLink(toAddress.address, chainId)),
96
+ },
97
+ ]}
76
98
  />
77
- </ListItemButton>
78
- <ContextMenu
79
- disabled={
80
- !!(
81
- requiredToChainType &&
82
- requiredToChainType !== toAddress.chainType
83
- )
84
- }
85
- items={[
86
- {
87
- icon: <ContentCopyRounded />,
88
- label: t('button.copyAddress'),
89
- onClick: () =>
90
- navigator.clipboard.writeText(toAddress.address),
91
- },
92
- {
93
- icon: <OpenInNewRounded />,
94
- label: t('button.viewOnExplorer'),
95
- onClick: () =>
96
- openInNewTab(
97
- getAddressLink(
98
- toAddress.address,
99
- defaultChainIdsByType[toAddress.chainType]
100
- )
101
- ),
102
- },
103
- ]}
104
- />
105
- </ListItem>
106
- ))}
99
+ </ListItem>
100
+ )
101
+ })}
107
102
  </List>
108
103
  </PageContainer>
109
104
  )