dlmm

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 15, 2026 License: MIT Imports: 0 Imported by: 0

README

Meteora DLMM Go SDK (github.com/azdharsyahputra/dlmm-sdk-go)

A complete Go library for interacting with Meteora's Concentrated Liquidity Market Maker (DLMM) protocol.

This SDK provides two components:

  1. REST API Client (client package): Queries historical data, statistics, active/closed portfolios, position PnL, daily volume/fees, and limit orders from Meteora's analytics endpoint.
  2. On-Chain Client (onchain package): Interfaces directly with the Solana blockchain to fetch pool accounts (LbPair, BinArray, PositionV2), derive PDA accounts, perform off-chain swap quoting/simulations, and construct instruction transactions.

Installation

go get github.com/azdharsyahputra/dlmm-sdk-go

Make sure your Go project initializes modules and fetches dependencies:

go mod tidy

1. REST API Client Usage

The REST API client communicates with https://dlmm.datapi.meteora.ag to retrieve statistical and analytical data.

Example: Fetching Pools and Protocol Overview
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/azdharsyahputra/dlmm-sdk-go/client"
)

func main() {
	// Initialize the client (defaults to Meteora DLMM production API)
	c := client.NewClient("")
	ctx := context.Background()

	// Fetch top 5 pools
	pageSize := 5
	pools, err := c.GetPools(ctx, &client.GetPoolsParams{
		PageSize: &pageSize,
	})
	if err != nil {
		log.Fatalf("Failed to fetch pools: %v", err)
	}

	for _, pool := range pools.Data {
		fmt.Printf("Pool: %s | Address: %s | TVL: $%.2f | APR: %.2f%%\n",
			pool.Name, pool.Address, pool.Tvl, pool.Apr)
	}

	// Fetch protocol overview stats
	overview, err := c.GetProtocolOverview(ctx)
	if err != nil {
		log.Fatalf("Failed to fetch overview: %v", err)
	}
	fmt.Printf("Meteora DLMM Total 24h Volume: $%.2f\n", overview.Volume24h)
}

2. On-Chain Client Usage

The on-chain client uses github.com/gagliardetto/solana-go to connect to a Solana RPC node and read state or build transactions.

Example: Fetching Pool State and Simulating a Swap Quote
package main

import (
	"context"
	"fmt"
	"log"
	"math/big"

	"github.com/azdharsyahputra/dlmm-sdk-go/onchain"
	"github.com/gagliardetto/solana-go"
	"github.com/gagliardetto/solana-go/rpc"
)

func main() {
	// Connect to Solana Mainnet RPC
	c := onchain.NewClient(rpc.MainNetBeta_RPC)
	ctx := context.Background()

	// SOL-USDC DLMM pool address
	poolAddr := solana.MustPublicKeyFromBase58("5rCf1DM8LjKTw4YqhnoLcngyZYeNnQqztScTogYHAS6")

	// 1. Fetch live pool state (LbPair)
	pair, err := c.GetLbPair(ctx, poolAddr)
	if err != nil {
		log.Fatalf("Failed to fetch pool: %v", err)
	}
	fmt.Printf("Active Bin ID: %d | Bin Step: %d BPS\n", pair.ActiveId, pair.BinStep)

	// Calculate current SOL price (SOL = 9 decimals, USDC = 6 decimals)
	price := onchain.BinIdToTokenPrice(pair.ActiveId, pair.BinStep, 9, 6)
	fmt.Printf("Current price: %.4f USDC per SOL\n", price)

	// 2. Fetch the active BinArray containing the current price
	activeIdx := onchain.BinIdToBinArrayIndex(pair.ActiveId)
	binArray, err := c.GetBinArrayByIndex(ctx, poolAddr, activeIdx)
	if err != nil {
		log.Fatalf("Failed to fetch active bin array: %v", err)
	}

	// 3. Simulating swap: 1 SOL -> USDC (swapForY = true)
	solInAmount := big.NewInt(1_000_000_000) // 1 SOL in lamports
	quote, err := onchain.ComputeSwapQuote(pair, []onchain.BinArray{*binArray}, solInAmount, true, false, 50, 0)
	if err != nil {
		log.Fatalf("Swap quote failed: %v", err)
	}

	fmt.Printf("--- Swap Quote: 1 SOL to USDC ---\n")
	fmt.Printf("Expected Out: %s USDC units (~$%.2f)\n", quote.OutAmount.String(), float64(quote.OutAmount.Int64())/1e6)
	fmt.Printf("Fee Paid: %s lamports\n", quote.Fee.String())
	fmt.Printf("Price Impact: %.6f%%\n", quote.PriceImpact)
}
Example: Building a Swap Instruction
package main

