在 Solana 程序中集成 Raydium 兑换功能

·

Solana 凭借其低廉的交易费用和出色的吞吐量,已成为区块链应用开发的首选平台之一。Raydium 作为运行在 Solana 上的知名自动化做市商(AMM)和流动性提供协议,以其高效的代币兑换、收益农场及流动性池功能而广受欢迎。将 Raydium 的兑换功能集成到自定义 Solana 程序中,能为开发者开启广阔的创新可能。

本篇指南将详细介绍如何利用 Raydium SDK 和 Solana Web3.js 框架,在您的 Solana 程序中实现 Raydium 的兑换功能。

环境准备

在开始集成之前,请确保满足以下先决条件:

项目设置与依赖安装

首先初始化一个新的 Node.js 项目并安装必要的依赖包:

npm init -y
npm install @solana/web3.js @solana/spl-token @raydium-io/raydium-sdk decimal.js fs

关键依赖说明:

连接 Solana 网络集群

建立与 Solana 开发网(devnet)的连接是第一步:

import { Connection, clusterApiUrl, Keypair, PublicKey, Transaction } from '@solana/web3.js';
const connection = new Connection(clusterApiUrl('devnet'), 'confirmed');
console.log("已连接到 Solana 开发网");

加载支付者密钥对

安全地加载支付交易的密钥对:

import * as fs from 'fs';
const data = fs.readFileSync('./secret.json', 'utf8');
const secretKey = Uint8Array.from(JSON.parse(data));
const payer = Keypair.fromSecretKey(secretKey);
console.log("支付者公钥:", payer.publicKey.toBase58());

创建与铸造 SPL 代币

为了测试兑换功能,我们需要创建两种测试代币:

import { createMint, getMint, mintTo, getOrCreateAssociatedTokenAccount } from '@solana/spl-token';
const token1 = await createMint(connection, payer, payer.publicKey, null, 9);
const token2 = await createMint(connection, payer, payer.publicKey, null, 9);
const token1Account = await getOrCreateAssociatedTokenAccount(connection, payer, token1, payer.publicKey);
const token2Account = await getOrCreateAssociatedTokenAccount(connection, payer, token2, payer.publicKey);
await mintTo(connection, payer, token1, token1Account.address, payer.publicKey, 1000000000); // 铸造 1000 个代币
await mintTo(connection, payer, token2, token2Account.address, payer.publicKey, 1000000000);
console.log("代币铸造完成,关联代币账户已创建");

在 Raydium 上创建流动性池

现在创建一个流动性池,为代币兑换提供基础:

import { Liquidity, DEVNET_PROGRAM_ID, TxVersion, BN } from '@raydium-io/raydium-sdk';
const targetMarketId = Keypair.generate().publicKey;
const startTime = Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7;
const walletAccount = await getWalletTokenAccount(connection, payer.publicKey);
const createPoolTx = await Liquidity.makeCreatePoolV4InstructionV2Simple({
 connection,
 programId: DEVNET_PROGRAM_ID.AmmV4,
 marketInfo: {
 marketId: targetMarketId,
 programId: DEVNET_PROGRAM_ID.OPENBOOK_MARKET,
 },
 baseMintInfo: { mint: token1, decimals: 9 },
 quoteMintInfo: { mint: new PublicKey('So11111111111111111111111111111111111111112'), decimals: 9 },
 baseAmount: new BN(10000),
 quoteAmount: new BN(10000),
 startTime: new BN(Math.floor(startTime)),
 ownerInfo: {
 feePayer: payer.publicKey,
 wallet: payer.publicKey,
 tokenAccounts: walletAccount,
 useSOLBalance: true,
 },
 associatedOnly: false,
 checkCreateATAOwner: true,
 makeTxVersion: TxVersion.V0,
});
console.log("Raydium 流动性池创建成功");

添加流动性

向新创建的流动性池中添加流动性:

const addLiquidityTx = await Liquidity.makeAddLiquidityInstructionSimple({
 connection,
 poolKeys,
 userKeys: {
 owner: payer.publicKey,
 payer: payer.publicKey,
 tokenAccounts: walletAccount,
 },
 amountInA: new TokenAmount(new Token(TOKEN_PROGRAM_ID, token1, 9, 'Token1', 'Token1'), 100),
 amountInB: maxAnotherAmount,
 fixedSide: 'a',
 makeTxVersion,
});
console.log("流动性添加成功");

执行兑换操作

最后,实现核心的兑换功能:

const swapInstruction = await Liquidity.makeSwapInstruction({
 poolKeys,
 userKeys: {
 owner: payer.publicKey,
 tokenAccountIn: fromTokenAccount,
 tokenAccountOut: toTokenAccount,
 },
 amountIn,
 amountOut: minimumAmountOut,
 fixedSide: "in",
});
// 通过正确访问内部交易对象来创建交易
const transaction = new Transaction().add(...swapInstruction.innerTransaction.instructions);
const transactionSignature = await connection.sendTransaction(
 transaction,
 [payer],
 { skipPreflight: false, preflightCommitment: "confirmed" }
);
console.log("兑换交易签名:", transactionSignature);

👉 获取更多高级开发工具和资源

总结

通过遵循本文的步骤,您已成功将 Raydium 的兑换功能集成到 Solana 程序中。Raydium 为去中心化金融领域提供了强大的兑换和流动性工具。掌握这些集成技术后,您可以构建更复杂和功能丰富的 DeFi 应用。

常见问题

Q1: 为什么选择 Raydium 而不是其他 AMM 协议?

Raydium 的独特之处在于它可以直接访问 Serum 的中央限价订单簿深度,结合了AMM的便捷性和订单簿的流动性优势,为交易者提供更好的价格发现和更低的滑点。

Q2: 集成过程中最常见的错误是什么?

最常见的错误包括密钥对处理不当、代币账户未正确初始化以及 gas 费估算不足。确保充分测试每个步骤,并在开发网络上进行完整验证后再部署到主网。

Q3: 如何优化兑换交易的执行成功率?

可以通过调整滑点容差、合理设置交易超时时间以及在网络拥堵较低时执行交易来提高成功率。此外,合理设置交易优先级费用也能加快交易确认速度。

Q4: 是否需要特殊的权限才能与 Raydium 协议交互?

不需要特殊权限,任何 Solana 程序都可以与 Raydium 协议交互。但是,执行交易需要支付相应的网络费用和协议费用。

Q5: 如何处理大额兑换交易?

对于大额交易,建议使用拆分成多个较小交易的方式执行,或者使用限价订单功能,以减少价格滑点的影响。也可以考虑通过多个流动性池路由来获得更好的汇率。

Q6: 如何监控兑换交易的执行状态?

可以使用 Solana 的 getSignatureStatuses API 来监控交易状态,同时 Raydium SDK 也提供了一些实用工具来追踪交易执行情况和兑换结果。