@lifi/widget 3.10.1-alpha.0 → 3.12.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 +19 -0
- package/dist/esm/components/Routes/RoutesExpanded.js +1 -0
- package/dist/esm/components/Routes/RoutesExpanded.js.map +1 -1
- package/dist/esm/components/TokenList/TokenList.d.ts +1 -1
- package/dist/esm/components/TokenList/TokenList.js +13 -0
- package/dist/esm/components/TokenList/TokenList.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/useGasRefuel.js +17 -5
- package/dist/esm/hooks/useGasRefuel.js.map +1 -1
- package/dist/esm/hooks/useRouteExecution.js +26 -2
- package/dist/esm/hooks/useRouteExecution.js.map +1 -1
- package/dist/esm/hooks/useToAddressRequirements.js +2 -1
- package/dist/esm/hooks/useToAddressRequirements.js.map +1 -1
- package/dist/esm/hooks/useTokenBalance.d.ts +1 -3
- package/dist/esm/hooks/useTokenBalance.js +8 -15
- package/dist/esm/hooks/useTokenBalance.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/pages/MainPage/ReviewButton.js +7 -0
- package/dist/esm/pages/MainPage/ReviewButton.js.map +1 -1
- package/dist/esm/pages/RoutesPage/RoutesPage.js +7 -0
- package/dist/esm/pages/RoutesPage/RoutesPage.js.map +1 -1
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.js +12 -16
- package/dist/esm/pages/TransactionPage/StatusBottomSheet.js.map +1 -1
- package/dist/esm/providers/WalletProvider/SDKProviders.js +11 -11
- package/dist/esm/providers/WalletProvider/SDKProviders.js.map +1 -1
- package/dist/esm/providers/WalletProvider/getSafeMultisigConfig.d.ts +8 -0
- package/dist/esm/providers/WalletProvider/getSafeMultisigConfig.js +95 -0
- package/dist/esm/providers/WalletProvider/getSafeMultisigConfig.js.map +1 -0
- package/dist/esm/types/events.d.ts +24 -11
- package/dist/esm/types/events.js +2 -0
- package/dist/esm/types/events.js.map +1 -1
- package/dist/esm/types/widget.d.ts +2 -11
- package/dist/esm/types/widget.js.map +1 -1
- package/package.json +5 -5
- package/src/components/Routes/RoutesExpanded.tsx +1 -0
- package/src/components/TokenList/TokenList.tsx +14 -1
- package/src/config/version.ts +1 -1
- package/src/hooks/useGasRefuel.ts +35 -7
- package/src/hooks/useRouteExecution.ts +29 -3
- package/src/hooks/useToAddressRequirements.ts +4 -1
- package/src/hooks/useTokenBalance.ts +9 -23
- package/src/index.ts +1 -0
- package/src/pages/MainPage/ReviewButton.tsx +7 -0
- package/src/pages/RoutesPage/RoutesPage.tsx +7 -0
- package/src/pages/TransactionPage/StatusBottomSheet.tsx +12 -20
- package/src/providers/WalletProvider/SDKProviders.tsx +14 -14
- package/src/providers/WalletProvider/getSafeMultisigConfig.ts +144 -0
- package/src/types/events.ts +20 -5
- package/src/types/widget.ts +0 -9
|
@@ -1,27 +1,21 @@
|
|
|
1
|
-
import type { ExtendedChain } from '@lifi/sdk'
|
|
2
1
|
import { type Token, type TokenAmount, getTokenBalances } from '@lifi/sdk'
|
|
3
|
-
import { useAccount } from '@lifi/wallet-management'
|
|
4
2
|
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
5
3
|
import { useCallback, useMemo } from 'react'
|
|
6
4
|
|
|
7
5
|
const defaultRefetchInterval = 30_000
|
|
8
6
|
|
|
9
|
-
export const useTokenBalance = (
|
|
10
|
-
accountAddress?: string,
|
|
11
|
-
token?: Token,
|
|
12
|
-
chain?: ExtendedChain
|
|
13
|
-
) => {
|
|
14
|
-
const { account } = useAccount(
|
|
15
|
-
// When we provide chain we want to be sure that account address used is from the same ecosystem as token
|
|
16
|
-
chain ? { chainType: chain.chainType } : undefined
|
|
17
|
-
)
|
|
7
|
+
export const useTokenBalance = (accountAddress?: string, token?: Token) => {
|
|
18
8
|
const queryClient = useQueryClient()
|
|
19
|
-
const walletAddress = accountAddress || account.address
|
|
20
9
|
|
|
21
10
|
const tokenBalanceQueryKey = useMemo(
|
|
22
11
|
() =>
|
|
23
|
-
[
|
|
24
|
-
|
|
12
|
+
[
|
|
13
|
+
'token-balance',
|
|
14
|
+
accountAddress,
|
|
15
|
+
token?.chainId,
|
|
16
|
+
token?.address,
|
|
17
|
+
] as const,
|
|
18
|
+
[token?.address, token?.chainId, accountAddress]
|
|
25
19
|
)
|
|
26
20
|
|
|
27
21
|
const { data, isLoading, refetch } = useQuery({
|
|
@@ -73,18 +67,11 @@ export const useTokenBalance = (
|
|
|
73
67
|
} as TokenAmount
|
|
74
68
|
},
|
|
75
69
|
|
|
76
|
-
enabled: Boolean(
|
|
70
|
+
enabled: Boolean(accountAddress && token),
|
|
77
71
|
refetchInterval: defaultRefetchInterval,
|
|
78
72
|
staleTime: defaultRefetchInterval,
|
|
79
73
|
})
|
|
80
74
|
|
|
81
|
-
const refetchAllBalances = () => {
|
|
82
|
-
queryClient.refetchQueries({
|
|
83
|
-
queryKey: ['token-balances', accountAddress, token?.chainId],
|
|
84
|
-
exact: false,
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
|
|
88
75
|
const refetchNewBalance = useCallback(() => {
|
|
89
76
|
queryClient.setQueryDefaults(tokenBalanceQueryKey, {
|
|
90
77
|
refetchInterval: 250,
|
|
@@ -97,7 +84,6 @@ export const useTokenBalance = (
|
|
|
97
84
|
isLoading,
|
|
98
85
|
refetch,
|
|
99
86
|
refetchNewBalance,
|
|
100
|
-
refetchAllBalances,
|
|
101
87
|
getTokenBalancesWithRetry,
|
|
102
88
|
}
|
|
103
89
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,14 +3,17 @@ import { useNavigate } from 'react-router-dom'
|
|
|
3
3
|
import { BaseTransactionButton } from '../../components/BaseTransactionButton/BaseTransactionButton.js'
|
|
4
4
|
import { useRoutes } from '../../hooks/useRoutes.js'
|
|
5
5
|
import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'
|
|
6
|
+
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
|
|
6
7
|
import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js'
|
|
7
8
|
import { useFieldValues } from '../../stores/form/useFieldValues.js'
|
|
8
9
|
import { useSplitSubvariantStore } from '../../stores/settings/useSplitSubvariantStore.js'
|
|
10
|
+
import { WidgetEvent } from '../../types/events.js'
|
|
9
11
|
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
10
12
|
|
|
11
13
|
export const ReviewButton: React.FC = () => {
|
|
12
14
|
const { t } = useTranslation()
|
|
13
15
|
const navigate = useNavigate()
|
|
16
|
+
const emitter = useWidgetEvents()
|
|
14
17
|
const { subvariant, subvariantOptions } = useWidgetConfig()
|
|
15
18
|
const splitState = useSplitSubvariantStore((state) => state.state)
|
|
16
19
|
const [toAddress] = useFieldValues('toAddress')
|
|
@@ -25,6 +28,10 @@ export const ReviewButton: React.FC = () => {
|
|
|
25
28
|
navigate(navigationRoutes.transactionExecution, {
|
|
26
29
|
state: { routeId: currentRoute.id },
|
|
27
30
|
})
|
|
31
|
+
emitter.emit(WidgetEvent.RouteSelected, {
|
|
32
|
+
route: currentRoute,
|
|
33
|
+
routes: routes!,
|
|
34
|
+
})
|
|
28
35
|
}
|
|
29
36
|
}
|
|
30
37
|
|
|
@@ -11,12 +11,15 @@ import { useHeader } from '../../hooks/useHeader.js'
|
|
|
11
11
|
import { useNavigateBack } from '../../hooks/useNavigateBack.js'
|
|
12
12
|
import { useRoutes } from '../../hooks/useRoutes.js'
|
|
13
13
|
import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js'
|
|
14
|
+
import { useWidgetEvents } from '../../hooks/useWidgetEvents.js'
|
|
14
15
|
import { useFieldValues } from '../../stores/form/useFieldValues.js'
|
|
16
|
+
import { WidgetEvent } from '../../types/events.js'
|
|
15
17
|
import { navigationRoutes } from '../../utils/navigationRoutes.js'
|
|
16
18
|
import { Stack } from './RoutesPage.style.js'
|
|
17
19
|
|
|
18
20
|
export const RoutesPage: React.FC<BoxProps> = () => {
|
|
19
21
|
const { navigate } = useNavigateBack()
|
|
22
|
+
const emitter = useWidgetEvents()
|
|
20
23
|
const {
|
|
21
24
|
routes,
|
|
22
25
|
isLoading,
|
|
@@ -54,6 +57,10 @@ export const RoutesPage: React.FC<BoxProps> = () => {
|
|
|
54
57
|
navigate(navigationRoutes.transactionExecution, {
|
|
55
58
|
state: { routeId: route.id },
|
|
56
59
|
})
|
|
60
|
+
emitter.emit(WidgetEvent.RouteSelected, {
|
|
61
|
+
route,
|
|
62
|
+
routes: routes!,
|
|
63
|
+
})
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
const routeNotFound = !routes?.length && !isLoading && !isFetching
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
WarningRounded,
|
|
6
6
|
} from '@mui/icons-material'
|
|
7
7
|
import { Box, Button, Skeleton, Typography } from '@mui/material'
|
|
8
|
-
import { useQueryClient } from '@tanstack/react-query'
|
|
9
8
|
import { useCallback, useEffect, useRef } from 'react'
|
|
10
9
|
import { useTranslation } from 'react-i18next'
|
|
11
10
|
import { BottomSheet } from '../../components/BottomSheet/BottomSheet.js'
|
|
@@ -78,14 +77,12 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
78
77
|
> = ({ status, route, onClose }) => {
|
|
79
78
|
const { t } = useTranslation()
|
|
80
79
|
const { navigateBack, navigate } = useNavigateBack()
|
|
81
|
-
const queryClient = useQueryClient()
|
|
82
80
|
const { setFieldValue } = useFieldActions()
|
|
83
81
|
const {
|
|
84
82
|
subvariant,
|
|
85
83
|
subvariantOptions,
|
|
86
84
|
contractSecondaryComponent,
|
|
87
85
|
contractCompactComponent,
|
|
88
|
-
feeConfig,
|
|
89
86
|
} = useWidgetConfig()
|
|
90
87
|
const { getChainById } = useAvailableChains()
|
|
91
88
|
|
|
@@ -101,25 +98,22 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
101
98
|
),
|
|
102
99
|
}
|
|
103
100
|
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
const { token, refetch, refetchNewBalance } = useTokenBalance(
|
|
102
|
+
route.toAddress,
|
|
103
|
+
toToken
|
|
104
|
+
)
|
|
108
105
|
|
|
109
|
-
const
|
|
110
|
-
refetchAllBalances()
|
|
106
|
+
const cleanFields = () => {
|
|
111
107
|
setFieldValue('fromAmount', '')
|
|
112
108
|
setFieldValue('toAmount', '')
|
|
113
|
-
queryClient.invalidateQueries({ queryKey: ['transaction-history'] })
|
|
114
109
|
}
|
|
115
110
|
|
|
116
111
|
const handleDone = () => {
|
|
117
|
-
|
|
112
|
+
cleanFields()
|
|
118
113
|
navigateBack()
|
|
119
114
|
}
|
|
120
115
|
|
|
121
116
|
const handlePartialDone = () => {
|
|
122
|
-
invalidateQueries()
|
|
123
117
|
if (
|
|
124
118
|
toToken.chainId !== route.toToken.chainId &&
|
|
125
119
|
toToken.address !== route.toToken.address
|
|
@@ -137,12 +131,14 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
137
131
|
setFieldValue('toToken', route.toToken.address, {
|
|
138
132
|
isTouched: true,
|
|
139
133
|
})
|
|
134
|
+
} else {
|
|
135
|
+
cleanFields()
|
|
140
136
|
}
|
|
141
137
|
navigateBack()
|
|
142
138
|
}
|
|
143
139
|
|
|
144
140
|
const handleClose = () => {
|
|
145
|
-
|
|
141
|
+
cleanFields()
|
|
146
142
|
onClose()
|
|
147
143
|
}
|
|
148
144
|
|
|
@@ -179,7 +175,7 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
179
175
|
primaryMessage = t('success.message.exchangeSuccessful', {
|
|
180
176
|
amount: formatTokenAmount(token.amount, token.decimals),
|
|
181
177
|
tokenSymbol: token.symbol,
|
|
182
|
-
chainName:
|
|
178
|
+
chainName: getChainById(toToken.chainId)?.name,
|
|
183
179
|
walletAddress: shortenAddress(route.toAddress),
|
|
184
180
|
})
|
|
185
181
|
}
|
|
@@ -196,7 +192,7 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
196
192
|
secondaryMessage = t('success.message.exchangeSuccessful', {
|
|
197
193
|
amount: formatTokenAmount(token.amount, token.decimals),
|
|
198
194
|
tokenSymbol: token.symbol,
|
|
199
|
-
chainName:
|
|
195
|
+
chainName: getChainById(toToken.chainId)?.name,
|
|
200
196
|
walletAddress: shortenAddress(route.toAddress),
|
|
201
197
|
})
|
|
202
198
|
}
|
|
@@ -213,7 +209,7 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
213
209
|
secondaryMessage = t('success.message.exchangeSuccessful', {
|
|
214
210
|
amount: formatTokenAmount(token.amount, token.decimals),
|
|
215
211
|
tokenSymbol: token.symbol,
|
|
216
|
-
chainName:
|
|
212
|
+
chainName: getChainById(toToken.chainId)?.name,
|
|
217
213
|
walletAddress: shortenAddress(route.toAddress),
|
|
218
214
|
})
|
|
219
215
|
}
|
|
@@ -252,9 +248,6 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
252
248
|
hasEnumFlag(status, RouteExecutionStatus.Done) &&
|
|
253
249
|
(contractCompactComponent || contractSecondaryComponent)
|
|
254
250
|
|
|
255
|
-
const VcComponent =
|
|
256
|
-
status === RouteExecutionStatus.Done ? feeConfig?._vcComponent : undefined
|
|
257
|
-
|
|
258
251
|
return (
|
|
259
252
|
<Box p={3} ref={ref}>
|
|
260
253
|
{!showContractComponent ? (
|
|
@@ -300,7 +293,6 @@ export const StatusBottomSheetContent: React.FC<
|
|
|
300
293
|
{secondaryMessage ? (
|
|
301
294
|
<Typography py={1}>{secondaryMessage}</Typography>
|
|
302
295
|
) : null}
|
|
303
|
-
{VcComponent ? <VcComponent route={route} /> : null}
|
|
304
296
|
<Box sx={{ display: 'flex', marginTop: 2, gap: 1.5 }}>
|
|
305
297
|
{hasEnumFlag(status, RouteExecutionStatus.Done) ? (
|
|
306
298
|
<Button variant="text" onClick={handleSeeDetails} fullWidth>
|
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
import { getConnectorClient as getBigmiConnectorClient } from '@bigmi/client'
|
|
2
2
|
import { useConfig as useBigmiConfig } from '@bigmi/react'
|
|
3
|
-
import type {
|
|
3
|
+
import type { SDKProvider } from '@lifi/sdk'
|
|
4
4
|
import { ChainType, EVM, Solana, UTXO, config } from '@lifi/sdk'
|
|
5
5
|
import type { SignerWalletAdapter } from '@solana/wallet-adapter-base'
|
|
6
6
|
import { useWallet } from '@solana/wallet-adapter-react'
|
|
7
|
-
import {
|
|
8
|
-
import { useConfig as useWagmiConfig } from 'wagmi'
|
|
7
|
+
import { useEffect } from 'react'
|
|
8
|
+
import { useAccount, useConfig as useWagmiConfig } from 'wagmi'
|
|
9
9
|
import {
|
|
10
10
|
getConnectorClient as getWagmiConnectorClient,
|
|
11
11
|
switchChain,
|
|
12
12
|
} from 'wagmi/actions'
|
|
13
13
|
import { useWidgetConfig } from '../WidgetProvider/WidgetProvider.js'
|
|
14
|
-
import {
|
|
14
|
+
import { getSafeMultisigConfig } from './getSafeMultisigConfig.js'
|
|
15
15
|
|
|
16
16
|
export const SDKProviders = () => {
|
|
17
17
|
const { sdkConfig } = useWidgetConfig()
|
|
18
18
|
const { wallet } = useWallet()
|
|
19
19
|
const wagmiConfig = useWagmiConfig()
|
|
20
20
|
const bigmiConfig = useBigmiConfig()
|
|
21
|
-
const
|
|
21
|
+
const account = useAccount({ config: wagmiConfig })
|
|
22
22
|
|
|
23
23
|
useEffect(() => {
|
|
24
24
|
// Configure SDK Providers
|
|
25
25
|
const providers: SDKProvider[] = []
|
|
26
|
-
const
|
|
26
|
+
const hasConfiguredEVMProvider = sdkConfig?.providers?.find(
|
|
27
27
|
(provider) => provider.type === ChainType.EVM
|
|
28
|
-
)
|
|
28
|
+
)
|
|
29
29
|
const hasConfiguredSVMProvider = sdkConfig?.providers?.some(
|
|
30
30
|
(provider) => provider.type === ChainType.SVM
|
|
31
31
|
)
|
|
32
32
|
const hasConfiguredUTXOProvider = sdkConfig?.providers?.some(
|
|
33
33
|
(provider) => provider.type === ChainType.UTXO
|
|
34
34
|
)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
if (!hasConfiguredEVMProvider) {
|
|
36
|
+
// TODO: refactor this in favor of EIP-5792: Wallet Call API
|
|
37
|
+
const multisig =
|
|
38
|
+
account.connector?.id === 'safe'
|
|
39
|
+
? getSafeMultisigConfig(account.connector)
|
|
40
|
+
: undefined
|
|
41
41
|
providers.push(
|
|
42
42
|
EVM({
|
|
43
43
|
getWalletClient: () => getWagmiConnectorClient(wagmiConfig),
|
|
@@ -70,8 +70,8 @@ export const SDKProviders = () => {
|
|
|
70
70
|
}
|
|
71
71
|
config.setProviders(providers)
|
|
72
72
|
}, [
|
|
73
|
+
account.connector,
|
|
73
74
|
bigmiConfig,
|
|
74
|
-
hasExternalEVMContext,
|
|
75
75
|
sdkConfig?.providers,
|
|
76
76
|
wagmiConfig,
|
|
77
77
|
wallet?.adapter,
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import type { MultisigTransaction, MultisigTxDetails } from '@lifi/sdk'
|
|
3
|
+
import type { Connector } from 'wagmi'
|
|
4
|
+
|
|
5
|
+
enum TransactionStatus {
|
|
6
|
+
AWAITING_CONFIRMATIONS = 'AWAITING_CONFIRMATIONS',
|
|
7
|
+
AWAITING_EXECUTION = 'AWAITING_EXECUTION',
|
|
8
|
+
CANCELLED = 'CANCELLED',
|
|
9
|
+
FAILED = 'FAILED',
|
|
10
|
+
SUCCESS = 'SUCCESS',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type GatewayTransactionDetails = {
|
|
14
|
+
safeAddress: string
|
|
15
|
+
txId: string
|
|
16
|
+
executedAt?: number
|
|
17
|
+
txStatus: TransactionStatus
|
|
18
|
+
txHash?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const getSafeMultisigConfig = (connector: Connector) => {
|
|
22
|
+
const getMultisigTransactionDetails = async (
|
|
23
|
+
txHash: string,
|
|
24
|
+
chainId: number,
|
|
25
|
+
updateIntermediateStatus?: () => void
|
|
26
|
+
): Promise<MultisigTxDetails> => {
|
|
27
|
+
const safeAppProvider = (await connector.getProvider()) as any
|
|
28
|
+
const safeProviderSDK = safeAppProvider.sdk
|
|
29
|
+
|
|
30
|
+
const safeTransactionDetails: GatewayTransactionDetails =
|
|
31
|
+
await safeProviderSDK.txs.getBySafeTxHash(txHash)
|
|
32
|
+
|
|
33
|
+
const safeTxHash = safeTransactionDetails.txId
|
|
34
|
+
|
|
35
|
+
const safeApiTransactionResponse = await fetch(
|
|
36
|
+
`https://safe-client.safe.global/v1/chains/${chainId}/transactions/${safeTxHash}`
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
const safeApiTransactionDetails = await safeApiTransactionResponse.json()
|
|
40
|
+
|
|
41
|
+
const nonTerminalStatus = [
|
|
42
|
+
TransactionStatus.SUCCESS,
|
|
43
|
+
TransactionStatus.CANCELLED,
|
|
44
|
+
TransactionStatus.FAILED,
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
const isSafeStatusPending =
|
|
48
|
+
!nonTerminalStatus.includes(safeTransactionDetails.txStatus) &&
|
|
49
|
+
!nonTerminalStatus.includes(safeApiTransactionDetails.txStatus)
|
|
50
|
+
|
|
51
|
+
const isAwaitingExecution = [
|
|
52
|
+
safeTransactionDetails.txStatus,
|
|
53
|
+
safeApiTransactionDetails.txStatus,
|
|
54
|
+
].includes(TransactionStatus.AWAITING_EXECUTION)
|
|
55
|
+
|
|
56
|
+
if (isAwaitingExecution) {
|
|
57
|
+
updateIntermediateStatus?.()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (isSafeStatusPending) {
|
|
61
|
+
await new Promise((resolve) => {
|
|
62
|
+
setTimeout(resolve, 5000)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
return await getMultisigTransactionDetails(
|
|
66
|
+
txHash,
|
|
67
|
+
chainId,
|
|
68
|
+
updateIntermediateStatus
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (
|
|
73
|
+
[
|
|
74
|
+
safeTransactionDetails.txStatus,
|
|
75
|
+
safeApiTransactionDetails.txStatus,
|
|
76
|
+
].includes(TransactionStatus.SUCCESS)
|
|
77
|
+
) {
|
|
78
|
+
return {
|
|
79
|
+
status: 'DONE',
|
|
80
|
+
txHash: `0x${safeTransactionDetails.txHash?.slice(2)}`,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
[
|
|
86
|
+
safeTransactionDetails.txStatus,
|
|
87
|
+
safeApiTransactionDetails.txStatus,
|
|
88
|
+
].includes(TransactionStatus.FAILED)
|
|
89
|
+
) {
|
|
90
|
+
return {
|
|
91
|
+
status: 'FAILED',
|
|
92
|
+
txHash: `0x${safeTransactionDetails.txHash?.slice(2)}`,
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (
|
|
97
|
+
[
|
|
98
|
+
safeTransactionDetails.txStatus,
|
|
99
|
+
safeApiTransactionDetails.txStatus,
|
|
100
|
+
].includes(TransactionStatus.CANCELLED)
|
|
101
|
+
) {
|
|
102
|
+
return {
|
|
103
|
+
status: 'CANCELLED',
|
|
104
|
+
txHash: `0x${safeTransactionDetails.txHash?.slice(2)}`,
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (isSafeStatusPending) {
|
|
109
|
+
return {
|
|
110
|
+
status: 'PENDING',
|
|
111
|
+
txHash: `0x${safeTransactionDetails.txHash?.slice(2)}`,
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
status: 'PENDING',
|
|
117
|
+
txHash: `0x${safeTransactionDetails.txHash?.slice(2)}`,
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const sendBatchTransaction = async (
|
|
122
|
+
batchTransactions: MultisigTransaction[]
|
|
123
|
+
): Promise<`0x${string}`> => {
|
|
124
|
+
const safeAppProvider = (await connector.getProvider()) as any
|
|
125
|
+
const safeProviderSDK = safeAppProvider.sdk
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
const { safeTxHash } = await safeProviderSDK.txs.send({
|
|
129
|
+
txs: batchTransactions,
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
return `0x${safeTxHash.slice(2)}`
|
|
133
|
+
} catch (error) {
|
|
134
|
+
throw new Error(error as string)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
isMultisigWalletClient: connector?.id === 'safe',
|
|
140
|
+
shouldBatchTransactions: connector?.id === 'safe',
|
|
141
|
+
sendBatchTransaction,
|
|
142
|
+
getMultisigTransactionDetails,
|
|
143
|
+
}
|
|
144
|
+
}
|
package/src/types/events.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ChainId, ChainType, Process, Route } from '@lifi/sdk'
|
|
|
2
2
|
import type { DefaultValues } from '../stores/form/types.js'
|
|
3
3
|
import type { SettingsProps } from '../stores/settings/types.js'
|
|
4
4
|
import type { NavigationRouteType } from '../utils/navigationRoutes.js'
|
|
5
|
+
import type { TokenAmount } from './token.js'
|
|
5
6
|
|
|
6
7
|
export enum WidgetEvent {
|
|
7
8
|
RouteExecutionStarted = 'routeExecutionStarted',
|
|
@@ -9,6 +10,7 @@ export enum WidgetEvent {
|
|
|
9
10
|
RouteExecutionCompleted = 'routeExecutionCompleted',
|
|
10
11
|
RouteExecutionFailed = 'routeExecutionFailed',
|
|
11
12
|
RouteHighValueLoss = 'routeHighValueLoss',
|
|
13
|
+
RouteSelected = 'routeSelected',
|
|
12
14
|
AvailableRoutes = 'availableRoutes',
|
|
13
15
|
ContactSupport = 'contactSupport',
|
|
14
16
|
SourceChainTokenSelected = 'sourceChainTokenSelected',
|
|
@@ -26,6 +28,7 @@ export enum WidgetEvent {
|
|
|
26
28
|
PageEntered = 'pageEntered',
|
|
27
29
|
FormFieldChanged = 'formFieldChanged',
|
|
28
30
|
SettingUpdated = 'settingUpdated',
|
|
31
|
+
TokenSearch = 'tokenSearch',
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
export type WidgetEvents = {
|
|
@@ -34,6 +37,7 @@ export type WidgetEvents = {
|
|
|
34
37
|
routeExecutionCompleted: Route
|
|
35
38
|
routeExecutionFailed: RouteExecutionUpdate
|
|
36
39
|
routeHighValueLoss: RouteHighValueLossUpdate
|
|
40
|
+
routeSelected: RouteSelected
|
|
37
41
|
availableRoutes: Route[]
|
|
38
42
|
contactSupport: ContactSupport
|
|
39
43
|
sourceChainTokenSelected: ChainTokenSelected
|
|
@@ -45,13 +49,14 @@ export type WidgetEvents = {
|
|
|
45
49
|
widgetExpanded: boolean
|
|
46
50
|
pageEntered: NavigationRouteType
|
|
47
51
|
settingUpdated: SettingUpdated
|
|
52
|
+
tokenSearch: TokenSearch
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
export
|
|
55
|
+
export type ContactSupport = {
|
|
51
56
|
supportId?: string
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
export
|
|
59
|
+
export type RouteHighValueLossUpdate = {
|
|
55
60
|
fromAmountUSD: number
|
|
56
61
|
toAmountUSD: number
|
|
57
62
|
gasCostUSD?: number
|
|
@@ -59,17 +64,27 @@ export interface RouteHighValueLossUpdate {
|
|
|
59
64
|
valueLoss: number
|
|
60
65
|
}
|
|
61
66
|
|
|
62
|
-
export
|
|
67
|
+
export type RouteExecutionUpdate = {
|
|
63
68
|
route: Route
|
|
64
69
|
process: Process
|
|
65
70
|
}
|
|
66
71
|
|
|
67
|
-
export
|
|
72
|
+
export type RouteSelected = {
|
|
73
|
+
route: Route
|
|
74
|
+
routes: Route[]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type TokenSearch = {
|
|
78
|
+
value: string
|
|
79
|
+
tokens: TokenAmount[]
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type ChainTokenSelected = {
|
|
68
83
|
chainId: ChainId
|
|
69
84
|
tokenAddress: string
|
|
70
85
|
}
|
|
71
86
|
|
|
72
|
-
export
|
|
87
|
+
export type WalletConnected = {
|
|
73
88
|
address?: string
|
|
74
89
|
chainId?: number
|
|
75
90
|
chainType?: ChainType
|
package/src/types/widget.ts
CHANGED
|
@@ -3,7 +3,6 @@ import type {
|
|
|
3
3
|
ChainType,
|
|
4
4
|
ContractCall,
|
|
5
5
|
Order,
|
|
6
|
-
RouteExtended,
|
|
7
6
|
RouteOptions,
|
|
8
7
|
SDKConfig,
|
|
9
8
|
StaticToken,
|
|
@@ -19,7 +18,6 @@ import type {
|
|
|
19
18
|
import type { TypographyOptions } from '@mui/material/styles/createTypography.js'
|
|
20
19
|
import type {
|
|
21
20
|
CSSProperties,
|
|
22
|
-
FC,
|
|
23
21
|
MutableRefObject,
|
|
24
22
|
ReactNode,
|
|
25
23
|
RefObject,
|
|
@@ -160,10 +158,6 @@ export interface WidgetFeeConfig {
|
|
|
160
158
|
* @returns A promise that resolves to the calculated fee as a number (e.g., 0.03 represents a 3% fee)
|
|
161
159
|
*/
|
|
162
160
|
calculateFee?(params: CalculateFeeParams): Promise<number | undefined>
|
|
163
|
-
/**
|
|
164
|
-
* @internal
|
|
165
|
-
*/
|
|
166
|
-
_vcComponent: FC<{ route: RouteExtended }>
|
|
167
161
|
}
|
|
168
162
|
|
|
169
163
|
export interface ToAddress {
|
|
@@ -212,9 +206,6 @@ export interface WidgetConfig {
|
|
|
212
206
|
contractTool?: WidgetContractTool
|
|
213
207
|
integrator: string
|
|
214
208
|
apiKey?: string
|
|
215
|
-
/**
|
|
216
|
-
* @deprecated Use `feeConfig` instead.
|
|
217
|
-
*/
|
|
218
209
|
fee?: number
|
|
219
210
|
feeConfig?: WidgetFeeConfig
|
|
220
211
|
referrer?: string
|