Solana Swap Library for Solana Tracker Swap API
npm install @solsdk/swapper_sdk> Efficient, type-safe, and developer-friendly library for integrating Solana-based token swaps into your TypeScript/JavaScript projects.
@solsdk/swapper_sdk provides a unified, high-performance API for executing token swaps on the Solana blockchain. It supports multiple DEXs, advanced fee and tip configuration, Jito bundle integration, and robust error handling. The library is strictly typed, follows modern best practices, and is suitable for both backend and frontend (browser) environments.
---
- Unified Swap API for all major Solana DEXs
- Strict TypeScript Typings (no any, no type assertions)
- Jito Bundle Support for MEV protection
- Custom Fee & Tip Logic (add/deduct, custom wallets, percentage)
- Auto Priority Fee & Slippage calculation
- Percentage & Full-Balance Swaps
- Custom RPC Endpoints (Helius, Nextblock, etc.)
- WebSocket & Polling Confirmations
- Detailed Transaction Error Parsing
- Connection Keep-Alive for custom endpoints
- Resource Cleanup for long-running apps
---
``bash`
npm install @solsdk/swapper_sdkor
yarn add @solsdk/swapper_sdkor
pnpm add @solsdk/swapper_sdk
---
`typescript
import { Keypair } from "@solana/web3.js";
import bs58 from "bs58";
import { SolanaTracker } from "@solsdk/swapper_sdk";
const keypair = Keypair.fromSecretKey(
bs58.decode("YOUR_SECRET_KEY") // Your wallet's secret key
);
const solanaTracker = new SolanaTracker(
keypair,
"https://api.mainnet-beta.solana.com", // RPC endpoint
"YOUR_API_KEY", // API key for swap instructions (optional)
false // Debug mode (optional)
);
async function swap() {
// Get swap instructions
const swapResponse = await solanaTracker.getSwapInstructions(
"So11111111111111111111111111111111111111112", // From token (SOL)
"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R", // To token (RAY)
0.01, // Amount to swap (number, "auto", or "50%")
30, // Slippage (number or "auto")
keypair.publicKey.toBase58(), // Payer public key
"auto" // Priority fee (number or "auto")
);
// Perform the swap
try {
const txid = await solanaTracker.performSwap(swapResponse, {
sendOptions: { skipPreflight: true },
confirmationRetries: 30,
confirmationRetryTimeout: 500,
commitment: "processed",
useWebSocket: true,
});
console.log("Transaction ID:", txid);
console.log("Transaction URL:", https://solscan.io/tx/${txid});
} catch (error) {
console.error("Swap failed:", error.message);
}
}
swap();
`
---
`typescript`
new SolanaTracker(
keypair: Keypair,
rpc: string,
apiKey?: string,
debug?: boolean = false
)
Parameters:
- keypair: Solana wallet keypair (fee payer and signer)rpc
- : Solana RPC endpoint (HTTP/HTTPS or WebSocket)apiKey
- : Optional API key for swap instructions (empty string if not provided)debug
- : Enable debug logging (default: false)
---
`typescript`
getSwapInstructions(
from: string,
to: string,
fromAmount: number | string,
slippage: number | "auto",
payer: string,
priorityFee?: number | "auto",
forceLegacy?: boolean,
additionalOptions?: SwapOptions
): Promise
Parameters:
- from, to: Token mint addresses (base58 strings)fromAmount
- : Amount to swap (number, "auto" for full balance, or "50%" for percentage)slippage
- : Slippage percent (number) or "auto"payer
- : Payer public key (base58 string)priorityFee
- : Priority fee in SOL (number) or "auto"forceLegacy
- : Force legacy transaction format (default: false, uses v0)additionalOptions
- : Advanced swap configuration options
Returns: Promise resolving to SwapResponse containing transaction data and rate information
#### SwapOptions
`typescript
interface SwapOptions {
priorityFee?: number | "auto";
priorityFeeLevel?:
| "min"
| "low"
| "medium"
| "high"
| "veryHigh"
| "unsafeMax";
txVersion?: "v0" | "legacy";
fee?: FeeConfig;
customTip?: CustomTip;
feeType?: "add" | "deduct";
onlyDirectRoutes?: boolean;
}
interface FeeConfig {
wallet: string;
percentage: number;
}
interface CustomTip {
wallet: string;
amount: number; // in SOL
}
`
---
`typescript`
getRate(
from: string,
to: string,
amount: number | string | "auto",
slippage: number | "auto"
): Promise
Parameters:
- from, to: Token mint addresses (base58 strings)amount
- : Amount to check rate for (number, "auto", or percentage string)slippage
- : Slippage percent (number) or "auto"
Returns: Promise resolving to RateResponse with pricing information
---
`typescript`
performSwap(
swapResponse: SwapResponse,
options?: TransactionSenderAndConfirmationWaiterOptions & {
debug?: boolean;
useWebSocket?: boolean;
jito?: { enabled: boolean; tip: number };
}
): Promise
Parameters:
- swapResponse: Response from getSwapInstructions containing transaction dataoptions
- : Transaction execution and confirmation options
Returns: Promise resolving to transaction signature (string)
Executes the swap transaction with support for Jito bundles, WebSocket or polling confirmation, and custom send endpoints.
---
`typescript`
performSwapWithDetails(
swapResponse: SwapResponse,
options?: TransactionSenderAndConfirmationWaiterOptions & {
debug?: boolean;
useWebSocket?: boolean;
jito?: { enabled: boolean; tip: number };
}
): Promise<{ signature: string; error?: TransactionError }>
Parameters:
- swapResponse: Response from getSwapInstructions containing transaction dataoptions
- : Transaction execution and confirmation options
Returns: Promise resolving to object with signature and optional error details
Same as performSwap, but returns detailed error information if the transaction fails instead of throwing.
---
`typescript`
setCustomSendTransactionEndpoint(
endpoint: string | null,
headers?: Record
): Promise
Parameters:
- endpoint: Custom RPC endpoint URL for sending transactions (null to clear)headers
- : Optional custom headers to include with requests
Returns: Promise that resolves when endpoint is configured
Set a custom endpoint for sending transactions (e.g., Helius, Nextblock). Maintains a keep-alive connection for performance with automatic ping every 5 seconds.
---
`typescript`
getTransactionDetails(signature: string): Promise
Parameters:
- signature: Transaction signature to fetch details for
Returns: Promise resolving to parsed transaction details or null if not found
---
`typescript`
parseTransactionError(signature: string): Promise
Parameters:
- signature: Transaction signature to parse errors for
Returns: Promise resolving to structured error information or null if no error
---
#### setDebug
`typescript`
setDebug(enabled: boolean): void
Enable or disable debug logging.
#### updateRpcEndpoint
`typescript`
updateRpcEndpoint(rpc: string): void
Change the main RPC endpoint. Creates new connection with WebSocket support.
#### getCustomSendEndpoint
`typescript`
getCustomSendEndpoint(): string | null
Get the currently configured custom send endpoint.
#### setBaseUrl
`typescript`
setBaseUrl(url: string): Promise
Set the base URL for the swap API (default: https://swap-v2.solanatracker.io).
#### destroy
`typescript`
destroy(): void
Clean up resources including keep-alive intervals and connections. Call this when done using the instance.
---
- Swap full balance: Pass "auto" as fromAmount"50%"
- Swap percentage: Pass as fromAmount (any percentage like "25%", "75%")
- Specific amount: Pass a number representing the token amount
- Auto priority fee: Pass "auto" for priorityFeepriorityFeeLevel
- Priority fee levels: Use with values: "min", "low", "medium", "high", "veryHigh", "unsafeMax"
- Manual fee: Pass a number representing SOL amount
- Platform fees: Use fee: { wallet: "address", percentage: 0.25 } in SwapOptionscustomTip: { wallet: "address", amount: 0.001 }
- Custom tips: Use (amount in SOL)feeType: "add"
- Fee handling: Set (add on top) or "deduct" (deduct from amount)
- Jito bundles: Use jito: { enabled: true, tip: 0.0001 } in performSwap optionsonlyDirectRoutes: true
- Direct routes only: Set in SwapOptionstxVersion: "v0"
- Transaction version: Set (default) or "legacy"useWebSocket: true
- WebSocket confirmation: Set in performSwap options
`typescript
// Set custom send endpoint (e.g., Helius, Nextblock)
await solanaTracker.setCustomSendTransactionEndpoint(
"https://ams-sender.helius-rpc.com/fast",
{ Authorization: "Bearer YOUR_TOKEN" }
);
// Clear custom endpoint
await solanaTracker.setCustomSendTransactionEndpoint(null);
`
---
The library provides comprehensive error handling with typed error objects:
`typescript
// Method 1: Using try/catch with performSwap
try {
const txid = await solanaTracker.performSwap(swapResponse, options);
console.log("Success:", txid);
} catch (error) {
console.error("Swap failed:", error.message);
}
// Method 2: Using performSwapWithDetails for structured errors
const result = await solanaTracker.performSwapWithDetails(
swapResponse,
options
);
if (result.error) {
console.error("Error type:", result.error.type);
console.error("Error message:", result.error.message);
if (result.error.programId) {
console.error("Failed program:", result.error.programId);
}
} else {
console.log("Success:", result.signature);
}
// Method 3: Parse transaction errors manually
const error = await solanaTracker.parseTransactionError(signature);
if (error) {
console.error(${error.type}: ${error.message});`
}
- "InstructionError": Specific instruction failed"InsufficientFunds"
- : Not enough funds for transaction"AccountNotFound"
- : Required account not found"ProgramError"
- : Program execution error"Unknown"
- : Unrecognized error type
---
`typescript
interface SwapResponse {
txn: string; // Base64 encoded transaction
txVersion: string;
rate: RateResponse;
forceLegacy?: boolean;
type: "v0" | "legacy";
}
interface RateResponse {
amountIn: number;
amountOut: number;
minAmountOut: number;
currentPrice: number;
executionPrice: number;
priceImpact: number;
fee: number;
baseCurrency: { decimals: number; mint: string };
quoteCurrency: { decimals: number; mint: string };
platformFee: number;
platformFeeUI: number;
rawQuoteResponse: any;
}
interface TransactionError {
type:
| "InstructionError"
| "InsufficientFunds"
| "AccountNotFound"
| "ProgramError"
| "Unknown";
message: string;
instructionIndex?: number;
programId?: string;
rawError?: any;
}
`
`typescript`
interface TransactionSenderAndConfirmationWaiterOptions {
sendOptions?: SendOptions;
confirmationRetries?: number;
confirmationRetryTimeout?: number;
lastValidBlockHeightBuffer?: number;
resendInterval?: number;
confirmationCheckInterval?: number;
skipConfirmationCheck?: boolean;
commitment?: "processed" | "confirmed" | "finalized";
jito?: { enabled: boolean; tip: number };
}
---
`typescript
import { SolanaTracker } from "@solsdk/swapper_sdk";
import { Keypair } from "@solana/web3.js";
import bs58 from "bs58";
const solanaTracker = new SolanaTracker(
"YOUR_API_KEY",
"https://api.mainnet-beta.solana.com"
);
const ownerKeypair = Keypair.fromSecretKey(bs58.decode("YOUR_PRIVATE_KEY"));
// Get swap instructions
const swapResponse = await solanaTracker.getSwapInstructions(
"So11111111111111111111111111111111111111112", // SOL
"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R", // RAY
0.01, // 0.01 SOL
30, // 30% slippage
ownerKeypair.publicKey.toString(),
0.0001 // Priority fee
);
// Perform the swap
const txid = await solanaTracker.performSwap(swapResponse, {
sendOptions: { skipPreflight: false },
confirmationRetries: 30,
confirmationRetryTimeout: 1000,
lastValidBlockHeightBuffer: 150,
commitment: "confirmed",
resendInterval: 1000,
confirmationCheckInterval: 1000,
});
console.log("Transaction:", https://solscan.io/tx/${txid});`
`typescript`
// Swap 50% of SOL balance with auto priority fee
const swapResponse = await solanaTracker.getSwapInstructions(
"So11111111111111111111111111111111111111112",
"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R",
"50%", // 50% of balance
"auto", // Auto slippage
ownerKeypair.publicKey.toString(),
"auto" // Auto priority fee
);
`typescript`
// Swap entire SOL balance using v0 transaction
const swapResponse = await solanaTracker.getSwapInstructions(
"So11111111111111111111111111111111111111112",
"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R",
"auto", // Full balance
30,
ownerKeypair.publicKey.toString(),
0.0001,
{
txVersion: "v0",
onlyDirectRoutes: false,
}
);
`typescript`
const swapResponse = await solanaTracker.getSwapInstructions(
"So11111111111111111111111111111111111111112",
"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R",
0.01,
30,
ownerKeypair.publicKey.toString(),
0.0001,
{
fee: {
wallet: "YOUR_FEE_WALLET_ADDRESS",
percentage: 0.25, // 0.25% platform fee
},
customTip: {
wallet: "YOUR_TIP_WALLET_ADDRESS",
amount: 0.001, // 0.001 SOL tip
},
feeType: "add", // Add fee on top of swap amount
}
);
`typescript`
const txid = await solanaTracker.performSwap(swapResponse, {
sendOptions: { skipPreflight: false },
confirmationRetries: 30,
jito: {
enabled: true,
tip: 0.0001, // 0.0001 SOL tip to Jito
},
});
`typescript`
const txid = await solanaTracker.performSwap(swapResponse, {
useWebSocket: true,
confirmationRetries: 30,
commitment: "confirmed",
});
`typescript
// Set Helius fast endpoint
await solanaTracker.setCustomSendTransactionEndpoint(
"https://ams-sender.helius-rpc.com/fast",
{ Authorization: "Bearer YOUR_HELIUS_TOKEN" }
);
// Set Nextblock endpoint
await solanaTracker.setCustomSendTransactionEndpoint(
"https://api.nextblock.dev/rpc",
{ "x-api-key": "YOUR_NEXTBLOCK_API_KEY" }
);
// Clear custom endpoint (use default RPC)
await solanaTracker.setCustomSendTransactionEndpoint(null);
`
`typescript
const result = await solanaTracker.performSwapWithDetails(swapResponse, {
sendOptions: { skipPreflight: false },
confirmationRetries: 30,
});
if (result.error) {
switch (result.error.type) {
case "InsufficientFunds":
console.error("Not enough funds for this swap");
break;
case "InstructionError":
console.error(
Instruction ${result.error.instructionIndex} failed:,Program ${result.error.programId} error:
result.error.message
);
break;
case "ProgramError":
console.error(
,https://solscan.io/tx/${result.signature}
result.error.message
);
break;
default:
console.error("Unknown error:", result.error.message);
}
} else {
console.log("Swap successful:", result.signature);
console.log("View transaction:", );`
}
`typescript`
// Always clean up resources when done
solanaTracker.destroy();
---
- 100% strict TypeScript typings
- No usage of any` or type assertions in public API
- All public interfaces and types are exported
- Full IntelliSense support in modern IDEs
- Comprehensive JSDoc documentation
---
MIT
---
Pull requests and issues are welcome.