Raydium SDK简明教程

Raydium 是 Solana 区块链上第一个去中心化自动做市商 (AMM),本文介绍如何利用Raydium SDK实现不同代币的去中心化兑换功能。

Raydium SDK简明教程
一键发币: SOL | BNB | ETH | BASE | Blast | ARB | OP | POLYGON | AVAX | FTM | OK

Raydium 是 Solana 区块链上第一个去中心化自动做市商 (AMM),Solana 区块链是一个优秀的第一层区块链,比以太坊更快、更便宜。

如果我们可以在 Raydium 中构建类似DEX功能的东西,不是很酷吗?

点击这里查看最终成果的演示 ,源代码可以从这里下载。

1、安装 Solana 钱包适配器

Solana 区块链上有许多可用的钱包。 要处理钱包连接,建议使用 Solana 钱包适配器。 你可以按照指南安装依赖项。

可以在同一目录中构建一个简单的前端应用程序。 Solana 钱包适配器提供了一些起始代码。 或者,你可以参考这个指南构建自己的 React 应用程序,而无需使用 Create-React-App。

在 App.tsx 中设置钱包连接:

// You can add or remove the wallet options here
const wallets = useMemo(
        () => [
            new PhantomWalletAdapter(),
            new GlowWalletAdapter(),
            new SlopeWalletAdapter(),
            new SolflareWalletAdapter({ network }),
            new TorusWalletAdapter(),
        ],
        [network]
    );
单击连接按钮时模式中显示的钱包选项

您可能会注意到,在我的 App.tsx 中,我使用主网作为网络,这意味着我们需要使用真实的资产来测试该功能。 但是,在开发网或测试网中没有发现 Raydium 智能合约。

如果想让这个交换功能在开发网或测试网中运行,我们必须自己在网络中部署和启动流动性池。 幸运的是,Solana 对每笔交易的收费非常低,因此在主网上测试它仍然是负担得起的。

一些可能有用的提示:

  • 如果你在安装 @solana/web3.js 时遇到任何问题,请检查正在使用的 Node 版本。
  • 成功安装软件包后,你在运行应用程序时可能会遇到一些问题。 阅读错误消息并尝试填充它们。

webpack.config.js 中,可以添加后备资源,如下所示:

resolve: {
  fallback: {
    "crypto": require.resolve("crypto-browserify"),
    "stream": require.resolve("stream-browserify"),
    "os": require.resolve("os-browserify/browser"),
  }
}

2、使用你选择的库构建 UI

在我的项目中,重用了之前的 ETH Swap 项目中的 UI,该项目使用 Bootstrap v5 并在 React 中构建。 主要的 UI 代码在此文件中。

你可以随意修改项目的外观!

3、获取代币余额

SOL 和其他代币(例如:RAY)的余额获取是不同的。

要获得 SOL 的余额:

import { useConnection, useWallet } from '@solana/wallet-adapter-react';
import { LAMPORTS_PER_SOL } from '@solana/web3.js';
const { publicKey } = useWallet();
const { connection } = useConnection();
const [solBalance, setSolBalance] = useState<number>(0);
// ...
if (publicKey !== null) {
  const balance = await connection.getBalance(publicKey);
  setSolBalance(balance / LAMPORTS_PER_SOL);
}

要获取 RAY 代币(或任何其他代币)的余额,我们必须使用 getTokenAccountsByOwner 来检索该用户的所有代币帐户。 然后我们可以通过RAY代币地址找到RAY代币账户(你可以在Solscan中找到代币地址)。

对于RAY代币账户,我们可以通过 getTokenAccountBalance来获取代币的余额。

import { useConnection, useWallet } from '@solana/wallet-adapter-react';
import { PublicKey } from '@solana/web3.js';
import { getTokenAccountsByOwner } from '../utils';

