gRPC

Market Data — gRPC

Stream real-time market data for liquidity pools across supported DEXs. Updates are emitted every block for pools that had transactions or state changes.

Endpoint

enterprise.guardis.io:443

Authentication

Include your API key in the request metadata using the x-api-key field.

x-api-key: your_api_key_here

Service Definition

syntax = "proto3";

package guardis.marketdata.v1;

import "google/protobuf/timestamp.proto";

service MarketDataService {
  // Stream pool updates for each processed block
  rpc StreamMarketData(StreamMarketDataRequest) returns (stream PoolBlockUpdate);
}

message StreamMarketDataRequest {
  // Optional: Filter by DEX names. If empty, all supported DEXs are included.
  repeated string dex_names = 1;
}

message PoolBlockUpdate {
  // The Solana slot number that was just processed
  uint64 block_number = 1;
  // Timestamp when the block update was sent
  google.protobuf.Timestamp timestamp = 2;
  // All pools that had state changes during this block
  repeated PoolSnapshot pools = 3;
}

message PoolSnapshot {
  // The on-chain address of the liquidity pool
  string pair_address = 1;
  // The base token address of the pool
  string base_address = 2;
  // the quote token address of the pool
  string quote_address = 3;
  // Amount of liquidity that is locked
  string percentage_of_liquidity_locked = 4;
  // Amount of SOL currently in the pool
  string base_amount = 5;
  // Amount of tokens currently in the pool
  string quote_amount = 6;
  // Price of SOL in USD at time of snapshot
  string sol_price_usd = 7;
  // Token price denominated in the base currency
  string price = 8;
  // Token price denominated in USD
  string price_usd = 9;
  // Total buy transactions on this pool
  int32 number_of_buys = 10;
  // Total sell transactions on this pool
  int32 number_of_sells = 11;
  // Cumulative buy volume in USD
  string buy_volume_usd = 12;
  // Cumulative sell volume in USD
  string sell_volume_usd = 13;
  // Cumulative trading volume in USD
  string total_volume_usd = 14;
  // All-time high token price in USD
  string ath_token_price_usd = 15;
}

Request Parameters

StreamMarketDataRequest

Field
Type
Required
Description

dex_names

repeated string

No

List of DEXs to filter by. If empty, all supported DEXs are included

Supported DEX values:

  • PumpFun

  • PumpSwap

  • MeteoraDLMM


Response Format

The server streams PoolBlockUpdate messages. Each message contains all pools that were modified during that block.

PoolBlockUpdate

Field
Type
Description

block_number

uint64

The Solana slot number that was just processed

timestamp

google.protobuf.Timestamp

ISO 8601 timestamp when the block update was sent

pools

repeated PoolSnapshot

All pools that had state changes during this block

PoolSnapshot

Field
Type
Description

pair_address

string

The on-chain address of the liquidity pool

base_address

string

The base address of the base currency in the pool

quote_address

string

The quote address of the quote currency in the pool

percentage_of_liquidity_locked

string

Percentage of base amount that is locked liquidity

base_amount

string

Amount of base currency currently in the pool

quote_amount

string

Amount of quote currency currently in the pool

sol_price_usd

string

Price of SOL in USD at time of snapshot

price

string

Token price denominated in the base currency

price_usd

string

Token price denominated in USD

number_of_buys

int32

Total buy transactions on this pool

number_of_sells

int32

Total sell transactions on this pool

buy_volume_usd

string

Cumulative buy volume in USD

sell_volume_usd

string

Cumulative sell volume in USD

total_volume_usd

string

Cumulative trading volume in USD

ath_token_price_usd

string

All-time high token price in USD

Note: Decimal values are returned as strings to preserve precision.


Example Usage

Python:

import grpc
from guardis.marketdata.v1 import marketdata_pb2, marketdata_pb2_grpc

metadata = [("x-api-key", "your_api_key_here")]

with grpc.secure_channel("enterprise.guardis.io:443", grpc.ssl_channel_credentials()) as channel:
    stub = marketdata_pb2_grpc.MarketDataServiceStub(channel)
    
    request = marketdata_pb2.StreamMarketDataRequest(
        dex_names=["PumpFun", "PumpSwap"]
    )
    
    for update in stub.StreamMarketData(request, metadata=metadata):
        print(f"Block {update.block_number}: {len(update.pools)} pools updated")
        
        for pool in update.pools:
            print(f"{pool.token_address}: ${pool.price_usd}")

Go:

package main

import (
    "context"
    "log"

    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
    "google.golang.org/grpc/metadata"
    
    pb "github.com/your-org/guardis-go/marketdata/v1"
)

func main() {
    creds := credentials.NewTLS(nil)
    conn, err := grpc.Dial("enterprise.guardis.io:443", grpc.WithTransportCredentials(creds))
    if err != nil {
        log.Fatalf("Failed to connect: %v", err)
    }
    defer conn.Close()

    client := pb.NewMarketDataServiceClient(conn)

    ctx := metadata.AppendToOutgoingContext(
        context.Background(),
        "x-api-key", "your_api_key_here",
    )

    request := &pb.StreamMarketDataRequest{
        DexNames: []string{"PumpFun", "PumpSwap"},
    }

    stream, err := client.StreamMarketData(ctx, request)
    if err != nil {
        log.Fatalf("Failed to stream: %v", err)
    }

    for {
        update, err := stream.Recv()
        if err != nil {
            log.Fatalf("Stream error: %v", err)
        }
        
        log.Printf("Block %d: %d pools updated", update.BlockNumber, len(update.Pools))
        
        for _, pool := range update.Pools {
            log.Printf("%s: $%s", pool.TokenAddress, pool.PriceUsd)
        }
    }
}

Connection Best Practices

  • Implement reconnection logic — Network interruptions happen; automatically reconnect with exponential backoff

  • Use deadlines — Set appropriate deadlines for your streaming calls to handle stale connections

  • Handle stream errors gracefully — Check for io.EOF and gRPC status codes to determine if reconnection is needed

Last updated