@layerswap/widget 1.1.0 → 1.1.1

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 (187) hide show
  1. package/dist/esm/components/ErrorFallback.js +1 -1
  2. package/dist/esm/components/Icons/CircularLoader.js +5 -0
  3. package/dist/esm/components/Icons/FailIcon.js +2 -2
  4. package/dist/esm/components/Icons/GlobeIcon.js +3 -0
  5. package/dist/esm/components/Icons/MenuIcon.js +5 -0
  6. package/dist/esm/components/Icons/TokenIcon.js +1 -1
  7. package/dist/esm/components/Icons/Wallets/index.js +0 -2
  8. package/dist/esm/components/Input/Address/AddressNote.js +2 -2
  9. package/dist/esm/components/Input/Address/AddressPicker/AddressWithIcon.js +5 -2
  10. package/dist/esm/components/Input/Address/ContractAddressNote.js +17 -0
  11. package/dist/esm/components/Input/Address/UrlAddressNote.js +10 -0
  12. package/dist/esm/components/Input/Amount/ExchangeReceiveAmount.js +1 -1
  13. package/dist/esm/components/Input/Amount/PriceImpact.js +3 -5
  14. package/dist/esm/components/Input/Amount/ReceiveAmount.js +1 -1
  15. package/dist/esm/components/Input/RoutePicker/Content.js +17 -1
  16. package/dist/esm/components/Input/RoutePicker/RouteTokenSwitch.js +4 -4
  17. package/dist/esm/components/Input/RoutePicker/Routes.js +12 -11
  18. package/dist/esm/components/Input/RoutePicker/TokenTitleDetails.js +10 -0
  19. package/dist/esm/components/Input/RoutePicker/index.js +1 -1
  20. package/dist/esm/components/Menu/MenuList.js +11 -19
  21. package/dist/esm/components/Menu/index.js +16 -7
  22. package/dist/esm/components/Modal/modalWithoutAnimation.js +3 -3
  23. package/dist/esm/components/Pages/Campaigns/Details/index.js +1 -1
  24. package/dist/esm/components/Pages/Swap/Form/FeeDetails/Rate.js +3 -2
  25. package/dist/esm/components/Pages/Swap/Form/FeeDetails/Refuel.js +6 -1
  26. package/dist/esm/components/Pages/Swap/Form/FeeDetails/index.js +2 -2
  27. package/dist/esm/components/Pages/Swap/Form/FormWrapper.js +29 -2
  28. package/dist/esm/components/Pages/Swap/Form/NetworkForm.js +4 -3
  29. package/dist/esm/components/Pages/Swap/Form/SecondaryComponents/FormButton.js +1 -1
  30. package/dist/esm/components/Pages/Swap/Form/SecondaryComponents/validationError/ContractAddressValidationCache.js +19 -0
  31. package/dist/esm/components/Pages/Swap/Withdraw/Processing/Processing.js +9 -5
  32. package/dist/esm/components/Pages/Swap/Withdraw/Summary/Summary.js +2 -3
  33. package/dist/esm/components/Pages/Swap/Withdraw/Wallet/Common/buttons.js +13 -6
  34. package/dist/esm/components/Pages/Swap/Withdraw/WalletTransferButton.js +1 -1
  35. package/dist/esm/components/Pages/Swap/Withdraw/messages/Message.js +4 -4
  36. package/dist/esm/components/Pages/SwapHistory/History.js +1 -1
  37. package/dist/esm/components/Pages/SwapHistory/HistorySummary.js +1 -1
  38. package/dist/esm/components/Select/Selector/SelectItem.js +1 -1
  39. package/dist/esm/components/Wallet/WalletComponents/ConnectedWallets.js +4 -4
  40. package/dist/esm/components/Wallet/WalletModal/ConnectorsList.js +74 -125
  41. package/dist/esm/components/Wallet/WalletModal/InstalledExtensionNotFound.js +16 -0
  42. package/dist/esm/components/Wallet/WalletModal/LoadingConnect.js +27 -0
  43. package/dist/esm/components/Wallet/WalletModal/MultichainConnectorPicker.js +23 -0
  44. package/dist/esm/components/Wallet/WalletModal/ProviderPicker.js +26 -0
  45. package/dist/esm/components/Wallet/WalletModal/WalletQrCode.js +18 -0
  46. package/dist/esm/components/Wallet/WalletModal/index.js +1 -1
  47. package/dist/esm/components/Wallet/WalletProviders/index.js +1 -1
  48. package/dist/esm/components/Widget/Footer.js +20 -20
  49. package/dist/esm/components/Widget/Index.js +1 -1
  50. package/dist/esm/components/shadcn/checkbox.js +1 -1
  51. package/dist/esm/context/callbackProvider.js +6 -0
  52. package/dist/esm/context/resolverContext.js +5 -1
  53. package/dist/esm/hooks/useAllWithdrawalBalances.js +5 -0
  54. package/dist/esm/hooks/useConnectors.js +72 -0
  55. package/dist/esm/lib/address/contractAddressResolver.js +12 -0
  56. package/dist/esm/lib/apiClients/layerSwapApiClient.js +8 -1
  57. package/dist/esm/lib/balances/balanceResolver.js +52 -2
  58. package/dist/esm/lib/balances/errorUtils.js +13 -0
  59. package/dist/esm/lib/balances/nodeErrorClassifier.js +22 -0
  60. package/dist/esm/lib/fees.js +2 -2
  61. package/dist/esm/lib/generateSwapInitialValues.js +2 -2
  62. package/dist/esm/lib/isNewListed.js +8 -0
  63. package/dist/esm/lib/knownIds.js +1 -0
  64. package/dist/esm/lib/resolvers/resolverService.js +10 -1
  65. package/dist/esm/stores/balanceStore.js +39 -17
  66. package/dist/esm/stores/contractAddressStore.js +178 -0
  67. package/dist/esm/types/balance.js +15 -2
  68. package/dist/esm/types/contract.js +1 -0
  69. package/dist/esm/types/index.js +1 -0
  70. package/dist/index.css +1 -1
  71. package/dist/tsconfig.tsbuildinfo +1 -1
  72. package/dist/types/Models/Balance.d.ts +13 -1
  73. package/dist/types/Models/Balance.d.ts.map +1 -1
  74. package/dist/types/components/Icons/CircularLoader.d.ts +4 -0
  75. package/dist/types/components/Icons/CircularLoader.d.ts.map +1 -0
  76. package/dist/types/components/Icons/FailIcon.d.ts.map +1 -1
  77. package/dist/types/components/Icons/GasIcon.d.ts.map +1 -1
  78. package/dist/types/components/Icons/GlobeIcon.d.ts +4 -0
  79. package/dist/types/components/Icons/GlobeIcon.d.ts.map +1 -0
  80. package/dist/types/components/Icons/MenuIcon.d.ts +4 -0
  81. package/dist/types/components/Icons/MenuIcon.d.ts.map +1 -0
  82. package/dist/types/components/Icons/TokenIcon.d.ts.map +1 -1
  83. package/dist/types/components/Icons/Wallets/index.d.ts +0 -2
  84. package/dist/types/components/Icons/Wallets/index.d.ts.map +1 -1
  85. package/dist/types/components/Input/Address/AddressNote.d.ts +3 -3
  86. package/dist/types/components/Input/Address/AddressNote.d.ts.map +1 -1
  87. package/dist/types/components/Input/Address/AddressPicker/AddressWithIcon.d.ts +1 -0
  88. package/dist/types/components/Input/Address/AddressPicker/AddressWithIcon.d.ts.map +1 -1
  89. package/dist/types/components/Input/Address/ContractAddressNote.d.ts +9 -0
  90. package/dist/types/components/Input/Address/ContractAddressNote.d.ts.map +1 -0
  91. package/dist/types/components/Input/Address/UrlAddressNote.d.ts +10 -0
  92. package/dist/types/components/Input/Address/UrlAddressNote.d.ts.map +1 -0
  93. package/dist/types/components/Input/Amount/PriceImpact.d.ts +2 -1
  94. package/dist/types/components/Input/Amount/PriceImpact.d.ts.map +1 -1
  95. package/dist/types/components/Input/RoutePicker/Content.d.ts.map +1 -1
  96. package/dist/types/components/Input/RoutePicker/RouterPickerWalletConnect.d.ts.map +1 -1
  97. package/dist/types/components/Input/RoutePicker/Routes.d.ts.map +1 -1
  98. package/dist/types/components/Input/RoutePicker/TokenTitleDetails.d.ts +18 -0
  99. package/dist/types/components/Input/RoutePicker/TokenTitleDetails.d.ts.map +1 -0
  100. package/dist/types/components/Menu/MenuList.d.ts.map +1 -1
  101. package/dist/types/components/Menu/index.d.ts.map +1 -1
  102. package/dist/types/components/Modal/modalWithoutAnimation.d.ts +4 -2
  103. package/dist/types/components/Modal/modalWithoutAnimation.d.ts.map +1 -1
  104. package/dist/types/components/Pages/Swap/Form/FeeDetails/Rate.d.ts.map +1 -1
  105. package/dist/types/components/Pages/Swap/Form/FeeDetails/Refuel.d.ts +0 -1
  106. package/dist/types/components/Pages/Swap/Form/FeeDetails/Refuel.d.ts.map +1 -1
  107. package/dist/types/components/Pages/Swap/Form/FeeDetails/index.d.ts.map +1 -1
  108. package/dist/types/components/Pages/Swap/Form/FormWrapper.d.ts.map +1 -1
  109. package/dist/types/components/Pages/Swap/Form/NetworkForm.d.ts.map +1 -1
  110. package/dist/types/components/Pages/Swap/Form/SecondaryComponents/FormButton.d.ts.map +1 -1
  111. package/dist/types/components/Pages/Swap/Form/SecondaryComponents/validationError/ContractAddressValidationCache.d.ts +10 -0
  112. package/dist/types/components/Pages/Swap/Form/SecondaryComponents/validationError/ContractAddressValidationCache.d.ts.map +1 -0
  113. package/dist/types/components/Pages/Swap/Withdraw/Processing/Processing.d.ts.map +1 -1
  114. package/dist/types/components/Pages/Swap/Withdraw/Summary/Summary.d.ts.map +1 -1
  115. package/dist/types/components/Pages/Swap/Withdraw/Wallet/Common/buttons.d.ts.map +1 -1
  116. package/dist/types/components/Pages/Swap/Withdraw/WalletTransferButton.d.ts.map +1 -1
  117. package/dist/types/components/Pages/Swap/Withdraw/messages/Message.d.ts.map +1 -1
  118. package/dist/types/components/Pages/SwapHistory/HistorySummary.d.ts.map +1 -1
  119. package/dist/types/components/Select/Command/commandSelect.d.ts.map +1 -1
  120. package/dist/types/components/Select/Selector/SelectItem.d.ts.map +1 -1
  121. package/dist/types/components/Wallet/WalletModal/ConnectorsList.d.ts.map +1 -1
  122. package/dist/types/components/Wallet/WalletModal/InstalledExtensionNotFound.d.ts +7 -0
  123. package/dist/types/components/Wallet/WalletModal/InstalledExtensionNotFound.d.ts.map +1 -0
  124. package/dist/types/components/Wallet/WalletModal/LoadingConnect.d.ts +8 -0
  125. package/dist/types/components/Wallet/WalletModal/LoadingConnect.d.ts.map +1 -0
  126. package/dist/types/components/Wallet/WalletModal/MultichainConnectorPicker.d.ts +12 -0
  127. package/dist/types/components/Wallet/WalletModal/MultichainConnectorPicker.d.ts.map +1 -0
  128. package/dist/types/components/Wallet/WalletModal/ProviderPicker.d.ts +8 -0
  129. package/dist/types/components/Wallet/WalletModal/ProviderPicker.d.ts.map +1 -0
  130. package/dist/types/components/Wallet/WalletModal/WalletQrCode.d.ts +6 -0
  131. package/dist/types/components/Wallet/WalletModal/WalletQrCode.d.ts.map +1 -0
  132. package/dist/types/components/Wallet/WalletModal/index.d.ts +1 -0
  133. package/dist/types/components/Wallet/WalletModal/index.d.ts.map +1 -1
  134. package/dist/types/components/Widget/Footer.d.ts.map +1 -1
  135. package/dist/types/context/callbackProvider.d.ts +1 -0
  136. package/dist/types/context/callbackProvider.d.ts.map +1 -1
  137. package/dist/types/context/resolverContext.d.ts.map +1 -1
  138. package/dist/types/context/swapAccounts.d.ts.map +1 -1
  139. package/dist/types/context/walletProviders.d.ts.map +1 -1
  140. package/dist/types/hooks/useAllWithdrawalBalances.d.ts.map +1 -1
  141. package/dist/types/hooks/useConnectors.d.ts +28 -0
  142. package/dist/types/hooks/useConnectors.d.ts.map +1 -0
  143. package/dist/types/lib/address/contractAddressResolver.d.ts +7 -0
  144. package/dist/types/lib/address/contractAddressResolver.d.ts.map +1 -0
  145. package/dist/types/lib/apiClients/layerSwapApiClient.d.ts.map +1 -1
  146. package/dist/types/lib/balances/balanceResolver.d.ts.map +1 -1
  147. package/dist/types/lib/balances/errorUtils.d.ts +12 -0
  148. package/dist/types/lib/balances/errorUtils.d.ts.map +1 -0
  149. package/dist/types/lib/balances/nodeErrorClassifier.d.ts +4 -0
  150. package/dist/types/lib/balances/nodeErrorClassifier.d.ts.map +1 -0
  151. package/dist/types/lib/fees.d.ts +2 -2
  152. package/dist/types/lib/fees.d.ts.map +1 -1
  153. package/dist/types/lib/isNewListed.d.ts +4 -0
  154. package/dist/types/lib/isNewListed.d.ts.map +1 -0
  155. package/dist/types/lib/knownIds.d.ts +1 -0
  156. package/dist/types/lib/knownIds.d.ts.map +1 -1
  157. package/dist/types/lib/resolvers/resolverService.d.ts +5 -2
  158. package/dist/types/lib/resolvers/resolverService.d.ts.map +1 -1
  159. package/dist/types/stores/balanceStore.d.ts +3 -0
  160. package/dist/types/stores/balanceStore.d.ts.map +1 -1
  161. package/dist/types/stores/contractAddressStore.d.ts +43 -0
  162. package/dist/types/stores/contractAddressStore.d.ts.map +1 -0
  163. package/dist/types/types/balance.d.ts.map +1 -1
  164. package/dist/types/types/contract.d.ts +6 -0
  165. package/dist/types/types/contract.d.ts.map +1 -0
  166. package/dist/types/types/index.d.ts +1 -0
  167. package/dist/types/types/index.d.ts.map +1 -1
  168. package/dist/types/types/logEvents.d.ts +19 -1
  169. package/dist/types/types/logEvents.d.ts.map +1 -1
  170. package/dist/types/types/wallet.d.ts +6 -3
  171. package/dist/types/types/wallet.d.ts.map +1 -1
  172. package/package.json +1 -1
  173. package/dist/esm/components/Icons/Wallets/Keplr.js +0 -3
  174. package/dist/esm/components/Icons/Wallets/Xverse.js +0 -3
  175. package/dist/esm/components/Modal/popover.js +0 -15
  176. package/dist/esm/components/Wallet/WalletModal/utils.js +0 -23
  177. package/dist/esm/lib/sorting.js +0 -63
  178. package/dist/types/components/Icons/Wallets/Keplr.d.ts +0 -4
  179. package/dist/types/components/Icons/Wallets/Keplr.d.ts.map +0 -1
  180. package/dist/types/components/Icons/Wallets/Xverse.d.ts +0 -4
  181. package/dist/types/components/Icons/Wallets/Xverse.d.ts.map +0 -1
  182. package/dist/types/components/Modal/popover.d.ts +0 -12
  183. package/dist/types/components/Modal/popover.d.ts.map +0 -1
  184. package/dist/types/components/Wallet/WalletModal/utils.d.ts +0 -2
  185. package/dist/types/components/Wallet/WalletModal/utils.d.ts.map +0 -1
  186. package/dist/types/lib/sorting.d.ts +0 -22
  187. package/dist/types/lib/sorting.d.ts.map +0 -1
