@lifi/widget 3.21.4-alpha.0 → 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/config/version.js.map +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/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/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
|
@@ -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
|
|
|
@@ -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",
|
|
@@ -52,23 +52,15 @@ export const IconCircle = styled(Box, {
|
|
|
52
52
|
return {
|
|
53
53
|
backgroundColor: `rgba(${color} / ${alphaValue})`,
|
|
54
54
|
borderRadius: '50%',
|
|
55
|
-
width:
|
|
56
|
-
height:
|
|
55
|
+
width: 72,
|
|
56
|
+
height: 72,
|
|
57
57
|
display: 'grid',
|
|
58
58
|
position: 'relative',
|
|
59
59
|
placeItems: 'center',
|
|
60
60
|
'& > svg': {
|
|
61
61
|
color: `color-mix(in srgb, rgb(${color}) ${(1 - darkenValue) * 100}%, black)`,
|
|
62
|
-
width:
|
|
63
|
-
height:
|
|
62
|
+
width: 36,
|
|
63
|
+
height: 36,
|
|
64
64
|
},
|
|
65
65
|
}
|
|
66
66
|
})
|
|
67
|
-
|
|
68
|
-
export const MessageSkeletonContainer = styled(Box)(({ theme }) => ({
|
|
69
|
-
display: 'flex',
|
|
70
|
-
flexDirection: 'column',
|
|
71
|
-
height: 64,
|
|
72
|
-
gap: theme.spacing(0.5),
|
|
73
|
-
paddingTop: theme.spacing(1),
|
|
74
|
-
}))
|
|
@@ -2,17 +2,18 @@ import Done from '@mui/icons-material/Done'
|
|
|
2
2
|
import ErrorRounded from '@mui/icons-material/ErrorRounded'
|
|
3
3
|
import InfoRounded from '@mui/icons-material/InfoRounded'
|
|
4
4
|
import WarningRounded from '@mui/icons-material/WarningRounded'
|
|
5
|
-
import { Box, Button,
|
|
5
|
+
import { Box, Button, Typography } from '@mui/material'
|
|
6
6
|
import { useCallback, useEffect, useRef } from 'react'
|
|
7
7
|
import { useTranslation } from 'react-i18next'
|
|
8
8
|
import { BottomSheet } from '../../components/BottomSheet/BottomSheet.js'
|
|
9
9
|
import type { BottomSheetBase } from '../../components/BottomSheet/types.js'
|
|
10
|
+
import { Card } from '../../components/Card/Card.js'
|
|
11
|
+
import { CardTitle } from '../../components/Card/CardTitle.js'
|
|
10
12
|
import { Token } from '../../components/Token/Token.js'
|
|
11
13
|
import { useAvailableChains } from '../../hooks/useAvailableChains.js'
|
|
12
14
|
import { useNavigateBack } from '../../hooks/useNavigateBack.js'
|
|
13
15
|
import { getProcessMessage } from '../../hooks/useProcessMessage.js'
|
|
14
16
|
import { useSetContentHeight } from '../../hooks/useSetContentHeight.js'
|
|
15
|
-
import { useTokenBalance } from '../../hooks/useTokenBalance.js'
|
|
16
17
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
17
18
|
import { useFieldActions } from '../../stores/form/useFieldActions.js'
|
|
18
19
|
import {
|
|
@@ -23,24 +24,12 @@ import { getSourceTxHash } from '../../stores/routes/utils.js'
|
|
|
23
24
|
import { hasEnumFlag } from '../../utils/enum.js'
|
|
24
25
|
import { formatTokenAmount } from '../../utils/format.js'
|
|
25
26
|
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
CenterContainer,
|
|
29
|
-
IconCircle,
|
|
30
|
-
MessageSkeletonContainer,
|
|
31
|
-
} from './StatusBottomSheet.style.js'
|
|
27
|
+
import { CenterContainer, IconCircle } from './StatusBottomSheet.style.js'
|
|
32
28
|
|
|
33
29
|
interface StatusBottomSheetContentProps extends RouteExecution {
|
|
34
30
|
onClose(): void
|
|
35
31
|
}
|
|
36
32
|
|
|
37
|
-
const MessageSkeleton = () => (
|
|
38
|
-
<MessageSkeletonContainer>
|
|
39
|
-
<Skeleton height={24} variant="text" width="92%" />
|
|
40
|
-
<Skeleton height={24} variant="text" width="56%" />
|
|
41
|
-
</MessageSkeletonContainer>
|
|
42
|
-
)
|
|
43
|
-
|
|
44
33
|
export const StatusBottomSheet: React.FC<RouteExecution> = ({
|
|
45
34
|
status,
|
|
46
35
|
route,
|
|
@@ -97,11 +86,6 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
97
86
|
),
|
|
98
87
|
}
|
|
99
88
|
|
|
100
|
-
const { token, refetch, refetchNewBalance } = useTokenBalance(
|
|
101
|
-
route.toAddress,
|
|
102
|
-
toToken
|
|
103
|
-
)
|
|
104
|
-
|
|
105
89
|
const cleanFields = () => {
|
|
106
90
|
setFieldValue('fromAmount', '')
|
|
107
91
|
setFieldValue('toAmount', '')
|
|
@@ -160,7 +144,7 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
160
144
|
|
|
161
145
|
let title: string | undefined
|
|
162
146
|
let primaryMessage: string | undefined
|
|
163
|
-
let
|
|
147
|
+
let failedMessage: string | undefined
|
|
164
148
|
let handlePrimaryButton = handleDone
|
|
165
149
|
switch (status) {
|
|
166
150
|
case RouteExecutionStatus.Done: {
|
|
@@ -170,14 +154,6 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
170
154
|
`success.title.${subvariantOptions?.custom ?? 'checkout'}Successful`
|
|
171
155
|
)
|
|
172
156
|
: t(`success.title.${transactionType}Successful`)
|
|
173
|
-
if (token) {
|
|
174
|
-
primaryMessage = t('success.message.exchangeSuccessful', {
|
|
175
|
-
amount: formatTokenAmount(token.amount, token.decimals),
|
|
176
|
-
tokenSymbol: token.symbol,
|
|
177
|
-
chainName: getChainById(toToken.chainId)?.name,
|
|
178
|
-
walletAddress: shortenAddress(route.toAddress),
|
|
179
|
-
})
|
|
180
|
-
}
|
|
181
157
|
handlePrimaryButton = handleDone
|
|
182
158
|
break
|
|
183
159
|
}
|
|
@@ -187,14 +163,6 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
187
163
|
tool: route.steps.at(-1)?.toolDetails.name,
|
|
188
164
|
tokenSymbol: route.steps.at(-1)?.action.toToken.symbol,
|
|
189
165
|
})
|
|
190
|
-
if (token) {
|
|
191
|
-
secondaryMessage = t('success.message.exchangeSuccessful', {
|
|
192
|
-
amount: formatTokenAmount(token.amount, token.decimals),
|
|
193
|
-
tokenSymbol: token.symbol,
|
|
194
|
-
chainName: getChainById(toToken.chainId)?.name,
|
|
195
|
-
walletAddress: shortenAddress(route.toAddress),
|
|
196
|
-
})
|
|
197
|
-
}
|
|
198
166
|
handlePrimaryButton = handlePartialDone
|
|
199
167
|
break
|
|
200
168
|
}
|
|
@@ -204,14 +172,6 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
204
172
|
tool: route.steps.at(-1)?.toolDetails.name,
|
|
205
173
|
tokenSymbol: route.steps.at(-1)?.action.toToken.symbol,
|
|
206
174
|
})
|
|
207
|
-
if (token) {
|
|
208
|
-
secondaryMessage = t('success.message.exchangeSuccessful', {
|
|
209
|
-
amount: formatTokenAmount(token.amount, token.decimals),
|
|
210
|
-
tokenSymbol: token.symbol,
|
|
211
|
-
chainName: getChainById(toToken.chainId)?.name,
|
|
212
|
-
walletAddress: shortenAddress(route.toAddress),
|
|
213
|
-
})
|
|
214
|
-
}
|
|
215
175
|
break
|
|
216
176
|
}
|
|
217
177
|
case RouteExecutionStatus.Failed: {
|
|
@@ -226,7 +186,7 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
226
186
|
}
|
|
227
187
|
const processMessage = getProcessMessage(t, getChainById, step, process)
|
|
228
188
|
title = processMessage.title
|
|
229
|
-
|
|
189
|
+
failedMessage = processMessage.message
|
|
230
190
|
handlePrimaryButton = handleClose
|
|
231
191
|
break
|
|
232
192
|
}
|
|
@@ -234,14 +194,6 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
234
194
|
break
|
|
235
195
|
}
|
|
236
196
|
|
|
237
|
-
useEffect(() => {
|
|
238
|
-
const hasSuccessFlag = hasEnumFlag(status, RouteExecutionStatus.Done)
|
|
239
|
-
if (hasSuccessFlag) {
|
|
240
|
-
refetchNewBalance()
|
|
241
|
-
refetch()
|
|
242
|
-
}
|
|
243
|
-
}, [refetch, refetchNewBalance, status])
|
|
244
|
-
|
|
245
197
|
const showContractComponent =
|
|
246
198
|
subvariant === 'custom' &&
|
|
247
199
|
hasEnumFlag(status, RouteExecutionStatus.Done) &&
|
|
@@ -289,36 +241,54 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
289
241
|
</CenterContainer>
|
|
290
242
|
{showContractComponent ? (
|
|
291
243
|
contractCompactComponent || contractSecondaryComponent
|
|
292
|
-
) : (
|
|
293
|
-
<CenterContainer>
|
|
294
|
-
{hasEnumFlag(status, RouteExecutionStatus.Done) ? (
|
|
295
|
-
<Token token={toToken} py={1} disableDescription />
|
|
296
|
-
) : null}
|
|
297
|
-
</CenterContainer>
|
|
298
|
-
)}
|
|
299
|
-
{!showContractComponent ? (
|
|
300
|
-
primaryMessage ? (
|
|
301
|
-
<Typography
|
|
302
|
-
sx={{
|
|
303
|
-
py: 1,
|
|
304
|
-
}}
|
|
305
|
-
>
|
|
306
|
-
{primaryMessage}
|
|
307
|
-
</Typography>
|
|
308
|
-
) : (
|
|
309
|
-
<MessageSkeleton />
|
|
310
|
-
)
|
|
311
|
-
) : null}
|
|
312
|
-
{secondaryMessage ? (
|
|
244
|
+
) : hasEnumFlag(status, RouteExecutionStatus.Failed) && failedMessage ? (
|
|
313
245
|
<Typography
|
|
314
246
|
sx={{
|
|
315
247
|
py: 1,
|
|
316
248
|
}}
|
|
317
249
|
>
|
|
318
|
-
{
|
|
250
|
+
{failedMessage}
|
|
319
251
|
</Typography>
|
|
252
|
+
) : hasEnumFlag(status, RouteExecutionStatus.Done) ? (
|
|
253
|
+
<Box
|
|
254
|
+
sx={{
|
|
255
|
+
display: 'flex',
|
|
256
|
+
flexDirection: 'column',
|
|
257
|
+
gap: 2,
|
|
258
|
+
marginTop: 2,
|
|
259
|
+
marginBottom: VcComponent ? 2 : 3,
|
|
260
|
+
}}
|
|
261
|
+
>
|
|
262
|
+
<Card
|
|
263
|
+
sx={{
|
|
264
|
+
display: 'flex',
|
|
265
|
+
flexDirection: 'column',
|
|
266
|
+
gap: 2,
|
|
267
|
+
padding: 2,
|
|
268
|
+
}}
|
|
269
|
+
>
|
|
270
|
+
<CardTitle sx={{ padding: 0 }}>
|
|
271
|
+
{hasEnumFlag(status, RouteExecutionStatus.Refunded)
|
|
272
|
+
? t('header.refunded')
|
|
273
|
+
: t('header.received')}
|
|
274
|
+
</CardTitle>
|
|
275
|
+
<Token token={toToken} disableDescription={false} />
|
|
276
|
+
{primaryMessage && (
|
|
277
|
+
<Typography
|
|
278
|
+
sx={{
|
|
279
|
+
color: 'text.secondary',
|
|
280
|
+
fontSize: '12px',
|
|
281
|
+
lineHeight: '16px',
|
|
282
|
+
fontWeight: 500,
|
|
283
|
+
}}
|
|
284
|
+
>
|
|
285
|
+
{primaryMessage}
|
|
286
|
+
</Typography>
|
|
287
|
+
)}
|
|
288
|
+
</Card>
|
|
289
|
+
{VcComponent ? <VcComponent route={route} /> : null}
|
|
290
|
+
</Box>
|
|
320
291
|
) : null}
|
|
321
|
-
{VcComponent ? <VcComponent route={route} /> : null}
|
|
322
292
|
<Box sx={{ display: 'flex', marginTop: 2, gap: 1.5 }}>
|
|
323
293
|
{hasEnumFlag(status, RouteExecutionStatus.Done) ? (
|
|
324
294
|
<Button variant="text" onClick={handleSeeDetails} fullWidth>
|