One of the more difficult things to do with Eth-flow orders is to determine their status, as to do so we need to know the orderUid of the order.
In this tutorial, we will learn how to determine the orderUid of an Eth-flow order, and how to use it to determine the order's status.
Determining the orderUid
Upon consulting the documentation's Technical reference on orderUid, we can see that the orderUid is composed of the following fields:
digest: The EIP-712 digest of theGPv2Order.Datastructowner: The address of the order's ownerexpiry: The order's expiry timestamp
For the case of all Eth-flow orders, it is immediately apparent that:
- The
owneris the address of the Eth-flow contract (they are just simpleERC-1271orders signed by the Eth-flow contract) - The
expiryis the maximum possible value for auint32, ie.2^32 - 1
Therefore, we can create a function that takes an ABI-encoded GPv2Order.Data struct, and returns the corresponding Eth-flow orderUid:
import type { Web3Provider } from '@ethersproject/providers'
import { utils } from "ethers";
import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { onchainOrderToHash } from "/src/lib/gpv2Order";
import abi from './ethFlow.abi.json'
export async function run(provider: Web3Provider): Promise<unknown> {
// ...
const ethFlowOrderUid = (onchainOrder: any) => {
const hash = onchainOrderToHash(onchainOrder, chainId);
return hash + ethFlowAddress.slice(2) + 'ffffffff';
}
// ...
}Unfortunately there are no functions exported (yet) from the
cow-sdkthat allow for computing theEIP-712digest of an ABI-encodedGPv2Order.Datastruct. TheonchainOrderToHashfunction is defined in thegpv2Order.tsfile and usable for this tutorial.
Contract (CoWSwapEthFlow) OrderPlacement events
For handling events from the smart contracts, the tutorials use ethers.js.
To handle events, we need to know:
- the ABI
- the contract address (optional, but recommended)
In the case of this tutorial, we already have the ABI from the previous tutorial, and we can use the ethFlowAddress constant from the previous tutorial.
Get transaction receipt
The CoWSwapEthFlow contract emits an OrderPlacement event whenever an order is created. This event log contains an order field, which is the GPv2Order.Data struct that we need to determine the orderUid.
Let's use a known transaction hash to extract the GPv2Order.Data struct from the OrderPlacement event:
import type { Web3Provider } from '@ethersproject/providers'
import { utils } from "ethers";
import { SupportedChainId } from '@cowprotocol/cow-sdk'
import abi from './ethFlow.abi.json'
export async function run(provider: Web3Provider): Promise<unknown> {
// ...
const txHash = '0x04d05fc2c953cc63608c19a79869301d62b1f077e0f795f716619b21f693f00c';
const receipt = await provider.getTransactionReceipt(txHash);
}Process event logs
Now that we have the transaction receipt, we can extract the OrderPlacement event logs from it:
// ...
export async function run(provider: Web3Provider): Promise<unknown> {
// ...
const ethFlowOrderUids: string[] = receipt.logs
.reduce((orderIds, log) => {
if (log.address !== ethFlowAddress) {
return orderIds;
}
const parsedLog = iface.parseLog(log);
if (parsedLog.name === 'OrderPlacement') {
const [, order, ,] = parsedLog.args;
orderIds.push(ethFlowOrderUid(order));
}
return orderIds;
}, []);
}Above we:
- Filter out all logs that are not from the
ethFlowAddress(i.e. this way we force that we don't accidentally look at logs from the other environment'sCoWSwapEthFlowcontract) - Parse the log using the ABI
- Extract the
GPv2Order.Datastruct from thedatafield of theOrderPlacementevent - Compute the
orderUidfrom theGPv2Order.Datastruct using theethFlowOrderUidfunction defined above - Filter out any
undefinedvalues (i.e. logs that were notOrderPlacementevents and/or were not from theethFlowAddress)
Run the code
To run the code, we can press the "Run" button in the bottom right panel (the web container).
When running the script, we may be asked to connect a wallet. We can use Rabby for this.
- Accept the connection request in Rabby
- Press the "Run" button again
- Observe the calculated
orderUidin the output panel
Now that we have determined the orderUid of an Eth-flow order, we can simply look up the order's status using CoW Explorer.
import type { Web3Provider } from '@ethersproject/providers'import { utils } from "ethers";import { SupportedChainId } from '@cowprotocol/cow-sdk'import abi from './ethFlow.abi.json'
export async function run(provider: Web3Provider): Promise<unknown> { const chainId = +(await provider.send('eth_chainId', [])); if (chainId !== SupportedChainId.GNOSIS_CHAIN) { await provider.send('wallet_switchEthereumChain', [{ chainId: 100 }]);}
const ethFlowAddress = '0x40A50cf069e992AA4536211B23F286eF88752187';
const iface = new utils.Interface(abi);
// TODO: Implement
}