@@ -1,23 +1,25 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useEffect, useMemo, useRef, useState } from "react";
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
3
3
  import useWallet from "../../../hooks/useWallet";
4
4
  import { useConnectModal } from ".";
5
- import { CircleX, Link2Off, RotateCw, SlidersHorizontal } from "lucide-react";
6
- import { resolveWalletConnectorIcon } from "../../../lib/wallets/utils/resolveWalletIcon";
7
- import { QRCodeSVG } from "qrcode.react";
8
- import CopyButton from "../../../components/Buttons/copyButton";
9
5
  import clsx from "clsx";
10
6
  import useWindowDimensions from "../../../hooks/useWindowDimensions";
11
7
  import Connector from "./Connector";
12
- import { removeDuplicatesWithKey } from "./utils";
13
8
  import { usePersistedState } from "../../../hooks/usePersistedState";
14
- import { Popover, PopoverContent, PopoverTrigger } from "../../../components/shadcn/popover";
15
- import LayerSwapLogoSmall from "../../../components/Icons/layerSwapLogoSmall";
16
- import { Checkbox } from "../../../components/shadcn/checkbox";
17
- import { ImageWithFallback } from "../../../components/Common/ImageWithFallback";
18
9
  import { SearchComponent } from "../../../components/Input/Search";
