Skip to content

Commit

Permalink
fix: make destination address required if source address is a smart c…
Browse files Browse the repository at this point in the history
…ontract wallet
  • Loading branch information
chybisov committed Oct 25, 2024
1 parent 74cbe75 commit 34d8528
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { ChainId, ChainType } from '@lifi/sdk'
import { Avatar, ListItemAvatar } from '@mui/material'
import type { WalletAdapter } from '@solana/wallet-adapter-base'
import { useWallet } from '@solana/wallet-adapter-react'
import { BPF_LOADER_DEPRECATED_PROGRAM_ID } from '@solana/web3.js'
import { ListItemButton } from '../components/ListItemButton.js'
import { ListItemText } from '../components/ListItemText.js'
import { useLastConnectedAccount } from '../hooks/useAccount.js'
Expand Down
26 changes: 7 additions & 19 deletions packages/widget/src/hooks/useGasSufficiency.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
import {
ChainType,
type EVMChain,
type RouteExtended,
type Token,
} from '@lifi/sdk'
import type { EVMChain, RouteExtended, Token } from '@lifi/sdk'
import { useAccount } from '@lifi/wallet-management'
import { useQuery } from '@tanstack/react-query'
import type { Address } from 'viem'
import { type Connector, useBytecode } from 'wagmi'
import { useAvailableChains } from './useAvailableChains.js'
import { useIsContractAddress } from './useIsContractAddress.js'
import { getTokenBalancesWithRetry } from './useTokenBalance.js'

export interface GasSufficiency {
Expand All @@ -27,18 +21,12 @@ export const useGasSufficiency = (route?: RouteExtended) => {
const { account } = useAccount({
chainType: getChainById(route?.fromChainId)?.chainType,
})
const { data: contractCode } = useBytecode({
address:
account.chainType === ChainType.EVM
? (account.address as Address)
: undefined,
query: {
refetchInterval: 300_000,
staleTime: 300_000,
},
})

const isContractAddress = !!contractCode
const isContractAddress = useIsContractAddress(
account.address,
route?.fromChainId,
account.chainType
)

const { data: insufficientGas, isLoading } = useQuery({
queryKey: ['gas-sufficiency-check', account.address, route?.id],
Expand Down
21 changes: 21 additions & 0 deletions packages/widget/src/hooks/useIsContractAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ChainType } from '@lifi/sdk'
import type { Address } from 'viem'
import { useBytecode } from 'wagmi'

export const useIsContractAddress = (
address?: string,
chainId?: number,
chainType?: ChainType
) => {
const { data: contractCode } = useBytecode({
address: address as Address,
chainId: chainId,
query: {
refetchInterval: 300_000,
staleTime: 300_000,
enabled: Boolean(chainType === ChainType.EVM && chainId),
},
})
const isContractAddress = !!contractCode
return isContractAddress
}
15 changes: 13 additions & 2 deletions packages/widget/src/hooks/useToAddressRequirements.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
import { useAccount } from '@lifi/wallet-management'
import { useChain } from '../hooks/useChain.js'
import { useWidgetConfig } from '../providers/WidgetProvider/WidgetProvider.js'
import { useFieldValues } from '../stores/form/useFieldValues.js'
import { RequiredUI } from '../types/widget.js'
import { useIsContractAddress } from './useIsContractAddress.js'

export const useToAddressRequirements = () => {
const { requiredUI } = useWidgetConfig()
const [fromChainId, toChainId] = useFieldValues('fromChain', 'toChain')

const { chain: fromChain } = useChain(fromChainId)
const { chain: toChain } = useChain(toChainId)
const { account } = useAccount({
chainType: fromChain?.chainType,
})
const isFromContractAddress = useIsContractAddress(
account.address,
fromChainId,
account.chainType
)

const isDifferentChainType =
fromChain && toChain && fromChain.chainType !== toChain.chainType

const requiredToAddress =
requiredUI?.includes(RequiredUI.ToAddress) || isDifferentChainType
requiredUI?.includes(RequiredUI.ToAddress) ||
isDifferentChainType ||
isFromContractAddress

return {
requiredToAddress,
Expand Down
2 changes: 1 addition & 1 deletion packages/widget/src/stores/header/useHeaderStore.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createContext, useContext, useRef } from 'react'
import { shallow } from 'zustand/shallow'
import { createWithEqualityFn } from 'zustand/traditional'
import type { PersistStoreProps, PersistStoreProviderProps } from '../types.js'
import type { PersistStoreProviderProps } from '../types.js'
import type { HeaderState, HeaderStore } from './types.js'

export const HeaderStoreContext = createContext<HeaderStore | null>(null)
Expand Down

0 comments on commit 34d8528

Please sign in to comment.