Solana Raydium SDK Swap Example in TypeScript with Magic SDK
TL;DR
- Use Raydium SDK's
Liquidity.makeSwapInstructionSimple()to build swap instructions - Sign transactions with Magic SDK for wallet-as-a-service integration
- Add priority fees with
ComputeBudgetProgramfor faster transaction processing
Requirements: Node.js, @solana/web3.js, @raydium-io/raydium-sdk, @magic-sdk/admin
npm install @solana/web3.js @raydium-io/raydium-sdk @magic-sdk/adminIn this tutorial, we'll demonstrate how to perform a token swap on Solana using the Raydium SDK in TypeScript. Additionally, we'll show how to use the Magic SDK for signing transactions. We'll also include a method to convert SOL to lamports using Solana's web3.js library.
Step 2: Import Necessary Modules
import {
Connection,
PublicKey,
SystemProgram,
TransactionInstruction,
LAMPORTS_PER_SOL,
ComputeBudgetProgram,
VersionedTransaction,
TransactionMessage,
} from "@solana/web3.js";
import { Liquidity } from "@raydium-io/raydium-sdk";
import { Magic } from "@magic-sdk/admin";Step 3: Setup Magic SDK and Solana Connection
Initialize the Magic SDK and Solana connection:
const magic = new Magic("YOUR_MAGIC_API_KEY", {
extensions: [
new SolanaExtension({
rpcUrl: "YOUR RPC URL",
}),
],
});
const connection = new Connection("YOUR RPC URL");
const wallet = magic.wallet;Step 4: Helper Functions
Add Priority Instructions (Optional)
You can omit this part if the makeSwapInstructionSimple already has a builtin setup for priority instructions.
function addPriorityInstructions(
instructions: TransactionInstruction[]
): TransactionInstruction[] {
const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({
units: 1000000,
});
const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 1000,
});
instructions.unshift(modifyComputeUnits, addPriorityFee);
return instructions;
}Create Fee Transfer Instruction (Optional)
If you want to have a fee usage mechanism you can add the instruction that is returned in this function.
async function createFeeTransferInstruction(
amount: number,
feeWallet: PublicKey,
userWallet: PublicKey
): Promise<TransactionInstruction> {
const feeAmount = Math.ceil(amount * 0.0005);
const feeAmountInLamports = feeAmount * LAMPORTS_PER_SOL;
return SystemProgram.transfer({
fromPubkey: userWallet,
toPubkey: feeWallet,
lamports: feeAmountInLamports,
});
}Step 5: Perform Swap Transaction
Integrate the helper functions to perform the swap:
async function performSwap(
amountIn: number,
minAmountOut: number,
poolKeys: any,
userTokenAccounts: any,
feeWallet: PublicKey,
fixedSide: any
) {
const swapTransaction = await Liquidity.makeSwapInstructionSimple({
connection,
poolKeys,
userKeys: {
tokenAccounts: userTokenAccounts,
owner: wallet.publicKey,
},
amountIn,
amountOut: minAmountOut,
fixedSide,
});
const recentBlockhash = await connection.getLatestBlockhash();
let instructions =
swapTransaction.innerTransactions[0].instructions.filter(Boolean);
const feeTransferInstruction = await createFeeTransferInstruction(
amountIn,
feeWallet,
wallet.publicKey
);
instructions.push(feeTransferInstruction);
instructions = addPriorityInstructions(instructions);
const versionedTransaction = new VersionedTransaction(
new TransactionMessage({
payerKey: wallet.publicKey,
recentBlockhash: recentBlockhash.blockhash,
instructions: instructions,
}).compileToV0Message()
);
const signedTransaction =
await magic.wallet.signTransaction(versionedTransaction);
return signedTransaction;
}Step 6: Example Usage
Call the performSwap function with the necessary parameters:
(async () => {
const amountInSOL = 1;
const amountInLamports = amountInSOL * LAMPORTS_PER_SOL;
const minAmountOut = 500000;
const poolKeys = {}; // Replace with actual pool keys
const userTokenAccounts = {}; // Replace with actual user token accounts
const feeWallet = new PublicKey("YOUR_FEE_WALLET_ADDRESS");
const fixedSide = {}; // Replace with actual fixed side information
try {
const signedTransaction = await performSwap(
amountInLamports,
minAmountOut,
poolKeys,
userTokenAccounts,
feeWallet,
fixedSide
);
console.log("Signed Transaction:", signedTransaction);
const signature = await connection.sendRawTransaction(
Buffer.from(swapTransaction.rawTransaction as string, "base64")
);
const recentBlockhashForSwap =
await connection.getLatestBlockhash("finalized");
const confirmation = await connection.confirmTransaction(
{
signature,
...recentBlockhashForSwap,
},
"confirmed"
);
if (confirmation.value.err) {
console.error("Error buying token:", confirmation.value.err);
}
console.log("Confirmed! Transaction ID:", `https://solscan.io/tx/${signature}`);
} catch (error) {
console.error("Error performing swap:", error);
}
})();Conclusion
In this guide, we've shown how to perform a token swap using the Raydium SDK with the Magic SDK for transaction signing in TypeScript. We also included how to convert SOL to lamports and add a priority fee to your transactions. This approach ensures that your swaps are processed efficiently while also including a usage fee.