DODO Docs
Search
⌃K

API Interface

DODO's Trading API

Introduction

To interact with the SmartTrade routing algorithm, you can use the DODO Trading API. The DODO Trading API provides real-time quotes for any coin swap on Ethereum Mainnet, Binance Smart Chain (BSC), Polygon, Arbitrum One, Huobi ECO Chain (HECO Chain), OKExChain (OEC), Aurora, MoonRiver, Boba, Avalanche, Optimism, Cronos, and directly available ABI data for contract interaction.
The DODO Trading API integrates real-time quotes from multiple sources including DODO V1, DODO V2, professional market makers, the 1inch, 0x, and ParaSwap APIs, as well as DODO's own aggregation algorithm. It returns the best and most current quotes it finds, to ensure that DODO always has a strong competitive edge.
The following are the current sources of price quotes used by the API:
  • Ethereum: DODO V1, DODO V2, 1inch API, 0x API, ParaSwap API, OneBit market maker, DODO's in-house routing
  • BSC: DODO V1, DODO V2, 1inch API, 0x API, ParaSwap API, Wootrade market maker, DODO's in-house routing
  • Polygon: DODO V1, DODO V2, 1inch API, 0x API, ParaSwap API, DODO's in-house routing, Wootrade market maker
  • Arbitrum One: DODO V1, DODO V2, DODO's in-house routing
  • Aurora: DODO V1, DODO V2 and DODO's custom aggregation algorithm
  • Boba: DODO V1, DODO V2 and DODO's custom aggregation algorithm
  • MoonRiver: DODO V1, DODO V2 and DODO's custom aggregation algorithm
  • HECO: DODO V2, DODO's in-house routing, Wootrade market maker
  • OEC: DODO V2, DODO's in-house routing
  • MoonRiver: DODO V2, DODO's in-house routing
  • Avalanche: DODO V2, DODO's in-house routing, 1inch API, 0x API, ParaSwap API
  • Optimism: DODO's in-house routing, 1inch API, 0x API
  • Cronos: DODO's in-house routing

API Description and Parameters

get
https://route-api.dodoex.io/dodoapi
/getdodoroute
Returns Trading Pair Routes and Price Quotes

Example Request

curl --location --header 'User-Agent:DODO-${your_id}' --request GET 'https://route-api.dodoex.io/dodoapi/getdodoroute?fromTokenAddress=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48&fromTokenDecimals=6&toTokenAddress=0xdac17f958d2ee523a2206206994597c13d831ec7&toTokenDecimals=6&fromAmount=5000000000000&slippage=1&userAddr=0x9f456D1633Df3DF0D65a7c0c553b2186151B622F&chainId=1&deadLine=1650266245&source=dodo'

Request header

name
param type
description
User-Agent
string
Please define your id as User-Agent, so that when you request a problem we can help you, the recommended format is: DODO-[your custom id]
example:
User-Agent:
DODO-user123

Example Response

{
"status": 200,
"data": {
"resAmount": 4997762.767397256,
"resPricePerToToken": 1.0004476468185604,
"resPricePerFromToken": 0.999552553479451,
"priceImpact": 0.0002821827512787811,
"useSource": "dodoV2Wasm",
"targetDecimals": 6,
"targetApproveAddr": "0xCB859eA579b28e02B87A1FDE08d087ab9dbE5149",
"to": "0xa2398842F37465f89540430bDC00219fA9E4D28a",
"data": "",
"routeData": "{\"subRoute\":[{\"midPath\":[{\"poolDetails\":[{\"poolName\":\"DODO V1\",\"poolPart\":100}],\"fromToken\":\"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\"toToken\":\"0xdAC17F958D2ee523a2206206994597C13D831ec7\",\"oneSplitTotalPart\":100}],\"midPathPart\":100}],\"subRouteTotalPart\":100}"
}
}

API Usage Examples

