@lifi/widget 3.37.0 → 3.38.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.
- package/CHANGELOG.md +26 -0
- package/dist/esm/components/AmountInput/PriceFormHelperText.style.js +3 -0
- package/dist/esm/components/AmountInput/PriceFormHelperText.style.js.map +1 -1
- package/dist/esm/components/AppContainer.js +1 -0
- package/dist/esm/components/AppContainer.js.map +1 -1
- package/dist/esm/components/Avatar/AccountAvatar.js +3 -3
- package/dist/esm/components/Avatar/AccountAvatar.js.map +1 -1
- package/dist/esm/components/Avatar/Avatar.d.ts +2 -0
- package/dist/esm/components/Avatar/Avatar.js +4 -3
- package/dist/esm/components/Avatar/Avatar.js.map +1 -1
- package/dist/esm/components/Avatar/ChainBadgeContent.d.ts +7 -0
- package/dist/esm/components/Avatar/ChainBadgeContent.js +10 -0
- package/dist/esm/components/Avatar/ChainBadgeContent.js.map +1 -0
- package/dist/esm/components/Avatar/TokenAvatar.js +3 -3
- package/dist/esm/components/Avatar/TokenAvatar.js.map +1 -1
- package/dist/esm/components/Chains/AllChainsAvatar.js +31 -5
- package/dist/esm/components/Chains/AllChainsAvatar.js.map +1 -1
- package/dist/esm/components/Chains/ChainSearchInput.js +7 -1
- package/dist/esm/components/Chains/ChainSearchInput.js.map +1 -1
- package/dist/esm/components/Header/NavigationHeader.js +5 -1
- package/dist/esm/components/Header/NavigationHeader.js.map +1 -1
- package/dist/esm/components/SelectTokenButton/SelectTokenButton.js +3 -1
- package/dist/esm/components/SelectTokenButton/SelectTokenButton.js.map +1 -1
- package/dist/esm/components/TokenList/TokenListItem.js +8 -2
- package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/hooks/useFilteredByTokenBalances.js +8 -2
- package/dist/esm/hooks/useFilteredByTokenBalances.js.map +1 -1
- package/dist/esm/hooks/useRoutes.js +10 -19
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useTokenSearch.js +15 -8
- package/dist/esm/hooks/useTokenSearch.js.map +1 -1
- package/dist/esm/hooks/useTokens.js +33 -53
- package/dist/esm/hooks/useTokens.js.map +1 -1
- package/dist/esm/i18n/en.json +1 -0
- package/dist/esm/pages/LanguagesPage.js +6 -7
- package/dist/esm/pages/LanguagesPage.js.map +1 -1
- package/dist/esm/stores/StoreProvider.js +2 -1
- package/dist/esm/stores/StoreProvider.js.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.js +20 -2
- package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
- package/dist/esm/types/token.d.ts +6 -1
- package/dist/esm/types/widget.d.ts +11 -2
- package/dist/esm/types/widget.js +1 -0
- package/dist/esm/types/widget.js.map +1 -1
- package/dist/esm/utils/token.d.ts +12 -1
- package/dist/esm/utils/token.js +44 -0
- package/dist/esm/utils/token.js.map +1 -1
- package/dist/esm/utils/tokenList.js +2 -0
- package/dist/esm/utils/tokenList.js.map +1 -1
- package/dist/esm/utils/variant.d.ts +2 -0
- package/dist/esm/utils/variant.js +10 -0
- package/dist/esm/utils/variant.js.map +1 -0
- package/package.json +7 -7
- package/package.json.tmp +9 -9
- package/src/components/AmountInput/PriceFormHelperText.style.tsx +3 -0
- package/src/components/AppContainer.tsx +1 -0
- package/src/components/Avatar/AccountAvatar.tsx +3 -15
- package/src/components/Avatar/Avatar.tsx +6 -7
- package/src/components/Avatar/ChainBadgeContent.tsx +22 -0
- package/src/components/Avatar/TokenAvatar.tsx +3 -11
- package/src/components/Chains/AllChainsAvatar.tsx +56 -8
- package/src/components/Chains/ChainSearchInput.tsx +9 -1
- package/src/components/Header/NavigationHeader.tsx +5 -1
- package/src/components/SelectTokenButton/SelectTokenButton.tsx +9 -1
- package/src/components/TokenList/TokenListItem.tsx +23 -1
- package/src/config/version.ts +1 -1
- package/src/hooks/useFilteredByTokenBalances.ts +8 -4
- package/src/hooks/useRoutes.ts +17 -23
- package/src/hooks/useTokenSearch.ts +17 -10
- package/src/hooks/useTokens.ts +51 -83
- package/src/i18n/en.json +1 -0
- package/src/pages/LanguagesPage.tsx +1 -2
- package/src/stores/StoreProvider.tsx +2 -1
- package/src/stores/chains/ChainOrderStore.tsx +24 -2
- package/src/types/token.ts +5 -0
- package/src/types/widget.ts +10 -1
- package/src/utils/token.ts +65 -1
- package/src/utils/tokenList.ts +2 -0
- package/src/utils/variant.ts +16 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variant.js","sourceRoot":"","sources":["../../../src/utils/variant.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAgD,EAC/B,EAAE;IACnB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,MAAM,CAAA;IACf,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,KAAK,CAAC,UAAU,CAAA;AACzB,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/widget",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.38.1",
|
|
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
|
"type": "module",
|
|
6
6
|
"main": "./dist/esm/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@bigmi/core": "^0.6.3",
|
|
35
35
|
"@emotion/react": "^11.14.0",
|
|
36
36
|
"@emotion/styled": "^11.14.1",
|
|
37
|
-
"@lifi/sdk": "^3.
|
|
37
|
+
"@lifi/sdk": "^3.14.1",
|
|
38
38
|
"@mui/icons-material": "^7.3.6",
|
|
39
39
|
"@mui/material": "^7.3.6",
|
|
40
40
|
"@mui/system": "^7.3.6",
|
|
@@ -42,17 +42,17 @@
|
|
|
42
42
|
"@solana/wallet-adapter-base": "^0.9.27",
|
|
43
43
|
"@solana/wallet-adapter-coinbase": "^0.1.23",
|
|
44
44
|
"@solana/web3.js": "^1.98.4",
|
|
45
|
-
"@tanstack/react-virtual": "^3.13.
|
|
46
|
-
"i18next": "^25.7.
|
|
45
|
+
"@tanstack/react-virtual": "^3.13.13",
|
|
46
|
+
"i18next": "^25.7.3",
|
|
47
47
|
"microdiff": "^1.5.0",
|
|
48
48
|
"mitt": "^3.0.1",
|
|
49
|
-
"react-i18next": "^16.
|
|
49
|
+
"react-i18next": "^16.5.0",
|
|
50
50
|
"react-intersection-observer": "^9.16.0",
|
|
51
51
|
"react-router-dom": "^6.30.1",
|
|
52
52
|
"react-transition-group": "^4.4.5",
|
|
53
|
-
"viem": "^2.
|
|
53
|
+
"viem": "^2.42.1",
|
|
54
54
|
"zustand": "^5.0.9",
|
|
55
|
-
"@lifi/wallet-management": "^3.
|
|
55
|
+
"@lifi/wallet-management": "^3.21.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
58
|
"@bigmi/react": ">=0.6.0",
|
package/package.json.tmp
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifi/widget",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.38.1",
|
|
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
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@bigmi/core": "^0.6.3",
|
|
54
54
|
"@emotion/react": "^11.14.0",
|
|
55
55
|
"@emotion/styled": "^11.14.1",
|
|
56
|
-
"@lifi/sdk": "^3.
|
|
56
|
+
"@lifi/sdk": "^3.14.1",
|
|
57
57
|
"@lifi/wallet-management": "workspace:^",
|
|
58
58
|
"@mui/icons-material": "^7.3.6",
|
|
59
59
|
"@mui/material": "^7.3.6",
|
|
@@ -62,25 +62,25 @@
|
|
|
62
62
|
"@solana/wallet-adapter-base": "^0.9.27",
|
|
63
63
|
"@solana/wallet-adapter-coinbase": "^0.1.23",
|
|
64
64
|
"@solana/web3.js": "^1.98.4",
|
|
65
|
-
"@tanstack/react-virtual": "^3.13.
|
|
66
|
-
"i18next": "^25.7.
|
|
65
|
+
"@tanstack/react-virtual": "^3.13.13",
|
|
66
|
+
"i18next": "^25.7.3",
|
|
67
67
|
"microdiff": "^1.5.0",
|
|
68
68
|
"mitt": "^3.0.1",
|
|
69
|
-
"react-i18next": "^16.
|
|
69
|
+
"react-i18next": "^16.5.0",
|
|
70
70
|
"react-intersection-observer": "^9.16.0",
|
|
71
71
|
"react-router-dom": "^6.30.1",
|
|
72
72
|
"react-transition-group": "^4.4.5",
|
|
73
|
-
"viem": "^2.
|
|
73
|
+
"viem": "^2.42.1",
|
|
74
74
|
"zustand": "^5.0.9"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@types/react-transition-group": "^4.4.12",
|
|
78
78
|
"cpy-cli": "^6.0.0",
|
|
79
79
|
"madge": "^8.0.0",
|
|
80
|
-
"react": "^19.2.
|
|
81
|
-
"react-dom": "^19.2.
|
|
80
|
+
"react": "^19.2.3",
|
|
81
|
+
"react-dom": "^19.2.3",
|
|
82
82
|
"typescript": "^5.9.3",
|
|
83
|
-
"vitest": "^4.0.
|
|
83
|
+
"vitest": "^4.0.16"
|
|
84
84
|
},
|
|
85
85
|
"peerDependencies": {
|
|
86
86
|
"@bigmi/react": ">=0.6.0",
|
|
@@ -4,12 +4,8 @@ import Wallet from '@mui/icons-material/Wallet'
|
|
|
4
4
|
import { Badge } from '@mui/material'
|
|
5
5
|
import { useChain } from '../../hooks/useChain.js'
|
|
6
6
|
import type { ToAddress } from '../../types/widget.js'
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
AvatarDefaultBadge,
|
|
10
|
-
AvatarMasked,
|
|
11
|
-
} from './Avatar.style.js'
|
|
12
|
-
import { SmallAvatar } from './SmallAvatar.js'
|
|
7
|
+
import { AvatarDefault, AvatarMasked } from './Avatar.style.js'
|
|
8
|
+
import { ChainBadgeContent } from './ChainBadgeContent.js'
|
|
13
9
|
|
|
14
10
|
interface AccountAvatarProps {
|
|
15
11
|
chainId?: number
|
|
@@ -45,15 +41,7 @@ export const AccountAvatar = ({
|
|
|
45
41
|
<Badge
|
|
46
42
|
overlap="circular"
|
|
47
43
|
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
|
48
|
-
badgeContent={
|
|
49
|
-
chain ? (
|
|
50
|
-
<SmallAvatar src={chain.logoURI} alt={chain.name}>
|
|
51
|
-
{chain.name[0]}
|
|
52
|
-
</SmallAvatar>
|
|
53
|
-
) : (
|
|
54
|
-
<AvatarDefaultBadge />
|
|
55
|
-
)
|
|
56
|
-
}
|
|
44
|
+
badgeContent={<ChainBadgeContent chain={chain} />}
|
|
57
45
|
>
|
|
58
46
|
{avatar}
|
|
59
47
|
</Badge>
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
+
import type { ExtendedChain } from '@lifi/sdk'
|
|
1
2
|
import type { SxProps, Theme } from '@mui/material'
|
|
2
3
|
import { Badge, Skeleton } from '@mui/material'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
AvatarDefaultBadge,
|
|
6
|
-
AvatarSkeletonMaskedContainer,
|
|
7
|
-
} from './Avatar.style.js'
|
|
4
|
+
import { AvatarDefault, AvatarSkeletonMaskedContainer } from './Avatar.style.js'
|
|
5
|
+
import { ChainBadgeContent } from './ChainBadgeContent.js'
|
|
8
6
|
import { SmallAvatarSkeleton } from './SmallAvatar.js'
|
|
9
7
|
|
|
10
8
|
export const AvatarBadgedDefault: React.FC<{
|
|
11
9
|
sx?: SxProps<Theme>
|
|
12
|
-
|
|
10
|
+
chain?: ExtendedChain
|
|
11
|
+
}> = ({ sx, chain }) => {
|
|
13
12
|
return (
|
|
14
13
|
<Badge
|
|
15
14
|
overlap="circular"
|
|
16
15
|
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
|
17
|
-
badgeContent={<
|
|
16
|
+
badgeContent={<ChainBadgeContent chain={chain} />}
|
|
18
17
|
sx={sx}
|
|
19
18
|
>
|
|
20
19
|
<AvatarDefault />
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Chain, ExtendedChain } from '@lifi/sdk'
|
|
2
|
+
import { AvatarDefaultBadge } from './Avatar.style.js'
|
|
3
|
+
import { SmallAvatar } from './SmallAvatar.js'
|
|
4
|
+
|
|
5
|
+
interface ChainBadgeContentProps {
|
|
6
|
+
chain?: Chain | ExtendedChain
|
|
7
|
+
size?: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const ChainBadgeContent: React.FC<ChainBadgeContentProps> = ({
|
|
11
|
+
chain,
|
|
12
|
+
size = 16,
|
|
13
|
+
}) => {
|
|
14
|
+
if (chain?.logoURI) {
|
|
15
|
+
return (
|
|
16
|
+
<SmallAvatar src={chain.logoURI} alt={chain.name} size={size}>
|
|
17
|
+
{chain.name?.[0]}
|
|
18
|
+
</SmallAvatar>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
return <AvatarDefaultBadge size={size} />
|
|
22
|
+
}
|
|
@@ -4,8 +4,8 @@ import { Badge } from '@mui/material'
|
|
|
4
4
|
import { useChain } from '../../hooks/useChain.js'
|
|
5
5
|
import { useToken } from '../../hooks/useToken.js'
|
|
6
6
|
import { AvatarBadgedSkeleton } from './Avatar.js'
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { AvatarMasked } from './Avatar.style.js'
|
|
8
|
+
import { ChainBadgeContent } from './ChainBadgeContent.js'
|
|
9
9
|
|
|
10
10
|
export const TokenAvatar: React.FC<{
|
|
11
11
|
token?: StaticToken
|
|
@@ -83,15 +83,7 @@ const TokenAvatarBase: React.FC<{
|
|
|
83
83
|
<Badge
|
|
84
84
|
overlap="circular"
|
|
85
85
|
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
|
86
|
-
badgeContent={
|
|
87
|
-
chain ? (
|
|
88
|
-
<SmallAvatar src={chain.logoURI} alt={chain.name} size={badgeSize}>
|
|
89
|
-
{chain.name[0]}
|
|
90
|
-
</SmallAvatar>
|
|
91
|
-
) : (
|
|
92
|
-
<AvatarDefaultBadge size={badgeSize} />
|
|
93
|
-
)
|
|
94
|
-
}
|
|
86
|
+
badgeContent={<ChainBadgeContent chain={chain} size={badgeSize} />}
|
|
95
87
|
sx={sx}
|
|
96
88
|
>
|
|
97
89
|
<AvatarMasked
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ChainId,
|
|
3
|
+
ChainType,
|
|
4
|
+
type EVMChain,
|
|
5
|
+
type ExtendedChain,
|
|
6
|
+
} from '@lifi/sdk'
|
|
2
7
|
import { Avatar, Box } from '@mui/material'
|
|
3
8
|
import { memo, useMemo } from 'react'
|
|
4
9
|
|
|
@@ -12,21 +17,25 @@ const chainTypeIcons = [
|
|
|
12
17
|
name: 'Ethereum',
|
|
13
18
|
chainType: ChainType.EVM,
|
|
14
19
|
icon: 'https://lifinance.github.io/types/src/assets/icons/chains/ethereum.svg',
|
|
20
|
+
defaultChainId: ChainId.ETH,
|
|
15
21
|
},
|
|
16
22
|
{
|
|
17
23
|
name: 'Solana',
|
|
18
24
|
chainType: ChainType.SVM,
|
|
19
25
|
icon: 'https://lifinance.github.io/types/src/assets/icons/chains/solana.svg',
|
|
26
|
+
defaultChainId: ChainId.SOL,
|
|
20
27
|
},
|
|
21
28
|
{
|
|
22
29
|
name: 'Bitcoin',
|
|
23
30
|
chainType: ChainType.UTXO,
|
|
24
31
|
icon: 'https://lifinance.github.io/types/src/assets/icons/chains/bitcoin.svg',
|
|
32
|
+
defaultChainId: ChainId.BTC,
|
|
25
33
|
},
|
|
26
34
|
{
|
|
27
35
|
name: 'Sui',
|
|
28
36
|
chainType: ChainType.MVM,
|
|
29
37
|
icon: 'https://lifinance.github.io/types/src/assets/icons/chains/sui.svg',
|
|
38
|
+
defaultChainId: ChainId.SUI,
|
|
30
39
|
},
|
|
31
40
|
]
|
|
32
41
|
|
|
@@ -35,10 +44,48 @@ const maxChainAvatarsCount = chainTypeIcons.length
|
|
|
35
44
|
export const AllChainsAvatar = memo(
|
|
36
45
|
({ chains, size }: AllChainsAvatarProps) => {
|
|
37
46
|
const icons = useMemo(() => {
|
|
47
|
+
// Create maps for efficient lookups
|
|
48
|
+
const chainsPerChainType = new Map<ChainType, number>()
|
|
49
|
+
const chainsByChainType = new Map<
|
|
50
|
+
ChainType,
|
|
51
|
+
(ExtendedChain | EVMChain)[]
|
|
52
|
+
>()
|
|
53
|
+
|
|
54
|
+
chains.forEach((chain) => {
|
|
55
|
+
chainsPerChainType.set(
|
|
56
|
+
chain.chainType,
|
|
57
|
+
(chainsPerChainType.get(chain.chainType) || 0) + 1
|
|
58
|
+
)
|
|
59
|
+
const chainsOfType = chainsByChainType.get(chain.chainType) || []
|
|
60
|
+
chainsOfType.push(chain)
|
|
61
|
+
chainsByChainType.set(chain.chainType, chainsOfType)
|
|
62
|
+
})
|
|
63
|
+
|
|
38
64
|
// Get existing ecosystem icons
|
|
39
|
-
const existingChainTypeIcons = chainTypeIcons.filter(
|
|
40
|
-
|
|
65
|
+
const existingChainTypeIcons = chainTypeIcons.filter(
|
|
66
|
+
(predefinedChain) => {
|
|
67
|
+
const numberOfChains =
|
|
68
|
+
chainsPerChainType.get(predefinedChain.chainType) ?? 0
|
|
69
|
+
|
|
70
|
+
// If there's only one chain of this type, check if it's not the default
|
|
71
|
+
if (numberOfChains === 1) {
|
|
72
|
+
const chainsOfType = chainsByChainType.get(
|
|
73
|
+
predefinedChain.chainType
|
|
74
|
+
)
|
|
75
|
+
const singleChain = chainsOfType?.[0]
|
|
76
|
+
// Exclude the predefined icon if the single chain is not the default
|
|
77
|
+
if (
|
|
78
|
+
singleChain &&
|
|
79
|
+
singleChain.id !== predefinedChain.defaultChainId
|
|
80
|
+
) {
|
|
81
|
+
return false
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return numberOfChains > 0
|
|
86
|
+
}
|
|
41
87
|
)
|
|
88
|
+
|
|
42
89
|
if (existingChainTypeIcons.length === maxChainAvatarsCount) {
|
|
43
90
|
return existingChainTypeIcons
|
|
44
91
|
}
|
|
@@ -46,13 +93,14 @@ export const AllChainsAvatar = memo(
|
|
|
46
93
|
const remainingSlots =
|
|
47
94
|
maxChainAvatarsCount - existingChainTypeIcons.length
|
|
48
95
|
|
|
96
|
+
// Create a Set for O(1) lookup of predefined icon names
|
|
97
|
+
const predefinedIconNames = new Set(
|
|
98
|
+
existingChainTypeIcons.map((icon) => icon.name)
|
|
99
|
+
)
|
|
100
|
+
|
|
49
101
|
const chainsWithLogos = chains.filter((chain) => {
|
|
50
102
|
// Filter out chain icons matching ecosystem icons
|
|
51
|
-
|
|
52
|
-
(icon) => icon.name === chain.name
|
|
53
|
-
)
|
|
54
|
-
const hasLogoURI = Boolean(chain.logoURI)
|
|
55
|
-
return !hasPredefinedIcon && hasLogoURI
|
|
103
|
+
return !predefinedIconNames.has(chain.name) && Boolean(chain.logoURI)
|
|
56
104
|
})
|
|
57
105
|
|
|
58
106
|
const additionalIcons = chainsWithLogos
|
|
@@ -29,7 +29,15 @@ export const ChainSearchInput = ({
|
|
|
29
29
|
|
|
30
30
|
if (inExpansion) {
|
|
31
31
|
return (
|
|
32
|
-
<Box
|
|
32
|
+
<Box
|
|
33
|
+
sx={{
|
|
34
|
+
pt: 3,
|
|
35
|
+
pb: 2,
|
|
36
|
+
px: 2.5,
|
|
37
|
+
height: searchHeaderHeight,
|
|
38
|
+
boxSizing: 'border-box',
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
33
41
|
<SearchInput
|
|
34
42
|
inputRef={inputRef}
|
|
35
43
|
onChange={onChange}
|
|
@@ -34,8 +34,12 @@ export const NavigationHeader: React.FC = () => {
|
|
|
34
34
|
const path = cleanedPathname.substring(cleanedPathname.lastIndexOf('/') + 1)
|
|
35
35
|
const hasPath = navigationRoutesValues.includes(path)
|
|
36
36
|
|
|
37
|
+
// Show tabs when split is undefined (default tabs) or an object with defaultTab
|
|
38
|
+
// Hide tabs when split is a string ('bridge' or 'swap' - single mode)
|
|
37
39
|
const showSplitOptions =
|
|
38
|
-
subvariant === 'split' &&
|
|
40
|
+
subvariant === 'split' &&
|
|
41
|
+
!hasPath &&
|
|
42
|
+
typeof subvariantOptions?.split !== 'string'
|
|
39
43
|
|
|
40
44
|
return (
|
|
41
45
|
<HeaderAppBar elevation={0} sx={{ paddingTop: 1, paddingBottom: 0.5 }}>
|
|
@@ -5,6 +5,8 @@ import { useChain } from '../../hooks/useChain.js'
|
|
|
5
5
|
import { useSwapOnly } from '../../hooks/useSwapOnly.js'
|
|
6
6
|
import { useToken } from '../../hooks/useToken.js'
|
|
7
7
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
8
|
+
import { useChainOrderStore } from '../../stores/chains/ChainOrderStore.js'
|
|
9
|
+
import type { ChainOrderState } from '../../stores/chains/types.js'
|
|
8
10
|
import type { FormTypeProps } from '../../stores/form/types.js'
|
|
9
11
|
import { FormKeyHelper } from '../../stores/form/types.js'
|
|
10
12
|
import { useFieldValues } from '../../stores/form/useFieldValues.js'
|
|
@@ -37,6 +39,10 @@ export const SelectTokenButton: React.FC<
|
|
|
37
39
|
const { chain, isLoading: isChainLoading } = useChain(chainId)
|
|
38
40
|
const { token, isLoading: isTokenLoading } = useToken(chainId, tokenAddress)
|
|
39
41
|
|
|
42
|
+
const isAllNetworks = useChainOrderStore(
|
|
43
|
+
(state: ChainOrderState) => state[`${formType}IsAllNetworks`]
|
|
44
|
+
)
|
|
45
|
+
|
|
40
46
|
const handleClick = () => {
|
|
41
47
|
navigate(
|
|
42
48
|
formType === 'from'
|
|
@@ -77,7 +83,9 @@ export const SelectTokenButton: React.FC<
|
|
|
77
83
|
isSelected ? (
|
|
78
84
|
<TokenAvatar token={token} chain={chain} />
|
|
79
85
|
) : (
|
|
80
|
-
<AvatarBadgedDefault
|
|
86
|
+
<AvatarBadgedDefault
|
|
87
|
+
chain={isAllNetworks ? undefined : chain}
|
|
88
|
+
/>
|
|
81
89
|
)
|
|
82
90
|
}
|
|
83
91
|
title={isSelected ? token.symbol : defaultPlaceholder}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { StaticToken } from '@lifi/sdk'
|
|
2
2
|
import { ChainType } from '@lifi/sdk'
|
|
3
3
|
import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'
|
|
4
|
+
import WarningRounded from '@mui/icons-material/WarningRounded'
|
|
4
5
|
import {
|
|
5
6
|
Avatar,
|
|
6
7
|
Box,
|
|
@@ -9,6 +10,7 @@ import {
|
|
|
9
10
|
listItemSecondaryActionClasses,
|
|
10
11
|
Skeleton,
|
|
11
12
|
Slide,
|
|
13
|
+
Tooltip,
|
|
12
14
|
Typography,
|
|
13
15
|
} from '@mui/material'
|
|
14
16
|
import type { MouseEventHandler } from 'react'
|
|
@@ -189,7 +191,27 @@ const TokenListItemButton: React.FC<TokenListItemButtonProps> = memo(
|
|
|
189
191
|
)}
|
|
190
192
|
</ListItemAvatar>
|
|
191
193
|
<ListItemText
|
|
192
|
-
primary={
|
|
194
|
+
primary={
|
|
195
|
+
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}>
|
|
196
|
+
{token.symbol}
|
|
197
|
+
{!token.verified && (
|
|
198
|
+
<Tooltip
|
|
199
|
+
title={t('warning.message.unverifiedToken')}
|
|
200
|
+
placement="top"
|
|
201
|
+
arrow
|
|
202
|
+
>
|
|
203
|
+
<WarningRounded
|
|
204
|
+
sx={{
|
|
205
|
+
display: 'flex',
|
|
206
|
+
fontSize: 16,
|
|
207
|
+
color: 'warning.main',
|
|
208
|
+
cursor: 'help',
|
|
209
|
+
}}
|
|
210
|
+
/>
|
|
211
|
+
</Tooltip>
|
|
212
|
+
)}
|
|
213
|
+
</Box>
|
|
214
|
+
}
|
|
193
215
|
slotProps={{
|
|
194
216
|
secondary: {
|
|
195
217
|
component: 'div',
|
package/src/config/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export const name = '@lifi/widget'
|
|
2
|
-
export const version = '3.
|
|
2
|
+
export const version = '3.38.1'
|
|
@@ -96,8 +96,8 @@ export const useFilteredTokensByBalance = (
|
|
|
96
96
|
formType
|
|
97
97
|
)
|
|
98
98
|
|
|
99
|
-
const additionalTokens = balances
|
|
100
|
-
(balance: WalletTokenExtended) => {
|
|
99
|
+
const additionalTokens = balances
|
|
100
|
+
.filter((balance: WalletTokenExtended) => {
|
|
101
101
|
const balanceKey = balance.address.toLowerCase()
|
|
102
102
|
return (
|
|
103
103
|
!chainTokenSet.has(balanceKey) &&
|
|
@@ -109,8 +109,12 @@ export const useFilteredTokensByBalance = (
|
|
|
109
109
|
(t) => t.address.toLowerCase()
|
|
110
110
|
)
|
|
111
111
|
)
|
|
112
|
-
}
|
|
113
|
-
|
|
112
|
+
})
|
|
113
|
+
// Mark tokens from wallet balances as unverified
|
|
114
|
+
.map((token: WalletTokenExtended) => ({
|
|
115
|
+
...token,
|
|
116
|
+
verified: false,
|
|
117
|
+
})) as TokenExtended[]
|
|
114
118
|
|
|
115
119
|
// Combine both sets of tokens - convert WalletTokenExtended to TokenAmount
|
|
116
120
|
const allTokens = [
|
package/src/hooks/useRoutes.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Route, Token
|
|
1
|
+
import type { Route, Token } from '@lifi/sdk'
|
|
2
2
|
import {
|
|
3
3
|
ChainType,
|
|
4
4
|
convertQuoteToRoute,
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
getRelayerQuote,
|
|
7
7
|
getRoutes,
|
|
8
8
|
isGaslessStep,
|
|
9
|
-
isTokenMessageSigningAllowed,
|
|
10
9
|
LiFiErrorCode,
|
|
11
10
|
} from '@lifi/sdk'
|
|
12
11
|
import { useAccount } from '@lifi/wallet-management'
|
|
@@ -20,8 +19,10 @@ import { useSetExecutableRoute } from '../stores/routes/useSetExecutableRoute.js
|
|
|
20
19
|
import { defaultSlippage } from '../stores/settings/createSettingsStore.js'
|
|
21
20
|
import { useSettings } from '../stores/settings/useSettings.js'
|
|
22
21
|
import { WidgetEvent } from '../types/events.js'
|
|
22
|
+
import type { TokensByChain } from '../types/token.js'
|
|
23
23
|
import { getChainTypeFromAddress } from '../utils/chainType.js'
|
|
24
24
|
import { getQueryKey } from '../utils/queries.js'
|
|
25
|
+
import { updateTokenInCache } from '../utils/token.js'
|
|
25
26
|
import { useChain } from './useChain.js'
|
|
26
27
|
import { useDebouncedWatch } from './useDebouncedWatch.js'
|
|
27
28
|
import { useGasRefuel } from './useGasRefuel.js'
|
|
@@ -352,8 +353,7 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
352
353
|
fromChain.nativeToken.address !== fromTokenAddress &&
|
|
353
354
|
useRelayerRoutes &&
|
|
354
355
|
!isBatchingSupported &&
|
|
355
|
-
(!observableRoute || isObservableRelayerRoute)
|
|
356
|
-
isTokenMessageSigningAllowed(fromToken!)
|
|
356
|
+
(!observableRoute || isObservableRelayerRoute)
|
|
357
357
|
|
|
358
358
|
const mainRoutesPromise = shouldUseMainRoutes
|
|
359
359
|
? getRoutes(
|
|
@@ -447,27 +447,21 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
447
447
|
// Update local tokens cache to keep priceUSD in sync
|
|
448
448
|
const { fromToken, toToken } = routesResult.routes[0]
|
|
449
449
|
;[fromToken, toToken].forEach((token) => {
|
|
450
|
-
|
|
450
|
+
// Update main tokens cache (verified)
|
|
451
|
+
queryClient.setQueriesData<TokensByChain>(
|
|
451
452
|
{ queryKey: [getQueryKey('tokens', keyPrefix)] },
|
|
452
|
-
(data) =>
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
clonedData.tokens[token.chainId][index] = {
|
|
463
|
-
...clonedData.tokens[token.chainId][index],
|
|
464
|
-
...token,
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
return clonedData
|
|
468
|
-
}
|
|
469
|
-
}
|
|
453
|
+
(data) => updateTokenInCache(data, token)
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
// Update search tokens cache (unverified) - matches any search query
|
|
457
|
+
queryClient.setQueriesData<TokensByChain>(
|
|
458
|
+
{
|
|
459
|
+
queryKey: [getQueryKey('tokens-search', keyPrefix)],
|
|
460
|
+
exact: false,
|
|
461
|
+
},
|
|
462
|
+
(data) => updateTokenInCache(data, token)
|
|
470
463
|
)
|
|
464
|
+
|
|
471
465
|
queryClient.setQueriesData<Token[]>(
|
|
472
466
|
{
|
|
473
467
|
queryKey: [
|
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
type ChainId,
|
|
4
4
|
getToken,
|
|
5
5
|
type TokenExtended,
|
|
6
|
-
type TokensResponse,
|
|
7
6
|
} from '@lifi/sdk'
|
|
8
7
|
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
9
8
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
10
9
|
import type { FormType } from '../stores/form/types.js'
|
|
10
|
+
import type { TokensByChain } from '../types/token.js'
|
|
11
11
|
import { getConfigItemSets, isFormItemAllowed } from '../utils/item.js'
|
|
12
12
|
import { getQueryKey } from '../utils/queries.js'
|
|
13
13
|
|
|
@@ -49,21 +49,28 @@ export const useTokenSearch = (
|
|
|
49
49
|
return null
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
// Add token to main tokens cache
|
|
53
|
+
queryClient.setQueriesData<TokensByChain>(
|
|
53
54
|
{ queryKey: [getQueryKey('tokens', keyPrefix)] },
|
|
54
55
|
(data) => {
|
|
56
|
+
if (!data) {
|
|
57
|
+
return data
|
|
58
|
+
}
|
|
59
|
+
const chainTokens = data[chainId as number]
|
|
55
60
|
if (
|
|
56
|
-
|
|
57
|
-
!data.tokens[chainId as number]?.some(
|
|
61
|
+
chainTokens?.some(
|
|
58
62
|
(t) => t.address.toLowerCase() === token.address.toLowerCase()
|
|
59
63
|
)
|
|
60
64
|
) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
return data
|
|
66
|
+
}
|
|
67
|
+
// Mark token from search as unverified
|
|
68
|
+
return {
|
|
69
|
+
...data,
|
|
70
|
+
[chainId as number]: [
|
|
71
|
+
...(chainTokens ?? []),
|
|
72
|
+
{ ...token, verified: false },
|
|
73
|
+
],
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
76
|
)
|