Raydium program library: your go-to tool for De-Fi use cases
Welcome to Week 5 of the Neon Dev Bootcamp!
This week, we're diving into Solana’s Raydium protocol and learning how to interact with it directly from your Solidity contracts using Neon EVM’s composability libraries. If you’re familiar with Uniswap on Ethereum, you’ll find some conceptual similarities but also important architectural differences that you’ll learn to navigate.
Raydium vs. Uniswap: Key Differences
Both offer:
- AMMs (Automated Market Makers)
- Swap logic with slippage control
- Liquidity management & pool creation
- LP token issuance and fee collection
Raydium’s native Solana logic can be triggered directly from Solidity using the Raydium composability library.
Here’s what you can do:
- Create CPMM (concentrated liquidity) pools
- Add/remove liquidity
- Lock LP positions as NFTs
- Collect swap fees
- Trigger swaps
Let’s break down how to call these Raydium program instructions from Solidity.
Library Instructions Overview
Here are the 7 main methods in the library:
1️⃣ Create Pool
To create a pool:
- Select Token A and Token B
- Mint initial liquidity tokens
- Define a pool start time
- Define premade ATAs to optimize execution
function createPoolInstruction(
bytes32 tokenA,
bytes32 tokenB,
uint64 mintAAmount,
uint64 mintBAmount,
uint64 startTime,
uint16 configIndex,
bool returnData,
bytes32[] memory premadeAccounts
Pool ID is returned from index 3 of the resulting accounts array. Then you can use the getCpmmPdaPoolId()
method in the LibRaydiumData
library to get the pool ID.
We’re using premade accounts to optimize to optimize performance. Specifically, we need associated token accounts (ATAs) to transfer tokens from the user. The Raydium program also requires these same ATAs. To avoid recalculating them and paying for additional external calls, the library includes an array of precomputed Solana accounts.
2️⃣ Add Liquidity
This lets any user provide liquidity to an existing pool.
Parameters:
- Pool ID
- Amounts of Token A and B
- Base token for LP calculation
- Slippage (recommended: 1–5%)
function addLiquidityInstruction(
bytes32 poolId,
uint64 inputAmount,
bool baseIn,
uint16 slippage,
bool returnData,
bytes32[] memory premadeAccounts
3️⃣ Withdraw Liquidity
When withdrawing liquidity:
- Always specify arbitrary token accounts (msg.sender) so the tokens go directly to the user - and not to the contract (they won’t be lost if they go the contract but it adds an extra step)
- Use
returnData = true
for success
function withdrawLiquidityInstruction(
bytes32 poolId,
uint64 lpAmount,
uint16 slippage,
bool returnData,
bytes32[] memory premadeAccounts
4️⃣ Lock Liquidity
This converts LP tokens into an NFT position. You can add metadata for resale.
function lockLiquidityInstruction(
bytes32 poolId,
uint64 lpAmount,
bool withMetadata,
bytes32 salt,
bool returnData,
bytes32[] memory premadeAccounts
5️⃣ Collect Fees
Can only be called after there’s been some traffic inside the pool, such as swaps.
function collectFeesInstruction(
bytes32 poolId,
uint64 lpFeeAmount,
bytes32 salt,
bool returnData,
bytes32[] memory premadeAccounts
6️⃣ Swap Input / Output
Use swapInputInstruction
for fixed input, swapOutputInstruction
for fixed output:
function buildSwapInputData(uint64 amountIn, uint64 amounOutMin) internal pure returns (bytes memory) {
require(amountIn > 0, LibRaydiumErrors.InsufficientInputAmount());
return abi.encodePacked(
hex"8fbe5adac41e33de", // swapBaseInput: [143, 190, 90, 218, 196, 30, 51, 222]
amountIn.readLittleEndianUnsigned64(),
amounOutMin.readLittleEndianUnsigned64()
);
or
function swapOutputInstruction(
bytes32 poolId,
bytes32 inputToken,
uint64 amountOut,
uint16 slippage,
bool returnData,
bytes32[] memory premadeAccounts
Both internally map to the same swap logic.
Practice Exercise
Your task this week is not just to follow along — but to come up with your own use case for the Raydium composability library. It’ll most likely be a DeFi use case, but feel free to get creative.
Here’s how to approach it based on your experience level:
Beginners
- Run the test script to see how a Raydium pool is created and used
- Then, think of a potential DeFi use case for this functionality
- In your
README.md
, describe your idea clearly — what the dApp would do and how it would use the Raydium instructions
You don’t need to write custom logic yet — just show that you understand what’s possible.
Advanced
- Come up with a DeFi use case that leverages one or more Raydium instructions
- Write your own smart contract(s) implementing this idea
- If you have time, feel free to add a simple UI — but this is optional
- You can showcase your work by:
- Writing and running test scripts
- Including deployment links
- Explaining your logic and user flow clearly in the
README.md
Resources