To get a sense of how to use the DODO Trading API, let's look at an example program that uses NodeJS to get transaction information from the API. The full project is available here.
Using NodeJS to call the API for transactions
const axios = require("axios").default;
const { ethers } = require("ethers");
const erc20ABI = require("./erc20.json");
const privateKey = env.YOUR_PK;
// please remember keep your wallet private key safe and split it from source code repo in your project
// this is just for demo usage.
const rpcUrl = "https://bsc-dataseed.binance.org";
const rpcProvider = new ethers.providers.JsonRpcProvider(rpcUrl);
const wallet = new ethers.Wallet(privateKey, rpcProvider);
const dodoAPI = "https://route-api.dodoex.io/dodoapi/getdodoroute";
const checkAllowance = async (
tokenAddress,
targetAddress,
userAddress,
fromAmount
) => {
const erc20Contract = new ethers.Contract(
tokenAddress,
erc20ABI,
rpcProvider
);
const allowance = await erc20Contract.allowance(userAddress, targetAddress);
console.log(
"allowance > fromAmount => ",
allowance.toString(),
fromAmount,
allowance.gt(`${fromAmount}`)
);
return allowance.gt(`${fromAmount}`);
};
const doApprove = async (
tokenAddress,
targetAddress,
userAddress,
fromAmount
) => {
const erc20Contract = new ethers.Contract(
tokenAddress,
erc20ABI,
rpcProvider
);
await erc20Contract.approve(targetAddress, fromAmount);
};
const doSwap = async (txObj) => {
const result = await wallet.sendTransaction(txObj);
console.log(
"txHash => ",
result,
`\nopen https://bscscan.com/tx/${result.hash} check result.`
);
return result;
};
const testFlight = () => {
const fromTokenAddress = "0x67ee3Cb086F8a16f34beE3ca72FAD36F7Db929e2";
const toTokenAddress = "0x55d398326f99059ff775485246999027b3197955";
const fromAmount = 0.3 * 1e18;
axios
.get(dodoAPI, {
params: {
// DODO
fromTokenAddress: fromTokenAddress,
fromTokenDecimals: 18,
// USDT
toTokenAddress: toTokenAddress,
toTokenDecimals: 6,
// amount with decimal
fromAmount: fromAmount,
slippage: 1,
userAddr: wallet.address,
// BSC chain id is 56
chainId: 56,
rpc: rpcUrl,
},
})
.then(async function (response) {
console.log("response data => ", response.data);
if (response.data.status === 200) {
const routeObj = response.data.data;
// check allowance first
const targetAddress = routeObj.targetApproveAddr;
// allowance should greater than fromAmount
const hasApproved = await checkAllowance(
fromTokenAddress,
targetAddress,
wallet.address,
fromAmount
);
if (!hasApproved) {
await doApprove(
fromTokenAddress,
targetAddress,
wallet.address,
fromAmount
);
}
const gasLimit = await wallet.estimateGas({
to: routeObj.to,
data: routeObj.data,
value: 0, // if fromToken is eth or bnb or ht, value should be fromAmount
});
console.log("gasLimit => ", gasLimit);
const gasPrice = await wallet.getGasPrice();
console.log("gasPrice => ", gasPrice);
const nonce = await wallet.getTransactionCount();
console.log("nonce => ", nonce);
const tx = {
from: wallet.address,
to: routeObj.to,
value: 0, // if fromToken is eth or bnb or ht, value should be fromAmount
nonce: nonce,
gasLimit: ethers.utils.hexlify(gasLimit),
gasPrice: ethers.utils.hexlify(gasPrice),
};
await doSwap(tx);
}
})
.catch(function (error) {
console.log(error);
})
.then(function () {
console.log("Swap Done.");
});
};
testFlight();
First, make sure to load the necessary modules and define global constants, including your wallet's private key, the RPC URL and provider, and the DODO Routing API URL.
const axios = require("axios").default;
const { ethers } = require("ethers");
const erc20ABI = require("./erc20.json");
const privateKey = env.YOUR_PK;
// please remember keep your wallet private key safe and split it from source code repo in your project
// this is just for demo usage.
const rpcUrl = "https://bsc-dataseed.binance.org";
const rpcProvider = new ethers.providers.JsonRpcProvider(rpcUrl);
const wallet = new ethers.Wallet(privateKey, rpcProvider);
const dodoAPI = "https://route-api.dodoex.io/dodoapi/getdodoroute";
Then, we can begin by defining the functions needed to process the data from the API.
First, the 'checkAllowance()' function, which returns 'True' if the 'targetAddress' has permission to withdraw certain tokens from the 'userAddress'. The token is specified by its address 'tokenAddress', and 'fromAmount' specifies the amount of tokens to be withdrawn.
const checkAllowance = async (
tokenAddress,
targetAddress,
userAddress,
fromAmount
) => {
const erc20Contract = new ethers.Contract(
tokenAddress,
erc20ABI,
rpcProvider
);
const allowance = await erc20Contract.allowance(userAddress, targetAddress);
console.log(
"allowance > fromAmount => ",
allowance.toString(),
fromAmount,
allowance.gt(`${fromAmount}`)
);
return allowance.gt(`${fromAmount}`);
};
In addition to checking token permissions, we need a function to grant permission to a specified address. The function 'doApprove()' does just that - it gives permission to the 'targetAddress' to use certain tokens from the 'userAddress'. As in 'checkAllowance', the token is specified by its address 'tokenAddress', and 'fromAmount' specifies the amount of tokens to be withdrawn.
const doApprove = async (
tokenAddress,
targetAddress,
userAddress,
fromAmount
) => {
const erc20Contract = new ethers.Contract(
tokenAddress,
erc20ABI,
rpcProvider
);
await erc20Contract.approve(targetAddress, fromAmount);
};
Now we can define the function that executes the actual token swap, known as 'doSwap()'. This function takes a transaction object (more on this below) and executes the specified transaction, returning the result of the transaction when complete.
const doSwap = async (txObj) => {
const result = await wallet.sendTransaction(txObj);
console.log(
"txHash => ",
result,
`\nopen https://bscscan.com/tx/${result.hash} check result.`
);
return result;
};
We are now ready to define our code's behavior in the 'testFlight()' function, which will execute a swap between two tokens.
First, let's define the two tokens being swapped by their addresses, as well as the amount of tokens that are being submitted for the swap.
const testFlight = () => {
const fromTokenAddress = "0x67ee3Cb086F8a16f34beE3ca72FAD36F7Db929e2";
const toTokenAddress = "0x55d398326f99059ff775485246999027b3197955";
const fromAmount = 0.3 * 1e18;
Then, we need to get price and routing information for the desired swap using the DODO Routing API.
axios
.get(dodoAPI, {
params: {
// DODO
fromTokenAddress: fromTokenAddress,
fromTokenDecimals: 18,
// USDT
toTokenAddress: toTokenAddress,
toTokenDecimals: 6,
// amount with decimal
fromAmount: fromAmount,
slippage: 1,
userAddr: wallet.address,
// BSC chain id is 56
chainId: 56,
rpc: rpcUrl,
},
})
If a successful response is returned from the API, the main execution of the token swap can begin. The route of the swap is determined and stored in the 'routeObj' variable.
The 'checkAllowance()' function is then run to make sure that the destination address has the authority to withdraw tokens from the source address. If not, it is granted this authority via the 'doApprove()' function.
.then(async function (response) {
console.log("response data => ", response.data);
if (response.data.status === 200) {
const routeObj = response.data.data;
// check allowance first
const targetAddress = routeObj.targetApproveAddr;
// allowance should greater than fromAmount
const hasApproved = await checkAllowance(
fromTokenAddress,
targetAddress,
wallet.address,
fromAmount
);
if (!hasApproved) {
await doApprove(
fromTokenAddress,
targetAddress,
wallet.address,
fromAmount
);
Before the transaction can be executed, the gas price for the swap must be determined.
const gasLimit = await wallet.estimateGas({
to: routeObj.to,
data: routeObj.data,
value: 0, // if fromToken is eth or bnb or ht, value should be fromAmount
});
console.log("gasLimit => ", gasLimit);
const gasPrice = await wallet.getGasPrice();
console.log("gasPrice => ", gasPrice);
const nonce = await wallet.getTransactionCount();
console.log("nonce => ", nonce);
Finally, we can execute the actual token swap. To do so, we define the transaction object (mentioned above) based on the wallet address, the routeObj, the gas price, and other information obtained earlier. Then, the 'doSwap()' function can be run to execute the swap.
const tx = {
from: wallet.address,
to: routeObj.to,
value: 0, // if fromToken is eth or bnb or ht, value should be fromAmount
nonce: nonce,
gasLimit: ethers.utils.hexlify(gasLimit),
gasPrice: ethers.utils.hexlify(gasPrice),
};
await doSwap(tx);
}
In case the response from the DODO API was not valid, the function displays an error message. If not, the function displays a successful completion message.
At the very end of our code is the line where we execute the 'testFlight()' function and begin the entire swap process.
})
.catch(function (error) {
console.log(error);
})
.then(function () {
console.log("Swap Done.");
});
};
testFlight();

Integration with Contracts

The data returned from the DODO Trading API can be used to send token transactions directly to the contract. However, if you want to use your own contract to encapsulate and send data to execute token transactions, you can refer to the following code sample: DODOApiEncapsulation.sol