A comprehensive tutorial for executing token swaps on Solana using Jupiter V6, incorporating advanced features like versioned transactions, priority fees, compute budget optimization, Address Lookup Tables (ALTs), and Jito bundles.
- Features
- Prerequisites
- Installation
- Usage
- Code Explanation
- Best Practices
- Contributing
- License
- 💖 Support the Developer
- Integration with Jupiter V6 for optimal swap routes
- Versioned transactions for improved efficiency
- Dynamic priority fees based on recent network conditions
- Compute budget optimization through transaction simulation
- Address Lookup Tables (ALTs) for reduced transaction size
- Jito bundles for MEV protection
- Comprehensive error handling and logging
- Node.js (v18 or later)
- npm (v6 or later)
- A Solana wallet with SOL for transaction fees
- 0.01 SOL in wallet for swap
-
Clone the repository:
git clone https://github.com/builderby/solana-swap-tutorial.git cd solana-swap-tutorial
-
Install dependencies:
npm install
-
Create a .env file in the project root and add your Solana RPC URL and wallet private key:
SOLANA_RPC_URL=https://your-rpc-url-here WALLET_PRIVATE_KEY=[your,private,keypair,array,here]
We have included an example .env file in the repository for your convenience.
Run the script with:
npm start
This will execute a sample swap of 0.01 SOL to USDC. Modify the main
function in index.js
to customize the swap parameters. Ensure you have the correct token addresses and amounts for your swap in the wallet for the swap to execute.
The index.js
file contains the following key components:
-
Setup and Imports: Essential libraries and modules are imported, and constants are defined for the Jupiter API and Jito RPC URL.
-
Helper Functions:
deserializeInstruction
: Converts raw instruction data into a structured format for processing.getAddressLookupTableAccounts
: Fetches and deserializes Address Lookup Table accounts to optimize transaction size.
-
Token Information Retrieval:
getTokenInfo
: Fetches token metadata, including decimals, to ensure accurate amount calculations.
-
Priority Fee Calculation:
getAveragePriorityFee
: Dynamically calculates the average priority fee based on recent network conditions, ensuring competitive transaction fees.
-
Jito Integration:
getTipAccounts
: Retrieves Jito tip accounts for MEV protection.createJitoBundle
: Bundles transactions for efficient execution and sends them to Jito.sendJitoBundle
: Sends the created Jito bundle to the network.
-
Transaction Simulation:
simulateTransaction
: Simulates the transaction to estimate compute units required, adding a buffer for safety.
-
Main Swap Function:
swap
: Orchestrates the entire swap process, including:- Fetching quotes from Jupiter V6
- Preparing swap instructions
- Simulating transactions for accurate compute units
- Fetching dynamic priority fees
- Creating versioned transactions with optimized parameters
- Applying compute budget and priority fees
- Bundling and sending transactions via Jito
-
Example Usage:
- The
main
function demonstrates how to initiate a swap operation, specifying input and output tokens, amount, and slippage.
- The
Address Lookup Tables are a feature in Solana that allows transactions to reference frequently used addresses stored on-chain. This reduces transaction size and cost, especially for complex operations like token swaps. Our tutorial demonstrates how to:
- Fetch ALT accounts associated with a swap
- Incorporate ALTs into versioned transactions
- Use ALTs to optimize transaction structure and reduce fees
To ensure accurate compute unit allocation, we simulate the transaction before sending it. This process:
- Constructs a transaction with all necessary instructions.
- Simulates the transaction using
connection.simulateTransaction()
. - Retrieves the actual compute units consumed.
- Adds a 20% buffer to the consumed units for safety.
This approach helps prevent transaction failures due to insufficient compute budget.
Instead of using a fixed priority fee, we now dynamically calculate it based on recent network conditions:
- Fetch recent prioritization fees using
connection.getRecentPrioritizationFees()
. - Calculate the average fee from the last 150 slots.
- Use this average as the priority fee for the transaction.
This ensures our transactions remain competitive even as network conditions change.
This tutorial implements several Solana development best practices:
- Versioned Transactions: Utilizes the latest transaction format for improved efficiency.
- Compute Budget Optimization: Uses transaction simulation to set appropriate compute units.
- Dynamic Priority Fees: Implements adaptive priority fees based on recent network activity.
- Address Lookup Tables: Leverages ALTs to reduce transaction size and cost.
- MEV Protection: Integrates with Jito for protection against MEV (Miner Extractable Value).
- Error Handling: Implements comprehensive error catching and logging for easier debugging.
- Modular Design: Separates concerns into distinct functions for better maintainability.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
If you found this tutorial helpful and would like to support the development of more resources like this, consider tipping! Your contributions help keep the project alive and thriving.
Solana Wallet Address: jaDpUj6FzoQFtA5hCcgDwqnCFqHFcZKDSz71ke9zHZA
ETH Wallet Address: 0x96aca495621E93c884A8cb054bB823Bc273C29Bb
Thank you for your support!
Happy swapping! If you have any questions or run into issues, please open an issue in the GitHub repository.