const { publicKey } = useWallet();
const { connection } = useConnection();
const RAY_TOKEN_MINT = '4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R';
const [rayBalance, setRayBalance] = useState<number>(0);
// ...
if (publicKey !== null) {
  // get all token accounts
  const tokenAccs = await getTokenAccountsByOwner(connection, publicKey as PublicKey);
  let rayTokenAddress: PublicKey;
  tokenAccs.filter(acc => acc.accountInfo.mint.toBase58() === RAY_TOKEN_MINT).map(async (acc) => {
    rayTokenAddress = acc.pubkey;
    const accBalance = await connection.getTokenAccountBalance(rayTokenAddress);
    const rayBal = accBalance.value.uiAmount || 0;
    setRayBalance(rayBal);
  });
}

4、获取流动性池信息

Solscan 中搜索流动性代币,并使用代币地址从流动性池列表中过滤池关键信息。

import { jsonInfo2PoolKeys, LiquidityPoolJsonInfo, LiquidityPoolKeys } from "@raydium-io/raydium-sdk";
const RAY_SOL_LP_V4_POOL_KEY = '89ZKE4aoyfLBe2RuV6jM3JGNhaV18Nxh8eNtjRcndBip';
const RAYDIUM_LIQUIDITY_JSON = 'https://api.raydium.io/v2/sdk/liquidity/mainnet.json';
const [raySolPoolKey, setRaySolPoolKey] = useState<LiquidityPoolKeys>();
// ...
const getPoolInfo = async () => {
// fetch the liquidity pool list
  const liquidityJsonResp = await fetch(RAYDIUM_LIQUIDITY_JSON);
if (!(await liquidityJsonResp).ok) return []
const liquidityJson = await liquidityJsonResp.json();
const allPoolKeysJson = [...(liquidityJson?.official ?? []), ...(liquidityJson?.unOfficial ?? [])]
// find the liquidity pair 
  const poolKeysRaySolJson: LiquidityPoolJsonInfo = allPoolKeysJson.filter((item) => item.lpMint === RAY_SOL_LP_V4_POOL_KEY)?.[0] || null;
// convert the json info to pool key using jsonInfo2PoolKeys
  const raySolPk = jsonInfo2PoolKeys(poolKeysRaySolJson);
setRaySolPoolKey(raySolPk);
}

5、使用矿池密钥计算出金额

我们几乎获得了进行兑换交易所需的所有信息! 但首先,我们必须计算出最低金额。 参考calcAmountOut函数,我们使用Raydium SDK中的Liquidity.fetchInfo来获取流动性池的信息。 之后,我们使用 Liquidity.computeAmountOut 获取价格和最低金额。

如果想知道 PriceImpact 是什么意思,您可以查看这里

6、进行兑换交易并发送! 🚀

计算出金额后,我们可以使用 Liquidity.makeSwapTransaction 生成交易,然后使用 sendTransaction 要求用户签名并发送。

import { Liquidity } from "@raydium-io/raydium-sdk";
import { useConnection, useWallet } from '@solana/wallet-adapter-react';
import { calcAmountOut } from '../utils';
const { publicKey, sendTransaction } = useWallet();
const { connection } = useConnection();
// ...
const { amountIn, minAmountOut } = await calcAmountOut(connection, raySolPoolKey, inputNumber, swapInDirection);
const { transaction, signers } = await Liquidity.makeSwapTransaction({
  connection,
  poolKeys: raySolPoolKey,
  userKeys: {
    tokenAccounts,
    owner: publicKey,
  },
  amountIn,
  amountOut: minAmountOut,
  fixedSide: "in"
});
const txid = await sendTransaction(transaction, connection, { signers, skipPreflight: true });
console.log(`https://solscan.io/tx/${txid}`);

就这样。 你可以添加一些功能,例如切换代币和显示汇率,以使应用程序更加完整。


原文链接:How to Use Raydium SDK to Build a Swap

DefiPlot翻译整理,转载请标明出处

通过 NowPayments 打赏