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.Data
structowner
: 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
owner
is the address of the Eth-flow contract (they are just simpleERC-1271
orders signed by the Eth-flow contract) - The
expiry
is 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-sdk
that allow for computing theEIP-712
digest of an ABI-encodedGPv2Order.Data
struct. TheonchainOrderToHash
function is defined in thegpv2Order.ts
file 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'sCoWSwapEthFlow
contract) - Parse the log using the ABI
- Extract the
GPv2Order.Data
struct from thedata
field of theOrderPlacement
event - Compute the
orderUid
from theGPv2Order.Data
struct using theethFlowOrderUid
function defined above - Filter out any
undefined
values (i.e. logs that were notOrderPlacement
events 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
orderUid
in 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
}