For an example using a separate approve transaction rather than permit, see request_order_approve.ts.
Direct Orders
This example submits a BUY order request to the OrderProcessor contract. This process involves two method calls bundled together into one transaction using the OrderProcessor's multicall utility.
The first step is to determine the fees to add to the desired order amount.
// ------------------ Configure Order ------------------// order amount (1000 USDC)constorderAmount=BigInt(1000_000_000);// buy order (Change to true for Sell Order)constsellOrder=false;// market orderconstorderType=Number(0);// check the order precision doesn't exceed max decimals// applicable to sell and limit orders onlyif (sellOrder || orderType ===1) {constmaxDecimals=awaitorderProcessor.maxOrderDecimals(assetTokenAddress);constassetTokenDecimals=awaitassetToken.decimals();constallowablePrecision=10** (assetTokenDecimals - maxDecimals);if (Number(orderAmount) % allowablePrecision !=0) {thrownewError(`Order amount precision exceeds max decimals of ${maxDecimals}`); }}// get fees, fees will be added to buy order deposit or taken from sell order proceedsconstfees=awaitorderProcessor.estimateTotalFeesForOrder(signer.address,false, paymentTokenAddress, orderAmount);consttotalSpendAmount= orderAmount + fees;console.log(`fees: ${ethers.formatUnits(fees,6)}`);
The first method call - selfPermit - gives the OrderProcessor permission to spend the payment token by pulling the order amount + fees from the user's account.
The second method call - requestOrder - submits the order request to be filled by the protocol. This is submitted with the spending permit.
Once the transaction is mined, the event logs from resulting transaction receipt can be unpacked to obtain the order recipient's order index. The recipient's order index can be used to query the OrderProcessor for the current state of the order or look up the event history for that order.
// ------------------ Submit Order ------------------// create requestOrder call data// see IOrderProcessor.Order struct for order parametersconstrequestOrderData=orderProcessor.interface.encodeFunctionData("requestOrder", [[signer.address, assetToken, paymentTokenAddress, sellOrder, orderType,0,// Asset amount to sell. Ignored for buys. Fees will be taken from proceeds for sells. orderAmount,// Payment amount to spend. Ignored for sells. Fees will be added to this amount for buys.0,// Unused limit price1,// GTCethers.ZeroAddress,// split recipient0,// split amount]]);// submit permit + request order multicall transactionconsttx=awaitorderProcessor.multicall([ selfPermitData, requestOrderData,]);constreceipt=awaittx.wait();console.log(tx.hash);// get order id from eventconstevents=receipt.logs.map((log:any) =>orderProcessor.interface.parseLog(log));if (!events) thrownewError("no events");constorderEvent=events.find((event:any) => event &&event.name ==="OrderRequested");if (!orderEvent) thrownewError("no order event");constorderId=orderEvent.args[0];constorderAccount=orderEvent.args[1];console.log(`Order ID: ${orderId}`);console.log(`Order Account: ${orderAccount}`);// use order id to get order status (ACTIVE, FULFILLED, CANCELLED)constorderStatus=awaitorderProcessor.getOrderStatus(orderId);console.log(`Order Status: ${orderStatus}`);