Skip to content

Commit 3208905

Browse files
committed
Improve README and add comments
1 parent eabf5c5 commit 3208905

File tree

3 files changed

+118
-16
lines changed

3 files changed

+118
-16
lines changed

README.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
1+
<img width="1200" alt="Labs" src="https://user-images.githubusercontent.com/99700157/213291931-5a822628-5b8a-4768-980d-65f324985d32.png">
2+
3+
<p>
4+
<h3 align="center">Chainstack is the leading suite of services connecting developers with Web3 infrastructure</h3>
5+
</p>
6+
7+
<p align="center">
8+
<a target="_blank" href="https://chainstack.com/build-better-with-ethereum/"><img src="https://github.com/soos3d/blockchain-badges/blob/main/protocols_badges/Ethereum.svg" /></a>&nbsp;
9+
<a target="_blank" href="https://chainstack.com/build-better-with-bnb-smart-chain/"><img src="https://github.com/soos3d/blockchain-badges/blob/main/protocols_badges/BNB.svg" /></a>&nbsp;
10+
<a target="_blank" href="https://chainstack.com/build-better-with-polygon/"><img src="https://github.com/soos3d/blockchain-badges/blob/main/protocols_badges/Polygon.svg" /></a>&nbsp;
11+
<a target="_blank" href="https://chainstack.com/build-better-with-avalanche/"><img src="https://github.com/soos3d/blockchain-badges/blob/main/protocols_badges/Avalanche.svg" /></a>&nbsp;
12+
<a target="_blank" href="https://chainstack.com/build-better-with-solana/"><img src="https://github.com/soos3d/blockchain-badges/blob/main/protocols_badges/Solana.svg" /></a>&nbsp;
13+
</p>
14+
15+
<p align="center">
16+
<a target="_blank" href="https://chainstack.com/protocols/">Supported protocols</a> •
17+
<a target="_blank" href="https://chainstack.com/blog/">Chainstack blog</a> •
18+
<a target="_blank" href="https://docs.chainstack.com/quickstart/">Chainstack docs</a> •
19+
<a target="_blank" href="https://docs.chainstack.com/quickstart/">Blockchain API reference</a> •
20+
<a target="_blank" href="https://console.chainstack.com/user/account/create">Start for free</a>
21+
</p>
22+
123
# Raydium SDK Swap Example
224

3-
This project demonstrates how to perform a token swap on the Solana blockchain using Raydium's protocol. The example specifically illustrates swapping SOL (native Solana token) for USDC (a stablecoin).
25+
This project demonstrates how to perform a token swap on the Solana blockchain using Raydium and Chainstack. The example specifically illustrates swapping SOL (native Solana token) for USDC (a stablecoin).
26+
27+
> Find the full guide on the Chainstack Developer Portal.
428
529
## Features
630

@@ -13,10 +37,19 @@ This project demonstrates how to perform a token swap on the Solana blockchain u
1337

1438
Before you begin, ensure you have met the following requirements:
1539

16-
- Node.js installed (v14 or above recommended)
40+
- Node.js installed (v18 or above recommended)
41+
- Yarn
1742
- A Solana wallet with some SOL for testing the swap
1843
- An environment file (.env) with your RPC URL and WALLET_PRIVATE_KEY
1944

