Solana Raydium SDK Swap Example Typescript with Magic SDK
Tags: web3, solana, magicsdk, raydiumsdk
Published: 2024-06-05 06:03:11

### Solana Raydium SDK Swap Example in TypeScript with Magic SDK

In 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.

## Prerequisites

Ensure you have the following installed:

- Node.js and npm
- Magic SDK
- Solana web3.js
- Raydium SDK

## Step 1: Install Required Libraries

First, install the necessary libraries:

```bash
npm install @solana/web3.js @raydium-io/raydium-sdk @magic-sdk/admin
```

## Step 2: Import Necessary Modules

```typescript
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:

```typescript
const magic = new Magic('YOUR_MAGIC_API_KEY', { // Replace with your Magic API key
  extensions: [
   new SolanaExtension({
     rpcUrl: 'YOUR RPC URL', // Replace with your RPC URL
   })
  ],
}); 
const connection = new Connection('YOUR RPC URL'); // Replace with your RPC URL
const wallet = magic.wallet; // Magic wallet instance
```

## Step 4: Helper Functions

#### Add Priority Instructions (Optional)

You can omit this part if the `makeSwapInstructionSimple` already has a builtin setup for priority instructions.

```typescript
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.

```typescript
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:

```typescript
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:

```typescript
(async () => {
  const amountInSOL = 1; // Example amount in SOL
  const amountInLamports = amountInSol * LAMPORTS_PER_SOL;
  const minAmountOut = 500000; // Example minimum amount out
  const poolKeys = {}; // Replace with actual pool keys
  const userTokenAccounts = {}; // Replace with actual user token accounts
  const feeWallet = new PublicKey('YOUR_FEE_WALLET_ADDRESS'); // Replace with 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: s,
      ...recentBlockhashForSwap,
    }, 'confirmed')
    if (confirmation.value.err) {
      console.error('Error buying token:', confirmation.value.err);
    }
    console.log('Confirmed! Transaction ID:', `https://solscan.io/tx/${s}`);
     

  } 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.