19
10
  import { isMobile } from "../../../lib/wallets/utils/isMobile";
20
11
  import AppSettings from "../../../lib/AppSettings";
12
+ import { MultichainConnectorPicker } from "./MultichainConnectorPicker";
13
+ import { ProviderPicker } from "./ProviderPicker";
14
+ import { InstalledExtensionNotFound } from "./InstalledExtensionNotFound";
15
+ import { WalletQrCode } from "./WalletQrCode";
16
+ import { LoadingConnect } from "./LoadingConnect";
17
+ import CircularLoader from "../../../components/Icons/CircularLoader";
18
+ import { useConnectors } from "../../../hooks/useConnectors";
19
+ const LAZY_LOAD_CONFIG = {
20
+ itemsPerLoad: 20,
21
+ enabled: true
22
+ };
21
23
  const ConnectorsList = ({ onFinish }) => {
22
24
  const { providers } = useWallet();
23
25
  const { setSelectedConnector, selectedProvider, setSelectedProvider, selectedConnector, selectedMultiChainConnector, setSelectedMultiChainConnector } = useConnectModal();
@@ -26,7 +28,11 @@ const ConnectorsList = ({ onFinish }) => {
26
28
  const [searchValue, setSearchValue] = useState(undefined);
27
29
  const [isScrolling, setIsScrolling] = useState(false);
28
30
  const scrollTimeout = useRef(null);
31
+ const isMobilePlatfrom = isMobile();
29
32
  const { isMobile: isMobileSize } = useWindowDimensions();
33
+ const [displayedCount, setDisplayedCount] = useState(LAZY_LOAD_CONFIG.itemsPerLoad);
34
+ const [isLoadingMore, setIsLoadingMore] = useState(false);
35
+ const loadMoreTriggerRef = useRef(null);
30
36
  const handleScroll = () => {
31
37
  setIsScrolling(true);
32
38
  if (scrollTimeout.current)
@@ -46,6 +52,8 @@ const ConnectorsList = ({ onFinish }) => {
46
52
  return;
47
53
  }
48
54
  setSelectedConnector(connector);
55
+ if (connector?.hasBrowserExtension && !connector?.showQrCode && connector.type == 'walletConnect' && !isMobilePlatfrom)
56
+ return;
49
57
  if (connector.installUrl)
50
58
  return;
51
59
  if (provider.ready === false) {
@@ -85,129 +93,70 @@ const ConnectorsList = ({ onFinish }) => {
85
93
  }
86
94
  }
87
95
  };
88
- const handleSelectProvider = (providerName) => {
89
- const provider = filteredProviders.find(p => p.name === providerName);
90
- if (!provider)
91
- return setSelectedProvider(undefined);
92
- setSelectedProvider({ ...provider, isSelectedFromFilter: true });
96
+ const [selectedProviderNames, setSelectedProviderNames] = useState([]);
97
+ const isFiltered = selectedProviderNames.length > 0 || !!searchValue;
98
+ const handleSelectProvider = (providerNames) => {
99
+ setSelectedProviderNames(providerNames);
100
+ if (providerNames.length === 0) {
101
+ setSelectedProvider(undefined);
102
+ }
103
+ else {
104
+ const provider = filteredProviders.find(p => p.name === providerNames[0]);
105
+ if (provider) {
106
+ setSelectedProvider({ ...provider, isSelectedFromFilter: true });
107
+ }
108
+ }
93
109
  };
94
110
  const filteredProviders = providers.filter(p => !p.hideFromList);
95
- const featuredProviders = selectedProvider ? [selectedProvider] : filteredProviders;
96
- const allFeaturedConnectors = useMemo(() => featuredProviders.filter(g => g.availableWalletsForConnect && g.availableWalletsForConnect?.length > 0).map((provider) => provider.availableWalletsForConnect?.filter(v => searchValue ? (v.name.toLowerCase().includes(searchValue?.toLowerCase())) : true).map((connector) => ({ ...connector, providerName: provider.name }))).flat(), [featuredProviders, searchValue]);
97
- const allHiddenConnectors = useMemo(() => featuredProviders
98
- .filter(g => g.availableHiddenWalletsForConnect && g.availableHiddenWalletsForConnect?.length > 0)
99
- .map((provider) => provider.availableHiddenWalletsForConnect
100
- ?.filter(v => (searchValue ? (v.name.toLowerCase().includes(searchValue?.toLowerCase())) : true) && !featuredWalletsIds.includes(v.id.toLowerCase()))
101
- .map((connector) => ({ ...connector, providerName: provider.name, isHidden: true })))
102
- .flat(), [featuredProviders, searchValue]);
103
- const allConnectors = useMemo(() => removeDuplicatesWithKey([...allFeaturedConnectors, ...allHiddenConnectors].filter(c => searchValue?.length ? true : !c.isHidden).sort((a, b) => sortRecentConnectors(a, b, recentConnectors)), 'name'), [allFeaturedConnectors, allHiddenConnectors, searchValue?.length]);
104
- if (selectedConnector?.qr?.state) {
105
- const ConnectorIcon = resolveWalletConnectorIcon({ connector: selectedConnector, iconUrl: selectedConnector.icon });
106
- return _jsxs("div", { className: "flex flex-col justify-start space-y-2", children: [_jsx("p", { className: "text-secondary-text", children: "Scan the QR code with your phone" }), _jsx("div", { className: "w-full h-full bg-secondary-600 py-3 rounded-lg", children: _jsxs("div", { className: 'flex flex-col justify-center items-center pt-2 w-fit mx-auto', children: [selectedConnector?.qr.state == 'fetched' ?
107
- _jsx(QRCodeSVG, { className: "rounded-lg", value: selectedConnector?.qr.value, includeMargin: true, size: 264, level: "H", imageSettings: selectedConnector.icon
108
- ? {
109
- src: selectedConnector.icon,
110
- height: 50,
111
- width: 50,
112
- excavate: true,
113
- }
114
- : undefined })
115
- :
116
- _jsxs("div", { className: "w-[264px] h-[264px] relative", children: [_jsx("div", { className: "w-full h-full bg-secondary-500 animate-pulse rounded-xl" }), _jsx(ConnectorIcon, { className: 'h-[50px] w-[50px] absolute top-[calc(50%-25px)] right-[calc(50%-25px)]' })] }), _jsx("div", { className: 'bg-secondary-400 text-secondary-text w-full px-2 py-1.5 rounded-md mt-3 flex justify-center items-center', children: _jsx(CopyButton, { disabled: !selectedConnector?.qr.value, toCopy: selectedConnector?.qr.value || '', children: "Copy QR URL" }) })] }) })] });
111
+ const featuredProviders = selectedProviderNames.length > 0 ? filteredProviders.filter(p => selectedProviderNames.includes(p.name)) : (selectedProvider ? [selectedProvider] : filteredProviders);
112
+ const { featuredConnectors, hiddenConnectors, initialConnectors, } = useConnectors({
113
+ featuredProviders,
114
+ filteredProviders,
115
+ searchValue,
116
+ recentConnectors,
117
+ });
118
+ const displayedConnectors = useMemo(() => {
119
+ if (isFiltered)
120
+ return initialConnectors.slice(0, displayedCount);
121
+ return initialConnectors.slice(0, Math.max(0, displayedCount - featuredConnectors.length));
122
+ }, [isFiltered, initialConnectors, featuredConnectors, displayedCount]);
123
+ const hasMoreToLoad = displayedCount < initialConnectors.length;
124
+ useEffect(() => setDisplayedCount(isFiltered ? LAZY_LOAD_CONFIG.itemsPerLoad : featuredConnectors.length + LAZY_LOAD_CONFIG.itemsPerLoad), [isFiltered, searchValue, selectedProviderNames, featuredConnectors.length]);
125
+ const loadMore = useCallback(() => {
126
+ if (!hasMoreToLoad || isLoadingMore)
127
+ return;
128
+ setIsLoadingMore(true);
129
+ setTimeout(() => { setDisplayedCount(prev => prev + LAZY_LOAD_CONFIG.itemsPerLoad); setIsLoadingMore(false); }, 300);
130
+ }, [hasMoreToLoad, isLoadingMore]);
131
+ useEffect(() => {
132
+ if (!loadMoreTriggerRef.current)
133
+ return;
134
+ const observer = new IntersectionObserver((e) => e[0].isIntersecting && hasMoreToLoad && !isLoadingMore && loadMore(), { threshold: 0.1, rootMargin: '100px' });
135
+ observer.observe(loadMoreTriggerRef.current);
136
+ return () => observer.disconnect();
137
+ }, [hasMoreToLoad, isLoadingMore, loadMore, selectedConnector, selectedMultiChainConnector]);
138
+ if (selectedConnector?.hasBrowserExtension && !selectedConnector?.showQrCode && selectedConnector.type == 'walletConnect' && !isMobilePlatfrom) {
139
+ const provider = featuredProviders.find(p => p.name === selectedConnector?.providerName);
140
+ return _jsx(InstalledExtensionNotFound, { selectedConnector: selectedConnector, onConnect: (connector) => { connect(connector, provider); } });
141
+ }
142
+ if (selectedConnector?.qr?.state && (!selectedConnector?.hasBrowserExtension || selectedConnector?.showQrCode)) {
143
+ return _jsx(WalletQrCode, { selectedConnector: selectedConnector });
117
144
  }
118
145
  if (selectedConnector) {
119
- const connector = allFeaturedConnectors.find(c => c?.name === selectedConnector.name);
120
- const provider = featuredProviders.find(p => p.name === connector?.providerName);
121
- return _jsx(LoadingConnect, { onRetry: () => { (connector && provider) && connect(connector, provider); }, selectedConnector: selectedConnector, connectionError: connectionError });
146
+ const provider = featuredProviders.find(p => p.name === selectedConnector?.providerName);
147
+ return _jsx(LoadingConnect, { onRetry: () => { (selectedConnector && provider) && connect(selectedConnector, provider); }, selectedConnector: selectedConnector, connectionError: connectionError });
122
148
  }
123
149
  if (selectedMultiChainConnector) {
124
- return _jsx(MultichainConnectorPicker, { selectedConnector: selectedMultiChainConnector, allConnectors: [...allFeaturedConnectors, ...allHiddenConnectors], providers: featuredProviders, connect: connect });
150
+ return _jsx(MultichainConnectorPicker, { selectedConnector: selectedMultiChainConnector, allConnectors: [...featuredConnectors, ...hiddenConnectors], providers: featuredProviders, connect: connect });
125
151
  }
126
- return (_jsx(_Fragment, { children: _jsxs("div", { className: "text-primary-text space-y-3 flex flex-col w-full styled-scroll relative h-full", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(SearchComponent, { searchQuery: searchValue || "", setSearchQuery: setSearchValue, placeholder: allHiddenConnectors.length > 300 ? "Search through 400+ wallets..." : "Search wallet", className: "w-full" }), (!selectedProvider || selectedProvider?.isSelectedFromFilter) &&
127
- _jsx(ProviderPicker, { providers: filteredProviders, selectedProviderName: selectedProvider?.name, setSelectedProviderName: handleSelectProvider })] }), _jsx("div", { onScroll: handleScroll, className: clsx('overflow-y-scroll -mr-4 pr-2 scrollbar:!w-1.5 scrollbar:!h-1.5 overflow-x-hidden scrollbar-thumb:bg-transparent', {
152
+ return (_jsx(_Fragment, { children: _jsxs("div", { className: "text-primary-text space-y-3 flex flex-col w-full styled-scroll relative h-full", children: [_jsxs("div", { className: "flex items-center gap-3 pt-1", children: [_jsx(SearchComponent, { searchQuery: searchValue || "", setSearchQuery: setSearchValue, placeholder: hiddenConnectors.length > 300 ? "Search through 400+ wallets..." : "Search wallet", className: "w-full mb-0!" }), (!selectedProvider || selectedProvider?.isSelectedFromFilter) &&
153
+ _jsx(ProviderPicker, { providers: filteredProviders, selectedProviderNames: selectedProviderNames, setSelectedProviderNames: handleSelectProvider })] }), _jsxs("div", { onScroll: handleScroll, className: clsx('overflow-y-scroll -mr-4 pr-2 scrollbar:!w-1.5 scrollbar:!h-1.5 overflow-x-hidden scrollbar-thumb:bg-transparent', {
128
154
  'max-sm:h-[55svh]': isMobileSize && AppSettings.ThemeData?.enablePortal,
129
155
  'styled-scroll': isScrolling
130
- }), children: _jsx("div", { className: 'grid grid-cols-2 gap-2', children: allConnectors.map(item => {
131
- const provider = featuredProviders.find(p => p.name === item.providerName);
132
- const isRecent = recentConnectors?.some(v => v.connectorName === item.name);
133
- return (_jsx(Connector, { connector: item, onClick: () => connect(item, provider), connectingConnector: selectedConnector, isRecent: isRecent, isProviderReady: typeof provider?.ready === 'boolean' ? provider.ready : true }, item.id));
134
- }) }) })] }) }));
135
- };
136
- const LoadingConnect = ({ onRetry, selectedConnector, connectionError }) => {
137
- const ConnectorIcon = resolveWalletConnectorIcon({ connector: selectedConnector, iconUrl: selectedConnector.icon });
138
- const { isMobile: isMobileSize } = useWindowDimensions();
139
- const isMobilePlatform = isMobile();
140
- if (selectedConnector.installUrl) {
141
- return _jsx("div", { className: clsx('w-full sm:h-full flex flex-col justify-center items-center font-semibold relative', {
142
- 'h-[60vh]': isMobileSize && AppSettings.ThemeData?.enablePortal,
143
- 'h-[300px]': isMobileSize && !AppSettings.ThemeData?.enablePortal,
144
- }), children: _jsx("div", { className: "flex grow items-center", children: _jsxs("div", { className: "flex flex-col gap-4 items-center justify-end row-start-2 row-span-1", children: [_jsxs("div", { className: "flex-col flex items-center gap-1", children: [_jsx(ConnectorIcon, { className: "w-11 h-auto p-0.5 rounded-md bg-secondary-800" }), _jsxs("p", { className: 'text-base font-semibold', children: [_jsx("span", { children: selectedConnector?.name }), " ", _jsx("span", { children: "is not installed" })] })] }), _jsx("button", { onClick: () => window.open(selectedConnector.installUrl, '_blank'), type: "button", className: "px-3 py-1 rounded-full bg-secondary-600 text-primary-500 font-semibold text-base hover:brightness-125 transition-all duration-200", children: "INSTALL" })] }) }) });
145
- }
146
- return (_jsxs("div", { className: clsx('w-full flex flex-col justify-center items-center font-semibold relative', {
147
- 'h-[60vh]': isMobileSize && AppSettings.ThemeData?.enablePortal,
148
- 'h-full': !isMobileSize || !AppSettings.ThemeData?.enablePortal,
149
- 'h-[300px]!': isMobileSize && !AppSettings.ThemeData?.enablePortal,
150
- }), children: [selectedConnector &&
151
- _jsx("div", { className: "flex grow items-center", children: _jsxs("div", { className: "flex flex-col gap-3 items-center justify-end row-start-2 row-span-1", children: [_jsx("div", { className: "flex-col flex items-center", children: _jsxs("div", { className: "grid grid-cols-3 items-center gap-2", children: [_jsx("div", { className: "p-3 bg-secondary-700 rounded-lg z-10", children: _jsx(LayerSwapLogoSmall, { className: "w-11 h-auto" }) }), connectionError ?
152
- _jsx(Link2Off, { className: "w-auto h-auto place-self-center" })
153
- :
154
- _jsx("div", { className: "loader !text-[3px] place-self-center" }), _jsx("div", { className: "p-3 bg-secondary-700 rounded-lg z-10", children: _jsx(ConnectorIcon, { className: "w-11 h-auto" }) })] }) }), !connectionError &&
155
- _jsxs("div", { className: "py-1 text-center", children: [_jsx("p", { className: "text-base font-medium", children: isMobilePlatform ? 'Approve connection in your wallet' : 'Approve connection in your wallet pop-up' }), _jsx("p", { className: "text-sm font-normal text-secondary-text", children: isMobilePlatform ? "Don't see the request? Check your wallet app." : "Don't see a pop-up? Check your browser windows." })] })] }) }), connectionError &&
156
- _jsxs("div", { className: `bg-secondary-500 rounded-lg flex flex-col gap-1.5 items-center p-3 w-full bottom-0`, children: [_jsxs("div", { className: "flex w-full gap-1 text-sm text-secondary-text justify-start", children: [_jsx(CircleX, { className: "w-5 h-5 stroke-primary-500 mr-1 mt-0.5 flex-shrink-0" }), _jsxs("div", { className: 'flex flex-col gap-1', children: [_jsx("p", { className: 'text-base text-primary-text', children: "Failed to connect" }), _jsx("p", { className: "text-sm font-normal", children: connectionError })] })] }), _jsxs("button", { type: "button", className: "flex gap-1.5 items-center justify-center bg-secondary-400 w-full text-primary-text p-4 border-none rounded-lg cursor-pointer text-sm font-medium leading-4", onClick: onRetry, children: [_jsx(RotateCw, { className: 'h-4 w-4' }), _jsx("span", { children: "Try again" })] })] })] }));
157
- };
158
- const ProviderPicker = ({ providers, selectedProviderName, setSelectedProviderName }) => {
159
- const values = providers.map(p => p.name);
160
- const onSelect = (item) => {
161
- setOpen(false);
162
- if (selectedProviderName === item)
163
- return setSelectedProviderName(undefined);
164
- setSelectedProviderName(item);
165
- };
166
- const [open, setOpen] = useState(false);
167
- return (_jsxs(Popover, { open: open, onOpenChange: () => setOpen(!open), children: [_jsx(PopoverTrigger, { className: clsx('p-3 border border-secondary-400 rounded-lg bg-secondary-500 hover:brightness-125', {
168
- '!bg-secondary-400 brightness-125': !!selectedProviderName,
169
- }), children: _jsx(SlidersHorizontal, { className: "h-4 w-4 text-secondary-text" }) }), _jsx(PopoverContent, { align: "end", className: "min-w-40 !text-primary-text p-2 space-y-1 !bg-secondary-600 !rounded-xl", children: values.sort().map((item, index) => (_jsxs("div", { className: "px-3 py-1 text-left flex items-center w-full gap-3 hover:bg-secondary-800 rounded-lg transition-colors duration-200 text-secondary-text cursor-pointer", children: [_jsx(Checkbox, { id: item, checked: selectedProviderName === item, onClick: () => onSelect(item) }), _jsx("label", { htmlFor: item, className: "w-full cursor-pointer", children: item })] }, index))) })] }));
156
+ }), children: [_jsx("div", { className: 'grid grid-cols-2 gap-2', children: displayedConnectors.map(item => {
157
+ const provider = featuredProviders.find(p => p.name === item.providerName);
158
+ const isRecent = recentConnectors?.some(v => v.connectorName === item.name);
159
+ return (_jsx(Connector, { connector: item, onClick: () => connect(item, provider), connectingConnector: selectedConnector, isRecent: isRecent, isProviderReady: typeof provider?.ready === 'boolean' ? provider.ready : true }, item.id));
160
+ }) }), hasMoreToLoad && (_jsx("div", { ref: loadMoreTriggerRef, className: "col-span-2 flex justify-center items-center pt-2.5", children: _jsx(CircularLoader, { className: "w-8 h-8 animate-spin" }) }))] })] }) }));
170
161
  };
