DEX API
Build bridge applications

Build bridge applications#

In this guide, we’ll show you how to do a cross-chain swap using USDT on the Ethereum chain for USDC on the Arbitrum chain as an example provided by OKX DEX. This process includes:

  • Set up your environment
  • Check allowance
  • Check approval parameters and send the approved transaction
  • Get the toChainId list that can be traded through fromChainId, and select one of the chains as the destination chain
  • Get the token list through toChainId and select one of the tokens as the destination token
  • Request the /quote endpoint and get the quote data, also retrieving the bridge ID
  • Request the /build-tx endpoint and send the cross-chain swap transaction
  • Get the transaction status
Note
This example uses the Ethereum chain network; however, the same method also supports horizontal expansion, which increases the capacity and throughput of a chain by adding nodes. At the same time, it allows the writing and execution of smart contracts, providing more possibilities for developing applications.

1. Set up your environment#

Import the necessary Node.js libraries and set your environment variables as well as define helper functions and assembly parameters Node.js Environment Settings.

2. Check allowance#

2.1 Please refer to the tutorial#

Get allowance

  • The variable allowanceAmount in the following text represents the actual allowance amount on the blockchain.

2.2 Get allowance amount#

Note
Get allowance amount. If allowanceAmount < fromTokenAmount, check out step 3. If allowanceAmount > fromTokenAmount, check out step 3 to increase the allowance amount, or go directly to step 4.
const { data: allowanceData } = await getAllowanceData();
const allowanceAmount = allowanceData?.[0]?.allowanceAmount;

3. Check approval parameters and send the approved transaction#

Note
Since allowanceAmount < fromTokenAmount, we need to approve this token.

3.1 Define approval parameters#

Next, define the parameters for the transaction approval you want to perform.

const getApproveTransactionParams = {
  chainId: fromChainId,
  tokenContractAddress: fromTokenAddress,
  userWalletAddress,
  approveAmount: fromTokenAmount,
};

3.2 Define helper functions#

Define helper functions to interact with the DEX API.

const approveTransaction = async () => {
  const { apiRequestUrl, path } = getAggregatorRequestUrl(
    '/approve-transaction',
    getApproveTransactionParams
  );

  return fetch(apiRequestUrl, {
    method: 'get',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

3.3 Get the transaction approval tx and send the approved transaction#

if (parseFloat(allowanceAmount) < parseFloat(fromTokenAmount)) {
  const { data } = await approveTransaction(allowanceAmount);
  let allowanceParams = {
    ...{ data: data[0].data }, // You can modify the data content you want in accordance with the Web3 official website
  };
  const { rawTransaction } = await web3.eth.accounts.signTransaction(
    allowanceParams,
    privateKey
  );
  await web3.eth.sendSignedTransaction(rawTransaction);
}

4. Get the toChainId list that can be traded through fromChainId, and select one of the chains as the destination chain#

4.1 Define the parameters to get a tradable destination chain#

Next, define the parameters to get the tradable toChainId list through fromChainId.

const toChainListParams = {
  chainId: fromChainId,
};

4.2 Define helper functions#

Define helper functions to interact with the DEX API.

const getSupportedChain = async () => {
  const { apiRequestUrl, path } = getCrossChainBaseUrl(
    '/supported/chain',
    toChainListParams
  );
  return fetch(apiRequestUrl, {
    method: 'get',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

4.3 Get the supported destination chains and select the Arbitrum chain.#

You can also select one of the other chains as the destination chain based on the list.

const { data: supportedChainList } = await getSupportedChain();
const selectChainItem = supportedChainList.find((item) => {
  return item.chainName === 'Arbitrum';
});
toChainId = selectChainItem?.chainId;

5. Get the token list through toChainId, and select one of the tokens as the destination token#

5.1 Define the parameters for getting a list of tradable destination tokens#

Next, define the parameters to get a list of tradable tokens through toChainId.

const toChainTokenListParams = {
  chainId: toChainId,
};

5.2 Define helper functions#

Define helper functions to interact with the DEX API.

const getToChainTokenList = async () => {
  const { apiRequestUrl, path } = getAggregatorRequestUrl(
    '/all-tokens',
    toChainTokenListParams
  );
  return fetch(apiRequestUrl, {
    method: 'get',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

5.3 Get the tradable token list and select USDC.#

You can also select another token as the destination token.

const { data: toChainTokenList } = await getToChainTokenList();
const selectToChainToken = toChainTokenList.find((item) => {
  return item.tokenSymbol === 'USDC';
});
toTokenAddress = selectToChainToken?.tokenContractAddress;

6. Request the /quote endpoint and get the quote data, also retrieving the bridge ID#

6.1 Define quote parameters#

Next, define the parameters to get basic information of the quote and the router list.

const quoteParams = {
  fromChainId,
  toChainId,
  fromTokenAddress,
  toTokenAddress,
  amount: fromTokenAmount,
  slippage,
};

6.2 Define helper functions#

Define helper functions to interact with the DEX API.

const getQuote = async () => {
  const { apiRequestUrl, path } = getCrossChainBaseUrl('/quote', quoteParams);
  return fetch(apiRequestUrl, {
    method: 'get',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

6.3 Get the quote information and select a router as the transaction router#

const { data: quoteData } = await getQuote();
bridgeId = quoteData[0]?.routerList[0]?.router?.bridgeId;

7. Request the /build-tx endpoint and send the cross-chain swap transaction#

7.1 Define cross-chain swap parameters#

Next, define the parameters to get the tx information of the cross-chain swap.

const swapParams = {
  fromChainId: fromChainId,
  toChainId: toChainId,
  fromTokenAddress,
  toTokenAddress,
  amount: fromTokenAmount,
  slippage,
  userWalletAddress,
  bridgeId,
};

7.2 Define helper functions#

Define helper functions to interact with the DEX API.

const getSwapData = async () => {
  const { apiRequestUrl, path } = getCrossChainBaseUrl('/build-tx', swapParams);
  return fetch(apiRequestUrl, {
    method: 'get',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

7.3 Request the /build-tx endpoint to get the tx information and send the cross-chain swap transaction#

const { data: swapData } = await getSwapData();
const swapDataTxInfo = swapData[0].tx;
const nonce = await web3.eth.getTransactionCount(userWalletAddress, 'latest');
// You can obtain the latest nonce and process the hexadecimal numbers starting with 0x according to your needs
let signTransactionParams = {
  data: swapDataTxInfo.data,
  gasPrice: swapDataTxInfo.gasPrice,
  to: swapDataTxInfo.to,
  value: swapDataTxInfo.value,
  nonce,
};
const { rawTransaction } = await web3.eth.accounts.signTransaction(
  signTransactionParams,
  privateKey
);
const chainTxInfo = await web3.eth.sendSignedTransaction(rawTransaction);
transactionTx = chainTxInfo;

8. Get the transaction status#

8.1 Define query parameters#

Next, define the parameters, mainly the source chain hash address.

const getCheckStatusParams = {
  hash: transactionTx,
};

8.2 Define helper functions#

Define helper functions to interact with the DEX API.

const checkTransactionStatus = async () => {
  const { apiRequestUrl, path } = getCrossChainBaseUrl(
    '/status',
    getCheckStatusParams
  );
  return fetch(apiRequestUrl, {
    method: 'get',
    headers: headersParams,
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    });
};

8.3 Get the transaction status#

Note
You can also add a polling method to get order status in real time. Here is an example of a single query.
const { data: statusInfo } = await checkTransactionStatus();
console.log(statusInfo?.data[0]?.detailStatus);