DEX API

Build swap applications on the Ton network#

Build single-chain applications#

In this guide, we’ll provide an example token swap through OKX DEX, using Ton from the Ton network to purchase JETTON. The process is as follows:

  1. Set up your environment
  2. Request the /quote endpoint and get the quote data
  3. Request the /swap endpoint send the swap transaction

1. Set up your environment#

# --------------------- npm package ---------------------
npm install @ton/ton @ton/crypto @ton/core buffer @orbs-network/ton-access
const cryptoJS = require('crypto-js'); // Import encryption modules for subsequent encryption calculations
const { TonClient, WalletContractV4, internal } = require("@ton/ton");
const { toNano, Cell } = require("@ton/core");
const { mnemonicToPrivateKey } = require("@ton/crypto");
const { getHttpEndpoint } = require("@orbs-network/ton-access");
// --------------------- environment variable ---------------------
const apiBaseUrl = 'https://www.okx.com/api/v5/dex/aggregator';
const chainId = '607';
// Native token contract address
const fromTokenAddress = 'EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c';
// JETTON token contract address
const toTokenAddress = 'EQAQXlWJvGbbFfE8F3oS8s87lIgdovS455IsWFaRdmJetTon';
// your wallet address
const user = 'UQDoI2kiSNQZxxxxxxxxxxxx6lM2ZSxKkEw3k1'
const fromAmount = '1000000'
// user wallet private key
const privateKey = 'xxxxx';
// open api Secret key
const secretkey = 'xxxxx'
// Get the current time
const date = new Date();

// --------------------- util function ---------------------
function getAggregatorRequestUrl(methodName, queryParams) {
    return apiBaseUrl + methodName + '?' + (new URLSearchParams(queryParams)).toString();
}

// Check https://www.okx.com/zh-hans/web3/build/docs/waas/rest-authentication for api-key

const headersParams = {
    'Content-Type': 'application/json',
    // The api Key obtained from the previous application
    'OK-ACCESS-KEY': 'xxxxx',
    'OK-ACCESS-SIGN': cryptoJS.enc.Base64.stringify(
    // The field order of headersParams should be consistent with the order of quoteParams.
    // example : quote  ==>   cryptoJS.HmacSHA256(date.toISOString() + 'GET' + '/api/v5/dex/aggregator/quote?amount=1000000&chainId=607&toTokenAddress=EQAQXlWJvGbbFfE8F3oS8s87lIgdovS455IsWFaRdmJetTon&fromTokenAddress=EQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM9c', secretKey)
        cryptoJS.HmacSHA256(date.toISOString() + 'GET' + '/api/v5/dex/aggregator/xxx/xxx/xxx', secretKey)
    ),
    // Convert the current time to the desired format
    'OK-ACCESS-TIMESTAMP': date.toISOString(),
    // The password created when applying for the key
    'OK-ACCESS-PASSPHRASE': 'xxxxxxx',
};
Note

Additional receiving addresses aren’t supported.

2. Request the /quote endpoint and get the quote data#

2.1 Define quote parameters#

  • Next, define the parameters to get basic information of the quote and the router list.
const quoteParams = {
  amount: fromAmount,
  chainId: chainId,
  toTokenAddress: toTokenAddress,
  fromTokenAddress: fromTokenAddress,
};

2.2 Define helper functions#

  • Define helper functions to interact with the DEX API.
const getQuote = async () => {
  const apiRequestUrl = getAggregatorRequestUrl('/quote', quoteParams);
  return fetch(apiRequestUrl, {
    method: 'get',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

3. Request the /swap endpoint and sent transaction#

3.1 Define swap parameters#

  • Next, define the parameters of the swap, and get the tx information.
const swapParams = {
  chainId: 1,
  fromTokenAddress: 'fromTokenAddress',
  toTokenAddress: 'toTokenAddress',
  amount: '1000000',
  slippage: '0.03',
  userWalletAddress: user
};

3.2 Define helper functions#

Define helper functions to interact with the DEX API

const getSwapData = async () => {
  const apiRequestUrl = getAggregatorRequestUrl('/swap', swapParams);
  return fetch(apiRequestUrl, {
    method: 'get',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

3.3 Request the /swap endpoint and send the transaction#

let tx = {
          "data": "te6cckEBBAEAwAABsA+KfqUAALgW1FkYQkBfXhAIAK3+NxydEq8Qc4csyQ7botOnBqxp3L54Fn7Zof9EjDx5ADoI2kiSNQZdnOIVsRSLrVMtiBySHg0Lt6lM2ZSxKkEwyC592wEBAZ8RMwAAAvrwgIALyzu3/eo7h8wFCa+0XsOg6z0IG/43fUuMnumWS8xS91AD0F/w35CTWUxTWRjefoV+400KRA2jX51X4ezIgmUUY/0AX5sDCAIBAQwDABgAAAABAAAAAAAAA+cKUcDO",
          "from": "UQDoI2kiSNQZdnOIVsRSLrVMtiBySHg0Lt6lM2ZSxKkEw3k1",
          "gas": "80234000",
          "gasPrice": "5000",
          "maxPriorityFeePerGas": "",
          "minReceiveAmount": "25062412",
          "to": "UQBXp1W7_UJWvsBrbaO8s-9i8O53s7hNNeZ0XqEEz12i0oDS",
          "value": "440000000"
}
// This is the response of the /swap endpoint

async function sendTx() {

    const endpoint = await getHttpEndpoint();
    const client = new TonClient({ endpoint });

    const mnemonic = ['range', 'xxxxxx']; //   Your mnemonic words  Decimal conversion

    const keyPair = await mnemonicToPrivateKey(mnemonic);

    const wallet = WalletContractV4.create({workchain: 0, publicKey: keyPair.publicKey});

    const contract = client.open(wallet)


    let seqno = await contract.getSeqno();
    const body = Cell.fromBase64(tx.data);
    const value = tx.value / Math.pow(10, 9); // Decimal conversion
    const to = tx.to;

    await contract.sendTransfer({
        seqno,
        secretKey: keyPair.secretKey,
        messages: [internal({
            value: toNano(value),
            to,
            body: body,
        })]
    });
}