Solana Tracker LogoSolana Tracker
Swap
Developers
⌘K
Affiliate
All Resources
Parse Meteora DLMM Swaps Without Losing Precision
MeteoraTypeScriptMarch 26, 20263 min readUpdated September 20, 2026Solana Tracker

Parse Meteora DLMM Swaps Without Losing Precision

Decode Meteora DLMM swap arguments and understand bin pricing, decimals, inner instructions, and the difference between constraints and executed amounts.

  • meteora,
  • dlmm,
  • grpc,
  • typescript,
  • liquidity
Yellowstone gRPC›Dedicated Nodes›Solana Data API›

Meteora DLMM organizes liquidity in discrete price bins. A swap can cross bins and incur dynamic fees, so instruction arguments alone do not describe its final execution. Use the program layout to decode the request and execution data to determine the fill.

Select the DLMM program and instruction version

Meteora DLMM, DAMM, and Dynamic Bonding Curve are separate programs. Verify the program address and instruction layout using the official DLMM SDK. Filter your gRPC subscription, then validate each instruction's resolved program ID.

A subscription filter only selects candidate transactions. Another program in the same transaction can have similar-looking bytes. Resolve loaded addresses and visit inner instructions before decoding routed swaps.

Decode the classic exact-input swap body

The function below handles the classic Anchor swap body: an eight-byte discriminator followed by two u64 arguments. It intentionally rejects other layouts. Run it as decode.mts with node --import tsx decode.mts after installing tsx.

import { createHash } from 'node:crypto';
import assert from 'node:assert/strict';
const discriminator = createHash('sha256').update('global:swap').digest().subarray(0, 8);
function decodeDlmmSwap(data: Uint8Array) {
  const bytes = Buffer.from(data);
  if (bytes.length !== 24 || !bytes.subarray(0, 8).equals(discriminator)) return null;
  return {
    amountInRaw: bytes.readBigUInt64LE(8).toString(),
    minimumAmountOutRaw: bytes.readBigUInt64LE(16).toString(),
  };
}
const fixture = Buffer.alloc(24);
discriminator.copy(fixture);
fixture.writeBigUInt64LE(123n, 8);
fixture.writeBigUInt64LE(100n, 16);
assert.deepEqual(decodeDlmmSwap(fixture), {
  amountInRaw: '123', minimumAmountOutRaw: '100',
});
assert.equal(decodeDlmmSwap(Buffer.alloc(24)), null);

This synthetic test establishes the function's byte-level behavior. It does not validate every live instruction version. Unknown discriminators should become observable unsupported records, not silently misdecoded swaps.

Attribute the fill and direction separately

minimumAmountOutRaw is a constraint, not actual output. Inspect the relevant transfers or decoded events and account for fees and other instructions. Preserve the raw integers until you know both mint decimals.

Classify direction relative to the token being displayed. A pool's X/Y ordering does not universally mean buy/sell, and quote tokens are not limited to SOL. The September platform updates expanded quote-token coverage across several launchpad markets; hardcoded SOL assumptions can miss supported pools.

Bin price needs token-decimal adjustment

For the standard signed bin ID convention, the raw bin ratio is (1 + binStep / 10000) ** binId. A human-unit Y-per-X quote also needs the X/Y decimal adjustment. Do not subtract an arbitrary large offset from an already signed bin ID.

Use the protocol SDK's price helpers for production calculations. Large positive or negative bin IDs and floating-point arithmetic can create precision or range problems. A bin price is also not the execution price of a swap that crosses several bins.

Liquidity actions are a separate data model

Adding, removing, and initializing positions do not share the swap layout. If your goal is an LP activity feed, use liquidity history and streams, which preserve token amounts and separate principal from transfer semantics.

FAQ

Does this handle swap2 or exact-output variants?

No. Dispatch those to the matching current IDL layout instead of reusing this decoder.

Why is my bin-derived price wrong by powers of ten?

Check mint decimals and price orientation before changing the bin formula.

Can a minimum-output field be used as trade volume?

No. It is a user constraint, not a realized fill.

References

  • Meteora DLMM SDK and IDL

Companion project

The companion example contains a fuller project layout. Check the companion dependencies and bundled program layouts against the versions described here before use. Keep credentials in a local environment file, never in a shared browser workspace.

View source on GitHub›

Runnable Node.js project — clone from GitHub, add keys to .env, then npm start. gRPC examples use native dependencies — run locally with Node.js.

Related Guides

Track Solana Liquidity Adds and Removes with SDK 0.5
Data API

Track Solana Liquidity Adds and Removes with SDK 0.5

Read more
Yellowstone gRPC Setup: Filters and Recovery
Infrastructure

Yellowstone gRPC Setup: Filters and Recovery

Read more
Detect Pump.fun Mints from gRPC Instructions
Pump.fun

Detect Pump.fun Mints from gRPC Instructions

Read more

Products

  • Data API
  • Pump.fun API
  • Solana RPC
  • Dedicated Nodes
  • Yellowstone gRPC
  • Raptor Swap API
  • Enterprise

Trading

  • Swap
  • Latest Tokens
  • Trending
  • Top Gainers
  • Memescope
  • Whale Watch
  • KOL Tracker

Tools

  • Wallet Tracker
  • Rugcheck
  • PnL Leaderboard
  • KOLScan
  • Axiom Leaderboard
  • Photon Leaderboard
  • Bloom Leaderboard
  • FOMO Leaderboard
  • GMGN Leaderboard
  • Pump.fun App Leaderboard
  • Terminal Leaderboard
  • Platform Compare
  • My Positions
  • Teams

Resources

  • Developer Guides
  • Blog
  • Documentation
  • API Reference
  • Status
  • Affiliate Program — 25% recurring, uncapped
Solana TrackerSolana Tracker© 2026
Terms of ServicePrivacy PolicyContact