@lifi/widget 4.8.0 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -3
- package/dist/esm/components/AmountInputCard/AmountInputCardPair.js +5 -2
- package/dist/esm/components/AmountInputCard/AmountInputCardPair.js.map +1 -1
- package/dist/esm/components/SelectChainAndToken.js +5 -2
- package/dist/esm/components/SelectChainAndToken.js.map +1 -1
- package/dist/esm/components/SendToWallet/SendToWalletButton.js +5 -4
- package/dist/esm/components/SendToWallet/SendToWalletButton.js.map +1 -1
- package/dist/esm/components/TokenList/TokenDetailsSheet.js +5 -8
- package/dist/esm/components/TokenList/TokenDetailsSheet.js.map +1 -1
- package/dist/esm/components/TokenList/TokenDetailsSheetContent.js +30 -2
- package/dist/esm/components/TokenList/TokenDetailsSheetContent.js.map +1 -1
- package/dist/esm/components/TokenList/TokenListItem.js +36 -47
- package/dist/esm/components/TokenList/TokenListItem.js.map +1 -1
- package/dist/esm/components/TokenList/VirtualizedTokenList.d.ts.map +1 -1
- package/dist/esm/components/TokenList/VirtualizedTokenList.js +2 -2
- package/dist/esm/components/TokenList/VirtualizedTokenList.js.map +1 -1
- package/dist/esm/components/TokenList/tokenVerificationIcons.js +29 -0
- package/dist/esm/components/TokenList/tokenVerificationIcons.js.map +1 -0
- package/dist/esm/components/TokenList/useTokenSelect.d.ts.map +1 -1
- package/dist/esm/components/TokenList/useTokenSelect.js +10 -0
- package/dist/esm/components/TokenList/useTokenSelect.js.map +1 -1
- package/dist/esm/config/constants.js.map +1 -1
- package/dist/esm/config/version.d.ts +1 -1
- package/dist/esm/config/version.js +1 -1
- package/dist/esm/config/version.js.map +1 -1
- package/dist/esm/hooks/useAccountsBalancesData.js +5 -2
- package/dist/esm/hooks/useAccountsBalancesData.js.map +1 -1
- package/dist/esm/hooks/useAddressValidation.d.ts +3 -2
- package/dist/esm/hooks/useAddressValidation.d.ts.map +1 -1
- package/dist/esm/hooks/useAddressValidation.js +48 -21
- package/dist/esm/hooks/useAddressValidation.js.map +1 -1
- package/dist/esm/hooks/useGasRefuel.js +4 -1
- package/dist/esm/hooks/useGasRefuel.js.map +1 -1
- package/dist/esm/hooks/useRoutes.d.ts.map +1 -1
- package/dist/esm/hooks/useRoutes.js +11 -6
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useToAddressAutoPopulate.js +6 -8
- package/dist/esm/hooks/useToAddressAutoPopulate.js.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.d.ts +3 -2
- package/dist/esm/hooks/useToAddressRequirements.d.ts.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.js +8 -7
- package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
- package/dist/esm/hooks/useToAddressReset.js +6 -3
- package/dist/esm/hooks/useToAddressReset.js.map +1 -1
- package/dist/esm/hooks/useTokenBalance.js +2 -1
- package/dist/esm/hooks/useTokenBalance.js.map +1 -1
- package/dist/esm/hooks/useTokens.js +1 -1
- package/dist/esm/i18n/bn.json +7 -2
- package/dist/esm/i18n/de.json +7 -2
- package/dist/esm/i18n/en.json +7 -2
- package/dist/esm/i18n/es.json +7 -2
- package/dist/esm/i18n/fr.json +7 -2
- package/dist/esm/i18n/hi.json +7 -2
- package/dist/esm/i18n/id.json +7 -2
- package/dist/esm/i18n/it.json +7 -2
- package/dist/esm/i18n/ja.json +7 -2
- package/dist/esm/i18n/ko.json +7 -2
- package/dist/esm/i18n/pl.json +7 -2
- package/dist/esm/i18n/pt.json +7 -2
- package/dist/esm/i18n/th.json +7 -2
- package/dist/esm/i18n/tr.json +7 -2
- package/dist/esm/i18n/uk.json +7 -2
- package/dist/esm/i18n/vi.json +7 -2
- package/dist/esm/i18n/zh.json +7 -2
- package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js +7 -4
- package/dist/esm/pages/SendToWallet/BookmarkAddressSheet.js.map +1 -1
- package/dist/esm/pages/SendToWallet/BookmarksPage.js +35 -31
- package/dist/esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js +4 -3
- package/dist/esm/pages/SendToWallet/ConnectedWalletsPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/RecentWalletsPage.js +43 -39
- package/dist/esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js +32 -26
- package/dist/esm/pages/SendToWallet/SendToConfiguredWalletPage.js.map +1 -1
- package/dist/esm/pages/SendToWallet/SendToWalletPage.js +5 -10
- package/dist/esm/pages/SendToWallet/SendToWalletPage.js.map +1 -1
- package/dist/esm/providers/WalletProvider/WalletProvider.d.ts.map +1 -1
- package/dist/esm/providers/WalletProvider/WalletProvider.js +14 -2
- package/dist/esm/providers/WalletProvider/WalletProvider.js.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.d.ts.map +1 -1
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js +10 -14
- package/dist/esm/providers/WidgetProvider/WidgetProvider.js.map +1 -1
- package/dist/esm/stores/bookmarks/types.d.ts +3 -0
- package/dist/esm/stores/bookmarks/types.d.ts.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.d.ts.map +1 -1
- package/dist/esm/stores/chains/ChainOrderStore.js +4 -1
- package/dist/esm/stores/chains/ChainOrderStore.js.map +1 -1
- package/dist/esm/stores/form/FormStore.js +3 -2
- package/dist/esm/stores/form/FormStore.js.map +1 -1
- package/dist/esm/stores/form/URLSearchParamsBuilder.js +7 -3
- package/dist/esm/stores/form/URLSearchParamsBuilder.js.map +1 -1
- package/dist/esm/stores/form/getDefaultValuesFromQueryString.js +4 -1
- package/dist/esm/stores/form/getDefaultValuesFromQueryString.js.map +1 -1
- package/dist/esm/utils/chainType.js +32 -1
- package/dist/esm/utils/chainType.js.map +1 -1
- package/dist/esm/utils/customReceiver.js +6 -1
- package/dist/esm/utils/customReceiver.js.map +1 -1
- package/dist/esm/utils/token.js +13 -1
- package/dist/esm/utils/token.js.map +1 -1
- package/package.json +7 -7
- package/src/components/AmountInputCard/AmountInputCardPair.tsx +6 -2
- package/src/components/SelectChainAndToken.tsx +5 -1
- package/src/components/SendToWallet/SendToWalletButton.tsx +13 -8
- package/src/components/TokenList/TokenDetailsSheet.tsx +5 -9
- package/src/components/TokenList/TokenDetailsSheetContent.tsx +46 -4
- package/src/components/TokenList/TokenListItem.tsx +44 -68
- package/src/components/TokenList/VirtualizedTokenList.tsx +3 -6
- package/src/components/TokenList/tokenVerificationIcons.ts +15 -0
- package/src/components/TokenList/types.ts +3 -11
- package/src/components/TokenList/useTokenSelect.ts +15 -0
- package/src/config/constants.ts +3 -0
- package/src/config/version.ts +1 -1
- package/src/hooks/useAccountsBalancesData.ts +6 -2
- package/src/hooks/useAddressValidation.ts +87 -32
- package/src/hooks/useGasRefuel.ts +11 -1
- package/src/hooks/useRoutes.ts +23 -18
- package/src/hooks/useToAddressAutoPopulate.ts +13 -17
- package/src/hooks/useToAddressRequirements.ts +19 -4
- package/src/hooks/useToAddressReset.ts +13 -4
- package/src/hooks/useTokenBalance.ts +6 -1
- package/src/pages/SendToWallet/BookmarkAddressSheet.tsx +5 -1
- package/src/pages/SendToWallet/BookmarksPage.tsx +42 -52
- package/src/pages/SendToWallet/ConnectedWalletsPage.tsx +4 -14
- package/src/pages/SendToWallet/RecentWalletsPage.tsx +59 -66
- package/src/pages/SendToWallet/SendToConfiguredWalletPage.tsx +45 -50
- package/src/pages/SendToWallet/SendToWalletPage.tsx +4 -16
- package/src/providers/WalletProvider/WalletProvider.tsx +28 -3
- package/src/providers/WidgetProvider/WidgetProvider.tsx +20 -19
- package/src/stores/bookmarks/types.ts +3 -0
- package/src/stores/chains/ChainOrderStore.tsx +4 -1
- package/src/stores/form/FormStore.tsx +2 -0
- package/src/stores/form/URLSearchParamsBuilder.tsx +4 -2
- package/src/stores/form/getDefaultValuesFromQueryString.ts +19 -0
- package/src/utils/chainType.ts +73 -1
- package/src/utils/customReceiver.ts +36 -0
- package/src/utils/token.ts +48 -0
package/src/hooks/useRoutes.ts
CHANGED
|
@@ -9,10 +9,7 @@ import {
|
|
|
9
9
|
parseUnits,
|
|
10
10
|
} from '@lifi/sdk'
|
|
11
11
|
import { useAccount } from '@lifi/wallet-management'
|
|
12
|
-
import {
|
|
13
|
-
useChainTypeFromAddress,
|
|
14
|
-
useEthereumContext,
|
|
15
|
-
} from '@lifi/widget-provider'
|
|
12
|
+
import { useAddressForChain, useEthereumContext } from '@lifi/widget-provider'
|
|
16
13
|
import {
|
|
17
14
|
keepPreviousData,
|
|
18
15
|
useQuery,
|
|
@@ -29,7 +26,11 @@ import { defaultSlippage } from '../stores/settings/createSettingsStore.js'
|
|
|
29
26
|
import { useSettings } from '../stores/settings/useSettings.js'
|
|
30
27
|
import { WidgetEvent } from '../types/events.js'
|
|
31
28
|
import type { TokensByChain } from '../types/token.js'
|
|
32
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
canQuoteWithToAddress,
|
|
31
|
+
isCustomReceiverBlocked,
|
|
32
|
+
isSignerInvalidReceiver,
|
|
33
|
+
} from '../utils/customReceiver.js'
|
|
33
34
|
import { getQueryKey } from '../utils/queries.js'
|
|
34
35
|
import { updateTokenInCache } from '../utils/token.js'
|
|
35
36
|
import { useChain } from './useChain.js'
|
|
@@ -138,7 +139,7 @@ export const useRoutes = ({
|
|
|
138
139
|
const { chain: toChain } = useChain(toChainId)
|
|
139
140
|
const { enabled: enabledRefuel, fromAmount: gasRecommendationFromAmount } =
|
|
140
141
|
useGasRefuel()
|
|
141
|
-
const {
|
|
142
|
+
const { isAddressForChain } = useAddressForChain()
|
|
142
143
|
const { isGaslessStep, disableMessageSigning } = useEthereumContext()
|
|
143
144
|
const { account } = useAccount({ chainType: fromChain?.chainType })
|
|
144
145
|
const { isBatchingSupported, isBatchingSupportedLoading } =
|
|
@@ -165,18 +166,22 @@ export const useRoutes = ({
|
|
|
165
166
|
? Boolean(account.address)
|
|
166
167
|
: mode !== 'custom' || customType === 'deposit'
|
|
167
168
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
169
|
+
// Quote as if disconnected while the signer would be taken as the receiver.
|
|
170
|
+
const effectiveFromAddress = isSignerInvalidReceiver({
|
|
171
|
+
signerAddress: account.address,
|
|
172
|
+
toAddress,
|
|
173
|
+
fromChain,
|
|
174
|
+
toChain,
|
|
175
|
+
isAddressForChain,
|
|
176
|
+
})
|
|
177
|
+
? quoteFromAddress
|
|
178
|
+
: (account.address ?? quoteFromAddress)
|
|
179
|
+
|
|
180
|
+
const isToAddressSatisfied = canQuoteWithToAddress(
|
|
181
|
+
toAddress,
|
|
182
|
+
toChain,
|
|
183
|
+
isAddressForChain
|
|
184
|
+
)
|
|
180
185
|
|
|
181
186
|
// Not `effectiveFromAddress`: a quote placeholder must never match a receiver.
|
|
182
187
|
const customReceiverBlocked = isCustomReceiverBlocked({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useAccount } from '@lifi/wallet-management'
|
|
2
|
-
import {
|
|
2
|
+
import { useAddressForChain } from '@lifi/widget-provider'
|
|
3
3
|
import { useCallback } from 'react'
|
|
4
4
|
import { useBookmarkActions } from '../stores/bookmarks/useBookmarkActions.js'
|
|
5
5
|
import type { FormType } from '../stores/form/types.js'
|
|
@@ -24,7 +24,7 @@ export const useToAddressAutoPopulate = (): ((
|
|
|
24
24
|
const { setSelectedBookmark } = useBookmarkActions()
|
|
25
25
|
const { getChainById } = useAvailableChains()
|
|
26
26
|
const { accounts } = useAccount()
|
|
27
|
-
const {
|
|
27
|
+
const { isAddressForChain } = useAddressForChain()
|
|
28
28
|
|
|
29
29
|
return useCallback(
|
|
30
30
|
({
|
|
@@ -52,22 +52,18 @@ export const useToAddressAutoPopulate = (): ((
|
|
|
52
52
|
) {
|
|
53
53
|
return
|
|
54
54
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const selectedToAddressChainType =
|
|
63
|
-
getChainTypeFromAddress(selectedToAddress)
|
|
64
|
-
if (destinationChainType === selectedToAddressChainType) {
|
|
65
|
-
return
|
|
66
|
-
}
|
|
55
|
+
const destinationChain =
|
|
56
|
+
formType === 'from' ? selectedOppositeChain : selectedChain
|
|
57
|
+
if (
|
|
58
|
+
selectedToAddress &&
|
|
59
|
+
isAddressForChain(selectedToAddress, destinationChain)
|
|
60
|
+
) {
|
|
61
|
+
return
|
|
67
62
|
}
|
|
68
|
-
// Find connected account compatible with the destination chain type
|
|
69
63
|
const destinationAccount = accounts?.find(
|
|
70
|
-
(account) =>
|
|
64
|
+
(account) =>
|
|
65
|
+
account.address &&
|
|
66
|
+
isAddressForChain(account.address, destinationChain)
|
|
71
67
|
)
|
|
72
68
|
// If a compatible destination account is found, set toAddress as if selecting it from the "Send to Wallet" connected wallets page
|
|
73
69
|
if (destinationAccount?.address) {
|
|
@@ -89,7 +85,7 @@ export const useToAddressAutoPopulate = (): ((
|
|
|
89
85
|
getChainById,
|
|
90
86
|
setFieldValue,
|
|
91
87
|
setSelectedBookmark,
|
|
92
|
-
|
|
88
|
+
isAddressForChain,
|
|
93
89
|
]
|
|
94
90
|
)
|
|
95
91
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { RouteExtended } from '@lifi/sdk'
|
|
2
2
|
import { useAccount } from '@lifi/wallet-management'
|
|
3
|
-
import { useEthereumContext } from '@lifi/widget-provider'
|
|
3
|
+
import { useAddressForChain, useEthereumContext } from '@lifi/widget-provider'
|
|
4
4
|
import { useChain } from '../hooks/useChain.js'
|
|
5
5
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
6
6
|
import { useFieldValues } from '../stores/form/useFieldValues.js'
|
|
@@ -16,7 +16,8 @@ export const useToAddressRequirements = (
|
|
|
16
16
|
requiredToAddress: boolean
|
|
17
17
|
unsupportedToAddress: boolean
|
|
18
18
|
unsupportedReceiverBlocking: boolean
|
|
19
|
-
|
|
19
|
+
/** Whether a saved or connected address can receive on the destination chain. */
|
|
20
|
+
isValidReceiver: (address?: string) => boolean
|
|
20
21
|
accountNotDeployedAtDestination: boolean
|
|
21
22
|
accountDeployedAtDestination: boolean
|
|
22
23
|
toAddress: string | undefined
|
|
@@ -32,6 +33,7 @@ export const useToAddressRequirements = (
|
|
|
32
33
|
'toAddress'
|
|
33
34
|
)
|
|
34
35
|
const { isDelegationDesignatorCode } = useEthereumContext()
|
|
36
|
+
const { isAddressForChain } = useAddressForChain()
|
|
35
37
|
|
|
36
38
|
const fromChainId = route?.fromChainId ?? formFromChainId
|
|
37
39
|
const toChainId = route?.toChainId ?? formToChainId
|
|
@@ -87,14 +89,27 @@ export const useToAddressRequirements = (
|
|
|
87
89
|
receiverRequired: requiredUI?.toAddress,
|
|
88
90
|
})
|
|
89
91
|
|
|
92
|
+
// A shared chain type is not a shared format: a Bitcoin signer cannot receive on ZEC.
|
|
93
|
+
const isSignerAddressInvalidAtDestination = Boolean(
|
|
94
|
+
fromAddress &&
|
|
95
|
+
fromChain &&
|
|
96
|
+
toChain &&
|
|
97
|
+
isAddressForChain(fromAddress, fromChain) &&
|
|
98
|
+
!isAddressForChain(fromAddress, toChain)
|
|
99
|
+
)
|
|
100
|
+
|
|
90
101
|
const requiredToAddress = Boolean(
|
|
91
102
|
(isDifferentChainType ||
|
|
92
103
|
isCrossChainContractAddress ||
|
|
104
|
+
isSignerAddressInvalidAtDestination ||
|
|
93
105
|
requiredUI?.toAddress) &&
|
|
94
106
|
!hiddenUI?.toAddress &&
|
|
95
107
|
!unsupportedToAddress
|
|
96
108
|
)
|
|
97
109
|
|
|
110
|
+
const isValidReceiver = (address?: string): boolean =>
|
|
111
|
+
!toChain || (!!address && isAddressForChain(address, toChain))
|
|
112
|
+
|
|
98
113
|
const accountNotDeployedAtDestination = Boolean(
|
|
99
114
|
isFromContractAddress &&
|
|
100
115
|
!fromContractCodeHasDelegationIndicator &&
|
|
@@ -113,7 +128,7 @@ export const useToAddressRequirements = (
|
|
|
113
128
|
requiredToAddress,
|
|
114
129
|
unsupportedToAddress,
|
|
115
130
|
unsupportedReceiverBlocking,
|
|
116
|
-
|
|
131
|
+
isValidReceiver,
|
|
117
132
|
accountNotDeployedAtDestination,
|
|
118
133
|
accountDeployedAtDestination,
|
|
119
134
|
toAddress,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ExtendedChain } from '@lifi/sdk'
|
|
2
|
+
import { useAddressForChain } from '@lifi/widget-provider'
|
|
2
3
|
import { useCallback } from 'react'
|
|
3
4
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
4
5
|
import { useBookmarkActions } from '../stores/bookmarks/useBookmarkActions.js'
|
|
@@ -12,16 +13,18 @@ export const useToAddressReset = (): {
|
|
|
12
13
|
const { setFieldValue } = useFieldActions()
|
|
13
14
|
const { selectedBookmark } = useBookmarks()
|
|
14
15
|
const { setSelectedBookmark } = useBookmarkActions()
|
|
16
|
+
const { isAddressForChain } = useAddressForChain()
|
|
15
17
|
|
|
16
18
|
const tryResetToAddress = useCallback(
|
|
17
19
|
(toChain: ExtendedChain) => {
|
|
18
20
|
const requiredToAddress = requiredUI?.toAddress
|
|
19
21
|
|
|
20
|
-
const
|
|
21
|
-
selectedBookmark
|
|
22
|
+
const bookmarkSatisfiesToChain = Boolean(
|
|
23
|
+
selectedBookmark && isAddressForChain(selectedBookmark.address, toChain)
|
|
24
|
+
)
|
|
22
25
|
|
|
23
26
|
const shouldResetToAddress =
|
|
24
|
-
!requiredToAddress && !
|
|
27
|
+
!requiredToAddress && !bookmarkSatisfiesToChain
|
|
25
28
|
|
|
26
29
|
// We reset toAddress on each chain change if it's no longer required, ensuring that
|
|
27
30
|
// switching chain types doesn't leave a stale toAddress from a different ecosystem.
|
|
@@ -30,7 +33,13 @@ export const useToAddressReset = (): {
|
|
|
30
33
|
setSelectedBookmark()
|
|
31
34
|
}
|
|
32
35
|
},
|
|
33
|
-
[
|
|
36
|
+
[
|
|
37
|
+
setFieldValue,
|
|
38
|
+
setSelectedBookmark,
|
|
39
|
+
requiredUI,
|
|
40
|
+
selectedBookmark,
|
|
41
|
+
isAddressForChain,
|
|
42
|
+
]
|
|
34
43
|
)
|
|
35
44
|
|
|
36
45
|
return {
|
|
@@ -8,6 +8,7 @@ import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
|
8
8
|
import { useCallback, useMemo } from 'react'
|
|
9
9
|
import { useSDKClient } from '../providers/SDKClientProvider.js'
|
|
10
10
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
11
|
+
import { isDestinationOnlyChain } from '../utils/chainType.js'
|
|
11
12
|
import { getQueryKey } from '../utils/queries.js'
|
|
12
13
|
|
|
13
14
|
const defaultRefetchInterval = 30_000
|
|
@@ -93,7 +94,11 @@ export const useTokenBalance = (
|
|
|
93
94
|
} as TokenAmount
|
|
94
95
|
},
|
|
95
96
|
|
|
96
|
-
|
|
97
|
+
// No provider reads a balance on a destination-only chain, and a balance
|
|
98
|
+
// without a block number is retried until the backoff gives up.
|
|
99
|
+
enabled:
|
|
100
|
+
Boolean(accountAddress && token) &&
|
|
101
|
+
!isDestinationOnlyChain(token?.chainId),
|
|
97
102
|
refetchInterval: defaultRefetchInterval,
|
|
98
103
|
staleTime: defaultRefetchInterval,
|
|
99
104
|
})
|
|
@@ -9,6 +9,7 @@ import { BottomSheet } from '../../components/BottomSheet/BottomSheet.js'
|
|
|
9
9
|
import type { BottomSheetBase } from '../../components/BottomSheet/types.js'
|
|
10
10
|
import { Input } from '../../components/Input.js'
|
|
11
11
|
import { AlertMessage } from '../../components/Messages/AlertMessage.js'
|
|
12
|
+
import { addressInputMaxLength } from '../../config/constants.js'
|
|
12
13
|
import { useAddressValidation } from '../../hooks/useAddressValidation.js'
|
|
13
14
|
import type { Bookmark } from '../../stores/bookmarks/types.js'
|
|
14
15
|
import { useBookmarkActions } from '../../stores/bookmarks/useBookmarkActions.js'
|
|
@@ -63,6 +64,7 @@ export const BookmarkAddressSheet = ({
|
|
|
63
64
|
name: nameValue,
|
|
64
65
|
address: validationResult.address,
|
|
65
66
|
chainType: validationResult.chainType,
|
|
67
|
+
chainId: validationResult.chainId,
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
70
|
|
|
@@ -74,6 +76,7 @@ export const BookmarkAddressSheet = ({
|
|
|
74
76
|
name: nameValue,
|
|
75
77
|
address: validatedWallet.address,
|
|
76
78
|
chainType: validatedWallet.chainType,
|
|
79
|
+
chainId: validatedWallet.chainId,
|
|
77
80
|
}
|
|
78
81
|
}
|
|
79
82
|
|
|
@@ -119,6 +122,7 @@ export const BookmarkAddressSheet = ({
|
|
|
119
122
|
name: validatedBookmark.name,
|
|
120
123
|
address: validatedBookmark.address,
|
|
121
124
|
chainType: validatedBookmark.chainType,
|
|
125
|
+
chainId: validatedBookmark.chainId,
|
|
122
126
|
})
|
|
123
127
|
}
|
|
124
128
|
}
|
|
@@ -198,7 +202,7 @@ export const BookmarkAddressSheet = ({
|
|
|
198
202
|
context: 'long',
|
|
199
203
|
})}
|
|
200
204
|
maxRows={2}
|
|
201
|
-
inputProps={{ maxLength:
|
|
205
|
+
inputProps={{ maxLength: addressInputMaxLength }}
|
|
202
206
|
multiline
|
|
203
207
|
/>
|
|
204
208
|
</SendToWalletCard>
|
|
@@ -34,7 +34,7 @@ export const BookmarksPage = (): JSX.Element => {
|
|
|
34
34
|
const listParentRef = useRef<HTMLUListElement | null>(null)
|
|
35
35
|
const buttonRef = useRef<HTMLDivElement | null>(null)
|
|
36
36
|
const { bookmarks } = useBookmarks()
|
|
37
|
-
const {
|
|
37
|
+
const { isValidReceiver } = useToAddressRequirements()
|
|
38
38
|
const { addBookmark, removeBookmark, setSelectedBookmark } =
|
|
39
39
|
useBookmarkActions()
|
|
40
40
|
const navigate = useNavigate()
|
|
@@ -70,59 +70,49 @@ export const BookmarksPage = (): JSX.Element => {
|
|
|
70
70
|
disablePadding
|
|
71
71
|
sx={{ paddingTop: 1.5 }}
|
|
72
72
|
>
|
|
73
|
-
{bookmarks.map((bookmark) =>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
<
|
|
84
|
-
chainId={
|
|
73
|
+
{bookmarks.map((bookmark) => {
|
|
74
|
+
const disabled = !isValidReceiver(bookmark.address)
|
|
75
|
+
const chainId =
|
|
76
|
+
bookmark.chainId ?? defaultChainIdsByType[bookmark.chainType]
|
|
77
|
+
return (
|
|
78
|
+
<ListItem key={bookmark.address} sx={{ position: 'relative' }}>
|
|
79
|
+
<ListItemButton
|
|
80
|
+
onClick={() => handleBookmarkSelected(bookmark)}
|
|
81
|
+
disabled={disabled}
|
|
82
|
+
>
|
|
83
|
+
<ListItemAvatar>
|
|
84
|
+
<AccountAvatar chainId={chainId} />
|
|
85
|
+
</ListItemAvatar>
|
|
86
|
+
<ListItemText
|
|
87
|
+
primary={bookmark.name}
|
|
88
|
+
secondary={shortenAddress(bookmark.address)}
|
|
85
89
|
/>
|
|
86
|
-
</
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
</ListItemButton>
|
|
91
|
+
<ContextMenu
|
|
92
|
+
disabled={disabled}
|
|
93
|
+
items={[
|
|
94
|
+
{
|
|
95
|
+
icon: <ContentCopyRounded />,
|
|
96
|
+
label: t('button.copyAddress'),
|
|
97
|
+
onClick: () =>
|
|
98
|
+
navigator.clipboard.writeText(bookmark.address),
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
icon: <OpenInNewRounded />,
|
|
102
|
+
label: t('button.viewOnExplorer'),
|
|
103
|
+
onClick: () =>
|
|
104
|
+
openInNewTab(getAddressLink(bookmark.address, chainId)),
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
icon: <DeleteOutline />,
|
|
108
|
+
label: t('button.delete'),
|
|
109
|
+
onClick: () => removeBookmark(bookmark.address),
|
|
110
|
+
},
|
|
111
|
+
]}
|
|
90
112
|
/>
|
|
91
|
-
</
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
!!(
|
|
95
|
-
requiredToChainType &&
|
|
96
|
-
requiredToChainType !== bookmark.chainType
|
|
97
|
-
)
|
|
98
|
-
}
|
|
99
|
-
items={[
|
|
100
|
-
{
|
|
101
|
-
icon: <ContentCopyRounded />,
|
|
102
|
-
label: t('button.copyAddress'),
|
|
103
|
-
onClick: () =>
|
|
104
|
-
navigator.clipboard.writeText(bookmark.address),
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
icon: <OpenInNewRounded />,
|
|
108
|
-
label: t('button.viewOnExplorer'),
|
|
109
|
-
onClick: () =>
|
|
110
|
-
openInNewTab(
|
|
111
|
-
getAddressLink(
|
|
112
|
-
bookmark.address,
|
|
113
|
-
defaultChainIdsByType[bookmark.chainType]
|
|
114
|
-
)
|
|
115
|
-
),
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
icon: <DeleteOutline />,
|
|
119
|
-
label: t('button.delete'),
|
|
120
|
-
onClick: () => removeBookmark(bookmark.address),
|
|
121
|
-
},
|
|
122
|
-
]}
|
|
123
|
-
/>
|
|
124
|
-
</ListItem>
|
|
125
|
-
))}
|
|
113
|
+
</ListItem>
|
|
114
|
+
)
|
|
115
|
+
})}
|
|
126
116
|
{!bookmarks.length && (
|
|
127
117
|
<EmptyListIndicator
|
|
128
118
|
icon={<TurnedIn />}
|
|
@@ -27,7 +27,7 @@ export const ConnectedWalletsPage = (): JSX.Element => {
|
|
|
27
27
|
const { t } = useTranslation()
|
|
28
28
|
const { accounts } = useAccount()
|
|
29
29
|
const { setSelectedBookmark } = useBookmarkActions()
|
|
30
|
-
const {
|
|
30
|
+
const { isValidReceiver } = useToAddressRequirements()
|
|
31
31
|
const navigate = useNavigate()
|
|
32
32
|
const { setFieldValue } = useFieldActions()
|
|
33
33
|
const { getAddressLink } = useExplorer()
|
|
@@ -91,15 +91,13 @@ export const ConnectedWalletsPage = (): JSX.Element => {
|
|
|
91
91
|
]
|
|
92
92
|
: []),
|
|
93
93
|
]
|
|
94
|
+
const disabled = !isValidReceiver(account.address)
|
|
94
95
|
|
|
95
96
|
return (
|
|
96
97
|
<ListItem key={account.address} sx={{ position: 'relative' }}>
|
|
97
98
|
<ListItemButton
|
|
98
99
|
onClick={() => handleWalletSelected(account)}
|
|
99
|
-
disabled={
|
|
100
|
-
requiredToChainType &&
|
|
101
|
-
requiredToChainType !== account.chainType
|
|
102
|
-
}
|
|
100
|
+
disabled={disabled}
|
|
103
101
|
>
|
|
104
102
|
<ListItemAvatar>
|
|
105
103
|
<AccountAvatar chainId={account.chainId} account={account} />
|
|
@@ -109,15 +107,7 @@ export const ConnectedWalletsPage = (): JSX.Element => {
|
|
|
109
107
|
secondary={walletAddress}
|
|
110
108
|
/>
|
|
111
109
|
</ListItemButton>
|
|
112
|
-
<ContextMenu
|
|
113
|
-
items={menuItems}
|
|
114
|
-
disabled={
|
|
115
|
-
!!(
|
|
116
|
-
requiredToChainType &&
|
|
117
|
-
requiredToChainType !== account.chainType
|
|
118
|
-
)
|
|
119
|
-
}
|
|
120
|
-
/>
|
|
110
|
+
<ContextMenu items={menuItems} disabled={disabled} />
|
|
121
111
|
</ListItem>
|
|
122
112
|
)
|
|
123
113
|
})}
|
|
@@ -35,7 +35,7 @@ export const RecentWalletsPage = (): JSX.Element => {
|
|
|
35
35
|
const bookmarkAddressSheetRef = useRef<BottomSheetBase>(null)
|
|
36
36
|
const listParentRef = useRef<HTMLUListElement | null>(null)
|
|
37
37
|
const { recentWallets } = useBookmarks()
|
|
38
|
-
const {
|
|
38
|
+
const { isValidReceiver } = useToAddressRequirements()
|
|
39
39
|
const {
|
|
40
40
|
removeRecentWallet,
|
|
41
41
|
addBookmark,
|
|
@@ -76,73 +76,66 @@ export const RecentWalletsPage = (): JSX.Element => {
|
|
|
76
76
|
disablePadding
|
|
77
77
|
sx={{ paddingTop: 1.5 }}
|
|
78
78
|
>
|
|
79
|
-
{recentWallets.map((recentWallet) =>
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
79
|
+
{recentWallets.map((recentWallet) => {
|
|
80
|
+
const disabled = !isValidReceiver(recentWallet.address)
|
|
81
|
+
const chainId =
|
|
82
|
+
recentWallet.chainId ??
|
|
83
|
+
defaultChainIdsByType[recentWallet.chainType]
|
|
84
|
+
return (
|
|
85
|
+
<ListItem key={recentWallet.address} sx={{ position: 'relative' }}>
|
|
86
|
+
<ListItemButton
|
|
87
|
+
disabled={disabled}
|
|
88
|
+
onClick={() => handleRecentSelected(recentWallet)}
|
|
89
|
+
>
|
|
90
|
+
<ListItemAvatar>
|
|
91
|
+
<AccountAvatar chainId={chainId} />
|
|
92
|
+
</ListItemAvatar>
|
|
93
|
+
<ListItemText
|
|
94
|
+
primary={
|
|
95
|
+
recentWallet.name || shortenAddress(recentWallet.address)
|
|
96
|
+
}
|
|
97
|
+
secondary={
|
|
98
|
+
recentWallet.name
|
|
99
|
+
? shortenAddress(recentWallet.address)
|
|
100
|
+
: undefined
|
|
101
|
+
}
|
|
91
102
|
/>
|
|
92
|
-
</
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
icon: <OpenInNewRounded />,
|
|
120
|
-
label: t('button.viewOnExplorer'),
|
|
121
|
-
onClick: () =>
|
|
122
|
-
openInNewTab(
|
|
123
|
-
getAddressLink(
|
|
124
|
-
recentWallet.address,
|
|
125
|
-
defaultChainIdsByType[recentWallet.chainType]
|
|
126
|
-
)
|
|
127
|
-
),
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
icon: <TurnedInNot />,
|
|
131
|
-
label: t('button.bookmark'),
|
|
132
|
-
onClick: () => {
|
|
133
|
-
setBookmarkTarget(recentWallet)
|
|
134
|
-
bookmarkAddressSheetRef.current?.open()
|
|
103
|
+
</ListItemButton>
|
|
104
|
+
<ContextMenu
|
|
105
|
+
disabled={disabled}
|
|
106
|
+
items={[
|
|
107
|
+
{
|
|
108
|
+
icon: <ContentCopyRounded />,
|
|
109
|
+
label: t('button.copyAddress'),
|
|
110
|
+
onClick: () =>
|
|
111
|
+
navigator.clipboard.writeText(recentWallet.address),
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
icon: <OpenInNewRounded />,
|
|
115
|
+
label: t('button.viewOnExplorer'),
|
|
116
|
+
onClick: () =>
|
|
117
|
+
openInNewTab(
|
|
118
|
+
getAddressLink(recentWallet.address, chainId)
|
|
119
|
+
),
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
icon: <TurnedInNot />,
|
|
123
|
+
label: t('button.bookmark'),
|
|
124
|
+
onClick: () => {
|
|
125
|
+
setBookmarkTarget(recentWallet)
|
|
126
|
+
bookmarkAddressSheetRef.current?.open()
|
|
127
|
+
},
|
|
135
128
|
},
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
)
|
|
129
|
+
{
|
|
130
|
+
icon: <DeleteOutline />,
|
|
131
|
+
label: t('button.delete'),
|
|
132
|
+
onClick: () => removeRecentWallet(recentWallet.address),
|
|
133
|
+
},
|
|
134
|
+
]}
|
|
135
|
+
/>
|
|
136
|
+
</ListItem>
|
|
137
|
+
)
|
|
138
|
+
})}
|
|
146
139
|
{!recentWallets.length && (
|
|
147
140
|
<EmptyListIndicator
|
|
148
141
|
icon={<AccountBalanceWalletIcon />}
|