import (
	"fmt"
	"log"

	"github.com/azdharsyahputra/dlmm-sdk-go/onchain"
	"github.com/gagliardetto/solana-go"
)

func main() {
	// Construct the instructions params
	params := onchain.SwapParams{
		LbPair:        solana.MustPublicKeyFromBase58("5rCf1DM8LjKTw4YqhnoLcngyZYeNnQqztScTogYHAS6"),
		ReserveX:      solana.MustPublicKeyFromBase58("..."), // reserve vaults derived from LbPair
		ReserveY:      solana.MustPublicKeyFromBase58("..."),
		UserTokenIn:   solana.MustPublicKeyFromBase58("..."), // user token accounts
		UserTokenOut:  solana.MustPublicKeyFromBase58("..."),
		TokenXMint:    solana.MustPublicKeyFromBase58("So11111111111111111111111111111111111111112"),
		TokenYMint:    solana.MustPublicKeyFromBase58("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"),
		Oracle:        solana.MustPublicKeyFromBase58("..."), // derived from LbPair
		User:          solana.MustPublicKeyFromBase58("..."), // signer wallet
		TokenXProgram: solana.TokenProgramID,
		TokenYProgram: solana.TokenProgramID,
		BinArrays:     []solana.PublicKey{
			// bin arrays to be traversed derived from ComputeSwapQuote's final active bin ID
		},
		AmountIn:     1000000000,
		MinAmountOut: 990000000, // custom slippage applied to Quote.OutAmount
	}

	swapIx, err := onchain.NewSwapInstruction(params)
	if err != nil {
		log.Fatalf("Failed to build swap instruction: %v", err)
	}

	fmt.Println("Created swap instruction successfully. Program ID:", swapIx.ProgramID())
}
High-Precision Decimal Math

To avoid float rounding issues in production, use the decimal.Decimal variants for bin-to-price conversions:

import (
	"fmt"
	"github.com/azdharsyahputra/dlmm-sdk-go/onchain"
)

func main() {
	// High-precision token price (Y per X)
	priceDec := onchain.BinIdToTokenPriceDecimal(-6388, 4, 9, 6)
	fmt.Println("SOL-USDC Price (Decimal):", priceDec.String()) // "77.7163906299..."

	// High-precision price-to-bin conversion
	binId := onchain.TokenPriceToBinIdDecimal(priceDec, 4, 9, 6)
	fmt.Println("Derived Bin ID:", binId) // -6388
}

Running Tests

To run the integration and unit tests (uses live mainnet calls to verify correctness):

# Test REST API Client
go test -v ./client

# Test On-Chain Client (Layouts, Quoting, Instructions)
go test -v ./onchain

Documentation

Overview

Package dlmm provides the official Go SDK for Meteora's Dynamic Liquidity Market Maker (DLMM).

This SDK is divided into two primary sub-packages tailored for different use cases:

1. client: A REST API client for interacting with Meteora's off-chain analytics, fetching pools, historical data (OHLCV), volume, and user portfolios.

2. onchain: Core blockchain utilities for parsing raw Solana accounts (LBPairs, BinArrays), calculating exact swap quotes locally, and constructing instructions for Swaps, Limit Orders, and Fee Claiming.

Examples

Full executable examples can be found in the "examples/" directory of this repository, including a complete Devnet E2E swap simulation.

Sub-packages

Please navigate to the "client" or "onchain" packages below to see their respective documentation, types, and runnable examples.

Directories

Path Synopsis
Package client provides a REST API client for Meteora's DLMM architecture.
Package client provides a REST API client for Meteora's DLMM architecture.
examples
devnet_swap command
Package onchain provides tools for interacting with Meteora's DLMM Solana smart contracts.
Package onchain provides tools for interacting with Meteora's DLMM Solana smart contracts.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL