@lifi/widget 3.21.3 → 3.22.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/CHANGELOG.md +20 -0
- package/dist/esm/AppProvider.js +2 -3
- package/dist/esm/AppProvider.js.map +1 -1
- package/dist/esm/components/AppContainer.js +23 -22
- package/dist/esm/components/AppContainer.js.map +1 -1
- package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.js +12 -7
- package/dist/esm/components/BaseTransactionButton/BaseTransactionButton.js.map +1 -1
- package/dist/esm/components/BaseTransactionButton/types.d.ts +2 -0
- package/dist/esm/components/ChainSelect/ChainSelect.js +3 -1
- package/dist/esm/components/ChainSelect/ChainSelect.js.map +1 -1
- package/dist/esm/components/ChainSelect/ChainSelect.style.d.ts +3 -1
- package/dist/esm/components/ChainSelect/ChainSelect.style.js +23 -9
- package/dist/esm/components/ChainSelect/ChainSelect.style.js.map +1 -1
- package/dist/esm/components/Messages/MissingRouteRequiredAccountMessage.d.ts +8 -0
- package/dist/esm/components/Messages/MissingRouteRequiredAccountMessage.js +20 -0
- package/dist/esm/components/Messages/MissingRouteRequiredAccountMessage.js.map +1 -0
- package/dist/esm/components/Messages/WarningMessages.js +3 -0
- package/dist/esm/components/Messages/WarningMessages.js.map +1 -1
- package/dist/esm/components/Messages/useMessageQueue.js +15 -4
- package/dist/esm/components/Messages/useMessageQueue.js.map +1 -1
- package/dist/esm/components/RouteCard/RouteCard.js +3 -3
- package/dist/esm/components/RouteCard/RouteCard.js.map +1 -1
- package/dist/esm/components/TokenList/TokenListItem.js +2 -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/useAvailableChains.js +3 -2
- package/dist/esm/hooks/useAvailableChains.js.map +1 -1
- package/dist/esm/hooks/useExplorer.d.ts +0 -1
- package/dist/esm/hooks/useExplorer.js +26 -31
- package/dist/esm/hooks/useExplorer.js.map +1 -1
- package/dist/esm/hooks/useFromTokenSufficiency.js +4 -1
- package/dist/esm/hooks/useFromTokenSufficiency.js.map +1 -1
- package/dist/esm/hooks/useGasRecommendation.js +9 -1
- package/dist/esm/hooks/useGasRecommendation.js.map +1 -1
- package/dist/esm/hooks/useGasSufficiency.js +50 -16
- package/dist/esm/hooks/useGasSufficiency.js.map +1 -1
- package/dist/esm/hooks/useIsBatchingSupported.js +8 -1
- package/dist/esm/hooks/useIsBatchingSupported.js.map +1 -1
- package/dist/esm/hooks/useIsContractAddress.js +1 -1
- package/dist/esm/hooks/useIsContractAddress.js.map +1 -1
- package/dist/esm/hooks/useRouteExecution.js +10 -4
- package/dist/esm/hooks/useRouteExecution.js.map +1 -1
- package/dist/esm/hooks/useRouteRequiredAccountConnection.d.ts +10 -0
- package/dist/esm/hooks/useRouteRequiredAccountConnection.js +45 -0
- package/dist/esm/hooks/useRouteRequiredAccountConnection.js.map +1 -0
- package/dist/esm/hooks/useRoutes.d.ts +1 -1
- package/dist/esm/hooks/useRoutes.js +13 -4
- package/dist/esm/hooks/useRoutes.js.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.d.ts +1 -1
- package/dist/esm/hooks/useToAddressRequirements.js +6 -5
- package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
- package/dist/esm/hooks/useTokenBalance.js +12 -3
- package/dist/esm/hooks/useTokenBalance.js.map +1 -1
- package/dist/esm/hooks/useTokenBalances.js +4 -1
- package/dist/esm/hooks/useTokenBalances.js.map +1 -1
- package/dist/esm/hooks/useTokenSearch.js +5 -2
- package/dist/esm/hooks/useTokenSearch.js.map +1 -1
- package/dist/esm/hooks/useTokens.js +3 -2
- package/dist/esm/hooks/useTokens.js.map +1 -1
- package/dist/esm/hooks/useTools.js +3 -2
- package/dist/esm/hooks/useTools.js.map +1 -1
- package/dist/esm/hooks/useTransactionDetails.js +9 -4
- package/dist/esm/hooks/useTransactionDetails.js.map +1 -1
- package/dist/esm/hooks/useTransactionHistory.js +7 -1
- package/dist/esm/hooks/useTransactionHistory.js.map +1 -1
- package/dist/esm/i18n/en.json +6 -4
- package/dist/esm/pages/MainPage/ReviewButton.js +1 -1
- package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StartTransactionButton.js +1 -1
- package/dist/esm/pages/TransactionPage/StartTransactionButton.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.js +26 -43
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.d.ts +0 -1
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.js +4 -11
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.style.js.map +1 -1
- package/dist/esm/providers/QueryClientProvider.d.ts +2 -0
- package/dist/esm/providers/QueryClientProvider.js +9 -0
- package/dist/esm/providers/QueryClientProvider.js.map +1 -0
- package/dist/esm/providers/WalletProvider/SuiBaseProvider.js +3 -8
- package/dist/esm/providers/WalletProvider/SuiBaseProvider.js.map +1 -1
- package/dist/esm/stores/form/FormStore.js +5 -12
- package/dist/esm/stores/form/FormStore.js.map +1 -1
- package/dist/esm/stores/form/useFormRef.js +1 -7
- package/dist/esm/stores/form/useFormRef.js.map +1 -1
- package/dist/esm/types/widget.d.ts +6 -1
- package/dist/esm/utils/queries.d.ts +1 -0
- package/dist/esm/utils/queries.js +2 -0
- package/dist/esm/utils/queries.js.map +1 -0
- package/dist/esm/utils/timer.js +8 -1
- package/dist/esm/utils/timer.js.map +1 -1
- package/package.json +11 -11
- package/package.json.tmp +10 -10
- package/src/AppProvider.tsx +2 -3
- package/src/components/AppContainer.tsx +24 -23
- package/src/components/BaseTransactionButton/BaseTransactionButton.tsx +15 -6
- package/src/components/BaseTransactionButton/types.ts +3 -0
- package/src/components/ChainSelect/ChainSelect.style.tsx +25 -9
- package/src/components/ChainSelect/ChainSelect.tsx +4 -1
- package/src/components/Messages/MissingRouteRequiredAccountMessage.tsx +44 -0
- package/src/components/Messages/WarningMessages.tsx +9 -0
- package/src/components/Messages/useMessageQueue.ts +17 -4
- package/src/components/RouteCard/RouteCard.tsx +3 -3
- package/src/components/TokenList/TokenListItem.tsx +2 -2
- package/src/config/version.ts +1 -1
- package/src/hooks/useAvailableChains.ts +4 -2
- package/src/hooks/useExplorer.ts +35 -36
- package/src/hooks/useFromTokenSufficiency.ts +4 -1
- package/src/hooks/useGasRecommendation.ts +9 -1
- package/src/hooks/useGasSufficiency.ts +76 -22
- package/src/hooks/useIsBatchingSupported.ts +9 -1
- package/src/hooks/useIsContractAddress.ts +1 -1
- package/src/hooks/useRouteExecution.ts +10 -4
- package/src/hooks/useRouteRequiredAccountConnection.ts +58 -0
- package/src/hooks/useRoutes.ts +13 -7
- package/src/hooks/useToAddressRequirements.ts +6 -5
- package/src/hooks/useTokenBalance.ts +12 -3
- package/src/hooks/useTokenBalances.ts +4 -1
- package/src/hooks/useTokenSearch.ts +5 -2
- package/src/hooks/useTokens.ts +3 -2
- package/src/hooks/useTools.ts +3 -2
- package/src/hooks/useTransactionDetails.ts +13 -4
- package/src/hooks/useTransactionHistory.ts +7 -1
- package/src/i18n/en.json +6 -4
- package/src/pages/MainPage/ReviewButton.tsx +1 -0
- package/src/pages/TransactionPage/StartTransactionButton.tsx +1 -0
- package/src/pages/TransactionPage/StatusBottomSheet.style.tsx +4 -12
- package/src/pages/TransactionPage/StatusBottomSheet.tsx +47 -77
- package/src/providers/QueryClientProvider.tsx +20 -0
- package/src/providers/WalletProvider/SuiBaseProvider.tsx +3 -9
- package/src/stores/form/FormStore.tsx +4 -15
- package/src/stores/form/useFormRef.ts +1 -8
- package/src/types/widget.ts +10 -2
- package/src/utils/queries.ts +2 -0
- package/src/utils/timer.ts +8 -1
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import type { EVMChain, RouteExtended, Token } from '@lifi/sdk'
|
|
2
|
-
import { isRelayerStep } from '@lifi/sdk'
|
|
1
|
+
import type { EVMChain, RouteExtended, Token, TokenAmount } from '@lifi/sdk'
|
|
2
|
+
import { ChainType, isRelayerStep } from '@lifi/sdk'
|
|
3
3
|
import { useAccount } from '@lifi/wallet-management'
|
|
4
4
|
import { useQuery } from '@tanstack/react-query'
|
|
5
|
+
import { useMemo } from 'react'
|
|
6
|
+
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
7
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
5
8
|
import { useAvailableChains } from './useAvailableChains.js'
|
|
6
9
|
import { useIsContractAddress } from './useIsContractAddress.js'
|
|
7
10
|
import { getTokenBalancesWithRetry } from './useTokenBalance.js'
|
|
@@ -19,30 +22,64 @@ const refetchInterval = 30_000
|
|
|
19
22
|
|
|
20
23
|
export const useGasSufficiency = (route?: RouteExtended) => {
|
|
21
24
|
const { getChainById } = useAvailableChains()
|
|
22
|
-
const { account } = useAccount({
|
|
23
|
-
chainType:
|
|
25
|
+
const { account: EVMAccount, accounts } = useAccount({
|
|
26
|
+
chainType: ChainType.EVM,
|
|
24
27
|
})
|
|
28
|
+
const { keyPrefix } = useWidgetConfig()
|
|
29
|
+
|
|
30
|
+
const { relevantAccounts, relevantAccountsQueryKey } = useMemo(() => {
|
|
31
|
+
const chainTypes = route?.steps.reduce((acc, step) => {
|
|
32
|
+
const chainType = getChainById(step.action.fromChainId)?.chainType
|
|
33
|
+
if (chainType) {
|
|
34
|
+
acc.add(chainType)
|
|
35
|
+
}
|
|
36
|
+
return acc
|
|
37
|
+
}, new Set<ChainType>())
|
|
38
|
+
|
|
39
|
+
const relevantAccounts = accounts.filter(
|
|
40
|
+
(account) =>
|
|
41
|
+
account.isConnected &&
|
|
42
|
+
account.address &&
|
|
43
|
+
chainTypes?.has(account.chainType)
|
|
44
|
+
)
|
|
45
|
+
return {
|
|
46
|
+
relevantAccounts,
|
|
47
|
+
relevantAccountsQueryKey: relevantAccounts
|
|
48
|
+
.map((account) => account.address)
|
|
49
|
+
.join(','),
|
|
50
|
+
}
|
|
51
|
+
}, [accounts, route?.steps, getChainById])
|
|
25
52
|
|
|
26
53
|
const { isContractAddress, isLoading: isContractAddressLoading } =
|
|
27
|
-
useIsContractAddress(
|
|
54
|
+
useIsContractAddress(
|
|
55
|
+
EVMAccount.address,
|
|
56
|
+
route?.fromChainId,
|
|
57
|
+
EVMAccount.chainType
|
|
58
|
+
)
|
|
28
59
|
|
|
29
60
|
const { data: insufficientGas, isLoading } = useQuery({
|
|
30
61
|
queryKey: [
|
|
31
|
-
'gas-sufficiency-check',
|
|
32
|
-
|
|
62
|
+
getQueryKey('gas-sufficiency-check', keyPrefix),
|
|
63
|
+
relevantAccountsQueryKey,
|
|
33
64
|
route?.id,
|
|
34
65
|
isContractAddress,
|
|
35
66
|
] as const,
|
|
36
|
-
queryFn: async (
|
|
67
|
+
queryFn: async () => {
|
|
37
68
|
if (!route) {
|
|
38
69
|
return
|
|
39
70
|
}
|
|
40
71
|
|
|
41
|
-
//
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
72
|
+
// Filter out steps that are relayer steps or have primaryType 'Permit' or 'Order'
|
|
73
|
+
const filteredSteps = route.steps.filter(
|
|
74
|
+
(step) =>
|
|
75
|
+
!isRelayerStep(step) &&
|
|
76
|
+
!step.typedData?.some(
|
|
77
|
+
(t) => t.primaryType === 'Permit' || t.primaryType === 'Order'
|
|
78
|
+
)
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
// If all steps are filtered out, we don't need to check for gas sufficiency
|
|
82
|
+
if (!filteredSteps.length) {
|
|
46
83
|
return
|
|
47
84
|
}
|
|
48
85
|
|
|
@@ -51,7 +88,7 @@ export const useGasSufficiency = (route?: RouteExtended) => {
|
|
|
51
88
|
.flatMap((step) => step.includedSteps)
|
|
52
89
|
.some((includedStep) => includedStep.tool === 'gasZip')
|
|
53
90
|
|
|
54
|
-
const gasCosts =
|
|
91
|
+
const gasCosts = filteredSteps
|
|
55
92
|
.filter((step) => !step.execution || step.execution.status !== 'DONE')
|
|
56
93
|
.reduce(
|
|
57
94
|
(groupedGasCosts, step) => {
|
|
@@ -70,6 +107,7 @@ export const useGasSufficiency = (route?: RouteExtended) => {
|
|
|
70
107
|
? groupedGasCosts[token.chainId].gasAmount + gasCostAmount
|
|
71
108
|
: gasCostAmount,
|
|
72
109
|
token,
|
|
110
|
+
chain: getChainById(token.chainId),
|
|
73
111
|
}
|
|
74
112
|
}
|
|
75
113
|
// Add fees paid in native tokens to gas sufficiency check (included: false)
|
|
@@ -88,11 +126,12 @@ export const useGasSufficiency = (route?: RouteExtended) => {
|
|
|
88
126
|
? groupedGasCosts[token.chainId].gasAmount + feeCostAmount
|
|
89
127
|
: feeCostAmount,
|
|
90
128
|
token,
|
|
91
|
-
|
|
129
|
+
chain: getChainById(token.chainId),
|
|
130
|
+
}
|
|
92
131
|
}
|
|
93
132
|
return groupedGasCosts
|
|
94
133
|
},
|
|
95
|
-
{} as Record<
|
|
134
|
+
{} as Record<string, GasSufficiency>
|
|
96
135
|
)
|
|
97
136
|
|
|
98
137
|
// Check whether we are sending a native token
|
|
@@ -104,15 +143,30 @@ export const useGasSufficiency = (route?: RouteExtended) => {
|
|
|
104
143
|
gasCosts[route.fromChainId]?.gasAmount + BigInt(route.fromAmount)
|
|
105
144
|
}
|
|
106
145
|
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
146
|
+
const gasCostsValues = Object.values(gasCosts)
|
|
147
|
+
|
|
148
|
+
const balanceChecks = await Promise.allSettled(
|
|
149
|
+
relevantAccounts.map((account) => {
|
|
150
|
+
const relevantTokens = gasCostsValues
|
|
151
|
+
.filter((gasCost) => gasCost.chain?.chainType === account.chainType)
|
|
152
|
+
.map((item) => item.token)
|
|
153
|
+
|
|
154
|
+
return getTokenBalancesWithRetry(account.address!, relevantTokens)
|
|
155
|
+
})
|
|
110
156
|
)
|
|
111
157
|
|
|
158
|
+
const tokenBalances = balanceChecks
|
|
159
|
+
.filter(
|
|
160
|
+
(result): result is PromiseFulfilledResult<TokenAmount[]> =>
|
|
161
|
+
result.status === 'fulfilled' && Boolean(result.value)
|
|
162
|
+
)
|
|
163
|
+
.flatMap((result) => result.value)
|
|
164
|
+
|
|
112
165
|
if (!tokenBalances?.length) {
|
|
113
166
|
return
|
|
114
167
|
}
|
|
115
|
-
|
|
168
|
+
|
|
169
|
+
Object.keys(gasCosts).forEach((chainId) => {
|
|
116
170
|
if (gasCosts[chainId]) {
|
|
117
171
|
const gasTokenBalance =
|
|
118
172
|
tokenBalances?.find(
|
|
@@ -135,7 +189,7 @@ export const useGasSufficiency = (route?: RouteExtended) => {
|
|
|
135
189
|
...gasCosts[chainId],
|
|
136
190
|
insufficient,
|
|
137
191
|
insufficientAmount,
|
|
138
|
-
chain: insufficient ? getChainById(chainId) : undefined,
|
|
192
|
+
chain: insufficient ? getChainById(Number(chainId)) : undefined,
|
|
139
193
|
}
|
|
140
194
|
}
|
|
141
195
|
})
|
|
@@ -150,7 +204,7 @@ export const useGasSufficiency = (route?: RouteExtended) => {
|
|
|
150
204
|
enabled: Boolean(
|
|
151
205
|
!isContractAddress &&
|
|
152
206
|
!isContractAddressLoading &&
|
|
153
|
-
|
|
207
|
+
relevantAccounts.length > 0 &&
|
|
154
208
|
route
|
|
155
209
|
),
|
|
156
210
|
refetchInterval,
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import { ChainType, isBatchingSupported } from '@lifi/sdk'
|
|
2
2
|
import type { ExtendedChain } from '@lifi/sdk'
|
|
3
3
|
import { useQuery } from '@tanstack/react-query'
|
|
4
|
+
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
5
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
4
6
|
|
|
5
7
|
export function useIsBatchingSupported(
|
|
6
8
|
chain?: ExtendedChain,
|
|
7
9
|
address?: string
|
|
8
10
|
) {
|
|
11
|
+
const { keyPrefix } = useWidgetConfig()
|
|
12
|
+
|
|
9
13
|
const enabled = Boolean(
|
|
10
14
|
chain && chain.chainType === ChainType.EVM && !!address
|
|
11
15
|
)
|
|
12
16
|
const { data, isLoading } = useQuery({
|
|
13
|
-
queryKey: [
|
|
17
|
+
queryKey: [
|
|
18
|
+
getQueryKey('isBatchingSupported', keyPrefix),
|
|
19
|
+
chain?.id,
|
|
20
|
+
address,
|
|
21
|
+
],
|
|
14
22
|
queryFn: () => {
|
|
15
23
|
return isBatchingSupported({ chainId: chain!.id })
|
|
16
24
|
},
|
|
@@ -4,6 +4,7 @@ import { useAccount } from '@lifi/wallet-management'
|
|
|
4
4
|
import { useMutation, useQueryClient } from '@tanstack/react-query'
|
|
5
5
|
import { useCallback, useEffect, useRef } from 'react'
|
|
6
6
|
import { shallow } from 'zustand/shallow'
|
|
7
|
+
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
7
8
|
import {
|
|
8
9
|
useRouteExecutionStore,
|
|
9
10
|
useRouteExecutionStoreContext,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
isRouteFailed,
|
|
16
17
|
} from '../stores/routes/utils.js'
|
|
17
18
|
import { WidgetEvent } from '../types/events.js'
|
|
19
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
18
20
|
import { useWidgetEvents } from './useWidgetEvents.js'
|
|
19
21
|
|
|
20
22
|
interface RouteExecutionProps {
|
|
@@ -34,6 +36,7 @@ export const useRouteExecution = ({
|
|
|
34
36
|
const queryClient = useQueryClient()
|
|
35
37
|
const { account } = useAccount()
|
|
36
38
|
const resumedAfterMount = useRef(false)
|
|
39
|
+
const { keyPrefix } = useWidgetConfig()
|
|
37
40
|
const emitter = useWidgetEvents()
|
|
38
41
|
const routeExecutionStoreContext = useRouteExecutionStoreContext()
|
|
39
42
|
const routeExecution = useRouteExecutionStore(
|
|
@@ -73,16 +76,16 @@ export const useRouteExecution = ({
|
|
|
73
76
|
if (executionCompleted || executionFailed) {
|
|
74
77
|
const invalidateKeys = [
|
|
75
78
|
[
|
|
76
|
-
'token-balances',
|
|
79
|
+
getQueryKey('token-balances', keyPrefix),
|
|
77
80
|
clonedUpdatedRoute.fromAddress,
|
|
78
81
|
clonedUpdatedRoute.fromChainId,
|
|
79
82
|
],
|
|
80
83
|
[
|
|
81
|
-
'token-balances',
|
|
84
|
+
getQueryKey('token-balances', keyPrefix),
|
|
82
85
|
clonedUpdatedRoute.toAddress,
|
|
83
86
|
clonedUpdatedRoute.toChainId,
|
|
84
87
|
],
|
|
85
|
-
['transaction-history'],
|
|
88
|
+
[getQueryKey('transaction-history', keyPrefix)],
|
|
86
89
|
]
|
|
87
90
|
for (const key of invalidateKeys) {
|
|
88
91
|
queryClient.invalidateQueries(
|
|
@@ -121,7 +124,10 @@ export const useRouteExecution = ({
|
|
|
121
124
|
if (!routeExecution?.route) {
|
|
122
125
|
throw new Error('Execution route not found.')
|
|
123
126
|
}
|
|
124
|
-
queryClient.removeQueries({
|
|
127
|
+
queryClient.removeQueries({
|
|
128
|
+
queryKey: [getQueryKey('routes', keyPrefix)],
|
|
129
|
+
exact: false,
|
|
130
|
+
})
|
|
125
131
|
return executeRoute(routeExecution.route, {
|
|
126
132
|
updateRouteHook,
|
|
127
133
|
acceptExchangeRateUpdateHook,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ExtendedChain, Route } from '@lifi/sdk'
|
|
2
|
+
import { useAccount } from '@lifi/wallet-management'
|
|
3
|
+
import { useMemo } from 'react'
|
|
4
|
+
import { useFieldValues } from '../stores/form/useFieldValues.js'
|
|
5
|
+
import { useChain } from './useChain.js'
|
|
6
|
+
|
|
7
|
+
export const useRouteRequiredAccountConnection = (
|
|
8
|
+
route?: Route,
|
|
9
|
+
chain?: ExtendedChain
|
|
10
|
+
) => {
|
|
11
|
+
const { account, accounts } = useAccount({ chainType: chain?.chainType })
|
|
12
|
+
const [toAddress] = useFieldValues('toAddress')
|
|
13
|
+
const { getChainById } = useChain()
|
|
14
|
+
|
|
15
|
+
return useMemo(() => {
|
|
16
|
+
if (!route?.steps.length) {
|
|
17
|
+
return {
|
|
18
|
+
connected: account.isConnected,
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const connectedChainTypes = new Map(
|
|
23
|
+
accounts
|
|
24
|
+
.filter((account) => account.isConnected && account.address)
|
|
25
|
+
.map((account) => [account.chainType, account])
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
if (!connectedChainTypes.size) {
|
|
29
|
+
return {
|
|
30
|
+
connected: false,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for (const step of route.steps) {
|
|
35
|
+
const chain = getChainById(step.action.fromChainId)
|
|
36
|
+
if (!chain) {
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const connectedAccount = connectedChainTypes.get(chain.chainType)
|
|
41
|
+
const isToAddressSatisfied = toAddress
|
|
42
|
+
? connectedAccount?.address === step.action.fromAddress
|
|
43
|
+
: true
|
|
44
|
+
|
|
45
|
+
if (!connectedAccount || !isToAddressSatisfied) {
|
|
46
|
+
return {
|
|
47
|
+
connected: false,
|
|
48
|
+
missingChain: chain,
|
|
49
|
+
missingAccountAddress: !isToAddressSatisfied
|
|
50
|
+
? step.action.fromAddress
|
|
51
|
+
: undefined,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return { connected: true }
|
|
57
|
+
}, [account.isConnected, route, accounts, getChainById, toAddress])
|
|
58
|
+
}
|
package/src/hooks/useRoutes.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { useSettings } from '../stores/settings/useSettings.js'
|
|
|
19
19
|
import { defaultSlippage } from '../stores/settings/useSettingsStore.js'
|
|
20
20
|
import { WidgetEvent } from '../types/events.js'
|
|
21
21
|
import { getChainTypeFromAddress } from '../utils/chainType.js'
|
|
22
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
22
23
|
import { useChain } from './useChain.js'
|
|
23
24
|
import { useDebouncedWatch } from './useDebouncedWatch.js'
|
|
24
25
|
import { useGasRefuel } from './useGasRefuel.js'
|
|
@@ -43,6 +44,7 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
43
44
|
fee,
|
|
44
45
|
feeConfig,
|
|
45
46
|
useRelayerRoutes,
|
|
47
|
+
keyPrefix,
|
|
46
48
|
} = useWidgetConfig()
|
|
47
49
|
const setExecutableRoute = useSetExecutableRoute()
|
|
48
50
|
const queryClient = useQueryClient()
|
|
@@ -135,7 +137,7 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
135
137
|
|
|
136
138
|
// Some values should be strictly typed and isEnabled ensures that
|
|
137
139
|
const queryKey = [
|
|
138
|
-
'routes',
|
|
140
|
+
getQueryKey('routes', keyPrefix),
|
|
139
141
|
account.address,
|
|
140
142
|
fromChain?.id as number,
|
|
141
143
|
fromToken?.address as string,
|
|
@@ -399,7 +401,13 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
399
401
|
const { fromToken, toToken } = routesResult.routes[0]
|
|
400
402
|
;[fromToken, toToken].forEach((token) => {
|
|
401
403
|
queryClient.setQueriesData<Token[]>(
|
|
402
|
-
{
|
|
404
|
+
{
|
|
405
|
+
queryKey: [
|
|
406
|
+
getQueryKey('token-balances', keyPrefix),
|
|
407
|
+
fromAddress,
|
|
408
|
+
token.chainId,
|
|
409
|
+
],
|
|
410
|
+
},
|
|
403
411
|
(data) => {
|
|
404
412
|
if (data) {
|
|
405
413
|
const clonedData = [...data]
|
|
@@ -464,11 +472,9 @@ export const useRoutes = ({ observableRoute }: RoutesProps = {}) => {
|
|
|
464
472
|
|
|
465
473
|
const setReviewableRoute = (route: Route) => {
|
|
466
474
|
const queryDataKey = queryKey.toSpliced(queryKey.length - 1, 1, route.id)
|
|
467
|
-
queryClient.setQueryData(
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
{ updatedAt: dataUpdatedAt || Date.now() }
|
|
471
|
-
)
|
|
475
|
+
queryClient.setQueryData(queryDataKey, [route], {
|
|
476
|
+
updatedAt: dataUpdatedAt || Date.now(),
|
|
477
|
+
})
|
|
472
478
|
setExecutableRoute(route)
|
|
473
479
|
}
|
|
474
480
|
|
|
@@ -3,12 +3,12 @@ import { useAccount } from '@lifi/wallet-management'
|
|
|
3
3
|
import { useChain } from '../hooks/useChain.js'
|
|
4
4
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
5
5
|
import { useFieldValues } from '../stores/form/useFieldValues.js'
|
|
6
|
-
import { RequiredUI } from '../types/widget.js'
|
|
6
|
+
import { HiddenUI, RequiredUI } from '../types/widget.js'
|
|
7
7
|
import { isDelegationDesignatorCode } from '../utils/eip7702.js'
|
|
8
8
|
import { useIsContractAddress } from './useIsContractAddress.js'
|
|
9
9
|
|
|
10
10
|
export const useToAddressRequirements = (route?: RouteExtended) => {
|
|
11
|
-
const { requiredUI } = useWidgetConfig()
|
|
11
|
+
const { requiredUI, hiddenUI } = useWidgetConfig()
|
|
12
12
|
const [formFromChainId, formToChainId, formToAddress] = useFieldValues(
|
|
13
13
|
'fromChain',
|
|
14
14
|
'toChain',
|
|
@@ -57,9 +57,10 @@ export const useToAddressRequirements = (route?: RouteExtended) => {
|
|
|
57
57
|
!fromContractCodeHasDelegationIndicator
|
|
58
58
|
|
|
59
59
|
const requiredToAddress =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
(isDifferentChainType ||
|
|
61
|
+
isCrossChainContractAddress ||
|
|
62
|
+
requiredUI?.includes(RequiredUI.ToAddress)) &&
|
|
63
|
+
!hiddenUI?.includes(HiddenUI.ToAddress)
|
|
63
64
|
|
|
64
65
|
const accountNotDeployedAtDestination =
|
|
65
66
|
isFromContractAddress &&
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import { type Token, type TokenAmount, getTokenBalances } from '@lifi/sdk'
|
|
2
2
|
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
3
3
|
import { useCallback, useMemo } from 'react'
|
|
4
|
+
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
5
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
4
6
|
|
|
5
7
|
const defaultRefetchInterval = 30_000
|
|
6
8
|
|
|
7
9
|
export const useTokenBalance = (accountAddress?: string, token?: Token) => {
|
|
8
10
|
const queryClient = useQueryClient()
|
|
11
|
+
const { keyPrefix } = useWidgetConfig()
|
|
9
12
|
|
|
10
13
|
const tokenBalanceQueryKey = useMemo(
|
|
11
14
|
() =>
|
|
12
15
|
[
|
|
13
|
-
'token-balance',
|
|
16
|
+
getQueryKey('token-balance', keyPrefix),
|
|
14
17
|
accountAddress,
|
|
15
18
|
token?.chainId,
|
|
16
19
|
token?.address,
|
|
17
20
|
] as const,
|
|
18
|
-
[token?.address, token?.chainId, accountAddress]
|
|
21
|
+
[token?.address, token?.chainId, accountAddress, keyPrefix]
|
|
19
22
|
)
|
|
20
23
|
|
|
21
24
|
const { data, isLoading, refetch } = useQuery({
|
|
@@ -45,7 +48,13 @@ export const useTokenBalance = (accountAddress?: string, token?: Token) => {
|
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
queryClient.setQueriesData<TokenAmount[]>(
|
|
48
|
-
{
|
|
51
|
+
{
|
|
52
|
+
queryKey: [
|
|
53
|
+
getQueryKey('token-balances', keyPrefix),
|
|
54
|
+
accountAddress,
|
|
55
|
+
tokenChainId,
|
|
56
|
+
],
|
|
57
|
+
},
|
|
49
58
|
(data) => {
|
|
50
59
|
if (data) {
|
|
51
60
|
const clonedData = [...data]
|
|
@@ -2,7 +2,9 @@ import { getTokenBalances } from '@lifi/sdk'
|
|
|
2
2
|
import { useAccount } from '@lifi/wallet-management'
|
|
3
3
|
import { useQuery } from '@tanstack/react-query'
|
|
4
4
|
import { formatUnits } from 'viem'
|
|
5
|
+
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
5
6
|
import type { TokenAmount } from '../types/token.js'
|
|
7
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
6
8
|
import { useTokens } from './useTokens.js'
|
|
7
9
|
|
|
8
10
|
const defaultRefetchInterval = 32_000
|
|
@@ -11,6 +13,7 @@ export const useTokenBalances = (selectedChainId?: number) => {
|
|
|
11
13
|
const { tokens, featuredTokens, popularTokens, chain, isLoading } =
|
|
12
14
|
useTokens(selectedChainId)
|
|
13
15
|
const { account } = useAccount({ chainType: chain?.chainType })
|
|
16
|
+
const { keyPrefix } = useWidgetConfig()
|
|
14
17
|
|
|
15
18
|
const isBalanceLoadingEnabled =
|
|
16
19
|
Boolean(account.address) &&
|
|
@@ -23,7 +26,7 @@ export const useTokenBalances = (selectedChainId?: number) => {
|
|
|
23
26
|
refetch,
|
|
24
27
|
} = useQuery({
|
|
25
28
|
queryKey: [
|
|
26
|
-
'token-balances',
|
|
29
|
+
getQueryKey('token-balances', keyPrefix),
|
|
27
30
|
account.address,
|
|
28
31
|
selectedChainId,
|
|
29
32
|
tokens?.length,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { type ChainId, type TokensResponse, getToken } from '@lifi/sdk'
|
|
2
2
|
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
3
|
+
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
3
4
|
import type { TokenAmount } from '../types/token.js'
|
|
5
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
4
6
|
|
|
5
7
|
export const useTokenSearch = (
|
|
6
8
|
chainId?: number,
|
|
@@ -8,8 +10,9 @@ export const useTokenSearch = (
|
|
|
8
10
|
enabled?: boolean
|
|
9
11
|
) => {
|
|
10
12
|
const queryClient = useQueryClient()
|
|
13
|
+
const { keyPrefix } = useWidgetConfig()
|
|
11
14
|
const { data, isLoading } = useQuery({
|
|
12
|
-
queryKey: ['token-search', chainId, tokenQuery],
|
|
15
|
+
queryKey: [getQueryKey('token-search', keyPrefix), chainId, tokenQuery],
|
|
13
16
|
queryFn: async ({ queryKey: [, chainId, tokenQuery], signal }) => {
|
|
14
17
|
const token = await getToken(chainId as ChainId, tokenQuery as string, {
|
|
15
18
|
signal,
|
|
@@ -17,7 +20,7 @@ export const useTokenSearch = (
|
|
|
17
20
|
|
|
18
21
|
if (token) {
|
|
19
22
|
queryClient.setQueriesData<TokensResponse>(
|
|
20
|
-
{ queryKey: ['tokens'] },
|
|
23
|
+
{ queryKey: [getQueryKey('tokens', keyPrefix)] },
|
|
21
24
|
(data) => {
|
|
22
25
|
if (
|
|
23
26
|
data &&
|
package/src/hooks/useTokens.ts
CHANGED
|
@@ -3,12 +3,13 @@ import { useQuery } from '@tanstack/react-query'
|
|
|
3
3
|
import { useMemo } from 'react'
|
|
4
4
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
5
5
|
import type { TokenAmount } from '../types/token.js'
|
|
6
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
6
7
|
import { useChains } from './useChains.js'
|
|
7
8
|
|
|
8
9
|
export const useTokens = (selectedChainId?: number) => {
|
|
9
|
-
const { tokens: configTokens } = useWidgetConfig()
|
|
10
|
+
const { tokens: configTokens, keyPrefix } = useWidgetConfig()
|
|
10
11
|
const { data, isLoading } = useQuery({
|
|
11
|
-
queryKey: ['tokens'],
|
|
12
|
+
queryKey: [getQueryKey('tokens', keyPrefix)],
|
|
12
13
|
queryFn: () =>
|
|
13
14
|
getTokens({
|
|
14
15
|
chainTypes: [
|
package/src/hooks/useTools.ts
CHANGED
|
@@ -3,12 +3,13 @@ import { useQuery } from '@tanstack/react-query'
|
|
|
3
3
|
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
4
4
|
import { useSettingsStore } from '../stores/settings/useSettingsStore.js'
|
|
5
5
|
import { isItemAllowed } from '../utils/item.js'
|
|
6
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
6
7
|
|
|
7
8
|
export const useTools = () => {
|
|
8
|
-
const { bridges, exchanges } = useWidgetConfig()
|
|
9
|
+
const { bridges, exchanges, keyPrefix } = useWidgetConfig()
|
|
9
10
|
const { data } = useQuery({
|
|
10
11
|
queryKey: [
|
|
11
|
-
'tools',
|
|
12
|
+
getQueryKey('tools', keyPrefix),
|
|
12
13
|
bridges?.allow,
|
|
13
14
|
bridges?.deny,
|
|
14
15
|
exchanges?.allow,
|
|
@@ -6,18 +6,27 @@ import {
|
|
|
6
6
|
useQuery,
|
|
7
7
|
useQueryClient,
|
|
8
8
|
} from '@tanstack/react-query'
|
|
9
|
+
import { useMemo } from 'react'
|
|
10
|
+
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
11
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
9
12
|
|
|
10
13
|
export const useTransactionDetails = (transactionHash?: string) => {
|
|
11
14
|
const { account, accounts } = useAccount()
|
|
12
15
|
const queryClient = useQueryClient()
|
|
16
|
+
const { keyPrefix } = useWidgetConfig()
|
|
17
|
+
|
|
18
|
+
const transactionHistoryQueryKey = useMemo(
|
|
19
|
+
() => getQueryKey('transaction-history', keyPrefix),
|
|
20
|
+
[keyPrefix]
|
|
21
|
+
)
|
|
13
22
|
|
|
14
23
|
const { data, isLoading } = useQuery({
|
|
15
|
-
queryKey: [
|
|
24
|
+
queryKey: [transactionHistoryQueryKey, transactionHash],
|
|
16
25
|
queryFn: async ({ queryKey: [, transactionHash], signal }) => {
|
|
17
26
|
if (transactionHash) {
|
|
18
27
|
for (const account of accounts) {
|
|
19
28
|
const cachedHistory = queryClient.getQueryData<StatusResponse[]>([
|
|
20
|
-
|
|
29
|
+
transactionHistoryQueryKey,
|
|
21
30
|
account.address,
|
|
22
31
|
])
|
|
23
32
|
|
|
@@ -41,7 +50,7 @@ export const useTransactionDetails = (transactionHash?: string) => {
|
|
|
41
50
|
|
|
42
51
|
if (fromAddress) {
|
|
43
52
|
queryClient.setQueryData<StatusResponse[]>(
|
|
44
|
-
[
|
|
53
|
+
[transactionHistoryQueryKey, fromAddress],
|
|
45
54
|
(data) => {
|
|
46
55
|
return [...data!, transaction!]
|
|
47
56
|
}
|
|
@@ -57,7 +66,7 @@ export const useTransactionDetails = (transactionHash?: string) => {
|
|
|
57
66
|
for (const account of accounts) {
|
|
58
67
|
const transaction = queryClient
|
|
59
68
|
.getQueryData<StatusResponse[]>([
|
|
60
|
-
|
|
69
|
+
transactionHistoryQueryKey,
|
|
61
70
|
account.address,
|
|
62
71
|
])
|
|
63
72
|
?.find((t) => t.sending.txHash === transactionHash)
|
|
@@ -3,13 +3,19 @@ import { type ExtendedTransactionInfo, getTransactionHistory } from '@lifi/sdk'
|
|
|
3
3
|
import { useAccount } from '@lifi/wallet-management'
|
|
4
4
|
import type { QueryFunction } from '@tanstack/react-query'
|
|
5
5
|
import { useQueries } from '@tanstack/react-query'
|
|
6
|
+
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
|
|
7
|
+
import { getQueryKey } from '../utils/queries.js'
|
|
6
8
|
|
|
7
9
|
export const useTransactionHistory = () => {
|
|
8
10
|
const { accounts } = useAccount()
|
|
11
|
+
const { keyPrefix } = useWidgetConfig()
|
|
9
12
|
|
|
10
13
|
const { data, isLoading } = useQueries({
|
|
11
14
|
queries: accounts.map((account) => ({
|
|
12
|
-
queryKey: [
|
|
15
|
+
queryKey: [
|
|
16
|
+
getQueryKey('transaction-history', keyPrefix),
|
|
17
|
+
account.address,
|
|
18
|
+
],
|
|
13
19
|
queryFn: (async ({ queryKey: [, accountAddress], signal }) => {
|
|
14
20
|
if (!accountAddress) {
|
|
15
21
|
return []
|
package/src/i18n/en.json
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"close": "Close",
|
|
22
22
|
"confirm": "Confirm",
|
|
23
23
|
"connectAnotherWallet": "Connect another wallet",
|
|
24
|
+
"connectChainWallet": "Connect {{chain}} wallet",
|
|
24
25
|
"connectWallet": "Connect wallet",
|
|
25
26
|
"contactSupport": "Contact support",
|
|
26
27
|
"continue": "Continue",
|
|
@@ -67,7 +68,9 @@
|
|
|
67
68
|
"gas": "Gas",
|
|
68
69
|
"payWith": "Pay with",
|
|
69
70
|
"receive": "Receive",
|
|
71
|
+
"received": "Received",
|
|
70
72
|
"recentWallets": "Recent wallets",
|
|
73
|
+
"refunded": "Refunded",
|
|
71
74
|
"selectChain": "Select chain",
|
|
72
75
|
"selectWallet": "Select your wallet",
|
|
73
76
|
"send": "Send",
|
|
@@ -91,7 +94,8 @@
|
|
|
91
94
|
"emptyTokenList": "We couldn't find tokens on {{chainName}} chain or you don't have any. Please search by contract address if your token doesn't appear or choose another chain.",
|
|
92
95
|
"emptyTransactionHistory": "Transaction history is only stored locally and will be deleted if you clear your browser data.",
|
|
93
96
|
"routeNotFound": "Reasons for that could be: low liquidity, amount selected is too low, gas costs are too high or there are no routes for the selected combination.",
|
|
94
|
-
"toAddressIsRequired": "The destination wallet address is required to proceed with the transfer."
|
|
97
|
+
"toAddressIsRequired": "The destination wallet address is required to proceed with the transfer.",
|
|
98
|
+
"missingRouteRequiredAccount": "Connect your {{chainName}} wallet to proceed. {{address}}"
|
|
95
99
|
},
|
|
96
100
|
"title": {
|
|
97
101
|
"autoRefuel": "Get {{chainName}} gas",
|
|
@@ -102,9 +106,7 @@
|
|
|
102
106
|
},
|
|
103
107
|
"success": {
|
|
104
108
|
"message": {
|
|
105
|
-
"exchangePartiallySuccessful": "We've tried to complete the transaction, but {{tool}} couldn't proceed due to either slippage settings or lack of liquidity for the {{tokenSymbol}} token."
|
|
106
|
-
"exchangeSuccessful": "There are now {{amount, numberExt}} {{tokenSymbol}} in {{walletAddress}} wallet on {{chainName}} chain.",
|
|
107
|
-
"checkoutSuccessful": "You now own {{assetName}} in {{walletAddress}} wallet on {{chainName}} chain."
|
|
109
|
+
"exchangePartiallySuccessful": "We've tried to complete the transaction, but {{tool}} couldn't proceed due to either slippage settings or lack of liquidity for the {{tokenSymbol}} token."
|
|
108
110
|
},
|
|
109
111
|
"title": {
|
|
110
112
|
"bridgePartiallySuccessful": "Bridge partially successful",
|