DEX API
Build swap applications on Solana

Build swap applications on Solana#

In this guide, we will provide a use case for Solana token exchange through the OKX DEX. The process includes:

  • Set up your environment
  • Obtain the token account address for toTokenAddress
  • Obtain the exchange path
  • Deserialize and sign
  • Execute the transaction

1. Set up your environment#

Import the necessary Node.js libraries and set up your environment variables. Define helper functions and assembly parameters Node.js Environment Settings.

Additionally, you need to import the following libraries after completing the above steps.

const bs58 = require('bs58');
  const solanaWeb3 = require('@solana/web3.js');
  const {Connection} = require("@solana/web3.js");
  npm i bs58
  npm i @solana/web3.js

2. Get the token account address of toTokenAddress#

Tip
If toTokenAddress refers to a non-native token, the parameter 'solTokenAccountAddress' is required .

2.1 Get the address#

// user wallet address
    const accountPublicKey = new web3.PublicKey(
        "3cUbuUEJkcgtzGxvsukksNzmgqaUK9jwFS5pqxxxxxxx"
    );

    // token address
    const mintAccount = new web3.PublicKey(
        "So11111111111111111111111111111111111111112"
    );

    await connection.getTokenAccountsByOwner(accountPublicKey, {
        mint: mintAccount,
    })

2.2 Pass the parameters#

  • If there is no token account address created for toTokenAddress on the blockchain, the solTokenAccountAddress field does not need to be passed for the swap interface.
  • If the token account address for toTokenAddress has been obtained on the blockchain, the solTokenAccountAddress field for the swap interface needs to be passed in as this token account address.

3. Obtain the exchange path#

Tip
Solana's NativeTokenAddress is 11111111111111111111111111111111.
  • Here, we obtain the callData for the exchange of SOL to wSOL on the Solana chain.
curl --location --request GET 'https://www.okx.com/api/v5/dex/aggregator/swap?amount=1000&chainId=501&fromTokenAddress=11111111111111111111111111111111&toTokenAddress=So11111111111111111111111111111111111111112&userWalletAddress=3cUbuUEJkcgtzGxvsukksNzmgqaUK9jwFS5pqxxxxxxx&slippage=0.05&solTokenAccountAddress=8iFT6gUrXfvjM4y2dWbo2HdqvDFk3S6iy7Co7nk9orD4' \

4. Deserialize and sign#

async function signTransaction(callData, privateKey) {

    // decode
    const transaction = bs58.decode(callData)

    let tx
    // There are two types of callData, one is the old version and the other is the new version.
    try {
        tx = solanaWeb3.Transaction.from(transaction)
    } catch (error) {
        tx = solanaWeb3.VersionedTransaction.deserialize(transaction)
    }

    // Replace the latest block hash
    const recentBlockHash = await connection.getRecentBlockhash()


    if (tx instanceof solanaWeb3.VersionedTransaction) {
        tx.message.recentBlockhash = recentBlockHash.blockhash;
    } else {
        tx.recentBlockhash = recentBlockHash.blockhash
    }



    let feePayer = solanaWeb3.Keypair.fromSecretKey(bs58.decode(privateKey))
    // sign
    if (tx instanceof solanaWeb3.VersionedTransaction) {
    // v0 callData
        tx.sign([feePayer])
      } else {
    // legacy callData
        tx.partialSign(feePayer)
      }
    console.log(tx)


}

// 'xxxxxxx' means your privateKey
signTransaction(callData,'xxxxxxx')

5. Execute the transaction#

const txId =  await connection.sendRawTransaction(tx.serialize());

  console.log('txId:', txId)

  // Verify whether it has been broadcast on the chain.
  await connection.confirmTransaction(txId);
  console.log(`https://solscan.io/tx/${txId}`);