Skip to content

Commit

Permalink
feat(sdk): report single order status (#3154)
Browse files Browse the repository at this point in the history
Merge tx, receipt, inbox, and outbox statuses into a single order status
enum.

Can do better type narrowing later.

issue: none

---------

Co-authored-by: ga-reth <[email protected]>
  • Loading branch information
kevinhalliday and ga-reth authored Feb 24, 2025
1 parent d49f566 commit 87c2850
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 96 deletions.
28 changes: 28 additions & 0 deletions sdk/src/hooks/useDidFill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Hex } from 'viem'
import { useReadContract } from 'wagmi'
import { useOmniContext } from '../context/omni.js'
import { outboxABI } from '../constants/abis.js'

type UseDidFillParams = {
destChainId: number
orderId?: Hex
originData?: Hex
}

export function useDidFill(params: UseDidFillParams) {
const { orderId, originData, destChainId } = params
const { outbox } = useOmniContext()
const filled = useReadContract({
chainId: destChainId,
address: outbox,
abi: outboxABI,
functionName: 'didFill',
args: orderId && originData ? [orderId, originData] : undefined,
query: {
enabled: !!orderId && !!originData,
refetchInterval: 1000,
},
})

return filled.data ?? false
}
4 changes: 2 additions & 2 deletions sdk/src/hooks/useGetOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export function useGetOrder({
chainId,
orderId,
}: {
chainId: number
chainId?: number
orderId?: Hex
}) {
const { inbox } = useOmniContext()
Expand All @@ -18,7 +18,7 @@ export function useGetOrder({
chainId,
args: orderId ? [orderId] : undefined,
query: {
enabled: !!orderId,
enabled: !!orderId && !!chainId,
refetchInterval: 1000,
},
})
Expand Down
2 changes: 2 additions & 0 deletions sdk/src/hooks/useInboxStatus.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { Hex } from 'viem'
import { useGetOrder } from './useGetOrder.js'

export type InboxStatus = ReturnType<typeof useInboxStatus>

export function useInboxStatus({
chainId,
orderId,
Expand Down
72 changes: 60 additions & 12 deletions sdk/src/hooks/useOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,41 @@ import {
type Config,
type UseWaitForTransactionReceiptReturnType,
type UseWriteContractReturnType,
useChainId,
useWaitForTransactionReceipt,
useWriteContract,
} from 'wagmi'
import { inboxABI } from '../constants/abis.js'
import { typeHash } from '../constants/typehash.js'
import { useOmniContext } from '../context/omni.js'
import type { Order, OrderStatus } from '../types/order.js'
import type { Order } from '../types/order.js'
import { encodeOrder } from '../utils/encodeOrder.js'
import { useDidFill } from './useDidFill.js'
import { useGetOpenOrder } from './useGetOpenOrder.js'
import { useOrderStatus } from './useOrderStatus.js'
import { type InboxStatus, useInboxStatus } from './useInboxStatus.js'
import { toJSON } from './util.js'

type UseOrderParams = {
order: Order
validateEnabled?: boolean
}

type OrderStatus =
| 'idle'
| 'opening'
| 'open'
| 'closed'
| 'rejected'
| 'error'
| 'filled'

type UseOrderReturnType = {
open: () => Promise<Hex>
validation?: Validation
txHash?: Hex
error?: WriteContractErrorType
validationError?: ValidationError
orderStatus?: OrderStatus
status: OrderStatus
canOpen: boolean
isTxPending: boolean
isTxSubmitted: boolean
Expand All @@ -43,18 +54,26 @@ type UseOrderReturnType = {

export function useOrder(params: UseOrderParams): UseOrderReturnType {
const txMutation = useWriteContract()
const wait = useWaitForTransactionReceipt({
hash: txMutation.data,
})
const wait = useWaitForTransactionReceipt({ hash: txMutation.data })

const { orderId, originData } = useGetOpenOrder({
status: wait.status,
logs: wait.data?.logs,
})
const orderStatus = useOrderStatus({
orderId: orderId,
originData: originData,
...params.order,
})

const connected = useChainId()
const srcChainId = params.order.srcChainId ?? connected
const destChainId = params.order.destChainId
const inboxStatus = useInboxStatus({ orderId, chainId: srcChainId })
const didFill = useDidFill({ destChainId, orderId, originData })

const status = deriveStatus(
inboxStatus,
didFill,
txMutation.status,
wait.status,
)

const validate = useValidateOrder(params.order, params.validateEnabled)

const validation = useMemo(() => {
Expand Down Expand Up @@ -103,7 +122,7 @@ export function useOrder(params: UseOrderParams): UseOrderReturnType {
open,
validation,
txHash: txMutation.data,
orderStatus,
status,
error: txMutation.error as WriteContractErrorType | undefined,
canOpen: validation?.accepted ?? false,
isTxPending: txMutation.isPending,
Expand Down Expand Up @@ -209,3 +228,32 @@ function useValidateOrder(order: Order, enabled = true) {
enabled,
})
}

// deriveStatus returns a status derived from open tx, inbox and outbox statuses
function deriveStatus(
inboxStatus: InboxStatus,
didFill: boolean,
txStatus: UseWriteContractReturnType['status'],
receiptStatus: UseWaitForTransactionReceiptReturnType['status'],
): OrderStatus {
// if outbox says filled, it's filled
if (didFill) return 'filled'

// prioritize inbox status over tx status
if (inboxStatus === 'filled') return 'filled'
if (inboxStatus === 'open') return 'open'
if (inboxStatus === 'rejected') return 'rejected'
if (inboxStatus === 'closed') return 'closed'

// prioritize receipt status over tx status
if (receiptStatus === 'error') return 'error'
if (receiptStatus === 'pending') return 'opening'
if (receiptStatus === 'success') return 'open' // receipt success == open (may be seen before inboxStatus is updated)

// fallback to tx status
if (txStatus === 'error') return 'error'
if (txStatus === 'pending') return 'opening'
if (txStatus === 'success') return 'opening' // still need to wait for receipt

return 'idle'
}
81 changes: 0 additions & 81 deletions sdk/src/hooks/useOrderStatus.ts

This file was deleted.

1 change: 0 additions & 1 deletion sdk/src/types/order.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Abi, Address } from 'viem'
import type { Prettify } from './utils.js'
export type OrderStatus = 'invalid' | 'pending' | 'rejected' | 'filled'

type NativeToken = {
readonly amount: bigint
Expand Down

0 comments on commit 87c2850

Please sign in to comment.