171
- const MultichainConnectorPicker = ({ selectedConnector, allConnectors, providers, connect }) => {
172
- const Icon = resolveWalletConnectorIcon({ connector: selectedConnector, iconUrl: selectedConnector.icon });
173
- return (_jsxs("div", { className: "flex flex-col justify-between h-full min-h-80", children: [_jsx("div", { className: "flex grow py-4", children: _jsxs("div", { className: "flex flex-col gap-2 grow items-center justify-center", children: [_jsx("div", { className: "flex justify-center gap-1", children: _jsx(Icon, { className: "w-14 h-auto rounded-lg" }) }), _jsxs("p", { className: "text-base text-center text-primary-text px-4", children: [_jsx("span", { children: selectedConnector.name }), " ", _jsx("span", { children: "supports multiple network types. Please select the one you'd like to use." })] })] }) }), _jsx("div", { className: "flex flex-col gap-2 w-full", children: Array.from(allConnectors
174
- .filter(c => c?.name === selectedConnector.name)
175
- .reduce((map, connector) => {
176
- if (!connector?.providerName)
177
- return map;
178
- if (!map.has(connector.providerName)) {
179
- map.set(connector.providerName, connector);
180
- }
181
- return map;
182
- }, new Map())
183
- .values()).map((connector, index) => {
184
- const provider = providers.find(p => p.name === connector?.providerName);
185
- return (_jsxs("button", { type: "button", onClick: async () => {
186
- await connect(connector, provider);
187
- }, className: "w-full h-fit flex items-center gap-3 bg-secondary-500 hover:bg-secondary-400 transition-colors duration-200 rounded-xl p-3", children: [provider?.providerIcon &&
188
- _jsx(ImageWithFallback, { className: "w-8 h-8 rounded-md", width: 30, height: 30, src: provider.providerIcon, alt: provider.name }), _jsx("p", { children: connector?.providerName })] }, index));
189
- }) })] }));
190
- };
191
- const featuredWalletsIds = [
192
- 'metamask',
193
- 'argent',
194
- 'rainbow',
195
- 'bitkeep',
196
- 'okx-wallet',
197
- ];
198
- function sortRecentConnectors(a, b, recentConnectors) {
199
- function getIndex(c) {
200
- const idx = recentConnectors?.findIndex(v => v.connectorName === c.name);
201
- return idx === -1 ? Infinity : idx;
202
- }
203
- const indexA = getIndex(a);
204
- const indexB = getIndex(b);
205
- if (indexA !== indexB) {
206
- return indexA - indexB;
207
- }
208
- if (a.type && b.type) {
209
- return a.type.localeCompare(b.type);
210
- }
211
- return 0;
212
- }
213
162
  export default ConnectorsList;
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ScanLine } from "lucide-react";
3
+ import { resolveWalletConnectorIcon } from "../../../lib/wallets/utils/resolveWalletIcon";
4
+ import SubmitButton from "../../../components/Buttons/submitButton";
5
+ import { AppSettings } from "../../../exports/internal";
6
+ import clsx from "clsx";
7
+ import useWindowDimensions from "../../../hooks/useWindowDimensions";
8
+ export const InstalledExtensionNotFound = ({ selectedConnector, onConnect }) => {
9
+ const ConnectorIcon = resolveWalletConnectorIcon({ connector: selectedConnector, iconUrl: selectedConnector.icon });
10
+ const { isMobile: isMobileSize } = useWindowDimensions();
11
+ return _jsxs("div", { className: clsx('w-full flex flex-col justify-center items-center font-semibold relative', {
12
+ 'h-[60vh]': isMobileSize && AppSettings.ThemeData?.enablePortal,
13
+ 'h-full': !isMobileSize || !AppSettings.ThemeData?.enablePortal,
14
+ 'h-[300px]!': isMobileSize && !AppSettings.ThemeData?.enablePortal,
15
+ }), children: [_jsx("div", { className: "flex grow items-center justify-center", children: _jsxs("div", { className: "flex-col flex items-center gap-1", children: [_jsx(ConnectorIcon, { className: "w-11 h-auto p-0.5 rounded-md bg-secondary-800" }), _jsxs("div", { className: "py-1 text-center text-base font-medium", children: [_jsx("p", { children: "Wallet not found on your browser," }), _jsx("p", { children: "make sure you have the wallet installed" })] })] }) }), _jsx(SubmitButton, { onClick: () => { onConnect({ ...selectedConnector, showQrCode: true }); }, buttonStyle: "secondary", className: "w-full", children: _jsxs("span", { className: "flex items-center justify-center gap-2", children: [_jsx(ScanLine, { className: "w-5 h-5" }), _jsx("span", { children: "Connect with your phone" })] }) })] });
16
+ };
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CircleX, Link2Off, RotateCw } from "lucide-react";
3
+ import { resolveWalletConnectorIcon } from "../../../lib/wallets/utils/resolveWalletIcon";
4
+ import clsx from "clsx";
5
+ import useWindowDimensions from "../../../hooks/useWindowDimensions";
6
+ import LayerSwapLogoSmall from "../../../components/Icons/layerSwapLogoSmall";
7
+ import { isMobile } from "../../../lib/wallets/utils/isMobile";
8
+ import AppSettings from "../../../lib/AppSettings";
9
+ export const LoadingConnect = ({ onRetry, selectedConnector, connectionError }) => {
10
+ const ConnectorIcon = resolveWalletConnectorIcon({ connector: selectedConnector, iconUrl: selectedConnector.icon });
11
+ const { isMobile: isMobileSize } = useWindowDimensions();
12
+ const isMobilePlatform = isMobile();
13
+ if (selectedConnector.installUrl) {
14
+ return _jsx("div", { className: 'w-full h-[60vh] sm:h-full flex flex-col justify-center items-center font-semibold relative', children: _jsx("div", { className: "flex grow items-center", children: _jsxs("div", { className: "flex flex-col gap-4 items-center justify-end row-start-2 row-span-1", children: [_jsxs("div", { className: "flex-col flex items-center gap-1", children: [_jsx(ConnectorIcon, { className: "w-11 h-auto p-0.5 rounded-md bg-secondary-800" }), _jsxs("p", { className: 'text-base font-semibold', children: [_jsx("span", { children: selectedConnector?.name }), " ", _jsx("span", { children: "is not installed" })] })] }), _jsx("button", { onClick: () => window.open(selectedConnector.installUrl, '_blank'), type: "button", className: "px-3 py-1 rounded-full bg-secondary-600 text-primary-500 font-semibold text-base hover:brightness-125 transition-all duration-200", children: "INSTALL" })] }) }) });
15
+ }
16
+ return (_jsxs("div", { className: clsx('w-full flex flex-col justify-center items-center font-semibold relative', {
17
+ 'h-[60vh]': isMobileSize && AppSettings.ThemeData?.enablePortal,
18
+ 'h-full': !isMobileSize || !AppSettings.ThemeData?.enablePortal,
19
+ 'h-[300px]!': isMobileSize && !AppSettings.ThemeData?.enablePortal,
20
+ }), children: [selectedConnector &&
21
+ _jsx("div", { className: "flex grow items-center", children: _jsxs("div", { className: "flex flex-col gap-3 items-center justify-end row-start-2 row-span-1", children: [_jsx("div", { className: "flex-col flex items-center", children: _jsxs("div", { className: "grid grid-cols-3 items-center gap-2", children: [_jsx("div", { className: "p-3 bg-secondary-700 rounded-lg z-10", children: _jsx(LayerSwapLogoSmall, { className: "w-11 h-auto" }) }), connectionError ?
22
+ _jsx(Link2Off, { className: "w-auto h-auto place-self-center" })
23
+ :
24
+ _jsx("div", { className: "loader text-[3px]! place-self-center" }), _jsx("div", { className: "p-3 bg-secondary-700 rounded-lg z-10", children: _jsx(ConnectorIcon, { className: "w-11 h-auto" }) })] }) }), !connectionError &&
25
+ _jsxs("div", { className: "py-1 text-center", children: [_jsx("p", { className: "text-base font-medium", children: isMobilePlatform ? 'Approve connection in your wallet' : 'Approve connection in your wallet pop-up' }), _jsx("p", { className: "text-sm font-normal text-secondary-text", children: isMobilePlatform ? "Don't see the request? Check your wallet app." : "Don't see a pop-up? Check your browser windows." })] })] }) }), connectionError &&
26
+ _jsxs("div", { className: `bg-secondary-500 rounded-lg flex flex-col gap-1.5 items-center p-3 w-full bottom-0`, children: [_jsxs("div", { className: "flex w-full gap-1 text-sm text-secondary-text justify-start", children: [_jsx(CircleX, { className: "w-5 h-5 stroke-primary-500 mr-1 mt-0.5 shrink-0" }), _jsxs("div", { className: 'flex flex-col gap-1', children: [_jsx("p", { className: 'text-base text-primary-text', children: "Failed to connect" }), _jsx("p", { className: "text-sm font-normal", children: connectionError })] })] }), _jsxs("button", { type: "button", className: "flex gap-1.5 items-center justify-center bg-secondary-400 w-full text-primary-text p-4 border-none rounded-lg cursor-pointer text-sm font-medium leading-4", onClick: onRetry, children: [_jsx(RotateCw, { className: 'h-4 w-4' }), _jsx("span", { children: "Try again" })] })] })] }));
27
+ };
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { resolveWalletConnectorIcon } from "../../../lib/wallets/utils/resolveWalletIcon";
3
+ import { ImageWithFallback } from "../../../components/Common/ImageWithFallback";
4
+ export const MultichainConnectorPicker = ({ selectedConnector, allConnectors, providers, connect }) => {
5
+ const Icon = resolveWalletConnectorIcon({ connector: selectedConnector, iconUrl: selectedConnector.icon });
6
+ return (_jsxs("div", { className: "flex flex-col justify-between h-full min-h-80", children: [_jsx("div", { className: "flex grow py-4", children: _jsxs("div", { className: "flex flex-col gap-2 grow items-center justify-center", children: [_jsx("div", { className: "flex justify-center gap-1", children: _jsx(Icon, { className: "w-14 h-auto rounded-lg" }) }), _jsxs("p", { className: "text-base text-center text-primary-text px-4", children: [_jsx("span", { children: selectedConnector.name }), " ", _jsx("span", { children: "supports multiple network types. Please select the one you'd like to use." })] })] }) }), _jsx("div", { className: "flex flex-col gap-2 w-full", children: Array.from(allConnectors
7
+ .filter(c => c?.name === selectedConnector.name)
8
+ .reduce((map, connector) => {
9
+ if (!connector?.providerName)
10
+ return map;
11
+ if (!map.has(connector.providerName)) {
12
+ map.set(connector.providerName, connector);
13
+ }
14
+ return map;
15
+ }, new Map())
16
+ .values()).map((connector, index) => {
17
+ const provider = providers.find(p => p.name === connector?.providerName);
18
+ return (_jsxs("button", { type: "button", onClick: async () => {
19
+ await connect(connector, provider);
20
+ }, className: "w-full h-fit flex items-center gap-3 bg-secondary-500 hover:bg-secondary-400 transition-colors duration-200 rounded-xl p-3", children: [provider?.providerIcon &&
21
+ _jsx(ImageWithFallback, { className: "w-8 h-8 rounded-md", width: 30, height: 30, src: provider.providerIcon, alt: provider.name }), _jsx("p", { children: connector?.providerName })] }, index));
22
+ }) })] }));
23
+ };
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo, useState } from "react";
3
+ import clsx from "clsx";
4
+ import { Popover, PopoverContent, PopoverTrigger } from "../../../components/shadcn/popover";
5
+ import { Checkbox } from "../../../components/shadcn/checkbox";
6
+ import MenuIcon from "../../../components/Icons/MenuIcon";
7
+ export const ProviderPicker = ({ providers, selectedProviderNames, setSelectedProviderNames }) => {
8
+ const values = useMemo(() => providers.map(p => p.name).sort(), [providers]);
9
+ const [open, setOpen] = useState(false);
10
+ const onSelect = (item) => {
11
+ if (selectedProviderNames.includes(item)) {
12
+ const next = selectedProviderNames.filter(p => p !== item);
13
+ setSelectedProviderNames(next);
14
+ }
15
+ else {
16
+ setSelectedProviderNames([...selectedProviderNames, item]);
17
+ }
18
+ };
19
+ const handleClear = () => {
20
+ setSelectedProviderNames([]);
21
+ setOpen(false);
22
+ };
23
+ return (_jsxs(Popover, { open: open, onOpenChange: () => setOpen(!open), children: [_jsxs(PopoverTrigger, { className: clsx('p-2 border border-secondary-500 rounded-lg bg-secondary-600 hover:brightness-125 relative overflow-visible z-50', {
24
+ 'bg-secondary-300! brightness-125': selectedProviderNames.length > 0,
25
+ }), children: [_jsx(MenuIcon, { className: "h-6 w-6 text-secondary-text" }), selectedProviderNames.length > 0 && (_jsx("div", { className: "absolute -top-1.5 -right-1.5 w-4 h-4 rounded-full bg-secondary-300 border border-secondary-700 flex items-center justify-center text-[10px] font-medium text-primary-text z-50", children: selectedProviderNames.length }))] }), _jsxs(PopoverContent, { align: "end", className: "w-[130px]! text-primary-text! p-2 space-y-1 bg-secondary-500! rounded-xl!", style: { width: '130px', minWidth: '130px', maxWidth: '130px' }, children: [values.map((item, index) => (_jsxs("div", { onClick: () => onSelect(item), className: "px-2 py-1 text-left flex items-center w-full gap-2.5 hover:bg-secondary-400 rounded-lg transition-colors duration-200 text-secondary-text cursor-pointer", children: [_jsx(Checkbox, { id: item, checked: selectedProviderNames.includes(item), onClick: (e) => e.stopPropagation(), onCheckedChange: () => onSelect(item) }), _jsx("label", { htmlFor: item, className: "w-full cursor-pointer text-sm leading-[17px]", onClick: (e) => e.preventDefault(), children: item })] }, index))), selectedProviderNames.length > 0 && (_jsx("button", { onClick: handleClear, className: "w-full px-3 py-1 mt-1 text-sm font-medium text-secondary-text hover:text-primary-text bg-secondary-300 hover:bg-secondary-200 rounded-lg transition-colors duration-200", children: "Clear" }))] })] }));
26
+ };
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { resolveWalletConnectorIcon } from "../../../lib/wallets/utils/resolveWalletIcon";
3
+ import { QRCodeSVG } from "qrcode.react";
4
+ import CopyButton from "../../../components/Buttons/copyButton";
5
+ export const WalletQrCode = ({ selectedConnector }) => {
6
+ const ConnectorIcon = resolveWalletConnectorIcon({ connector: selectedConnector, iconUrl: selectedConnector.icon });
7
+ return _jsxs("div", { className: "flex flex-col justify-start space-y-2", children: [_jsx("p", { className: "text-secondary-text", children: "Scan the QR code with your phone" }), _jsx("div", { className: "w-full h-full bg-secondary-600 py-3 rounded-lg", children: _jsxs("div", { className: 'flex flex-col justify-center items-center pt-2 w-fit mx-auto', children: [selectedConnector?.qr?.state == 'fetched' ?
8
+ _jsx(QRCodeSVG, { className: "rounded-lg", value: selectedConnector?.qr.value, includeMargin: true, size: 264, level: "H", imageSettings: selectedConnector.icon
9
+ ? {
10
+ src: selectedConnector.icon,
11
+ height: 50,
12
+ width: 50,
13
+ excavate: true,
14
+ }
15
+ : undefined })
16
+ :
17
+ _jsxs("div", { className: "w-[264px] h-[264px] relative", children: [_jsx("div", { className: "w-full h-full bg-secondary-500 animate-pulse rounded-xl" }), _jsx(ConnectorIcon, { className: 'h-[50px] w-[50px] absolute top-[calc(50%-25px)] right-[calc(50%-25px)]' })] }), _jsx("div", { className: 'bg-secondary-400 text-secondary-text w-full px-2 py-1.5 rounded-md mt-3 flex justify-center items-center', children: _jsx(CopyButton, { disabled: !selectedConnector?.qr?.value, toCopy: selectedConnector?.qr?.value || '', children: "Copy QR URL" }) })] }) })] });
18
+ };
@@ -57,7 +57,7 @@ export function WalletModalProvider({ children }) {
57
57
  }
