Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: unable to trade on non-evm assets on multi-hop ui #5847

Merged
merged 3 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ export const AssetChainDropdown: React.FC<ChainDropdownProps> = ({
borderRadius='full'
color='text.base'
isDisabled
variant='ghost'
isLoading={isLoading}
variant={!isLoading ? 'ghost' : undefined}
_disabled={disabled}
_hover={hover}
{...buttonProps}
Expand Down
11 changes: 9 additions & 2 deletions src/components/MultiHopTrade/components/AssetSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const TradeAssetAwaitingAsset = () => {
type TradeAssetSelectProps = {
assetId?: AssetId
isReadOnly?: boolean
isLoading: boolean
onAssetClick?: () => void
onAssetChange: (asset: Asset) => void
}
Expand All @@ -40,11 +41,16 @@ export const TradeAssetSelectWithAsset: React.FC<TradeAssetSelectProps> = ({
onAssetChange,
assetId,
isReadOnly,
isLoading,
}) => {
const assets = useAppSelector(selectAssets)
const asset = useAppSelector(state => selectAssetById(state, assetId ?? ''))

const { data, isLoading, isError } = useGetRelatedAssetIdsQuery(assetId ?? '')
const {
data,
isLoading: isRelatedAssetsLoading,
isError,
} = useGetRelatedAssetIdsQuery(assetId ?? '')

const handleAssetChange = useCallback(
(assetId: AssetId) => {
Expand Down Expand Up @@ -80,6 +86,7 @@ export const TradeAssetSelectWithAsset: React.FC<TradeAssetSelectProps> = ({
isDisabled={isReadOnly}
_disabled={disabledStyle}
rightIcon={rightIcon}
isLoading={isLoading || isRelatedAssetsLoading}
>
{icon}
{asset?.symbol}
Expand All @@ -89,7 +96,7 @@ export const TradeAssetSelectWithAsset: React.FC<TradeAssetSelectProps> = ({
assetIds={data}
assetId={assetId}
onClick={handleAssetChange}
isLoading={isLoading}
isLoading={isLoading || isRelatedAssetsLoading}
isError={isError}
/>
</Flex>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import type { AccountId } from '@shapeshiftoss/caip'
import type { EvmChainId } from '@shapeshiftoss/chain-adapters'
import { evmChainIds } from '@shapeshiftoss/chain-adapters'
import type { TradeQuoteStep } from '@shapeshiftoss/swapper'
import { Err, type Result } from '@sniptt/monads'
import type { QueryFunction } from '@tanstack/react-query'
Expand All @@ -11,7 +13,7 @@ import {
} from 'components/MultiHopTrade/hooks/useAllowanceApproval/helpers'
import { useWallet } from 'hooks/useWallet/useWallet'

import { useBlockNumber } from './useBlockNumber'
import { useEvmBlockNumber } from './useBlockNumber'

type QueryKeyArgs = Partial<Omit<GetAllowanceArgs, 'wallet'>> & { blockNumber: bigint | undefined }

Expand Down Expand Up @@ -86,7 +88,13 @@ export function useAllowance(
[wallet],
)

const blockNumber = useBlockNumber(chainId, watch)
const maybeEvmChainId = useMemo(() => {
const isEvmChainId = chainId && evmChainIds.includes(chainId as EvmChainId)
if (!isEvmChainId) return
return chainId as EvmChainId
}, [chainId])

const blockNumber = useEvmBlockNumber(maybeEvmChainId, watch)

const allowanceQuery = useQuery({
queryKey: queryKey({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { ChainId } from '@shapeshiftoss/caip'
import type { EvmChainId } from '@shapeshiftoss/chain-adapters'
import { useEffect, useState } from 'react'
import { assertGetViemClient } from 'lib/viem-client'

export const useBlockNumber = (chainId: ChainId | undefined, enabled: boolean) => {
export const useEvmBlockNumber = (chainId: EvmChainId | undefined, enabled: boolean) => {
const [blockNumber, setBlockNumber] = useState<bigint>()

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { AccountId } from '@shapeshiftoss/caip'
import { type EvmChainId, evmChainIds } from '@shapeshiftoss/chain-adapters'
import type { TradeQuoteStep } from '@shapeshiftoss/swapper'
import { useMemo } from 'react'
import { useAllowance } from 'components/MultiHopTrade/components/MultiHopTradeConfirm/hooks/useAllowance'
Expand All @@ -17,6 +18,10 @@ export const useIsApprovalNeeded = (
const isApprovalNeeded = useMemo(() => {
if (tradeQuoteStep === undefined) return undefined

const isEvmChainId = evmChainIds.includes(tradeQuoteStep.sellAsset.chainId as EvmChainId)

if (!isEvmChainId) return false

if (data?.isErr()) {
const error = data.unwrapErr()
// the error type is a GetAllowanceErr enum so we can handle all cases with exhaustiveness
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,9 +557,10 @@ export const TradeInput = memo(() => {
assetId={sellAsset.assetId}
onAssetClick={handleSellAssetClick}
onAssetChange={setSellAsset}
isLoading={isSupportedAssetsLoading}
/>
),
[handleSellAssetClick, sellAsset.assetId, setSellAsset],
[handleSellAssetClick, isSupportedAssetsLoading, sellAsset.assetId, setSellAsset],
)

const buyTradeAssetSelect = useMemo(
Expand All @@ -568,9 +569,10 @@ export const TradeInput = memo(() => {
assetId={buyAsset.assetId}
onAssetClick={handleBuyAssetClick}
onAssetChange={setBuyAsset}
isLoading={isSupportedAssetsLoading}
/>
),
[buyAsset.assetId, handleBuyAssetClick, setBuyAsset],
[buyAsset.assetId, handleBuyAssetClick, isSupportedAssetsLoading, setBuyAsset],
)

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { isLedger } from '@shapeshiftoss/hdwallet-ledger'
import type { TradeQuote } from '@shapeshiftoss/swapper'
import type { Result } from '@sniptt/monads'
import { Err, Ok } from '@sniptt/monads'
import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import { bn } from 'lib/bignumber/bignumber'
import { MAX_ALLOWANCE } from 'lib/swapper/swappers/utils/constants'
import { assertGetChainAdapter } from 'lib/utils'
import { getApproveContractData, getErc20Allowance, getFees } from 'lib/utils/evm'

export type GetAllowanceArgs = {
Expand All @@ -35,10 +35,8 @@ export const getAllowance = async ({
wallet,
accountId,
}: GetAllowanceArgs): Promise<Result<string, GetAllowanceErr>> => {
const adapterManager = getChainAdapterManager()
const adapter = adapterManager.get(chainId)
const adapter = assertGetChainAdapter(chainId)

if (!adapter) throw Error(`no chain adapter found for chain Id: ${chainId}`)
if (!wallet) throw new Error('no wallet available')

// No approval needed for selling a non-EVM asset
Expand Down
14 changes: 11 additions & 3 deletions src/pages/Lending/Pool/components/Borrow/BorrowInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export const BorrowInput = ({
const translate = useTranslate()
const history = useHistory()

const { data: borrowAssets } = useLendingSupportedAssets({ type: 'borrow' })
const { data: borrowAssets, isLoading: isLendingSupportedAssetsLoading } =
useLendingSupportedAssets({ type: 'borrow' })

const collateralAsset = useAppSelector(state => selectAssetById(state, collateralAssetId))

Expand Down Expand Up @@ -346,19 +347,26 @@ export const BorrowInput = ({
onAssetClick={noop}
onAssetChange={handleAssetChange}
isReadOnly
isLoading={isLendingSupportedAssetsLoading}
/>
)
}, [collateralAssetId, handleAssetChange])
}, [collateralAssetId, handleAssetChange, isLendingSupportedAssetsLoading])

const borrowAssetSelectComponent = useMemo(() => {
return (
<TradeAssetSelect
assetId={borrowAsset?.assetId ?? ''}
onAssetClick={handleBorrowAssetClick}
onAssetChange={handleAssetChange}
isLoading={isLendingSupportedAssetsLoading}
/>
)
}, [borrowAsset?.assetId, handleAssetChange, handleBorrowAssetClick])
}, [
borrowAsset?.assetId,
handleAssetChange,
handleBorrowAssetClick,
isLendingSupportedAssetsLoading,
])

const quoteErrorTranslation = useMemo(() => {
if (_isSmartContractAddress) return 'trade.errors.smartContractWalletNotSupported'
Expand Down
19 changes: 16 additions & 3 deletions src/pages/Lending/Pool/components/Repay/RepayInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ export const RepayInput = ({

const swapIcon = useMemo(() => <ArrowDownIcon />, [])

const { data: lendingSupportedAssets } = useLendingSupportedAssets({ type: 'borrow' })
const { data: lendingSupportedAssets, isLoading: isLendingSupportedAssetsLoading } =
useLendingSupportedAssets({ type: 'borrow' })

useEffect(() => {
if (!(lendingSupportedAssets && collateralAsset)) return
Expand Down Expand Up @@ -159,9 +160,15 @@ export const RepayInput = ({
// Users have the possibility to repay in any supported asset, not only their collateral/borrowed asset
// https://docs.thorchain.org/thorchain-finance/lending#loan-repayment-closeflow
isReadOnly={false}
isLoading={isLendingSupportedAssetsLoading}
/>
)
}, [handleAssetChange, handleRepaymentAssetClick, repaymentAsset?.assetId])
}, [
handleAssetChange,
handleRepaymentAssetClick,
isLendingSupportedAssetsLoading,
repaymentAsset?.assetId,
])

const collateralAssetSelectComponent = useMemo(() => {
return (
Expand All @@ -170,9 +177,15 @@ export const RepayInput = ({
onAssetClick={handleRepaymentAssetClick}
onAssetChange={handleAssetChange}
isReadOnly
isLoading={isLendingSupportedAssetsLoading}
/>
)
}, [collateralAssetId, handleAssetChange, handleRepaymentAssetClick])
}, [
collateralAssetId,
handleAssetChange,
handleRepaymentAssetClick,
isLendingSupportedAssetsLoading,
])

const handleSeenNotice = useCallback(() => setSeenNotice(true), [])

Expand Down