@lifi/widget 1.12.1 → 1.13.2

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 (68) hide show
  1. package/components/Initializer.js +1 -1
  2. package/components/LiFiLogo.js +1 -2
  3. package/components/PoweredBy/PoweredBy.js +3 -2
  4. package/components/StepActions/StepActions.js +1 -1
  5. package/components/SwapInput/FormPriceHelperText.js +2 -2
  6. package/components/SwapInput/SwapInputAdornment.js +2 -2
  7. package/components/SwapRouteCard/SwapRouteCard.style.js +1 -1
  8. package/components/TokenAvatar/TokenAvatar.js +3 -2
  9. package/components/TokenList/TokenList.js +25 -43
  10. package/components/TokenList/TokenList.style.js +5 -2
  11. package/components/TokenList/TokenListItem.d.ts +2 -2
  12. package/components/TokenList/TokenListItem.js +7 -10
  13. package/components/TokenList/TokenNotFound.d.ts +2 -0
  14. package/components/TokenList/TokenNotFound.js +15 -0
  15. package/components/TokenList/VirtualizedTokenList.d.ts +3 -0
  16. package/components/TokenList/VirtualizedTokenList.js +53 -0
  17. package/components/TokenList/types.d.ts +16 -1
  18. package/config/sentry.d.ts +1 -1
  19. package/config/sentry.js +36 -18
  20. package/config/version.d.ts +1 -1
  21. package/config/version.js +1 -1
  22. package/hooks/index.d.ts +3 -0
  23. package/hooks/index.js +3 -0
  24. package/hooks/useChains.d.ts +10 -10
  25. package/hooks/useFeaturedTokens.d.ts +1 -0
  26. package/hooks/useFeaturedTokens.js +6 -0
  27. package/hooks/useToken.d.ts +2 -1
  28. package/hooks/useToken.js +2 -1
  29. package/hooks/useTokenBalance.d.ts +2 -4
  30. package/hooks/useTokenBalance.js +11 -42
  31. package/hooks/useTokenBalances.d.ts +5 -4
  32. package/hooks/useTokenBalances.js +25 -13
  33. package/hooks/useTokenSearch.d.ts +7 -0
  34. package/hooks/useTokenSearch.js +37 -0
  35. package/hooks/useTokens.d.ts +2 -1
  36. package/hooks/useTokens.js +12 -4
  37. package/i18n/en/translation.json +2 -0
  38. package/i18n/index.d.ts +2 -0
  39. package/icons/LiFiFullLogo.d.ts +2 -0
  40. package/icons/LiFiFullLogo.js +2 -0
  41. package/icons/LiFiLogo.d.ts +2 -0
  42. package/icons/LiFiLogo.js +2 -0
  43. package/icons/LiFiToolLogo.d.ts +2 -0
  44. package/icons/LiFiToolLogo.js +2 -0
  45. package/icons/index.d.ts +3 -0
  46. package/icons/index.js +3 -0
  47. package/package.json +12 -13
  48. package/pages/SelectTokenPage/ChainSelect.js +8 -5
  49. package/pages/SelectTokenPage/SearchTokenInput.js +2 -2
  50. package/pages/SelectWalletPage/SelectWalletPage.js +1 -1
  51. package/pages/SwapPage/StatusBottomSheet.js +2 -2
  52. package/providers/SwapFormProvider/SwapFormProvider.d.ts +1 -1
  53. package/providers/SwapFormProvider/SwapFormProvider.js +28 -5
  54. package/providers/SwapFormProvider/types.d.ts +2 -3
  55. package/providers/SwapFormProvider/types.js +1 -2
  56. package/providers/WalletProvider/WalletProvider.d.ts +5 -0
  57. package/providers/WalletProvider/WalletProvider.js +12 -6
  58. package/providers/WidgetProvider/WidgetProvider.js +24 -15
  59. package/types/index.d.ts +1 -0
  60. package/types/index.js +1 -0
  61. package/types/token.d.ts +4 -0
  62. package/types/token.js +1 -0
  63. package/types/widget.d.ts +3 -2
  64. package/components/TokenList/utils.d.ts +0 -15
  65. package/components/TokenList/utils.js +0 -10
  66. package/icons/LiFiFullLogo.svg +0 -10
  67. package/icons/LiFiLogo.svg +0 -5
  68. package/icons/LiFiToolLogo.svg +0 -6
@@ -1,46 +1,15 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { useQuery, useQueryClient } from '@tanstack/react-query';
11
- import { useCallback } from 'react';
12
- import { LiFi } from '../config/lifi';
13
- import { useWallet } from '../providers/WalletProvider';
14
- import { formatTokenAmount } from '../utils';
15
- import { useToken } from './useToken';
1
+ import { useMemo } from 'react';
2
+ import { useTokenBalances } from './useTokenBalances';
16
3
  export const useTokenBalance = (chainId, tokenAddress) => {
17
- const { account } = useWallet();
18
- const queryClient = useQueryClient();
19
- const { token } = useToken(chainId, tokenAddress);
20
- const { data: tokenWithBalance, isLoading, isFetching, refetch, } = useQuery(['token-balance', account.address, chainId, tokenAddress], ({ queryKey: [, address] }) => __awaiter(void 0, void 0, void 0, function* () {
21
- if (!address || !token) {
22
- return null;
23
- }
24
- const tokenBalance = yield LiFi.getTokenBalance(address, token);
25
- return Object.assign(Object.assign(Object.assign({}, token), tokenBalance), { amount: formatTokenAmount(tokenBalance === null || tokenBalance === void 0 ? void 0 : tokenBalance.amount) });
26
- }), {
27
- enabled: Boolean(account.address) && Boolean(token),
28
- refetchIntervalInBackground: true,
29
- refetchInterval: 30000,
30
- staleTime: 30000,
31
- cacheTime: 30000,
32
- });
33
- const refetchBalance = useCallback((chainId, tokenAddress) => __awaiter(void 0, void 0, void 0, function* () {
34
- if (!chainId && !tokenAddress) {
35
- refetch();
36
- return;
37
- }
38
- yield queryClient.invalidateQueries(['token', account.address, chainId, tokenAddress], { type: 'all', exact: true });
39
- }), [account.address, queryClient, refetch]);
4
+ const { tokens, tokensWithBalance, isBalanceLoading, refetch } = useTokenBalances(chainId);
5
+ const token = useMemo(() => {
6
+ var _a;
7
+ const token = (_a = (tokensWithBalance !== null && tokensWithBalance !== void 0 ? tokensWithBalance : tokens)) === null || _a === void 0 ? void 0 : _a.find((token) => token.address === tokenAddress && token.chainId === chainId);
8
+ return token;
9
+ }, [chainId, tokenAddress, tokens, tokensWithBalance]);
40
10
  return {
41
- token: tokenWithBalance !== null && tokenWithBalance !== void 0 ? tokenWithBalance : token,
42
- isLoading,
43
- isFetching,
44
- refetchBalance,
11
+ token,
12
+ isLoading: isBalanceLoading,
13
+ refetch,
45
14
  };
46
15
  };
