Solana Dex Transaction Parser
A TypeScript library for parsing Solana DEX swap transactions. Supports multiple DEX protocols including Jupiter, Raydium, Meteora, PumpFun, BoopFun and Moonit.
Future Development
If you find this project useful, consider donating at
SOL: 879mxY5QKJH1J8x8suzB3rrV2YPVsoauaSJ7nT85YLU7
to support future development. Thanks!
Contents
Features
✅ DexParser - Parse DEX transactions and extract Trade/Liquidity/Transfer data
✅ Multi-Protocol Support - Jupiter, Raydium, Orca, Meteora, Pumpfun, Moonit, etc.
✅ Type Safety - Strongly typed TypeScript interfaces
✅ High Performance - Optimized for large transaction volumes
✅ Rich Data Extraction - Trades, liquidity events, transfers, and fees
✅ Block Processing - Support for both getBlock and getParsedBlock
✅ Meme Parsing - MemeEvent parsers for Pumpfun/MeteoraDBC/Raydium Launchpad/Moonit .etc
✅ gRPC Support - Raw data processing capabilities
Supported Protocols
DEX Aggregators & Routers
Protocol | Trades | Liquidity | Transfers | Notes |
---|---|---|---|---|
Jupiter (All versions) | ✅ | ❌ | ✅ | Priority parsing, aggregated trades |
OKX DEX | ✅ | ❌ | ✅ | Route aggregator |
Major AMMs
Protocol | Trades | Liquidity | Transfers | Notes |
---|---|---|---|---|
PumpSwap | ✅ | ✅ | ✅ | Pumpfun AMM |
Raydium V4 | ✅ | ✅ | ✅ | Classic AMM |
Raydium CPMM | ✅ | ✅ | ✅ | Constant product |
Raydium CL | ✅ | ✅ | ✅ | Concentrated liquidity |
Orca Whirlpool | ✅ | ✅ | ✅ | CL pools |
Meteora DLMM | ✅ | ✅ | ✅ | Dynamic liquidity |
Meteora Pools | ✅ | ✅ | ✅ | Multi-token AMM |
Meteora DAMM V2 | ✅ | ✅ | ✅ | Dynamic AMM |
Sanctum | ✅ | ❌ | ✅ | LST swaps |
Phoenix | ✅ | ❌ | ✅ | Order book DEX |
Lifinity | ✅ | ❌ | ✅ | Proactive market maker |
Meme & Launch Platforms
Protocol | Trades | Create | Migrate | Notes |
---|---|---|---|---|
Pumpfun | ✅ | ✅ | ✅ | Bonding curve |
Raydium Launchpad | ✅ | ✅ | ✅ | Meme launcher |
Meteora DBC | ✅ | ✅ | ✅ | Meme launcher |
Moonit | ✅ | ✅ | ✅ | Meme launcher |
Heaven.xyz | ✅ | ✅ | ✅ | Meme launcher |
Sugar.money | ✅ | ✅ | ✅ | Meme launcher |
Bonk | ✅ | ✅ | ✅ | Meme launcher |
BoopFun | ✅ | ✅ | ✅ | Meme launcher |
Trading Bots
Bot | Trades | Notes |
---|---|---|
BananaGun | ✅ | MEV bot |
Maestro | ✅ | Trading bot |
Nova | ✅ | Sniper bot |
Bloom | ✅ | Copy trading |
Mintech | ✅ | Trading bot |
Apepro | ✅ | Trading bot |
Installation
yarn add solana-dex-parser
Quick Start
Configuration Options
The DexParser class supports the following configuration:
interface ParseConfig {
tryUnknowDEX?: boolean; // Try to parse unknown DEX programs,results may be inaccurate (default: true)
programIds?: string[]; // Only parse specific program IDs
ignoreProgramIds?: string[]; // Ignore specific program IDs
}
Parse All (Trades, Liquidity and Transfers)
Parse all types of transactions including DEX trades, liquidity operations, and token transfers.
import { Connection } from '@solana/web3.js';
import { DexParser } from 'solana-dex-parser';
async function parseAll() {
const connection = new Connection('https://api.mainnet-beta.solana.com');
const signature = 'your-transaction-signature';
const tx = await connection.getTransaction(signature, {
maxSupportedTransactionVersion: 0,
});
// Parse all types of transactions in one call
const parser = new DexParser();
const result = parser.parseAll(tx);
console.log({
trades: result.trades, // DEX trading activities
liquidities: result.liquidities, // Liquidity operations
transfers: result.transfers, // Regular token transfers (non-DEX)
state: result.state, // Parsing state
msg: result.msg, // Error message if any
});
}
Parse Result
/**
* Complete parsing result containing all extracted transaction data
*/
export interface ParseResult {
/** Parsing success status - true if parsing completed successfully */
state: boolean;
/** Transaction gas fee paid in SOL */
fee: TokenAmount;
/** Aggregated trade information combining multiple related trades */
aggregateTrade?: TradeInfo;
/** Array of individual trade transactions found in the transaction */
trades: TradeInfo[];
/** Array of liquidity operations (add/remove/create pool) */
liquidities: PoolEvent[];
/** Array of token transfer operations not related to trades */
transfers: TransferData[];
/** SOL balance change for the transaction signer */
solBalanceChange?: BalanceChange;
/** Token balance changes mapped by token mint address */
tokenBalanceChange?: Map<string, BalanceChange>;
/** Meme platform events (create/buy/sell/migrate/complete) */
memeEvents: MemeEvent[];
/** Solana slot number where the transaction was included */
slot: number;
/** Unix timestamp when the transaction was processed */
timestamp: number;
/** Unique transaction signature identifier */
signature: string;
/** Array of public keys that signed this transaction */
signer: string[];
/** Compute units consumed by the transaction execution */
computeUnits: number;
/** Final execution status of the transaction */
txStatus: TransactionStatus;
/** Optional error or status message */
msg?: string;
}
Examples
1. Basic Usage > Swap (Buy and Sell)
import { Connection } from '@solana/web3.js';
import { DexParser } from 'solana-dex-parser';
async function parseSwap() {
// Setup connection
const connection = new Connection('https://api.mainnet-beta.solana.com');
// Get transaction (supports both parsed and compiled transactions)
const signature = 'your-transaction-signature';
const tx = await connection.getTransaction(signature, {
maxSupportedTransactionVersion: 0,
});
// Or use getParsedTransaction
// const tx = await connection.getParsedTransaction(signature);
// Parse trades
const parser = new DexParser();
const trades = await parser.parseTrades(tx);
console.log("trades:", trades);
}
Trades Output
[
{
"type": "BUY",
"inputToken": {
"mint": "So11111111111111111111111111111111111111112",
"amount": 0.099009801,
"amountRaw": "99009801",
"decimals": 9,
"source": "5o5VW6zPTwTk2j9fkQJ7ueHL4rcEtzDhcGafsxE71AyB",
"destination": "8Wyi1ikEcLsHKA7daP1JmUrAyEc96jLn3tzLnuMwN5nH",
"destinationBalance": {
"amount": "24617904743",
"uiAmount": 24.617904743,
"decimals": 9
},
"destinationPreBalance": {
"amount": "24518894942",
"uiAmount": 24.518894942,
"decimals": 9
},
"sourceBalance": {
"amount": "266958890",
"uiAmount": 0.26695889,
"decimals": 9
},
"sourcePreBalance": {
"amount": "366963789",
"uiAmount": 0.366963789,
"decimals": 9
}
},
"outputToken": {
"mint": "B3Pza9YDAaTrMtxR5JeFFEGKSdJSyNLnj49nSYHDpump",
"amount": 1070376.821916,
"amountRaw": "1070376821916",
"decimals": 6,
"authority": "8Wyi1ikEcLsHKA7daP1JmUrAyEc96jLn3tzLnuMwN5nH",
"source": "E7v5iScw1vUupebaDd7grmjVrSgsgdhVpm4w2bbDxbPn",
"destination": "3QvZvTSWt4gS1Vyiz1zR3afJjETzaev9JKJ3J356Sk1b",
"destinationOwner": "5o5VW6zPTwTk2j9fkQJ7ueHL4rcEtzDhcGafsxE71AyB",
"destinationBalance": {
"amount": "1383049394757",
"decimals": 6,
"uiAmount": 1383049.394757,
"uiAmountString": "1383049.394757"
},
"destinationPreBalance": {
"amount": "312672572841",
"decimals": 6,
"uiAmount": 312672.572841,
"uiAmountString": "312672.572841"
},
"sourceBalance": {
"amount": "516380474293765",
"decimals": 6,
"uiAmount": 516380474.293765,
"uiAmountString": "516380474.293765"
},
"sourcePreBalance": {
"amount": "517450851115681",
"decimals": 6,
"uiAmount": 517450851.115681,
"uiAmountString": "517450851.115681"
}
},
"user": "5o5VW6zPTwTk2j9fkQJ7ueHL4rcEtzDhcGafsxE71AyB",
"programId": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P",
"amm": "Pumpfun",
"route": "OKX",
"slot": 324037348,
"timestamp": 1740898227,
"signature": "648cwSysqKXnb3XLPy577Lu4oBk7jimaY8p95JGfS9QUNabYar5pzfcRdu518TWw3dbopquJnMne9qx22xuf8xqn",
"idx": "7-5"
}
]
Block Transaction Parsing
import { Connection } from '@solana/web3.js';
import { DexParser } from 'solana-dex-parser';
// Works with both getBlock and getParsedBlock
async function parseBlockTransactions() {
const connection = new Connection('https://api.mainnet-beta.solana.com');
const slot = 'your-block-slot';
try {
const block = await connection.getBlock(slot, {
commitment: 'confirmed',
maxSupportedTransactionVersion: 0,
transactionDetails: 'full',
});
// Or use getParsedBlock
// const block = await connection.getParsedBlock(slot,{
// commitment: 'confirmed',
// maxSupportedTransactionVersion: 0,
// transactionDetails: 'full',
// });
const parser = new DexParser();
const trades = [];
const liquidityEvents = [];
for (const tx of block.transactions) {
if (tx.meta?.err) continue;
const txData = {
...tx!,
slot: block.parentSlot + 1,
blockTime: block.blockTime
};
trades.push(...parser.parseTrades(txData));
liquidityEvents.push(...parser.parseLiquidity(txData));
}
return { trades, liquidityEvents };
} catch (error) {
console.error('Failed to parse block:', error);
throw error;
}
}
2. Liquidity Events Parsing
import { Connection } from '@solana/web3.js';
import { DexParser } from 'solana-dex-parser';
async function parseLiquidityEvents() {
const connection = new Connection('https://api.mainnet-beta.solana.com');
const signature = 'your-transaction-signature';
// Works with both parsed and unparsed transactions
const tx = await connection.getTransaction(signature, {
maxSupportedTransactionVersion: 0,
});
const parser = new DexParser();
const events = await parser.parseLiquidity(tx);
console.log("events:", events);
}
2.1 Output - pumpfun events
[
{
type: 'CREATE',
data: {
name: 'Central African Republic Meme',
symbol: 'CAR',
uri: 'https://ipfs.io/ipfs/QmTWn4hHDQRPH1e9qtn3cYVoNr9UDUVT2e78XWDsPSXDmj',
mint: '7oBYdEhV4GkXC19ZfgAvXpJWp2Rn9pm1Bx2cVNxFpump',
bondingCurve: 'AoUhiHypP1mMzgRjV7FMHpbQTe6sMZ8PTWt4MBABNUky',
user: '121ftnYRm3WJmDHCWrazzRoyZAzZQ4xc5XD7dp3sfpfo'
},
slot: 319598427,
timestamp: 1739140071,
signature: '3EopoRXpPKHUwZcfGpV4yp7v5kTyQSdKHMB88oM7BqoUqaaCgst93oNLHTNiDg2XzW8j1KRfu2e6tVMxb3czAPMN',
idx: '2-14'
},
{
type: 'COMPLETE',
data: {
user: '121ftnYRm3WJmDHCWrazzRoyZAzZQ4xc5XD7dp3sfpfo',
mint: '7oBYdEhV4GkXC19ZfgAvXpJWp2Rn9pm1Bx2cVNxFpump',
bondingCurve: 'AoUhiHypP1mMzgRjV7FMHpbQTe6sMZ8PTWt4MBABNUky',
timestamp: 1739140071n
},
slot: 319598427,
timestamp: 1739140071,
signature: '3EopoRXpPKHUwZcfGpV4yp7v5kTyQSdKHMB88oM7BqoUqaaCgst93oNLHTNiDg2XzW8j1KRfu2e6tVMxb3czAPMN',
idx: '4-0'
},
{
type: 'TRADE',
data: {
mint: '7oBYdEhV4GkXC19ZfgAvXpJWp2Rn9pm1Bx2cVNxFpump',
solAmount: 85.005359057,
tokenAmount: 793100000,
isBuy: true,
user: '121ftnYRm3WJmDHCWrazzRoyZAzZQ4xc5XD7dp3sfpfo',
timestamp: 1739140071n,
virtualSolReserves: 115.005359057,
virtualTokenReserves: 279900000
},
slot: 319598427,
timestamp: 1739140071,
signature: '3EopoRXpPKHUwZcfGpV4yp7v5kTyQSdKHMB88oM7BqoUqaaCgst93oNLHTNiDg2XzW8j1KRfu2e6tVMxb3czAPMN',
idx: '4-4'
}
]
2.2 Output - Meteora
[
{
user: 'KYaNZJsLWbgdc22JqM3x6FLBTz5JVZiwNdByFPoPHLL',
type: 'REMOVE',
programId: 'LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo',
amm: 'MeteoraDLMM',
slot: 322956851,
timestamp: 1740470617,
signature: 'Cj2c5dEmHvmMWwkMa4QMauQE6aBbyRz5mn4fEYARez2bHqukkJ3nbYAdst9ixQsAMh9G9tUNntAxEXpgrz5T1Qi',
idx: '6',
poolId: 'BoeMUkCLHchTD31HdXsbDExuZZfcUppSLpYtV3LZTH6U',
poolLpMint: 'BoeMUkCLHchTD31HdXsbDExuZZfcUppSLpYtV3LZTH6U',
token0Mint: 'J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn',
token1Mint: 'So11111111111111111111111111111111111111112',
token0Amount: 18.504862033,
token1Amount: 6.074752463
}
]
3. More Use Cases
3.1 Extracting Pumpfun events (create/trade/complete):
import { PumpfunEventParser,TransactionAdapter } from 'solana-dex-parser';
// Setup connection
const connection = new Connection('https://api.mainnet-beta.solana.com');
// Get transaction
const signature = 'your-transaction-signature';
const tx = await connection.getParsedTransaction(signature, {
maxSupportedTransactionVersion: 0,
});
const eventParser = new PumpfunEventParser(new TransactionAdapter(tx));
const events = eventParser.processEvents(); // PumpfunEvent[]
console.log(events);
export interface PumpfunEvent {
type: "TRADE" | "CREATE" | "COMPLETE";
data: PumpfunTradeEvent | PumpfunCreateEvent | PumpfunCompleteEvent;
slot: number;
timestamp: number;
signature: string;
}
3.2 Raydium v4 logs decode:
import { decodeRaydiumLog, LogType, parseRaydiumSwapLog } from 'solana-dex-parser';
const log = decodeRaydiumLog("ray_log: A0lQ1uGPAAAAWnKACwAAAAABAAAAAAAAACRBWYc/AgAANLV+oBcAAACInZmY0pIAAO8MAhcAAAAA");
if (log) {
if (log.logType == LogType.SwapBaseIn || log.logType == LogType.SwapBaseOut) {
const swap = parseRaydiumSwapLog(log as any);
console.log('swap', swap); // buy and sell
}
else {
console.log('log', log); // add/remove liquidity
}
}
// output
swap {
type: 'Buy',
mode: 'Exact Input',
inputAmount: 617969242185n,
outputAmount: 386010351n,
slippageProtection: 192967258n
}
3.3 Raydium Launchpad events:
import { RaydiumLCPEvent,TransactionAdapter } from 'solana-dex-parser';
// Setup connection
const connection = new Connection('https://api.mainnet-beta.solana.com');
// Get transaction
const signature = 'your-transaction-signature';
const tx = await connection.getParsedTransaction(signature, {
maxSupportedTransactionVersion: 0,
});
const parser = new RaydiumLaunchpadEventParser(new TransactionAdapter(tx));
const events = parser.processEvents(); // RaydiumLCPEvent[]
console.log(events);
Launchpad Outputs
// Output (RaydiumLCPCreateEvent, RaydiumLCPTradeEvent,RaydiumLCPCompleteEvent)
// CREATE -> PoolCreateEvent (Initialize)
{
type: 'CREATE',
data: {
poolState: 'CPTNvVYT7qCzX3HnRRtSRAFpMipVgSP3eynXrW9p9YgD',
creator: 'J88snVaNTCW7T6saPvAmYDmjnhPiSpkw8uJ8FFCyfcGA',
config: '6s1xP3hpbAfFoNtUNF8mfHsjr2Bd97JxFJRWLbL6aHuX',
baseMintParam: [Object],
curveParam: [Object],
vestingParam: [Object],
baseMint: '25phz2ZHEfB81RQXKvNLvkDbK32nyUwFnQdqk6MLcook',
quoteMint: 'So11111111111111111111111111111111111111112'
},
slot: 334260517,
timestamp: 1744972806,
signature: '4x8k2aQKevA8yuCVX1V8EaH2GBqdbZ1dgYxwtkwZJ7SmCQeng7CCs17AvyjFv6nMoUkBgpBwLHAABdCxGHbAWxo4',
idx: '0-7'
},
// TRADE -> TradeEvent (buy/sell)
{
type: 'TRADE',
data: {
poolState: 'GeSSWHbFkeYknLX3edkTP3JcsjHRnCJG3SymEkBzaFDo',
totalBaseSell: <BN: 2d79883d20000>,
virtualBase: <BN: 3ca20afc2aaaa>,
virtualQuote: <BN: 698cc5b55>,
realBaseBefore: <BN: 223b2a6f528bb>,
realQuoteBefore: <BN: 88d98e8cb>,
realBaseAfter: <BN: 22404db66ad1b>,
amountIn: <BN: 2faf080>,
amountOut: <BN: 5234718460>,
protocolFee: <BN: 1e848>,
platformFee: <BN: 5b8d8>,
shareFee: <BN: 0>,
tradeDirection: 0,
poolStatus: 0,
baseMint: 'Dph84TcDoGzCv43eZzxdDe9Dn7f2eFU4kbJFm3tHEray',
quoteMint: 'So11111111111111111111111111111111111111112',
user: 'A8BNMXfxCkjuEJ83piEBKdDydk1RVeDQ7jYoUFCTSWuv'
},
slot: 334244130,
timestamp: 1744966356,
signature: 'Gi44zBwsd8eUGEVPS1jstts457hKLbm8SSMLrRVHVK2McrhJjosiszb65U1LdrjsF1WfCXoesLMhm8RX3dchx4s',
idx: '4-0'
},
// COMPLETE -> Migrate to AMM / CPSwap
{
type: 'COMPLETE',
data: {
baseMint: 'Em8DYuvdQ28PNZqSiAvUxjG32XbpFPm9kwu2y5pdTray',
quoteMint: 'So11111111111111111111111111111111111111112',
poolMint: '9N82SeWs9cFrThpNyU8dngUjRHe9vzVjDnQrgQ115tEy',
lpMint: '5Jg51sVNevcDeuzoHcfJFGMcYszuWSqSsZuDjiakXuXq',
amm: 'RaydiumCPMM'
},
slot: 334174234,
timestamp: 1744938781,
signature: '2gWHLTb1utduUkZCTo9GZpcCZr7hVPXTJajdoVjMURgVG6eJdKJQY6jF954XN15sSmDvsPCmMD7XSRyofLrQWuFv',
idx: '2-0'
}
Note
- Jupiter Swap outputs aggregated transaction records
- Other aggregators (e.g., OKX) output multiple swap transaction records per AMM
- Most swap records are parsed from transfer actions except for Jupiter, Pumpfun, and Moonit
- Orca Liquidity analysis: OrcaV1 and OrcaV2 support is limited
Development
Prerequisites
- Node.js >= 18.8.0
- yarn
Setup
Clone the repository
git clone https://github.com/cxcx-ai/solana-dex-parser.git cd solana-dex-parser
Install dependencies
yarn install
Build the project
yarn build
Testing
Run the test suite:
yarn test
Run unit tests:
yarn test parser.test.ts
yarn test liquidity-raydium.test.ts
......
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Solana Foundation - Blockchain infrastructure and documentation
- DEX Protocol Teams - Jupiter, Raydium, Orca, Meteora, and others for public APIs
- TypeScript Community - Excellent tooling and libraries
- Contributors - Community members improving the library
- Original Go Implementation - solanaswap-go for inspiration
Built with ❤️ for the Solana ecosystem