45+
## Chainstack Solana node
46+
47+
Deploy a Solana node on Chainstack; the following steps will guide you:
48+
49+
1. [Sign up with Chainstack](https://console.chainstack.com/user/account/create).
50+
2. [Deploy a node](https://docs.chainstack.com/docs/manage-your-networks#join-a-public-network).
51+
3. [View node access and credentials](https://docs.chainstack.com/docs/manage-your-node#view-node-access-and-credentials).
52+
2053
## Environment variables
2154

2255
Add your RPC endoint and private key to a `.env` file:

src/RaydiumSwap.ts

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,45 @@ import bs58 from 'bs58'
1616
import 'dotenv/config';
1717
import { swapConfig } from './swapConfig'; // Import the configuration
1818

19-
19+
/**
20+
* Class representing a Raydium Swap operation.
21+
*/
2022
class RaydiumSwap {
2123
allPoolKeysJson: LiquidityPoolJsonInfo[]
2224
connection: Connection
2325
wallet: Wallet
2426

27+
/**
28+
* Create a RaydiumSwap instance.
29+
* @param {string} RPC_URL - The RPC URL for connecting to the Solana blockchain.
30+
* @param {string} WALLET_PRIVATE_KEY - The private key of the wallet in base58 format.
31+
*/
2532
constructor(RPC_URL: string, WALLET_PRIVATE_KEY: string) {
2633
this.connection = new Connection(process.env.RPC_URL
2734
, { commitment: 'confirmed' })
28-
this.wallet = new Wallet(Keypair.fromSecretKey(Uint8Array.from(bs58.decode(process.env.WALLET_PRIVATE_KEY))))//base58.decode(WALLET_PRIVATE_KEY)))
35+
this.wallet = new Wallet(Keypair.fromSecretKey(Uint8Array.from(bs58.decode(process.env.WALLET_PRIVATE_KEY))))
2936
}
3037

38+
/**
39+
* Loads all the pool keys available from a JSON configuration file.
40+
* @async
41+
* @returns {Promise<void>}
42+
*/
3143
async loadPoolKeys() {
32-
const liquidityJsonResp = await fetch(swapConfig.liquidityFile); //https://pastebin.com/raw/CHPMmnDh
44+
const liquidityJsonResp = await fetch(swapConfig.liquidityFile);
3345
if (!liquidityJsonResp.ok) return []
3446
const liquidityJson = (await liquidityJsonResp.json()) as { official: any; unOfficial: any }
3547
const allPoolKeysJson = [...(liquidityJson?.official ?? []), ...(liquidityJson?.unOfficial ?? [])]
3648

3749
this.allPoolKeysJson = allPoolKeysJson
3850
}
3951

52+
/**
53+
* Finds pool information for the given token pair.
54+
* @param {string} mintA - The mint address of the first token.
55+
* @param {string} mintB - The mint address of the second token.
56+
* @returns {LiquidityPoolKeys | null} The liquidity pool keys if found, otherwise null.
57+
*/
4058
findPoolInfoForTokens(mintA: string, mintB: string) {
4159
const poolData = this.allPoolKeysJson.find(
4260
(i) => (i.baseMint === mintA && i.quoteMint === mintB) || (i.baseMint === mintB && i.quoteMint === mintA)
@@ -47,6 +65,11 @@ class RaydiumSwap {
4765
return jsonInfo2PoolKeys(poolData) as LiquidityPoolKeys
4866
}
4967

68+
/**
69+
* Retrieves token accounts owned by the wallet.
70+
* @async
71+
* @returns {Promise<TokenAccount[]>} An array of token accounts.
72+
*/
5073
async getOwnerTokenAccounts() {
5174
const walletTokenAccount = await this.connection.getTokenAccountsByOwner(this.wallet.publicKey, {
5275
programId: TOKEN_PROGRAM_ID,
@@ -59,6 +82,17 @@ class RaydiumSwap {
5982
}))
6083
}
6184

85+
/**
86+
* Builds a swap transaction.
87+
* @async
88+
* @param {string} toToken - The mint address of the token to receive.
89+
* @param {number} amount - The amount of the token to swap.
90+
* @param {LiquidityPoolKeys} poolKeys - The liquidity pool keys.
91+
* @param {number} [maxLamports=100000] - The maximum lamports to use for transaction fees.
92+
* @param {boolean} [useVersionedTransaction=true] - Whether to use a versioned transaction.
93+
* @param {'in' | 'out'} [fixedSide='in'] - The fixed side of the swap ('in' or 'out').
94+
* @returns {Promise<Transaction | VersionedTransaction>} The constructed swap transaction.
95+
*/
6296
async getSwapTransaction(
6397
toToken: string,
6498
// fromToken: string,
@@ -121,6 +155,12 @@ class RaydiumSwap {
121155
return legacyTransaction
122156
}
123157

158+
/**
159+
* Sends a legacy transaction.
160+
* @async
161+
* @param {Transaction} tx - The transaction to send.
162+
* @returns {Promise<string>} The transaction ID.
163+
*/
124164
async sendLegacyTransaction(tx: Transaction) {
125165
const txid = await this.connection.sendTransaction(tx, [this.wallet.payer], {
126166
skipPreflight: true,
@@ -130,6 +170,12 @@ class RaydiumSwap {
130170
return txid
131171
}
132172

173+
/**
174+
* Sends a versioned transaction.
175+
* @async
176+
* @param {VersionedTransaction} tx - The versioned transaction to send.
177+
* @returns {Promise<string>} The transaction ID.
178+
*/
133179
async sendVersionedTransaction(tx: VersionedTransaction) {
134180
const txid = await this.connection.sendTransaction(tx, {
135181
skipPreflight: true,
@@ -139,18 +185,35 @@ class RaydiumSwap {
139185
return txid
140186
}
141187

188+
/**
189+
* Simulates a versioned transaction.
190+
* @async
191+
* @param {VersionedTransaction} tx - The versioned transaction to simulate.
192+
* @returns {Promise<any>} The simulation result.
193+
*/
142194
async simulateLegacyTransaction(tx: Transaction) {
143195
const txid = await this.connection.simulateTransaction(tx, [this.wallet.payer])
144196

145197
return txid
146198
}
147199

200+
/**
201+
* Simulates a versioned transaction.
202+
* @async
203+
* @param {VersionedTransaction} tx - The versioned transaction to simulate.
204+
* @returns {Promise<any>} The simulation result.
205+
*/
148206
async simulateVersionedTransaction(tx: VersionedTransaction) {
149207
const txid = await this.connection.simulateTransaction(tx)
150208

151209
return txid
152210
}
153211

212+
/**
213+
* Gets a token account by owner and mint address.
214+
* @param {PublicKey} mint - The mint address of the token.
215+
* @returns {TokenAccount} The token account.
216+
*/
154217
getTokenAccountByOwnerAndMint(mint: PublicKey) {
155218
return {
156219
programId: TOKEN_PROGRAM_ID,
@@ -162,6 +225,14 @@ class RaydiumSwap {
162225
} as unknown as TokenAccount
163226
}
164227

228+
/**
229+
* Calculates the amount out for a swap.
230+
* @async
231+
* @param {LiquidityPoolKeys} poolKeys - The liquidity pool keys.
232+
* @param {number} rawAmountIn - The raw amount of the input token.
233+
* @param {boolean} swapInDirection - The direction of the swap (true for in, false for out).
234+
* @returns {Promise<Object>} The swap calculation result.
235+
*/
165236
async calcAmountOut(poolKeys: LiquidityPoolKeys, rawAmountIn: number, swapInDirection: boolean) {
166237
const poolInfo = await Liquidity.fetchInfo({ connection: this.connection, poolKeys })
167238

src/swapConfig.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
export const swapConfig = {
2-
executeSwap: true, // Send tx when true, simulate tx when false
3-
useVersionedTransaction: true,
4-
tokenAAmount: 0.01, // Swap 0.01 SOL for USDT in this example
5-
tokenAAddress: 'So11111111111111111111111111111111111111112', // Token to swap for the other, SOL in this case
6-
tokenBAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC address
7-
LPpoolAddress: '8HoQnePLqPj4M7PUDzfw8e3Ymdwgc7NLGnaTUapubyvu',
8-
maxLamports: 1000000, // Max lamports allowed for fees
9-
direction: 'in' as 'in' | 'out', // Swap direction: 'in' or 'out'
10-
liquidityFile: 'https://api.raydium.io/v2/sdk/liquidity/mainnet.json'
11-
};
12-
2+
executeSwap: false, // Send tx when true, simulate tx when false
3+
useVersionedTransaction: true,
4+
tokenAAmount: 0.01, // Swap 0.01 SOL for USDT in this example
5+
tokenAAddress: "So11111111111111111111111111111111111111112", // Token to swap for the other, SOL in this case
6+
tokenBAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC address
7+
maxLamports: 1000000, // Max lamports allowed for fees
8+
direction: "in" as "in" | "out", // Swap direction: 'in' or 'out'
9+
liquidityFile: "https://api.raydium.io/v2/sdk/liquidity/mainnet.json",
10+
};

0 commit comments

Comments
 (0)