DEX Parsers
Multi-chain transaction normalizers
Solana DEXes
96.3% AccuracyTested against 4,468 real transactions with 1,319 swaps extracted.
| DEX | Program ID | Volume | Status | File |
|---|---|---|---|---|
| Raydium AMM | 675kP...3YVRx |
66% | Active | raydium.ts |
| Jupiter v6 | JUP6L...8rGJi |
15% | Active | jupiter.ts |
| Pump.fun | 6Ezm6...aV1uV |
12% | Active | pumpfun.ts |
| Orca Whirlpool | whirL...qdvzp |
2% | Active | orca.ts |
| Meteora DLMM | LBUZd...Dndqe |
1% | Active | meteora.ts |
| Raydium CLMM | CAMMc...M7mqq |
<1% | Active | raydium.ts |
Base DEXes
EVMBase chain (EVM) support using viem for transaction parsing.
| DEX | Router | Status | File |
|---|---|---|---|
| Uniswap V3 | 0x2626...1e481 |
Active | uniswap-v3.ts |
| Uniswap V2 | 0x4752...f7526 |
Active | uniswap-v2.ts |
| Aerodrome | 0xcF77...74E43 |
Active | aerodrome.ts |
| SushiSwap | 0x6BDE...92cF8 |
Planned | sushiswap.ts |
| Curve | Multiple pools | Planned | curve.ts |
Hyperliquid
PerpetualsHyperliquid perpetual futures parsing via REST API.
| Data Type | API Endpoint | Status |
|---|---|---|
| User Fills | POST /info (type: userFills) |
Active |
| Positions | POST /info (type: clearinghouseState) |
Active |
| Funding History | POST /info (type: userFunding) |
Active |
| Liquidations | POST /info (type: userLiquidations) |
Active |
Parser Interface
All chain parsers implement the IChainParser interface:
interface IChainParser<TTransaction, TTrade> {
readonly chain: ChainId;
readonly marketType: 'spot' | 'perpetual';
// Fetch transactions for an address
fetchTransactions(address: string, options?: FetchOptions): Promise<TTransaction[]>;
// Parse raw transaction to trade(s)
parseTransaction(tx: TTransaction, address: string): TTrade[];
// Get address balance
getBalance(address: string, token?: string): Promise<bigint>;
// Validate address format
isValidAddress(address: string): boolean;
// Normalize address to canonical form
normalizeAddress(address: string): string;
}
Normalized Swap Output
interface NormalizedSwap {
signature: string;
timestamp: number;
chain: 'solana' | 'base' | 'hyperliquid';
venue: string;
tokenIn: {
mint: string;
amount: bigint;
decimals: number;
};
tokenOut: {
mint: string;
amount: bigint;
decimals: number;
};
fee?: {
amount: bigint;
mint: string;
recipient?: string;
};
bot?: {
name: string;
fee: bigint;
};
// MEV/Slippage detection
mevLossUsd?: number;
realisedSlippageBps?: number;
}
Bot Detection
Bot transactions are identified by fee recipients and source patterns:
Known Bot Patterns
const BOT_SOURCE_PATTERNS = {
'BONKBOT': 'bonkbot',
'TROJAN': 'trojan',
'PHOTON': 'photon',
'MAESTRO': 'maestro',
'BULLX': 'bullx',
'AXIOM': 'axiom',
'BANANA': 'banana',
'SOL_TRADING_BOT': 'sol_trading_bot',
};
MEV/Slippage Detection
The parser detects MEV attacks and calculates realized slippage:
- Sandwich detection - Identifies front-run + back-run patterns
- MEV loss calculation - USD value lost to MEV
- Slippage calculation - Actual vs expected execution price
- Severity classification - Low, Medium, High, Critical
Adding a New DEX
- Create a new file in
packages/parser/src/chains/{chain}/normalizers/ - Implement the normalizer interface for that chain
- Add to the normalizer registry in
index.ts - Add tests for common transaction patterns
- Update the venue enum in the database schema
File Structure
packages/parser/src/
├── chains/
│ ├── types.ts # IChainParser interface
│ ├── factory.ts # Parser factory
│ ├── solana/
│ │ ├── parser.ts
│ │ └── normalizers/
│ │ ├── jupiter.ts
│ │ ├── raydium.ts
│ │ ├── pumpfun.ts
│ │ ├── orca.ts
│ │ └── meteora.ts
│ ├── base/
│ │ ├── parser.ts
│ │ └── normalizers/
│ │ ├── uniswap-v2.ts
│ │ ├── uniswap-v3.ts
│ │ └── aerodrome.ts
│ └── hyperliquid/
│ ├── parser.ts
│ ├── client.ts
│ └── types.ts
├── cost-basis.ts
├── mev.ts
└── slippage.ts