58
58
  export const useConnectModal = () => {
59
59
  const context = useContext(ConnectModalContext);
60
- if (context === undefined) {
60
+ if (!context) {
61
61
  throw new Error('useConnectModal must be used within a ConnectModalProvider');
62
62
  }
63
63
  const connect = (provider) => new Promise((res) => {
@@ -38,7 +38,7 @@ const DynamicProviderWrapper = ({ providers, children, themeData, appName }) =>
38
38
  */
39
39
  const WalletsProviders = ({ children, themeData, appName, walletProviders }) => {
40
40
  const providersWithWalletConnectionProvider = useMemo(() => walletProviders.filter(provider => typeof provider === 'object' && 'walletConnectionProvider' in provider), [walletProviders]);
41
- return (_jsx(WalletProvidersListContext.Provider, { value: walletProviders, children: _jsx(DynamicProviderWrapper, { providers: walletProviders, themeData: themeData, appName: appName, children: _jsx(WalletModalProvider, { children: _jsx(WalletProvidersProvider, { walletProviders: providersWithWalletConnectionProvider, children: children }) }) }) }));
41
+ return (_jsx(WalletProvidersListContext.Provider, { value: walletProviders, children: _jsx(WalletModalProvider, { children: _jsx(DynamicProviderWrapper, { providers: walletProviders, themeData: themeData, appName: appName, children: _jsx(WalletProvidersProvider, { walletProviders: providersWithWalletConnectionProvider, children: children }) }) }) }));
42
42
  };
43
43
  export default WalletsProviders;
44
44
  export const WalletProvidersListContext = createContext([]);
@@ -24,31 +24,31 @@ const variants = {
24
24
  });
25
25
  },
26
26
  };
27
- const Comp = ({ children, hidden, sticky = true }) => {
27
+ const Comp = ({ children, hidden, sticky = true, showPoweredBy }) => {
28
28
  let [footerRef, { height }] = useMeasure();
29
- return (sticky ?
30
- _jsxs(_Fragment, { children: [_jsx(motion.div, { ref: footerRef, transition: {
31
- duration: 0.15,
32
- }, custom: { direction: -1, width: 100 }, variants: variants, className: `text-primary-text text-base
33
- max-sm:fixed
34
- max-sm:inset-x-0
35
- max-sm:bottom-0
36
- max-sm:z-30
37
- max-sm:bg-secondary-700
38
- max-sm:shadow-widget-footer
39
- max-sm:p-4
40
- max-sm:px-4
41
- max-sm:w-full ${hidden ? 'animation-slide-out' : ''} w-full`, children: children }), _jsx("div", { style: { height: `${height}px` }, className: `text-primary-text text-base
42
- max-sm:inset-x-0
43
- max-sm:bottom-0
44
- max-sm:p-4 max-sm:w-full invisible sm:hidden w-full` })] })
45
- :
46
- children);
29
+ return (_jsx(_Fragment, { children: sticky ?
30
+ _jsxs(_Fragment, { children: [_jsx(motion.div, { ref: footerRef, transition: {
31
+ duration: 0.15,
32
+ }, custom: { direction: -1, width: 100 }, variants: variants, className: `text-primary-text text-base
33
+ max-sm:fixed
34
+ max-sm:inset-x-0
35
+ max-sm:bottom-0
36
+ max-sm:z-30
37
+ max-sm:bg-secondary-700
38
+ max-sm:shadow-widget-footer
39
+ max-sm:p-4
40
+ max-sm:px-4
41
+ max-sm:w-full ${hidden ? 'animation-slide-out' : ''} w-full`, children: children }), _jsx("div", { style: { height: `${height}px` }, className: `text-primary-text text-base
42
+ max-sm:inset-x-0
43
+ max-sm:bottom-0
44
+ max-sm:p-4 max-sm:w-full invisible sm:hidden w-full` })] })
45
+ :
46
+ _jsx("div", { className: clsx('space-y-3', { 'mb-3 sm:mb-0': !showPoweredBy }), children: children }) }));
47
47
  };
48
48
  const Footer = ({ children, hidden, sticky, showPoweredBy }) => {
49
49
  const isFooterSticky = (AppSettings.ThemeData?.enablePortal && AppSettings.ThemeData?.enablePortal == true) ?? false;
50
50
  const isPoweredByVisible = !AppSettings.ThemeData?.hidePoweredBy && showPoweredBy;
51
- return (_jsxs(Comp, { hidden: hidden, sticky: isFooterSticky ? sticky : false, children: [children, isPoweredByVisible &&
51
+ return (_jsxs(Comp, { hidden: hidden, sticky: isFooterSticky ? sticky : false, showPoweredBy: isPoweredByVisible, children: [children, isPoweredByVisible &&
52
52
  _jsx("div", { className: clsx("flex justify-center text-secondary-text", {
53
53
  'mt-3 sm:!mb-0': isFooterSticky,
54
54
  'mb-3 sm:!mb-0': !isFooterSticky,
@@ -11,7 +11,7 @@ const Widget = ({ children, hideMenu, goBack, contextualMenu }) => {
11
11
  return _jsxs("div", { className: "relative p-px h-full", children: [AppSettings.ThemeData?.enableWideVersion &&
12
12
  _jsx("div", { className: "invisible sm:visible absolute inset-0 rounded-[25px] bg-linear-to-t from-secondary-800 to-secondary-300 pointer-events-none" }), _jsxs("div", { id: "widget", style: AppSettings.ThemeData?.cardBackgroundStyle, className: clsx("sm:pb-4 rounded-3xl w-full overflow-hidden relative bg-secondary-700 h-full flex flex-col has-expandContainerHeight:min-h-[650px]", {
13
13
  "max-sm:has-openpicker:min-h-svh max-sm:min-h-[99.8svh] sm:has-openpicker:min-h-[79svh]": AppSettings.ThemeData?.enableWideVersion,
14
- "has-openpicker:min-h-[650px]": !AppSettings.ThemeData?.enableWideVersion
14
+ "has-openpicker:min-h-[675px]": !AppSettings.ThemeData?.enableWideVersion
15
15
  }), children: [AppSettings.ApiVersion === 'testnet' &&
16
16
  _jsx("div", { className: "relative z-20", children: _jsx("div", { className: "absolute -top-1 right-[calc(50%-68px)] bg-warning-foreground py-0.5 px-10 rounded-b-md text-xs scale-75", children: "TESTNET" }) }), !hideMenu &&
17
17
  _jsx(HeaderWithMenu, { goBack: goBack, contextualMenu: contextualMenu }), _jsx("div", { className: "relative flex-col px-4 h-full min-h-0 flex flex-1", children: _jsx("div", { className: "flex flex-col flex-1 items-start h-full min-h-0 w-full gap-3", ref: wrapper, children: children }) }), _jsx("div", { id: "widget_root" })] })] });
@@ -4,6 +4,6 @@ import * as React from "react";
4
4
  import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
5
5
  import { Check } from "lucide-react";
6
6
  import { classNames } from "../utils/classNames";
7
- const Checkbox = React.forwardRef(({ className, ...props }, ref) => (_jsx(CheckboxPrimitive.Root, { ref: ref, className: classNames("peer h-4 w-4 shrink-0 rounded border border-secondary-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-secondary-text data-[state=checked]:text-secondary-800", className), ...props, children: _jsx(CheckboxPrimitive.Indicator, { className: classNames("flex items-center justify-center text-current"), children: _jsx(Check, { className: "h-4 w-4" }) }) })));
7
+ const Checkbox = React.forwardRef(({ className, ...props }, ref) => (_jsx(CheckboxPrimitive.Root, { ref: ref, className: classNames("peer h-3 w-3 shrink-0 rounded border border-secondary-text data-[state=checked]:border-primary-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary-text data-[state=checked]:text-secondary-800", className), ...props, children: _jsx(CheckboxPrimitive.Indicator, { className: classNames("flex items-center justify-center text-current"), children: _jsx(Check, { className: "h-3 w-3" }) }) })));
8
8
  Checkbox.displayName = CheckboxPrimitive.Root.displayName;
9
9
  export { Checkbox };
@@ -47,6 +47,12 @@ export function CallbackProvider({ children, callbacks }) {
47
47
  catch (error) {
48
48
  ErrorHandler(error);
49
49
  } },
50
+ onMenuNavigationChange: (path) => { try {
51
+ callbacks?.onMenuNavigationChange?.(path);
52
+ }
53
+ catch (error) {
54
+ ErrorHandler(error);
55
+ } },
50
56
  };
51
57
  }, [callbacks]);
52
58
  return (_jsx(CallbackContext.Provider, { value: value, children: children }));
@@ -8,6 +8,10 @@ export const ResolverProviders = ({ children, walletProviders }) => {
8
8
  .flat()
9
9
  .filter((provider) => Boolean(provider))
10
10
  .map(provider => provider());
11
+ const contractAddressProviders = walletProviders
12
+ .map(provider => provider.contractAddressProvider)
13
+ .flat()
14
+ .filter((provider) => Boolean(provider));
11
15
  const isInitialized = useMemo(() => {
12
16
  // Extract balance providers from wallet providers
13
17
  const balanceProviders = walletProviders
@@ -28,7 +32,7 @@ export const ResolverProviders = ({ children, walletProviders }) => {
28
32
  .map(provider => provider.nftProvider)
29
33
  .flat()
30
34
  .filter((provider) => Boolean(provider));
31
- resolverService.setProviders(balanceProviders, gasProviders, addressUtilsProviders, nftProviders, transferProviders);
35
+ resolverService.setProviders(balanceProviders, gasProviders, addressUtilsProviders, nftProviders, transferProviders, contractAddressProviders);
32
36
  return true;
33
37
  }, [walletProviders, transferProviders]);
34
38
  return (_jsx(ResolverContext.Provider, { value: { isInitialized }, children: children }));
@@ -28,6 +28,11 @@ export default function useAllWithdrawalBalances() {
28
28
  if (walletNetworks)
29
29
  useBalanceStore.getState().initSortingBalances(walletNetworks);
30
30
  }, [walletNetwokrsString]);
31
+ useEffect(() => {
32
+ return () => {
33
+ useBalanceStore.getState().cleanupSortingBalances();
34
+ };
35
+ }, []);
31
36
  const lastBalancesRef = useRef(null);
32
37
  const resolvedBalances = useBalanceStore(selectResolvedSortingBalances);
33
38
  const isLoading = useBalanceStore(s => s.sortingDataIsLoading);
@@ -0,0 +1,72 @@
1
+ import { useMemo } from "react";
2
+ export function useConnectors({ featuredProviders, filteredProviders, searchValue, recentConnectors, }) {
3
+ const featuredConnectors = useMemo(() => featuredProviders
4
+ .filter(g => g.availableWalletsForConnect && g.availableWalletsForConnect?.length > 0)
5
+ .map((provider) => provider.availableWalletsForConnect
6
+ ?.filter(v => searchValue ? v.name.toLowerCase().includes(searchValue.toLowerCase()) : true)
7
+ .map((connector) => ({ ...connector, providerName: provider.name })))
8
+ .flat(), [featuredProviders, searchValue]);
9
+ const hiddenConnectors = useMemo(() => featuredProviders
10
+ .filter(g => g.availableHiddenWalletsForConnect && g.availableHiddenWalletsForConnect?.length > 0)
11
+ .map((provider) => provider.availableHiddenWalletsForConnect
12
+ ?.filter(v => (searchValue ? v.name.toLowerCase().includes(searchValue.toLowerCase()) : true) &&
13
+ !featuredWalletsIds.includes(v.id.toLowerCase()))
14
+ .map((connector) => ({ ...connector, providerName: provider.name, isHidden: true })))
15
+ .flat(), [featuredProviders, searchValue]);
16
+ const initialConnectors = useMemo(() => {
17
+ return removeDuplicatesWithKey([...featuredConnectors, ...hiddenConnectors]
18
+ .sort((a, b) => sortRecentConnectors(a, b, recentConnectors)), 'name');
19
+ }, [featuredConnectors, hiddenConnectors, searchValue?.length, recentConnectors]);
20
+ return {
21
+ featuredConnectors,
22
+ hiddenConnectors,
23
+ initialConnectors,
24
+ featuredProviders,
25
+ filteredProviders,
26
+ };
27
+ }
28
+ const featuredWalletsIds = [
29
+ 'metamask',
30
+ 'argent',
31
+ 'rainbow',
32
+ 'bitkeep',
33
+ 'okx-wallet',
34
+ ];
35
+ function removeDuplicatesWithKey(arr, key) {
36
+ const countMap = {};
37
+ // First pass: Count occurrences of each unique key.
38
+ arr.forEach(item => {
39
+ const identifier = item[key];
40
+ countMap[identifier] = (countMap[identifier] || 0) + 1;
41
+ });
42
+ // Second pass: Create a new array with one instance of each object.
43
+ const unique = [];
44
+ const seen = new Set();
45
+ arr.forEach(item => {
46
+ const identifier = item[key];
47
+ if (!seen.has(identifier)) {
48
+ seen.add(identifier);
49
+ // Add a property 'duplicateCount' to indicate extra duplicates found.
50
+ unique.push({
51
+ ...item,
52
+ isMultiChain: countMap[identifier] > 1
53
+ });
54
+ }
55
+ });
56
+ return unique;
57
+ }
58
+ export function sortRecentConnectors(a, b, recentConnectors) {
59
+ function getIndex(c) {
60
+ const idx = recentConnectors?.findIndex(v => v.connectorName === c.name);
61
+ return idx === -1 ? Infinity : idx;
62
+ }
63
+ const indexA = getIndex(a);
64
+ const indexB = getIndex(b);
65
+ if (indexA !== indexB) {
66
+ return indexA - indexB;
67
+ }
68
+ if (a.type && b.type) {
69
+ return a.type.localeCompare(b.type);
70
+ }
71
+ return 0;
72
+ }