Solana DEXes

96.3% Accuracy

Tested 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

EVM

Base 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

Perpetuals

Hyperliquid 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:

Adding a New DEX

  1. Create a new file in packages/parser/src/chains/{chain}/normalizers/
  2. Implement the normalizer interface for that chain
  3. Add to the normalizer registry in index.ts
  4. Add tests for common transaction patterns
  5. 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