@@ -1,9 +1,10 @@
1
- import { TokenAmount } from '@lifi/sdk';
1
+ import { Token } from '../types';
2
2
  export declare const useTokenBalances: (selectedChainId: number) => {
3
- tokens: import("@lifi/sdk").Token[] | undefined;
4
- tokensWithBalance: TokenAmount[] | undefined;
3
+ tokens: Token[] | undefined;
4
+ tokensWithBalance: Token[] | undefined;
5
+ featuredTokens: import("@lifi/types").Token[] | undefined;
5
6
  isLoading: boolean;
6
7
  isBalanceLoading: boolean;
7
8
  isBalanceFetched: boolean;
8
- updateBalances: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<TokenAmount[] | undefined, unknown>>;
9
+ refetch: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<Token[] | undefined, unknown>>;
9
10
  };
@@ -7,20 +7,23 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ /* eslint-disable consistent-return */
10
11
  import { useQuery } from '@tanstack/react-query';
11
12
  import { useState } from 'react';
12
13
  import { LiFi } from '../config/lifi';
13
14
  import { useWallet } from '../providers/WalletProvider';
14
15
  import { formatTokenAmount } from '../utils';
16
+ import { useFeaturedTokens } from './useFeaturedTokens';
15
17
  import { useTokens } from './useTokens';
16
18
  const defaultRefetchInterval = 60000;
17
19
  const minRefetchInterval = 1000;
