Skip to content

Commit

Permalink
refactor: Introduce existingorder type, keep the current logic, trigg…
Browse files Browse the repository at this point in the history
…er refetch after success
  • Loading branch information
memoyil committed Jul 31, 2024
1 parent 79c83bc commit 1637b9c
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { memo } from 'react'
import { useCallback } from 'react'
import {
Table,
Th,
Expand All @@ -23,6 +23,9 @@ import { gelatoLimitABI } from 'config/abi/gelatoLimit'
import { ToastDescriptionWithTx } from 'components/Toast'
import useCatchTxError from 'hooks/useCatchTxError'
import truncateHash from '@pancakeswap/utils/truncateHash'
import { ExistingOrder } from 'views/LimitOrders/types'
import { useQueryClient } from '@tanstack/react-query'
import { EXISTING_ORDERS_QUERY_KEY } from 'views/LimitOrders/hooks/useGelatoLimitOrdersHistory'

const RowStyle = styled.tr`
cursor: pointer;
Expand All @@ -32,7 +35,7 @@ const RowStyle = styled.tr`
}
`

const ExistingLimitOrderTable = ({ orders }) => {
const ExistingLimitOrderTable = ({ orders }: { orders: ExistingOrder[] }) => {
const { t } = useTranslation()
const { isMobile } = useMatchBreakpoints()
const { address } = useAccount()
Expand All @@ -42,6 +45,45 @@ const ExistingLimitOrderTable = ({ orders }) => {
const gelatoLimitOrders = useGelatoLimitOrdersLib()
const { toastSuccess } = useToast()
const { fetchWithCatchTxError } = useCatchTxError()
const queryClient = useQueryClient()

const handleCancelOrder = useCallback(
async (order: ExistingOrder) => {
if (publicClient && gelatoLimitOrders?.contract.address && walletClient) {
const { request } = await publicClient.simulateContract({
address: gelatoLimitOrders?.contract.address as `0x${string}`,
abi: gelatoLimitABI,
functionName: 'cancelOrder',
account: address,
args: [order.module, order.inputToken, order.owner, order.witness, order.data],
})

const receipt = await fetchWithCatchTxError(() => {
return walletClient.writeContract({
...request,
gas: 5000000n,
})
})

if (receipt?.status) {
toastSuccess(t('Transaction receipt'), <ToastDescriptionWithTx txHash={receipt.transactionHash} />)
queryClient.invalidateQueries({
queryKey: [...EXISTING_ORDERS_QUERY_KEY, address],
})
}
}
},
[
publicClient,
gelatoLimitOrders?.contract.address,
walletClient,
address,
t,
fetchWithCatchTxError,
queryClient,
toastSuccess,
],
)

return (
<Table>
Expand All @@ -62,47 +104,25 @@ const ExistingLimitOrderTable = ({ orders }) => {
</thead>
<tbody>
{orders.map((order) => (
<RowStyle key={order[0]}>
<RowStyle key={order.transactionHash}>
<Td>
<Flex width="100%" justifyContent="center" alignItems="center">
<Box width="100%">
<Flex justifyContent="space-between">
<Link external small href={getBlockExploreLink(order[0], 'transaction', ChainId.BSC)}>
{isMobile ? truncateHash(order[0]) : order[0]}
<Link
external
small
href={getBlockExploreLink(order.transactionHash, 'transaction', ChainId.BSC)}
>
{isMobile ? truncateHash(order.transactionHash) : order.transactionHash}
<BscScanIcon color="invertedContrast" ml="4px" />
</Link>
</Flex>
</Box>
</Flex>
</Td>
<Td>
<Button
onClick={async () => {
if (publicClient && gelatoLimitOrders?.contract.address && walletClient) {
const { request } = await publicClient.simulateContract({
address: gelatoLimitOrders?.contract.address as `0x${string}`,
abi: gelatoLimitABI,
functionName: 'cancelOrder',
account: address,
args: [order[1], order[2], order[3], order[4], order[5]],
})
const receipt = await fetchWithCatchTxError(() => {
return walletClient.writeContract({
...request,
gas: 5000000n,
})
})
if (receipt?.status) {
toastSuccess(
t('Transaction receipt'),
<ToastDescriptionWithTx txHash={receipt.transactionHash} />,
)
}
}
}}
>
{t('Cancel Order')}
</Button>
<Button onClick={() => handleCancelOrder(order)}>{t('Cancel Order')}</Button>
</Td>
</RowStyle>
))}
Expand All @@ -112,4 +132,4 @@ const ExistingLimitOrderTable = ({ orders }) => {
)
}

export default memo(ExistingLimitOrderTable)
export default ExistingLimitOrderTable
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,25 @@ import { ORDER_CATEGORY } from '../../types'

import Navigation from './TableNavigation'
import ExistingLimitOrderTable from './ExistingLimitOrderTable'
import SpaciousLimitOrderTable from './SpaciousLimitOrderTable'
import CompactLimitOrderTable from './CompactLimitOrderTable'

const OrderTable: React.FC<React.PropsWithChildren<{ isCompact: boolean; orderCategory: ORDER_CATEGORY }>> = memo(
({ orderCategory }) => {
({ orderCategory, isCompact }) => {
const orders = useGelatoLimitOrdersHistory(orderCategory)

return (
<Navigation data={orders} orderCategory={orderCategory}>
{({ paginatedData }) => <ExistingLimitOrderTable orders={paginatedData} />}
{({ paginatedData }) => {
if (orderCategory === ORDER_CATEGORY.Existing) {
return <ExistingLimitOrderTable orders={paginatedData} />
}
return isCompact ? (
<CompactLimitOrderTable orders={paginatedData} />
) : (
<SpaciousLimitOrderTable orders={paginatedData} />
)
}}
</Navigation>
)
},
Expand Down
94 changes: 45 additions & 49 deletions apps/web/src/views/LimitOrders/hooks/useGelatoLimitOrdersHistory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import useAccountActiveChain from 'hooks/useAccountActiveChain'
import { usePublicClient } from 'wagmi'
import { Transaction, decodeFunctionData } from 'viem'
import { gelatoLimitABI } from 'config/abi/gelatoLimit'
import { LimitOrderStatus, ORDER_CATEGORY } from '../types'
import { useMemo } from 'react'
import orderBy from 'lodash/orderBy'
import { ExistingOrder, LimitOrderStatus, ORDER_CATEGORY } from '../types'

export const EXISTING_ORDERS_QUERY_KEY = ['limitOrders', 'gelato', 'existingOrders']
export const OPEN_ORDERS_QUERY_KEY = ['limitOrders', 'gelato', 'openOrders']
Expand Down Expand Up @@ -71,20 +73,15 @@ async function syncOrderToLocalStorage({
})
}

const useExistingOrders = (): [
`0x${string}`,
`0x${string}`,
`0x${string}`,
`0x${string}`,
`0x${string}`,
`0x${string}`,
][] => {
const useExistingOrders = (turnOn: boolean): ExistingOrder[] => {
const { account, chainId } = useAccountActiveChain()

const gelatoLimitOrders = useGelatoLimitOrdersLib()

const provider = usePublicClient({ chainId })

const startFetch = turnOn && gelatoLimitOrders && account && chainId

const { data = [] } = useQuery({
queryKey: [...EXISTING_ORDERS_QUERY_KEY, account],

Expand All @@ -104,7 +101,7 @@ const useExistingOrders = (): [
hashes.map((hash) => provider.getTransaction({ hash })),
)

const contractData = transactionDetails
const orders = transactionDetails
.map((transaction) => {
if (!transaction.input) return undefined
const { args } = decodeFunctionData({
Expand All @@ -118,44 +115,38 @@ const useExistingOrders = (): [
const module_ = `0x${data_.substr(offset + 64 * 0 + 24, 40)}`
const inputToken = `0x${data_.substr(offset + 64 * 1 + 24, 40)}`
const witness = `0x${data_.substr(offset + 64 * 3 + 24, 40)}`
return [
transaction.hash,
module_,
return {
transactionHash: transaction.hash,
module: module_,
inputToken,
owner,
witness,
`0x${data_.substr(offset + 64 * 7, 64 * 3)}`,
]
data: `0x${data_.substr(offset + 64 * 7, 64 * 3)}`,
}
}
return undefined
})
.filter(Boolean) as [
`0x${string}`,
`0x${string}`,
`0x${string}`,
`0x${string}`,
`0x${string}`,
`0x${string}`,
][]
.filter(Boolean) as ExistingOrder[]

const existRoles = await provider.multicall({
contracts: contractData.map(([, ...args]) => {
contracts: orders.map((order) => {
return {
abi: gelatoLimitABI,
address: gelatoLimitOrders.contract.address,
functionName: 'existOrder',
args,
args: [order.module, order.inputToken, order.owner, order.witness, order.data],
}
}) as any[],
allowFailure: false,
})
return contractData.filter((_, index) => existRoles[index])
return orders.filter((_, index) => existRoles[index])
}
} catch (e) {
console.error('Error fetching open orders from subgraph', e)
}
return undefined
},
enabled: Boolean(startFetch),
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
Expand Down Expand Up @@ -307,27 +298,32 @@ const useExpiredOrders = (turnOn: boolean): Order[] => {
}

export default function useGelatoLimitOrdersHistory(orderCategory: ORDER_CATEGORY) {
// const historyOrders = useHistoryOrders(orderCategory === ORDER_CATEGORY.History)
// const openOrders = useOpenOrders(orderCategory === ORDER_CATEGORY.Open)
// const expiredOrders = useExpiredOrders(orderCategory === ORDER_CATEGORY.Expired)

// const orders = useMemo(() => {
// switch (orderCategory as ORDER_CATEGORY) {
// case ORDER_CATEGORY.Open:
// return openOrders
// case ORDER_CATEGORY.History:
// return historyOrders
// case ORDER_CATEGORY.Expired:
// return expiredOrders
// default:
// return []
// }
// }, [orderCategory, openOrders, historyOrders, expiredOrders])

return useExistingOrders()

// return useMemo(
// () => (Array.isArray(orders) ? orderBy(orders, (order) => parseInt(order.createdAt), 'desc') : orders),
// [orders],
// )
const historyOrders = useHistoryOrders(orderCategory === ORDER_CATEGORY.History)
const openOrders = useOpenOrders(orderCategory === ORDER_CATEGORY.Open)
const expiredOrders = useExpiredOrders(orderCategory === ORDER_CATEGORY.Expired)
const existingOrders = useExistingOrders(orderCategory === ORDER_CATEGORY.Existing)

const orders = useMemo(() => {
switch (orderCategory as ORDER_CATEGORY) {
case ORDER_CATEGORY.Open:
return openOrders
case ORDER_CATEGORY.History:
return historyOrders
case ORDER_CATEGORY.Expired:
return expiredOrders
case ORDER_CATEGORY.Existing:
return existingOrders
default:
return []
}
}, [orderCategory, openOrders, historyOrders, expiredOrders, existingOrders])

return useMemo(() => {
if (orderCategory === ORDER_CATEGORY.Existing) {
return orders
}
return Array.isArray(orders)
? (orderBy(orders, (order: Order) => parseInt(order.createdAt), 'desc') as Order[])
: orders
}, [orders, orderCategory])
}
9 changes: 9 additions & 0 deletions apps/web/src/views/LimitOrders/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ export enum ORDER_CATEGORY {
Existing = 3,
}

export interface ExistingOrder {
transactionHash: string
module: string
inputToken: string
owner: string
witness: string
data: string
}

export enum LimitOrderStatus {
OPEN = 'open',
CANCELLED = 'cancelled',
Expand Down

0 comments on commit 1637b9c

Please sign in to comment.