Development Guide

This page describes how to execute GUD Engine trade in a few steps.

Step 1: Get Trade Estimate

Call the /order/estimate endpoint to get a quote and transaction data.

Step 2: Handle ERC20 Approvals

For ERC20 tokens, remember to check if the user has sufficient allowance for the GudEngine contract:

// Check current allowance
const allowance = await erc20Contract.allowance(userAddress, gudEngineAddress);

if (allowance < srcAmountWei) {
  // Request approval
  await erc20Contract.approve(gudEngineAddress, srcAmountWei);
}

Step 3: Transaction Execution

Gud Engine allows your users to execute trade - either directly by themselves or in a gasless fashion. We will explain both cases below.

Case 1: User executing the transaction

Signatures are not needed if the address calling the engine is the trader. The backend provide calldata ready to be executed:

const txHash = await userWallet.sendTransaction({
  to: tx.to,
  data: tx.data,
  value: tx.value
});

Case 2: Gasless Execution For Your Users

Protocol allow relayers to execute ERC-20 trades on behalf of traders by using off-chain signatures. User trading must sign the data contained in trade.eip712 object using user's wallet. trade.eip712 object is formatted to be compatible with main blockchain libraries like viem or ethers.

ⓘ Info This flow is only available for trades with ERC-20 tokens as source token. For trades with native ETH as source token, trade.eip712 object will be undefined in the estimated quote.

const userSignature = await userWallet.signTypedData({
  types: eip712.types,
  domain: eip712.domain,
  message: eip712.message,
  primaryType: eip712.primaryType
});

Update the calldata with the user's signature and send the transaction:

const tradeStruct = {
  ...estimate.data.trade.eip712.message, // This contains all the trade data
  signature: userSignature,              // User's signature of the trade
};

// Encode the final calldata
const calldata = encodeFunctionData({
  abi: gudEngineAbi, // Find it at the end of this document
  functionName: 'execute',
  args: [tradeStruct]
});

// Send the transaction from any account
const txHash = await relayerWallet.sendTransaction({
  to: estimate.data.tx.to,
  data: calldata,
  value: 0
  // WARNING: Your relayer should not send native ETH in behalf of users. Otherwise, your relayer account will be paying the trade instead of the user!
  // A trade with native ETH as input token could drain your relayer account!
});

⚠ Warning Your relayer should not send native ETH in behalf of users. Otherwise, your relayer account will be paying the trade instead of the user!

Error Handling

Common Error Codes

Status Code
Error
Description

400

Bad Request

Invalid request parameters

401

Unauthorized

Missing or invalid API key

404

Not Found

No quotes found for the requested trade

429

Too Many Requests

Rate Limit Exceeded

500

Internal Server Error

Server error during processing

Error Response Format

{
  "error": "Error description",
  "message": "Detailed error message"
}

ⓘ Info As the Trading Engine API is in beta, our API could limit or ban you if the number of requests is excessive. If you think you are being rate limited or have specific needs, please contact us.

Last updated