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
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#
Taking ETH chain as an example#
This demo is in JavaScript
Connect to an Ethereum node
: You need to ensure that you have connected to an available Ethereum node. You can use web3.js or other Ethereum development libraries to connect to the node. In the code, you need to specify the node's HTTP or WebSocket endpoint.Obtain a token contract instance
: Using the contract address and ABI of the token, you need to create an instance of the token contract. You can use the web3.eth.Contract in web3.js to achieve this. Pass the contract address and ABI as arguments to the contract instance.Query the authorized amount
: Query the authorized allowance by calling the allowance function of the contract instance. This function requires two parameters: the owner's address and the authorized party's address (spenderAddress). You can query the authorized allowance by providing these two addresses during the call.- The spenderAddress can refer to the dexTokenApproveAddress from Here in the Response interface.。
const { Web3 } = require('web3');
// Connect to an Ethereum node
const web3 = new Web3('https://xxxxx');
// token address and ABI
const tokenAddress = '0xxxxxxxxx';
// user address
const ownerAddress = '0xxxxxxxx';
// ETH dex token approval address
const spenderAddress = '0x40aa958dd87fc8305b97f2ba922cddca374bcd7f';
const tokenABI = [
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
}
];
// Create token contract instance
const tokenContract = new web3.eth.Contract(tokenABI, tokenAddress);
// Query token approve allowance function
async function getAllowance(ownerAddress, spenderAddress) {
try {
const allowance = await tokenContract.methods.allowance(ownerAddress, spenderAddress).call();
console.log(`Allowance for ${ownerAddress} to ${spenderAddress}: ${allowance}`);
} catch (error) {
console.error('Failed to query allowance:', error);
}
}
getAllowance(ownerAddress, spenderAddress).then(r => console.log(r));
2.2 Get allowance amount#
const { data: allowanceData } = await getAllowanceData();
const allowanceAmount = allowanceData?.[0]?.allowanceAmount;
3. Check approval parameters and send the approved transaction#
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#
const { data: statusInfo } = await checkTransactionStatus();
console.log(statusInfo?.data[0]?.detailStatus);
- 1. Set up your environment2. Check allowance3. Check approval parameters and send the approved transaction4. Get the toChainId list that can be traded through fromChainId, and select one of the chains as the destination chain5. Get the token list through toChainId, and select one of the tokens as the destination token6. Request the /quote endpoint and get the quote data, also retrieving the bridge ID7. Request the /build-tx endpoint and send the cross-chain swap transaction8. Get the transaction status