18
20
  export const useTokenBalances = (selectedChainId) => {
19
21
  const { account } = useWallet();
22
+ const featuredTokens = useFeaturedTokens(selectedChainId);
20
23
  const { tokens, isLoading } = useTokens(selectedChainId);
21
24
  const [refetchInterval, setRefetchInterval] = useState(defaultRefetchInterval);
22
- const isBalanceLoadingEnabled = Boolean(account.address) && Boolean(tokens);
23
- const { data: tokensWithBalance, isLoading: isBalanceLoading, isFetched: isBalanceFetched, refetch, } = useQuery(['token-balances', selectedChainId, account.address], ({ queryKey: [, , accountAddress] }) => __awaiter(void 0, void 0, void 0, function* () {
25
+ const isBalanceLoadingEnabled = Boolean(account.address) && Boolean(tokens === null || tokens === void 0 ? void 0 : tokens.length);
26
+ const { data: tokensWithBalance, isLoading: isBalanceLoading, isFetched: isBalanceFetched, refetch, } = useQuery(['token-balances', account.address, selectedChainId, tokens === null || tokens === void 0 ? void 0 : tokens.length], ({ queryKey: [, accountAddress] }) => __awaiter(void 0, void 0, void 0, function* () {
24
27
  if (!accountAddress || !tokens) {
25
28
  return;
26
29
  }
@@ -33,20 +36,28 @@ export const useTokenBalances = (selectedChainId) => {
33
36
  : interval * 2);
34
37
  return;
35
38
  }
36
- const formatedTokens = (tokenBalances.length === 0 ? tokens : tokenBalances).map((token) => {
39
+ const featuredTokenAddresses = new Set(featuredTokens === null || featuredTokens === void 0 ? void 0 : featuredTokens.map((token) => token.address));
40
+ const sortFn = (a, b) => {
41
+ var _a, _b, _c, _d;
42
+ return parseFloat((_a = b.amount) !== null && _a !== void 0 ? _a : '0') * parseFloat((_b = b.priceUSD) !== null && _b !== void 0 ? _b : '0') -
43
+ parseFloat((_c = a.amount) !== null && _c !== void 0 ? _c : '0') * parseFloat((_d = a.priceUSD) !== null && _d !== void 0 ? _d : '0');
44
+ };
45
+ const formattedTokens = (tokenBalances.length === 0 ? tokens : tokenBalances).map((token) => {
37
46
  token.amount = formatTokenAmount(token.amount);
38
47
  return token;
39
48
  });
40
- return [
41
- ...formatedTokens
42
- .filter((token) => token.amount !== '0')
43
- .sort((a, b) => {
44
- var _a, _b, _c, _d;
45
- return parseFloat((_a = b.amount) !== null && _a !== void 0 ? _a : '0') * parseFloat((_b = b.priceUSD) !== null && _b !== void 0 ? _b : '0') -
46
- parseFloat((_c = a.amount) !== null && _c !== void 0 ? _c : '0') * parseFloat((_d = a.priceUSD) !== null && _d !== void 0 ? _d : '0');
47
- }),
48
- ...formatedTokens.filter((token) => token.amount === '0'),
49
+ const result = [
50
+ ...formattedTokens
51
+ .filter((token) => token.amount !== '0' && featuredTokenAddresses.has(token.address))
52
+ .sort(sortFn),
53
+ ...formattedTokens.filter((token) => token.amount === '0' && featuredTokenAddresses.has(token.address)),
54
+ ...formattedTokens
55
+ .filter((token) => token.amount !== '0' &&
56
+ !featuredTokenAddresses.has(token.address))
57
+ .sort(sortFn),
58
+ ...formattedTokens.filter((token) => token.amount === '0' && !featuredTokenAddresses.has(token.address)),
49
59
  ];
60
+ return result;
50
61
  }), {
51
62
  enabled: isBalanceLoadingEnabled,
52
63
  refetchIntervalInBackground: true,
@@ -56,9 +67,10 @@ export const useTokenBalances = (selectedChainId) => {
56
67
  return {
57
68
  tokens,
58
69
  tokensWithBalance,
70
+ featuredTokens,
59
71
  isLoading,
60
72
  isBalanceLoading: isBalanceLoading && isBalanceLoadingEnabled,
61
73
  isBalanceFetched,
62
- updateBalances: refetch,
74
+ refetch,
63
75
  };
64
76
  };
@@ -0,0 +1,7 @@
1
+ import { Token } from '../types';
2
+ export declare const useTokenSearch: (token: string, chainId: number, enabled?: boolean) => {
3
+ token: Token | undefined;
4
+ isLoading: boolean;
5
+ isFetching: boolean;
6
+ isFetched: boolean;
7
+ };
@@ -0,0 +1,37 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { useQuery, useQueryClient } from '@tanstack/react-query';
11
+ import { LiFi } from '../config/lifi';
12
+ export const useTokenSearch = (token, chainId, enabled) => {
13
+ const queryClient = useQueryClient();
14
+ const { data, isLoading, isFetching, isFetched } = useQuery(['token-search', chainId, token], ({ queryKey: [, chainId, token], signal }) => __awaiter(void 0, void 0, void 0, function* () {
15
+ const data = yield LiFi.getToken(chainId, token, {
16
+ signal,
17
+ });
18
+ if (data) {
19
+ queryClient.setQueriesData(['tokens', chainId], (tokens) => {
20
+ if (!(tokens === null || tokens === void 0 ? void 0 : tokens.some((token) => token.address === data.address))) {
21
+ tokens === null || tokens === void 0 ? void 0 : tokens.push(data);
22
+ }
23
+ return tokens;
24
+ });
25
+ }
26
+ return data;
27
+ }), {
28
+ enabled,
29
+ retry: false,
30
+ });
31
+ return {
32
+ token: data,
33
+ isLoading,
34
+ isFetching,
35
+ isFetched,
36
+ };
37
+ };
@@ -1,5 +1,6 @@
1
+ import { Token } from '../types';
1
2
  export declare const useTokens: (selectedChainId: number) => {
2
- tokens: import("@lifi/types").Token[] | undefined;
3
+ tokens: Token[] | undefined;
3
4
  isLoading: boolean;
4
5
  isFetching: boolean;
5
6
  };
@@ -9,12 +9,20 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { useQuery } from '@tanstack/react-query';
11
11
  import { LiFi } from '../config/lifi';
12
+ import { useFeaturedTokens } from './useFeaturedTokens';
12
13
  export const useTokens = (selectedChainId) => {
13
- const { data: tokens, isLoading, isFetching, } = useQuery(['tokens', selectedChainId], () => __awaiter(void 0, void 0, void 0, function* () {
14
- var _a;
14
+ const featuredTokens = useFeaturedTokens(selectedChainId);
15
+ const { data: tokens, isLoading, isFetching, } = useQuery(['tokens', selectedChainId, featuredTokens === null || featuredTokens === void 0 ? void 0 : featuredTokens.length], () => __awaiter(void 0, void 0, void 0, function* () {
16
+ var _a, _b, _c;
15
17
  const data = yield LiFi.getTokens({ chains: [selectedChainId] });
16
- return (_a = data.tokens) === null || _a === void 0 ? void 0 : _a[selectedChainId];
17
- // .sort((a, b) => (a.symbol > b.symbol ? 1 : -1));
18
+ const featuredTokenAddresses = new Set(featuredTokens === null || featuredTokens === void 0 ? void 0 : featuredTokens.map((token) => token.address));
19
+ return [
20
+ ...((_a = featuredTokens === null || featuredTokens === void 0 ? void 0 : featuredTokens.map((token) => {
21
+ token.featured = true;
22
+ return token;
23
+ })) !== null && _a !== void 0 ? _a : []),
24
+ ...((_c = (_b = data.tokens) === null || _b === void 0 ? void 0 : _b[selectedChainId].filter((token) => !featuredTokenAddresses.has(token.address))) !== null && _c !== void 0 ? _c : []),
25
+ ];
18
26
  }));
19
27
  return {
20
28
  tokens,
@@ -50,6 +50,8 @@
50
50
  "selectChain": "Chain",
51
51
  "selectToken": "Token",
52
52
  "selectChainAndToken": "Select chain and token",
53
+ "featuredTokens": "Featured tokens",
54
+ "otherTokens": "Other tokens",
53
55
  "inProgress": "In progress",
54
56
  "couldntFindTokens": "We couldn't find tokens on this chain or you don't have any.",
55
57
  "stepSwap": "Swap",
package/i18n/index.d.ts CHANGED
@@ -53,6 +53,8 @@ export declare const resources: {
53
53
  selectChain: string;
54
54
  selectToken: string;
55
55
  selectChainAndToken: string;
56
+ featuredTokens: string;
57
+ otherTokens: string;
56
58
  inProgress: string;
57
59
  couldntFindTokens: string;
58
60
  stepSwap: string;
@@ -0,0 +1,2 @@
1
+ import { SVGProps } from 'react';
2
+ export declare const LiFiFullLogo: (props: SVGProps<SVGSVGElement>) => JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export const LiFiFullLogo = (props) => (_jsxs("svg", Object.assign({ width: "84", height: "32", viewBox: "0 0 84 32", fill: "inherit", xmlns: "http://www.w3.org/2000/svg" }, props, { children: [_jsx("path", { d: "M50.6689 20.5714H42.6849V8H39V24H50.6689V20.5714Z" }), _jsx("path", { d: "M53.0717 24H56.7566V8H53.0717V24Z" }), _jsx("path", { d: "M59.5088 24H63.0117V20.48H59.5088V24Z" }), _jsx("path", { d: "M69.4396 17.76H77.1506V14.6057H69.4396V11.2457H77.8103V8H65.7547V24H69.4396V17.76Z" }), _jsx("path", { d: "M80.3151 24H84V8H80.3151V24Z" }), _jsx("path", { d: "M14.6163 21.6947L5.1336 23.89C4.78772 23.9766 4.52832 24.3232 4.52832 24.6698V31.1978C4.52832 31.7467 4.96066 32.0933 5.50829 31.9777L18.7379 28.9159C19.2856 28.8004 19.5162 28.2805 19.2856 27.7894L16.8933 22.8501C16.5186 22.0702 16.8933 21.2614 17.7291 21.0881L26.376 19.0084C26.9813 18.864 27.5001 18.2285 27.5001 17.593V11.5561C27.5001 11.0073 27.0677 10.6318 26.5201 10.7762L14.0398 13.7514C13.2616 13.9247 12.9157 14.6757 13.2616 15.3978L15.4521 19.9327C15.8268 20.7126 15.4521 21.4925 14.6163 21.6947Z" }), _jsx("path", { d: "M8.36225 5.3748L10.841 10.4585C11.1581 11.1229 10.841 11.8161 10.1204 11.9606L5.53762 13.0293C4.96116 13.1737 4.5 13.7514 4.5 14.3291V19.7884C4.5 20.7127 5.24939 21.2904 6.1429 21.0882L10.4087 20.1061C10.9851 19.9906 11.4463 19.384 11.4463 18.8063L11.4751 13.2026C11.4751 12.4227 12.1092 11.6428 12.8586 11.4695L26.8376 8.11886C27.1835 8.03221 27.4429 7.68559 27.4429 7.33897V0.810981C27.4429 0.262168 27.0106 -0.113336 26.4629 0.0310883L8.90988 4.24829C8.36225 4.36383 8.13167 4.88375 8.36225 5.3748Z" })] })));
@@ -0,0 +1,2 @@
1
+ import { SVGProps } from 'react';
2
+ export declare const LiFiLogo: (props: SVGProps<SVGSVGElement>) => JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export const LiFiLogo = (props) => (_jsxs("svg", Object.assign({ width: "32", height: "32", viewBox: "0 0 32 32", fill: "inherit", xmlns: "http://www.w3.org/2000/svg" }, props, { children: [_jsx("path", { d: "M14.6163 21.6947L5.1336 23.89C4.78772 23.9766 4.52832 24.3232 4.52832 24.6698V31.1978C4.52832 31.7467 4.96066 32.0933 5.50829 31.9777L18.7379 28.9159C19.2856 28.8004 19.5162 28.2805 19.2856 27.7894L16.8933 22.8501C16.5186 22.0702 16.8933 21.2614 17.7291 21.0881L26.376 19.0084C26.9813 18.864 27.5001 18.2285 27.5001 17.593V11.5561C27.5001 11.0073 27.0677 10.6318 26.5201 10.7762L14.0398 13.7514C13.2616 13.9247 12.9157 14.6757 13.2616 15.3978L15.4521 19.9327C15.8268 20.7126 15.4521 21.4925 14.6163 21.6947Z" }), _jsx("path", { d: "M8.36225 5.3748L10.841 10.4585C11.1581 11.1229 10.841 11.8161 10.1204 11.9606L5.53762 13.0293C4.96116 13.1737 4.5 13.7514 4.5 14.3291V19.7884C4.5 20.7127 5.24939 21.2904 6.1429 21.0882L10.4087 20.1061C10.9851 19.9906 11.4463 19.384 11.4463 18.8063L11.4751 13.2026C11.4751 12.4227 12.1092 11.6428 12.8586 11.4695L26.8376 8.11886C27.1835 8.03221 27.4429 7.68559 27.4429 7.33897V0.810981C27.4429 0.262168 27.0106 -0.113336 26.4629 0.0310883L8.90988 4.24829C8.36225 4.36383 8.13167 4.88375 8.36225 5.3748Z" })] })));
@@ -0,0 +1,2 @@
1
+ import { SVGProps } from 'react';
2
+ export declare const LiFiToolLogo: (props: SVGProps<SVGSVGElement>) => JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export const LiFiToolLogo = (props) => (_jsxs("svg", Object.assign({ width: "32", height: "32", viewBox: "0 0 32 32", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, props, { children: [_jsx("circle", { cx: "16", cy: "16", r: "16", fill: "#F5B5FF" }), _jsx("path", { d: "M15.5031 19.2031L10.1691 20.4379C9.97453 20.4867 9.82861 20.6816 9.82861 20.8766V24.5486C9.82861 24.8573 10.0718 25.0523 10.3798 24.9873L17.8215 23.265C18.1296 23.2 18.2593 22.9076 18.1296 22.6314L16.7839 19.853C16.5731 19.4143 16.7839 18.9594 17.2541 18.8619L22.1179 17.692C22.4584 17.6108 22.7502 17.2534 22.7502 16.8959V13.5001C22.7502 13.1914 22.507 12.9802 22.199 13.0614L15.1788 14.735C14.7411 14.8324 14.5465 15.2549 14.7411 15.6611L15.9733 18.212C16.184 18.6507 15.9733 19.0893 15.5031 19.2031Z", fill: "black" }), _jsx("path", { d: "M11.985 10.0233L13.3793 12.8829C13.5577 13.2566 13.3793 13.6466 12.974 13.7278L10.3962 14.329C10.0719 14.4102 9.8125 14.7352 9.8125 15.0601V18.1309C9.8125 18.6509 10.234 18.9758 10.7366 18.8621L13.1361 18.3097C13.4604 18.2447 13.7198 17.9035 13.7198 17.5785L13.736 14.4265C13.736 13.9878 14.0927 13.5491 14.5142 13.4516L22.3774 11.5669C22.572 11.5181 22.7179 11.3231 22.7179 11.1282V7.45618C22.7179 7.14747 22.4747 6.93625 22.1666 7.01749L12.2931 9.38966C11.985 9.45465 11.8553 9.74711 11.985 10.0233Z", fill: "black" })] })));
@@ -0,0 +1,3 @@
1
+ export * from './LiFiFullLogo';
2
+ export * from './LiFiLogo';
3
+ export * from './LiFiToolLogo';
package/icons/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from './LiFiFullLogo';
2
+ export * from './LiFiLogo';
3
+ export * from './LiFiToolLogo';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/widget",
3
- "version": "1.12.1",
3
+ "version": "1.13.2",
4
4
  "description": "LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.",
5
5
  "sideEffects": false,
6
6
  "main": "./index.js",
@@ -42,25 +42,24 @@
42
42
  "@ethersproject/experimental": "^5.6.3",
43
43
  "@ethersproject/providers": "^5.6.8",
44
44
  "@lifi/sdk": "^1.1.3",
45
- "@lifi/wallet-management": "^1.1.3",
45
+ "@lifi/wallet-management": "^1.1.4",
46
46
  "@mui/icons-material": "^5.8.4",
47
- "@mui/lab": "^5.0.0-alpha.93",
48
- "@mui/material": "^5.9.3",
49
- "@sentry/integrations": "^7.9.0",
50
- "@sentry/react": "^7.9.0",
51
- "@sentry/tracing": "^7.9.0",
52
- "@tanstack/react-query": "^4.0.10",
47
+ "@mui/lab": "^5.0.0-alpha.95",
48
+ "@mui/material": "^5.10.1",
49
+ "@sentry/integrations": "^7.10.0",
50
+ "@sentry/react": "^7.10.0",
51
+ "@sentry/tracing": "^7.10.0",
52
+ "@tanstack/react-query": "^4.1.3",
53
+ "@tanstack/react-virtual": "^3.0.0-beta.17",
53
54
  "big.js": "^6.2.1",
54
- "i18next": "^21.8.16",
55
+ "i18next": "^21.9.1",
55
56
  "immer": "^9.0.15",
56
57
  "react": "^18.2.0",
57
58
  "react-dom": "^18.2.0",
58
- "react-hook-form": "^7.34.0",
59
- "react-i18next": "^11.18.3",
60
- "react-resize-detector": "^7.1.2",
59
+ "react-hook-form": "^7.34.2",
60
+ "react-i18next": "^11.18.4",
61
61
  "react-router-dom": "^6.3.0",
62
62
  "react-timer-hook": "^3.0.5",
63
- "react-virtual": "^2.10.4",
64
63
  "zustand": "^4.0.0"
65
64
  },
66
65
  "eslintConfig": {
@@ -6,20 +6,23 @@ import { useTranslation } from 'react-i18next';
6
6
  import { Card, CardTitle } from '../../components/Card';
7
7
  import { Select } from '../../components/Select';
8
8
  import { useChains } from '../../hooks';
9
- import { SwapFormKeyHelper, } from '../../providers/SwapFormProvider';
9
+ import { SwapFormKey, SwapFormKeyHelper, } from '../../providers/SwapFormProvider';
10
10
  import { useWidgetConfig } from '../../providers/WidgetProvider';
11
11
  export const ChainSelect = ({ formType }) => {
12
12
  const { t } = useTranslation();
13
- const { setValue } = useFormContext();
13
+ const { setValue, register } = useFormContext();
14
14
  const { fromChain, toChain } = useWidgetConfig();
15
15
  const { chains, isLoading } = useChains();
16
+ const chainKey = SwapFormKeyHelper.getChainKey(formType);
16
17
  const [chainId] = useWatch({
17
- name: [SwapFormKeyHelper.getChainKey(formType)],
18
+ name: [chainKey],
18
19
  });
20
+ const { onChange, onBlur, name, ref } = register(chainKey);
19
21
  const handleChain = (event) => {
20
- setValue(SwapFormKeyHelper.getChainKey(formType), event.target.value);
22
+ onChange(event);
21
23
  setValue(SwapFormKeyHelper.getTokenKey(formType), '');
22
24
  setValue(SwapFormKeyHelper.getAmountKey(formType), '');
25
+ setValue(SwapFormKey.TokenSearchFilter, '');
23
26
  };
24
- return !isLoading ? (_jsxs(Card, { children: [_jsx(CardTitle, { children: t(`swap.selectChain`) }), _jsx(FormControl, Object.assign({ fullWidth: true }, { children: _jsx(Select, Object.assign({ labelId: "label", MenuProps: { elevation: 2 }, defaultValue: formType === 'from' ? fromChain : toChain, value: chainId, onChange: handleChain, IconComponent: KeyboardArrowDownIcon }, { children: chains === null || chains === void 0 ? void 0 : chains.map((chain) => (_jsxs(MenuItem, Object.assign({ value: chain.id }, { children: [_jsx(ListItemAvatar, { children: _jsx(Avatar, Object.assign({ src: chain.logoURI, alt: chain.key }, { children: chain.name[0] })) }), chain.name] }), chain.key))) })) }))] })) : (_jsx(Skeleton, { variant: "rectangular", width: "100%", height: 98, sx: { borderRadius: 1 } }));
27
+ return !isLoading ? (_jsxs(Card, { children: [_jsx(CardTitle, { children: t(`swap.selectChain`) }), _jsx(FormControl, Object.assign({ fullWidth: true }, { children: _jsx(Select, Object.assign({ ref: ref, labelId: chainKey, name: name, MenuProps: { elevation: 2 }, defaultValue: formType === 'from' ? fromChain : toChain, value: chainId, onChange: handleChain, onBlur: onBlur, IconComponent: KeyboardArrowDownIcon }, { children: chains === null || chains === void 0 ? void 0 : chains.map((chain) => (_jsxs(MenuItem, Object.assign({ value: chain.id }, { children: [_jsx(ListItemAvatar, { children: _jsx(Avatar, Object.assign({ src: chain.logoURI, alt: chain.key }, { children: chain.name[0] })) }), chain.name] }), chain.key))) })) }))] })) : (_jsx(Skeleton, { variant: "rectangular", width: "100%", height: 98, sx: { borderRadius: 1 } }));
25
28
  };
@@ -11,7 +11,7 @@ export const SearchTokenInput = () => {
11
11
  const { t } = useTranslation();
12
12
  const { register, setValue } = useFormContext();
13
13
  useEffect(() => () => {
14
- setValue(SwapFormKey.SearchTokensFilter, '');
14
+ setValue(SwapFormKey.TokenSearchFilter, '');
15
15
  }, [setValue]);
16
- return (_jsx(Card, { children: _jsx(FormControl, Object.assign({ fullWidth: true }, { children: _jsx(Input, { size: "small", placeholder: t(`swap.tokenSearch`), defaultValue: "", endAdornment: _jsx(InputAdornment, Object.assign({ position: "end" }, { children: _jsx(SearchIcon, {}) })), inputProps: Object.assign({ inputMode: 'search' }, register(SwapFormKey.SearchTokensFilter)), autoComplete: "off" }) })) }));
16
+ return (_jsx(Card, { children: _jsx(FormControl, Object.assign({ fullWidth: true }, { children: _jsx(Input, { size: "small", placeholder: t(`swap.tokenSearch`), defaultValue: "", endAdornment: _jsx(InputAdornment, Object.assign({ position: "end" }, { children: _jsx(SearchIcon, {}) })), inputProps: Object.assign({ inputMode: 'search' }, register(SwapFormKey.TokenSearchFilter)), autoComplete: "off" }) })) }));
17
17
  };
@@ -43,7 +43,7 @@ export const SelectWalletPage = () => {
43
43
  return (_jsxs(Container, Object.assign({ disableGutters: true }, { children: [_jsx(List, Object.assign({ sx: {
44
44
  paddingLeft: 2,
45
45
  paddingRight: 2,
46
- } }, { children: supportedWallets.map((wallet) => (_jsxs(WalletListItemButton, Object.assign({ onClick: (event) => handleConnect(event, wallet), disableRipple: true }, { children: [_jsx(ListItemAvatar, { children: _jsx(Avatar, Object.assign({ src: wallet.icon, alt: wallet.name }, { children: wallet.name[0] })) }), _jsx(WalletListItemText, { primary: wallet.name })] }), wallet.name))) })), _jsxs(Dialog, Object.assign({ open: walletIdentity.show, onClose: closeDialog }, { children: [_jsx(DialogContent, { children: _jsx(DialogContentText, { children: t('wallet.extensionNotFound', {
46
+ } }, { children: supportedWallets.map((wallet) => (_jsxs(WalletListItemButton, Object.assign({ onClick: (event) => handleConnect(event, wallet), disableRipple: true }, { children: [_jsx(ListItemAvatar, { children: _jsx(Avatar, Object.assign({ src: wallet.icon.src || wallet.icon, alt: wallet.name }, { children: wallet.name[0] })) }), _jsx(WalletListItemText, { primary: wallet.name })] }), wallet.name))) })), _jsxs(Dialog, Object.assign({ open: walletIdentity.show, onClose: closeDialog }, { children: [_jsx(DialogContent, { children: _jsx(DialogContentText, { children: t('wallet.extensionNotFound', {
47
47
  name: (_a = walletIdentity.wallet) === null || _a === void 0 ? void 0 : _a.name,
48
48
  }) }) }), _jsx(DialogActions, { children: _jsx(Button, Object.assign({ onClick: closeDialog, autoFocus: true }, { children: t('button.ok') })) })] }))] })));
49
49
  };
@@ -17,10 +17,10 @@ export const StatusBottomSheet = ({ status, route, }) => {
17
17
  const navigate = useNavigate();
18
18
  const ref = useRef(null);
19
19
  const { getChainById } = useChains();
20
- const { token, refetchBalance } = useTokenBalance(route.toChainId, route.toToken.address);
20
+ const { token, refetch: refetchBalance } = useTokenBalance(route.toChainId, route.toToken.address);
21
21
  const { setValue } = useFormContext();
22
22
  const clearFromAmount = () => {
23
- refetchBalance(route.fromChainId, route.fromToken.address);
23
+ refetchBalance();
24
24
  setValue(SwapFormKey.FromAmount, '');
25
25
  };
26
26
  const handleDone = () => {
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  export declare const formDefaultValues: {
3
3
  fromAmount: string;
4
- searchTokensFilter: string;
4
+ tokenSearchFilter: string;
5
5
  };
6
6
  export declare const SwapFormProvider: React.FC<React.PropsWithChildren<{}>>;
@@ -1,18 +1,41 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { ChainId } from '@lifi/sdk';
3
+ import { useEffect } from 'react';
2
4
  import { FormProvider, useForm } from 'react-hook-form';
5
+ import { useWallet } from '../WalletProvider';
3
6
  import { useWidgetConfig } from '../WidgetProvider';
4
7
  import { SwapFormKey } from './types';
5
8
  export const formDefaultValues = {
6
9
  [SwapFormKey.FromAmount]: '',
7
- [SwapFormKey.SearchTokensFilter]: '',
10
+ [SwapFormKey.TokenSearchFilter]: '',
8
11
  };
9
12
  export const SwapFormProvider = ({ children, }) => {
10
- var _a;
13
+ const { account } = useWallet();
11
14
  const { fromChain, fromToken, fromAmount, toChain, toToken } = useWidgetConfig();
12
15
  const methods = useForm({
13
- defaultValues: Object.assign(Object.assign({}, formDefaultValues), { fromChain,
14
- fromToken, fromAmount: (_a = fromAmount === null || fromAmount === void 0 ? void 0 : fromAmount.toPrecision()) !== null && _a !== void 0 ? _a : formDefaultValues.fromAmount, toChain,
15
- toToken }),
16
+ defaultValues: Object.assign(Object.assign({}, formDefaultValues), { fromChain: fromChain !== null && fromChain !== void 0 ? fromChain : ChainId.ETH, fromToken, fromAmount: (typeof fromAmount === 'number'
17
+ ? fromAmount === null || fromAmount === void 0 ? void 0 : fromAmount.toPrecision()
18
+ : fromAmount) || formDefaultValues.fromAmount, toChain: toChain !== null && toChain !== void 0 ? toChain : ChainId.ETH, toToken }),
16
19
  });
20
+ // Set wallet chain as default if no chains are provided by config and if they were not changed during widget usage
21
+ useEffect(() => {
22
+ if (!account.isActive || !account.chainId) {
23
+ return;
24
+ }
25
+ const { isDirty: isFromChainDirty, isTouched: isFromChainTouched } = methods.getFieldState(SwapFormKey.FromChain, methods.formState);
26
+ if (!fromChain && !isFromChainDirty && !isFromChainTouched) {
27
+ methods.setValue(SwapFormKey.FromChain, account.chainId, {
28
+ shouldDirty: false,
29
+ shouldTouch: false,
30
+ });
31
+ }
32
+ const { isDirty: isToChainDirty, isTouched: isToChainTouched } = methods.getFieldState(SwapFormKey.ToChain, methods.formState);
33
+ if (!toChain && !isToChainDirty && !isToChainTouched) {
34
+ methods.setValue(SwapFormKey.ToChain, account.chainId, {
35
+ shouldDirty: false,
36
+ shouldTouch: false,
37
+ });
38
+ }
39
+ }, [account.chainId, account.isActive, fromChain, methods, toChain]);
17
40
  return _jsx(FormProvider, Object.assign({}, methods, { children: children }));
18
41
  };
@@ -2,7 +2,7 @@ export declare enum SwapFormKey {
2
2
  FromAmount = "fromAmount",
3
3
  FromChain = "fromChain",
4
4
  FromToken = "fromToken",
5
- SearchTokensFilter = "searchTokensFilter",
5
+ TokenSearchFilter = "tokenSearchFilter",
6
6
  ToChain = "toChain",
7
7
  ToToken = "toToken"
8
8
  }
@@ -10,7 +10,7 @@ export declare type SwapFormValues = {
10
10
  [SwapFormKey.FromAmount]: string;
11
11
  [SwapFormKey.FromChain]: number;
12
12
  [SwapFormKey.FromToken]: string;
13
- [SwapFormKey.SearchTokensFilter]: string;
13
+ [SwapFormKey.TokenSearchFilter]: string;
14
14
  [SwapFormKey.ToChain]: number;
15
15
  [SwapFormKey.ToToken]: string;
16
16
  };
@@ -19,7 +19,6 @@ export declare const SwapFormKeyHelper: {
19
19
  getChainKey: (formType: SwapFormDirection) => 'fromChain' | 'toChain';
20
20
  getTokenKey: (formType: SwapFormDirection) => 'fromToken' | 'toToken';
21
21
  getAmountKey: (formType: SwapFormDirection) => 'fromAmount' | 'toAmount';
22
- getSearchTokensFilterKey: (formType: SwapFormDirection) => string;
23
22
  };
24
23
  export interface SwapFormTypeProps {
25
24
  formType: SwapFormDirection;
@@ -3,7 +3,7 @@ export var SwapFormKey;
3
3
  SwapFormKey["FromAmount"] = "fromAmount";
4
4
  SwapFormKey["FromChain"] = "fromChain";
5
5
  SwapFormKey["FromToken"] = "fromToken";
6
- SwapFormKey["SearchTokensFilter"] = "searchTokensFilter";
6
+ SwapFormKey["TokenSearchFilter"] = "tokenSearchFilter";
7
7
  SwapFormKey["ToChain"] = "toChain";
8
8
  SwapFormKey["ToToken"] = "toToken";
9
9
  })(SwapFormKey || (SwapFormKey = {}));
@@ -11,5 +11,4 @@ export const SwapFormKeyHelper = {
11
11
  getChainKey: (formType) => `${formType}Chain`,
12
12
  getTokenKey: (formType) => `${formType}Token`,
13
13
  getAmountKey: (formType) => `${formType}Amount`,
14
- getSearchTokensFilterKey: (formType) => `${formType}SearchTokensFilter`,
15
14
  };
@@ -11,4 +11,9 @@ export declare const extractAccountFromSigner: (signer?: Signer) => Promise<{
11
11
  isActive: boolean;
12
12
  signer: Signer | undefined;
13
13
  chainId: number | undefined;
14
+ } | {
15
+ address?: undefined;
16
+ isActive?: undefined;
17
+ signer?: undefined;
18
+ chainId?: undefined;
14
19
  }>;
@@ -85,10 +85,16 @@ export const WalletProvider = ({ children, walletManagement }) => {
85
85
  return (_jsx(WalletContext.Provider, Object.assign({ value: value }, { children: children })));
86
86
  };
87
87
  export const extractAccountFromSigner = (signer) => __awaiter(void 0, void 0, void 0, function* () {
88
- return ({
89
- address: (yield (signer === null || signer === void 0 ? void 0 : signer.getAddress())) || undefined,
90
- isActive: (signer && !!(yield signer.getAddress()) === null) || !!signer,
91
- signer,
92
- chainId: (yield (signer === null || signer === void 0 ? void 0 : signer.getChainId())) || undefined,
93
- });
88
+ try {
89
+ return {
90
+ address: (yield (signer === null || signer === void 0 ? void 0 : signer.getAddress())) || undefined,
91
+ isActive: (signer && !!(yield signer.getAddress()) === null) || !!signer,
92
+ signer,
93
+ chainId: (yield (signer === null || signer === void 0 ? void 0 : signer.getChainId())) || undefined,
94
+ };
95
+ }
96
+ catch (error) {
97
+ console.log(error);
98
+ return {};
99
+ }
94
100
  });
@@ -10,10 +10,9 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
- import { ChainId, getChainByKey } from '@lifi/sdk';
13
+ import { getChainByKey } from '@lifi/sdk';
14
14
  import { createContext, useContext, useEffect, useMemo } from 'react';
15
15
  import { updateLiFiConfig } from '../../config/lifi';
16
- import { useWallet } from '../WalletProvider';
17
16
  const stub = () => {
18
17
  throw new Error('You forgot to wrap your component in <WidgetProvider>.');
19
18
  };
@@ -23,26 +22,36 @@ const initialContext = {
23
22
  const WidgetContext = createContext(initialContext);
24
23
  export const useWidgetConfig = () => useContext(WidgetContext);
25
24
  export const WidgetProvider = (_a) => {
26
- var { children } = _a, _b = _a.config, _c = _b === void 0 ? {} : _b, { fromChain, fromToken, toChain, toToken, integrator } = _c, config = __rest(_c, ["fromChain", "fromToken", "toChain", "toToken", "integrator"]);
27
- const { account } = useWallet();
25
+ var { children } = _a, _b = _a.config, _c = _b === void 0 ? {} : _b, { fromChain, fromToken, toChain, toToken, fromAmount, integrator } = _c, config = __rest(_c, ["fromChain", "fromToken", "toChain", "toToken", "fromAmount", "integrator"]);
28
26
  const value = useMemo(() => {
29
- var _a;
27
+ var _a, _b, _c, _d;
30
28
  try {
31
- return Object.assign(Object.assign({}, config), { fromChain: typeof fromChain === 'number'
32
- ? fromChain
33
- : typeof fromChain === 'string'
34
- ? getChainByKey(fromChain.toLowerCase()).id
35
- : (_a = account.chainId) !== null && _a !== void 0 ? _a : ChainId.ETH, toChain: typeof toChain === 'number'
36
- ? toChain
37
- : typeof toChain === 'string'
38
- ? getChainByKey(toChain.toLowerCase()).id
39
- : ChainId.ETH, fromToken: fromToken === null || fromToken === void 0 ? void 0 : fromToken.toLowerCase(), toToken: toToken === null || toToken === void 0 ? void 0 : toToken.toLowerCase() });
29
+ const searchParams = Object.fromEntries(new URLSearchParams(window === null || window === void 0 ? void 0 : window.location.search));
30
+ return Object.assign(Object.assign({}, config), { fromChain: (searchParams.fromChain &&
31
+ isNaN(parseInt(searchParams.fromChain, 10))) ||
32
+ typeof fromChain === 'string'
33
+ ? getChainByKey((_a = (searchParams.fromChain || fromChain)) === null || _a === void 0 ? void 0 : _a.toLowerCase()).id
34
+ : (searchParams.fromChain &&
35
+ !isNaN(parseInt(searchParams.fromChain, 10))) ||
36
+ typeof fromChain === 'number'
37
+ ? parseInt(searchParams.fromChain, 10) || fromChain
38
+ : undefined, toChain: (searchParams.toChain && isNaN(parseInt(searchParams.toChain, 10))) ||
39
+ typeof toChain === 'string'
40
+ ? getChainByKey((_b = (searchParams.toChain || toChain)) === null || _b === void 0 ? void 0 : _b.toLowerCase()).id
41
+ : (searchParams.toChain &&
42
+ !isNaN(parseInt(searchParams.toChain, 10))) ||
43
+ typeof toChain === 'number'
44
+ ? parseInt(searchParams.toChain, 10) || toChain
45
+ : undefined, fromToken: ((_c = searchParams.fromToken) === null || _c === void 0 ? void 0 : _c.toLowerCase()) || (fromToken === null || fromToken === void 0 ? void 0 : fromToken.toLowerCase()), toToken: ((_d = searchParams.toToken) === null || _d === void 0 ? void 0 : _d.toLowerCase()) || (toToken === null || toToken === void 0 ? void 0 : toToken.toLowerCase()), fromAmount: typeof searchParams.fromAmount === 'string' &&
46
+ !isNaN(parseFloat(searchParams.fromAmount))
47
+ ? searchParams.fromAmount
48
+ : fromAmount });
40
49
  }
41
50
  catch (e) {
42
51
  console.warn(e);
43
52
  return config;
44
53
  }
45
- }, [account.chainId, config, fromChain, fromToken, toChain, toToken]);
54
+ }, [config, fromAmount, fromChain, fromToken, toChain, toToken]);
46
55
  useEffect(() => {
47
56
  updateLiFiConfig({
48
57
  defaultRouteOptions: {
package/types/index.d.ts CHANGED
@@ -1 +1,2 @@
1
+ export * from './token';
1
2
  export * from './widget';