DEX API
在 Solana 链上构建兑换应用

在 Solana 链上构建兑换应用#

在本指南中,我们将通过欧易 DEX 提供一个用例来进行 Solana 代币交换。这个过程包括:

  • 设置你的环境
  • 获取 toTokenAddress 的代币账户地址
  • 获取兑换路径
  • 反序列化并签名
  • 执行交易
提示
暂不支持分佣和额外接收地址。

1. 设置你的环境#

导入必要的 Node.js 库并设置你的环境变量以及定义辅助函数和组装参数 Node.js 环境设置

在以上基础上需要导入以下库

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.获取 toTokenAddress 的代币账户地址#

提示
当只有 toTokenAddress 不是主网币时,需要获取 solTokenAccountAddress

2.1 获取方式#

// 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 传参方式#

  • 如果链上没有创建 toTokenAddress 的代币账户地址, 兑换 solTokenAccountAddress 字段无需传入。
  • 如果链上获取到了 toTokenAddress 的代币账户地址, 兑换 solTokenAccountAddress 字段需要传入。

3. 获取兑换路径#

提示
Solana 的 NativeTokenAddress 为 11111111111111111111111111111111
  • 在这里,获取 Solana 链 SOL 到 wSOL 交换的 callData。
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. 反序列化并签名#

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. 执行交易#

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}`);