Fulfilling EVM Orders
The delivery of assets varies based on the destination type: VM chains or Bitcoin.
EVM deliveries
For EVM (Ethereum Virtual Machine) chains, you must interact with the specified oracle on the destination chain. Use the following details from the order to make the necessary call:
- Oracle Address: Found in
OrderDto.order.orderData.outputs[].remoteOracle
. - Destination Chain: Identified by
OrderDto.order.orderData.outputs[].chainId
.
// It is assumed you are continuing from the above steps.import { ethers } from "ethers";
const oracleAbi = "...";
// The oracle allows filling multiple outputs from different orders// in a single transaction. They do have to go to the same chain.// For simplicity, this function assumes that all outputs goes to// the same chain but it may not be the case.async function fillSingleChainOrder(order: CrossChainOrder) { let recordedChain; let recordedOracle; for (const output of order.orderData.outputs) { if (recordedChain === undefined) recordedChain = output.chainId; if (recodedOracle === undefined) recodedOracle = output.remoteOracle; if (recordedChain !== output.chainId) throw Error( `Mixed ChainIds, seen ${recordedChain} and ${output.chainId}` ); if (recodedOracle !== output.remoteOracle) throw Error( `Mixed Oracles, seen ${recodedOracle} and ${output.remoteOracle}` ); } const oracle = new ethers.Contract(recordedOracle, oracleAbi, signer);
// TODO: Set approvals for the oracleAddress for the value of the output.
// We need to provide fill times. These have to be set to proofTime. // These are used to ensure you can't reuse fills. const fillTimes = order.orderData.outputs.map( (_) => order.orderData.proofDeadline );
// Call the reactor to initiate the order. return oracle.fill(outputs, fillTimes);}
# It is assumed you are continuing from the above steps.
oracleAbi = "...";
# The oracle allows filling multiple outputs from different orders in a single transaction.# They do have to go to the same chain.# For simplicity, this function assumes that all outputs goes to the same chain but it may not be the case.def fill_single_chain_order(order): oracle_address = order['orderData']['remoteOracle']
recordedChain = ""; recordedOracle = ""; for (output in order['orderData']['outputs']): if (recordedChain == ""): recordedChain = output.chainId if (recordedOracle == ""): recordedOracle = output.remoteOracle if (recordedChain != output.chainId): raise Exception(f"Mixed ChainIds, seen {recordedChain} and {output.chainId}"); if (recordedOracle != output.remoteOracle): raise Exception(f"Mixed Oracles, seen {recordedOracle} and {output.remoteOracle}");
oracle = web3.eth.contract(address=recordedOracle, abi=oracle_abi)
# TODO: Set approvals for the oracleAddress for the value of the output.
# We need to provide fill times. These have to be set to proofTime. # These are used to ensure you can't reuse fills. fillTimes = [order.orderData.proofDeadline for _ in order.orderData.outputs]
# Build the transaction txn = oracle.functions.fill(order.orderData.outputs, fillTimes).build_transaction({ 'from': signer_address, 'nonce': web3.eth.get_transaction_count(signer_address) }) # Sign the transaction signed_txn = web3.eth.account.sign_transaction(txn, private_key=signer_private_key) # Send the transaction tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction) # Wait for the transaction receipt receipt = web3.eth.wait_for_transaction_receipt(tx_hash) return receipt