# 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:

```javascript
// 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:

```javascript
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.

> <mark style="color:blue;">**ⓘ Info**</mark>\
> 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.

```javascript
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:

```javascript
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

<table><thead><tr><th width="143.02734375">Status Code</th><th>Error</th><th>Description</th></tr></thead><tbody><tr><td>400</td><td>Bad Request</td><td>Invalid request parameters</td></tr><tr><td>401</td><td>Unauthorized</td><td>Missing or invalid API key</td></tr><tr><td>404</td><td>Not Found</td><td>No quotes found for the requested trade</td></tr><tr><td>429</td><td>Too Many Requests</td><td>Rate Limit Exceeded</td></tr><tr><td>500</td><td>Internal Server Error</td><td>Server error during processing</td></tr></tbody></table>

#### Error Response Format

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

> <mark style="color:blue;">**ⓘ Info**</mark>\
> 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.
