bitquery

package module
v1.0.0 Latest Latest
Warning

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

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

README

Bitquery Golang Client/SDK/Library

Bitquery Golang SDK Client

CI Tests Go Version License CodeQL Codecov GitHub Release GoDoc

bitquery-go is a production-oriented Go SDK for Bitquery GraphQL. It keeps the two Bitquery contracts deliberately separate:

  • V1 is the historical HTTPS GraphQL API.
  • V2 is the streaming GraphQL API: HTTPS queries plus opt-in WebSocket subscriptions.

The library never rewrites a document, changes an endpoint, or falls back from one version to the other. That matters because V1 and V2 have different schemas and coverage.

  • Module: github.com/tigusigalpa/bitquery-go
  • Go: 1.21 or newer (CI covers Go 1.21–1.26)
  • License: MIT — © Igor Sazonov

Pick the right client first

If you need… Use Important detail
An existing historical V1 document v1.Client HTTPS only; no subscription API
A new supported EVM or Solana integration v2.Client Start with the current V2 schema in the Bitquery IDE
Live V2 updates subscription.Client A separate, explicit WebSocket worker

V1 still has legacy coverage, but Bitquery marks Ethereum, BSC, Matic/Polygon and Tron V1 usage as deprecated. The SDK reports this as a typed notice; it never blocks a deliberate V1 call. V2 is not a drop-in replacement for every V1 dataset. Check the live schema and the V1/V2 coverage guide before migrating.

Install

go get github.com/tigusigalpa/bitquery-go

Creating a client makes no network request. Requests happen only when you call Execute; a socket is opened only when you call Subscribe.

Authentication: choose one safe source of tokens

Keep credentials in your process environment or your own secret store — never in source code, examples, or logs.

// A pre-minted Bitquery access token.
provider := bitquery.NewStaticTokenProvider(os.Getenv("BITQUERY_TOKEN"))

// Or client credentials. The provider coalesces concurrent refreshes
// and caches the token until shortly before expiry.
provider := bitquery.NewClientCredentialsProvider(
    os.Getenv("BITQUERY_CLIENT_ID"),
    os.Getenv("BITQUERY_CLIENT_SECRET"),
)

HTTP requests use Authorization: Bearer <token>. WebSocket authentication is different: Bitquery requires the OAuth token in the ?token= URL query parameter, which this SDK adds internally. Do not put that parameter in a custom endpoint. The SDK redacts it from its errors and logger output.

For a proxy or a test OAuth server, use bitquery.WithOAuthTokenEndpoint("https://…") while creating the credentials provider. bitquery.WithTokenEndpoint also configures a default ClientCredentialsProvider supplied to a client; an explicit OAuth-provider endpoint takes precedence.

Make an HTTP query

V2 EVM: generic GraphQL is the main API

Use a raw Operation whenever you need a field or cube the helpers do not cover. Values belong in Variables, never in string-concatenated GraphQL.

client, err := v2.New(provider, bitquery.WithRegion(bitquery.RegionUS))
if err != nil { return err }

resp, err := client.Execute(ctx, bitquery.Operation{
    OperationName: "LatestBlocks",
    Query: `query LatestBlocks($network: evm_network!) {
        EVM(network: $network) {
            Blocks(limit: {count: 3}) { Block { Number Time } }
        }
    }`,
    Variables: map[string]any{"network": "eth"},
})
if err != nil { return err }

There are deliberately thin helpers for a few documented common cases; they still produce an ordinary Operation that you can inspect or modify:

resp, err := client.Execute(ctx, v2.EVMDexTrades(bitquery.NetworkBSC, 20, false))
V2 Solana: use the Solana cube
client, err := v2.New(provider)
if err != nil { return err }

op := v2.SolanaTransfers(25, os.Getenv("SOLANA_MINT")) // a non-empty mint address
resp, err := client.Execute(ctx, op)
if err != nil { return err }

The helper set includes EVM DEX trades, transfers and transactions, and Solana DEX trades, transfers, balance updates, instructions and transactions. It intentionally does not generate a brittle model of every evolving Bitquery cube.

V1 historical query: explicit and inspectable
client, err := v1.New(provider)
if err != nil { return err }

op := v1.Blocks(bitquery.NetworkEthereum, 10, "", "")
for _, notice := range client.DeprecationNotices(op) {
    log.Printf("%s: %s", notice.Network, notice.Message)
}

resp, err := client.Execute(ctx, op)
if err != nil { return err }

V1 helpers cover blocks, transactions, transfers, DEX trades and smart contract calls. They are conveniences, not a replacement for Execute.

Read responses without losing numeric precision

Bitquery amounts, decimals, block heights and IDs can exceed the safe range of float64. The SDK leaves Data as json.RawMessage and uses json.Number when decoding into interface{} values.

if resp.HasErrors() {
    // HTTP 200 can still contain GraphQL errors.
    for _, graphQLError := range resp.Errors {
        log.Printf("GraphQL: %s", graphQLError.Message)
    }
}
if resp.HasPartialData() {
    // Some data is still usable; decide case by case.
}

var data map[string]any
if err := resp.DecodeData(&data); err != nil { return err }
// Convert an amount explicitly with math/big or a decimal package.

The default is tolerant: GraphQL errors[] live on Response. Use ExecuteStrict (or bitquery.WithStrict()) if your application wants a KindGraphQL error instead. Even then, the error retains the complete response so partial data is not discarded.

Regions and endpoint overrides

The default is Europe. Choose the closest region for your deployment:

client, err := v2.New(provider,
    bitquery.WithRegion(bitquery.RegionAsia),
    bitquery.WithTimeout(20*time.Second),
    bitquery.WithUserAgent("my-indexer/1.0"),
)
Region V1 HTTPS V2 HTTPS V2 WebSocket
Europe (default) https://graphql.bitquery.io https://streaming.bitquery.io/graphql wss://streaming.bitquery.io/graphql
Asia https://asia.graphql.bitquery.io https://asia.streaming.bitquery.io/graphql wss://asia.streaming.bitquery.io/graphql
US https://us.graphql.bitquery.io https://us.streaming.bitquery.io/graphql wss://us.streaming.bitquery.io/graphql

WithBaseURL overrides the selected HTTP endpoint. For a private proxy or a local test socket, use WithWebSocketURL; it overrides the derived WSS endpoint. Only absolute HTTP(S) and WS(S) URLs are accepted, and credential-bearing URL parameters are rejected.

Network is an open string type, not a closed list. Bitquery coverage varies by region, plan, dataset and cube, so verify unfamiliar networks in the Bitquery schema instead of waiting for an SDK release.

Retries, limits, and cancellation

The default retry policy is intentionally conservative: up to four attempts with an approximately 5-second exponential backoff, capped at 60 seconds and jittered. Retry-After wins when Bitquery supplies it. It handles transient network errors, 429, temporary 5xx responses and documented shared-compute blocks.

Only read operations are retried. Mutations and HTTP subscriptions are never replayed automatically — whether they are safe to repeat is your decision. Pass bitquery.WithRetryPolicy(bitquery.NoRetry()) to turn off SDK retries.

client, err := v2.New(provider,
    bitquery.WithRateLimiter(bitquery.NewRateLimiter(30)), // 30 req/min burst + pace
    bitquery.WithTimeout(20*time.Second),
)

NewRateLimiter(0) is a convenient no-op. The SDK does not fan out or parallelize heavy queries; use your own worker limits and respect your Bitquery plan's concurrency allowance. Every request and reconnect obeys the supplied context.Context.

Subscribe to V2 updates

Run subscriptions in a long-lived worker, not a short HTTP handler. Cancellation closes the WebSocket, which is the way Bitquery ends a stream. Delivery is at-least-once and can be unordered across block portions, so persist a stable event key and deduplicate downstream.

workerCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

client, err := subscription.New(provider,
    bitquery.WithSubProtocol(bitquery.SubProtocolGraphQLTransportWS),
    bitquery.WithSubscriptionQueue(500, bitquery.OverflowDropOldest),
)
if err != nil { return err }

stream, err := client.Subscribe(workerCtx, bitquery.Operation{
    Query: `subscription {
        EVM(network: eth) { Blocks { Block { Number Time } } }
    }`,
})
if err != nil { return err }
defer stream.Close()

for event := range stream.Events {
    switch event.Type {
    case subscription.EventData:
        // Deduplicate event.Payload before writing it anywhere.
    case subscription.EventKeepalive:
        // The connection is healthy.
    case subscription.EventComplete:
        // The server completed this operation.
    }
}
if err := stream.Err(); err != nil { return err }

Both graphql-transport-ws and graphql-ws are supported. The stream handles connection_init/acknowledgement, next/data, ping/pong and ka, bounded reconnects, and clean shutdown. Its bounded event queue protects memory: drop_oldest keeps the newest events and reports the count via Dropped(); fail stops the stream rather than losing an event silently. See the lifecycle guide for the state machine and recovery checklist.

Errors you can act on

All SDK failures use *bitquery.Error; errors.Is and errors.As work as expected.

var apiErr *bitquery.Error
if errors.As(err, &apiErr) {
    switch apiErr.Kind {
    case bitquery.KindAuthentication:  // 401 or OAuth rejection
    case bitquery.KindAuthorization:   // 403
    case bitquery.KindPlanEntitlement: // 402; do not retry
    case bitquery.KindRateLimited:     // 429; inspect RetryAfter
    case bitquery.KindServer:          // temporary for 500/502/503/504
    case bitquery.KindGraphQL:         // strict mode; Response is retained
    case bitquery.KindSubscription:
    }
}

Diagnostic messages and the built-in structured logger redact Bearer tokens, OAuth secrets and URL token parameters. The logger is a no-op unless you supply one with WithLogger.

Runnable examples

Every example compiles without a credential and only contacts Bitquery when you run it with the required environment variables.

Example Run Shows
examples/http BITQUERY_TOKEN=… go run ./examples/http V2 EVM HTTP query and partial GraphQL errors
examples/oauth BITQUERY_CLIENT_ID=… BITQUERY_CLIENT_SECRET=… go run ./examples/oauth client-credentials token provider
examples/subscription BITQUERY_TOKEN=… go run ./examples/subscription graceful V2 subscription worker
examples/v1-historical BITQUERY_TOKEN=… go run ./examples/v1-historical V1 helper and deprecation signal
examples/v2-solana BITQUERY_TOKEN=… go run ./examples/v2-solana V2 Solana transfers helper
examples/custom-endpoint BITQUERY_TOKEN=… go run ./examples/custom-endpoint region, endpoint, timeout and user-agent options

Reference and project docs

Verify a checkout

go build ./...
gofmt -l .            # no output means formatted
go vet ./...
go test ./...         # no network
go test -race ./...   # concurrency suite
go mod verify

Live smoke tests are opt-in only: set both BITQUERY_LIVE=1 and BITQUERY_TOKEN. They never run in public CI.

Documentation

Overview

Package bitquery is a Go SDK for the Bitquery blockchain data APIs.

Bitquery exposes two deliberately separate API contracts:

  • V1 — historical GraphQL over HTTPS (see package v1)
  • V2 — streaming GraphQL over HTTPS plus WebSocket subscriptions (see packages v2 and subscription)

The two versions are NOT interchangeable: different schemas, endpoints and capabilities. This SDK never rewrites documents, substitutes endpoints or falls back between them — the version is always chosen explicitly by the caller via the v1/v2 packages.

Authentication: OAuth access tokens are sent as "Authorization: Bearer <token>" for HTTP and as the "?token=" URL query parameter for WebSocket connections (the only mechanism Bitquery accepts for WSS). Credentials are redacted from all errors and logs.

Numeric precision: response Data is exposed as json.RawMessage and helper decoding uses json.Number — token amounts and large integers are never silently converted to float64.

Docs: https://docs.bitquery.io/docs/start/endpoints/

Example (V1)

Example_v1 — the V1 historical GraphQL client (HTTPS only).

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/tigusigalpa/bitquery-go"
	v1 "github.com/tigusigalpa/bitquery-go/v1"
)

func main() {
	client, err := v1.New(bitquery.NewStaticTokenProvider(os.Getenv("BITQUERY_TOKEN")))
	if err != nil {
		panic(err)
	}
	resp, err := client.Execute(context.Background(), bitquery.Operation{
		Query: `query { ethereum { blocks { height } } }`,
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.StatusCode)
}
Example (V2)

Example_v2 — the V2 streaming GraphQL client over HTTPS.

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/tigusigalpa/bitquery-go"

	v2 "github.com/tigusigalpa/bitquery-go/v2"
)

func main() {
	client, err := v2.New(
		bitquery.NewClientCredentialsProvider(
			os.Getenv("BITQUERY_CLIENT_ID"),
			os.Getenv("BITQUERY_CLIENT_SECRET"),
		),
		bitquery.WithRegion(bitquery.RegionUS),
	)
	if err != nil {
		panic(err)
	}
	resp, err := client.Execute(context.Background(), bitquery.Operation{
		Query: `query { EVM(network: eth) { Blocks(limit: {count: 1}) { Block { Number } } } }`,
	})
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.HasErrors())
}

Index

Examples

Constants

View Source
const (
	OverflowDropOldest = "drop_oldest"
	OverflowFail       = "fail"
)

Overflow policies for the subscription bounded queue.

View Source
const (
	V1EndpointEurope = "https://graphql.bitquery.io"
	V1EndpointAsia   = "https://asia.graphql.bitquery.io"
	V1EndpointUS     = "https://us.graphql.bitquery.io"

	V2EndpointEurope = "https://streaming.bitquery.io/graphql"
	V2EndpointAsia   = "https://asia.streaming.bitquery.io/graphql"
	V2EndpointUS     = "https://us.streaming.bitquery.io/graphql"

	// OAuthTokenEndpoint issues OAuth2 access tokens (all regions).
	OAuthTokenEndpoint = "https://oauth2.bitquery.io/oauth2/token" // #nosec G101 -- public endpoint, not a credential.
)

Default regional endpoints. All are overridable via Config options.

https://docs.bitquery.io/docs/start/endpoints/

Variables

View Source
var (
	ErrTransport       = errors.New("bitquery: transport error")
	ErrAuthentication  = errors.New("bitquery: authentication failed (401)")
	ErrAuthorization   = errors.New("bitquery: authorization failed (403)")
	ErrPlanEntitlement = errors.New("bitquery: plan entitlement error (402)")
	ErrRateLimited     = errors.New("bitquery: rate limited (429)")
	ErrServer          = errors.New("bitquery: server error (5xx)")
	ErrGraphQL         = errors.New("bitquery: graphql errors in response")
	ErrSubscription    = errors.New("bitquery: subscription error")
	ErrInvalidConfig   = errors.New("bitquery: invalid configuration")
)

Sentinel errors for errors.Is.

Functions

func HTTPURL

func HTTPURL(version APIVersion, region Region, override string) (string, error)

HTTPURL resolves the GraphQL HTTPS endpoint for a version/region. An explicit override always wins over the region default.

func IsRetryable

func IsRetryable(err error) bool

IsRetryable reports whether err is a typed transient error a caller could safely retry beyond the built-in policy.

func WebSocketURL

func WebSocketURL(region Region, httpsOverride, wsOverride string) (string, error)

WebSocketURL resolves the V2 subscription endpoint. An explicit WS override wins; otherwise the V2 HTTPS endpoint with https→wss.

Types

type APIVersion

type APIVersion int

APIVersion identifies the Bitquery API contract. V1 and V2 are separate contracts — never interchangeable.

const (
	// V1 is the historical GraphQL API.
	V1 APIVersion = 1
	// V2 is the streaming GraphQL API (queries + subscriptions).
	V2 APIVersion = 2
)

func ParseAPIVersion

func ParseAPIVersion(s string) (APIVersion, error)

ParseAPIVersion accepts "v1"/"1" and "v2"/"2".

func (APIVersion) String

func (v APIVersion) String() string

type ClientCredentialsOption

type ClientCredentialsOption func(*ClientCredentialsProvider)

ClientCredentialsOption configures the provider.

func WithOAuthHTTPClient

func WithOAuthHTTPClient(hc *http.Client) ClientCredentialsOption

WithOAuthHTTPClient supplies a caller-owned HTTP client for token calls.

func WithOAuthScope

func WithOAuthScope(scope string) ClientCredentialsOption

WithOAuthScope overrides the requested scope (default "api").

func WithOAuthTokenEndpoint

func WithOAuthTokenEndpoint(endpoint string) ClientCredentialsOption

WithOAuthTokenEndpoint overrides the OAuth token endpoint. It is useful for regional proxies and local test servers; the endpoint must be an absolute HTTP(S) URL.

type ClientCredentialsProvider

type ClientCredentialsProvider struct {
	// contains filtered or unexported fields
}

ClientCredentialsProvider mints OAuth tokens via client_credentials (grant_type=client_credentials, scope=api) against the Bitquery OAuth endpoint, caches them to expiry (minus a safety margin) and coalesces concurrent refreshes.

https://docs.bitquery.io/docs/authorization/how-to-generate/

func NewClientCredentialsProvider

func NewClientCredentialsProvider(clientID, clientSecret string, opts ...ClientCredentialsOption) *ClientCredentialsProvider

NewClientCredentialsProvider builds a provider using the default OAuth endpoint.

func (*ClientCredentialsProvider) Refresh

Refresh obtains a new OAuth token even when a cached token remains valid.

func (*ClientCredentialsProvider) Token

Token returns a cached OAuth token or obtains a new one when it has expired.

type Config

type Config struct {
	Region        Region
	BaseURL       string // explicit HTTPS endpoint override
	WebSocketURL  string // explicit WSS endpoint override
	TokenEndpoint string

	HTTPClient *http.Client
	Timeout    time.Duration

	TokenProvider TokenProvider
	Retry         *RetryPolicy
	RateLimiter   RateLimiter
	Logger        Logger
	UserAgent     string

	// Strict makes Execute fail on any GraphQL errors[] — partial data is
	// still preserved on the returned Response inside *Error.
	Strict bool

	// --- V2 subscription options ---
	SubProtocol               SubProtocol
	SubscriptionMaxReconnects int
	SubscriptionQueueCapacity int
	// OverflowPolicy: "drop_oldest" (default) or "fail".
	OverflowPolicy string
	// Dialer overrides the WebSocket dial implementation (tests/custom transport).
	Dialer Dialer
}

Config holds client configuration. Construct via NewConfig with functional options; explicit URL overrides always win over region.

func NewConfig

func NewConfig(opts ...Option) (*Config, error)

NewConfig builds a Config with defaults.

type Dialer

type Dialer func(ctx context.Context, url string, subprotocols []string) (WSConn, error)

Dialer establishes a WebSocket connection to url requesting the given Sec-WebSocket-Protocol values. The url may carry a `token` query parameter — never log it raw.

type Error

type Error struct {
	Kind       Kind
	Message    string
	StatusCode int
	// RetryAfter carries the server hint for 429/shared-compute errors.
	RetryAfter time.Duration
	// Temporary marks documented transient failures (429, shared compute,
	// 502/503/504) that are safe to retry.
	Temporary bool
	// GraphQLErrors is populated for KindGraphQL.
	GraphQLErrors []GraphQLError
	// Response keeps the full response for partial-data inspection.
	Response *Response
	// Context holds sanitized diagnostic fields.
	Context map[string]any
	// contains filtered or unexported fields
}

Error is the typed SDK error. Message and Context are sanitized — tokens, client secrets and `token` URL params never leak.

func Wrap

func Wrap(kind Kind, message string, cause error) *Error

Wrap builds an *Error of the given kind around cause — the exported constructor for subpackages and consumers extending the taxonomy.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Is

func (e *Error) Is(target error) bool

Is reports whether target is the sentinel associated with e.Kind.

func (*Error) Unwrap

func (e *Error) Unwrap() error

type Executor

type Executor struct {
	// contains filtered or unexported fields
}

Executor runs GraphQL operations for one explicit API version. It is wrapped by the v1 and v2 client packages — use those for the public API rather than constructing this directly.

func NewExecutor

func NewExecutor(version APIVersion, opts ...Option) (*Executor, error)

NewExecutor builds an executor for an explicit API version.

func (*Executor) Config

func (e *Executor) Config() *Config

Config returns the executor config.

func (*Executor) Endpoint

func (e *Executor) Endpoint() (string, error)

Endpoint returns the resolved HTTPS endpoint.

func (*Executor) Execute

func (e *Executor) Execute(ctx context.Context, op Operation) (*Response, error)

Execute runs a GraphQL operation. Tolerant mode returns responses that contain errors[] as-is (check resp.HasErrors / HasPartialData). Strict mode (Config.Strict or ExecuteStrict) fails with *Error of KindGraphQL — partial data stays available via Error.Response.

func (*Executor) ExecuteStrict

func (e *Executor) ExecuteStrict(ctx context.Context, op Operation) (*Response, error)

ExecuteStrict fails on any GraphQL errors[] regardless of Strict config.

func (*Executor) Version

func (e *Executor) Version() APIVersion

Version returns the executor's API version.

type GraphQLError

type GraphQLError struct {
	Message    string           `json:"message"`
	Locations  []map[string]any `json:"locations,omitempty"`
	Path       []any            `json:"path,omitempty"`
	Extensions map[string]any   `json:"extensions,omitempty"`
	Raw        json.RawMessage  `json:"-"`
}

GraphQLError is one entry of a GraphQL errors[] array.

func (GraphQLError) Error

func (e GraphQLError) Error() string

type Kind

type Kind int

Kind classifies SDK errors for errors.Is checks.

const (
	// KindTransport covers network, response parsing and unexpected HTTP failures.
	KindTransport Kind = iota + 1
	// KindAuthentication covers rejected or missing credentials.
	KindAuthentication
	// KindAuthorization covers requests that the current token cannot perform.
	KindAuthorization
	// KindPlanEntitlement covers requests unavailable to the current plan.
	KindPlanEntitlement
	// KindRateLimited covers rate-limit and temporary shared-compute failures.
	KindRateLimited
	// KindServer covers HTTP 5xx failures returned by Bitquery.
	KindServer
	// KindGraphQL covers GraphQL errors returned in a successful HTTP response.
	KindGraphQL
	// KindSubscription covers WebSocket lifecycle failures.
	KindSubscription
	// KindConfig covers invalid SDK configuration or caller input.
	KindConfig
)

Error kinds classify failures from the Bitquery SDK.

type Logger

type Logger interface {
	Debug(msg string, args ...any)
	Info(msg string, args ...any)
	Warn(msg string, args ...any)
	Error(msg string, args ...any)
}

Logger is a minimal structured logger (slog-compatible shape). Implementations must accept nil — the default is no-op. All output is redacted before reaching the sink.

type Network

type Network string

Network is a blockchain network identifier. Deliberately an open string type — the supported set depends on region, plan, cube and dataset and evolves over time.

const (
	NetworkEthereum Network = "eth"
	NetworkBSC      Network = "bsc"
	NetworkMatic    Network = "matic"
	NetworkTron     Network = "tron"
	NetworkSolana   Network = "solana"
	NetworkArbitrum Network = "arbitrum"
	NetworkOptimism Network = "optimism"
	NetworkBase     Network = "base"
)

Common networks — convenience only, not an exhaustive list.

type NopLogger

type NopLogger struct{}

NopLogger is the default no-op logger.

func (NopLogger) Debug

func (NopLogger) Debug(string, ...any)

Debug discards a debug message.

func (NopLogger) Error

func (NopLogger) Error(string, ...any)

Error discards an error message.

func (NopLogger) Info

func (NopLogger) Info(string, ...any)

Info discards an informational message.

func (NopLogger) Warn

func (NopLogger) Warn(string, ...any)

Warn discards a warning message.

type NopRateLimiter

type NopRateLimiter struct{}

NopRateLimiter never delays.

func (NopRateLimiter) Wait

Wait immediately succeeds without delaying the caller.

type Operation

type Operation struct {
	Query         string         `json:"query"`
	Variables     map[string]any `json:"variables,omitempty"`
	OperationName string         `json:"operationName,omitempty"`
}

Operation is a GraphQL document plus variables. Values always travel as variables — never interpolate user input into the document.

type Option

type Option func(*Config)

Option mutates Config.

func WithBaseURL

func WithBaseURL(u string) Option

WithBaseURL sets an explicit HTTPS endpoint override — wins over region.

func WithDialer

func WithDialer(d Dialer) Option

WithDialer overrides the WebSocket dialer (tests/custom transport).

func WithHTTPClient

func WithHTTPClient(hc *http.Client) Option

WithHTTPClient supplies a caller-owned http.Client. The SDK will not mutate it; set your own timeout/transport there if needed.

func WithLogger

func WithLogger(l Logger) Option

WithLogger installs a structured logger (default no-op). Output is redacted before logging.

func WithRateLimiter

func WithRateLimiter(l RateLimiter) Option

WithRateLimiter installs client-side request pacing.

func WithRegion

func WithRegion(r Region) Option

WithRegion selects the endpoint region (europe/asia/us).

func WithRetryPolicy

func WithRetryPolicy(p *RetryPolicy) Option

WithRetryPolicy overrides the retry policy (nil disables retries).

func WithStrict

func WithStrict() Option

WithStrict enables strict mode: any errors[] fails the call.

func WithSubProtocol

func WithSubProtocol(p SubProtocol) Option

WithSubProtocol selects graphql-ws or graphql-transport-ws.

func WithSubscriptionQueue

func WithSubscriptionQueue(capacity int, policy string) Option

WithSubscriptionQueue sets the bounded event-buffer capacity and overflow policy (OverflowDropOldest or OverflowFail).

func WithSubscriptionReconnect

func WithSubscriptionReconnect(n int) Option

WithSubscriptionReconnect sets max reconnect attempts.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets the per-request timeout when no custom client is given.

func WithTokenEndpoint

func WithTokenEndpoint(u string) Option

WithTokenEndpoint overrides the OAuth token endpoint.

func WithTokenProvider

func WithTokenProvider(tp TokenProvider) Option

WithTokenProvider supplies the OAuth token source (required).

func WithUserAgent

func WithUserAgent(ua string) Option

WithUserAgent sets the HTTP User-Agent.

func WithWebSocketURL

func WithWebSocketURL(u string) Option

WithWebSocketURL sets an explicit WSS endpoint override for subscriptions.

type RateLimiter

type RateLimiter interface {
	Wait(ctx context.Context) error
}

RateLimiter paces outgoing requests. Wait is called once per HTTP request and must respect context cancellation.

type Region

type Region string

Region selects the Bitquery regional endpoint family. It is a string type, not a closed enum, so future regions can pass through.

const (
	// RegionEurope selects the Europe endpoint family and is the default.
	RegionEurope Region = "europe"
	// RegionAsia selects the Asia endpoint family.
	RegionAsia Region = "asia"
	// RegionUS selects the United States endpoint family.
	RegionUS Region = "us"
)

Well-known Bitquery regional endpoint families.

type Response

type Response struct {
	Data       json.RawMessage `json:"-"`
	Errors     []GraphQLError  `json:"-"`
	Extensions json.RawMessage `json:"-"`
	StatusCode int             `json:"-"`
	Header     map[string][]string
	RawBody    []byte `json:"-"`
}

Response is the parsed GraphQL response plus HTTP metadata and the raw body. Data stays json.RawMessage so monetary values, decimals and large integers are never silently converted to float64 — decode with DecodeData (json.Number) or handle RawMessage directly.

func (*Response) DecodeData

func (r *Response) DecodeData(v any) error

DecodeData unmarshals Data into v. Numbers inside interface{} targets decode as json.Number (never float64), preserving precision.

func (*Response) HasErrors

func (r *Response) HasErrors() bool

HasErrors reports whether errors[] is non-empty.

func (*Response) HasPartialData

func (r *Response) HasPartialData() bool

HasPartialData reports a GraphQL partial response: data AND errors[].

type RetryPolicy

type RetryPolicy struct {
	// MaxAttempts is the total number of tries including the first. 1 disables retries.
	MaxAttempts int
	BaseDelay   time.Duration
	MaxDelay    time.Duration
	// Jitter is a 0.0–1.0 randomisation factor applied to each delay.
	Jitter float64
	// RetryableStatuses — HTTP statuses allowed to retry.
	RetryableStatuses []int
	// Sleep sleeps d or returns early on ctx cancellation. Defaults to a
	// context-aware real sleep.
	Sleep func(ctx context.Context, d time.Duration) error
	// Rand is the jitter source. It defaults to a cryptographically secure
	// source; tests may supply a deterministic source with Int63n.
	Rand interface{ Int63n(int64) int64 }
	// contains filtered or unexported fields
}

RetryPolicy controls retry behaviour. Defaults follow official guidance: ~5s initial delay, exponential doubling, ~60s cap, jitter. Sleep and Rand are injectable for deterministic tests.

https://docs.bitquery.io/docs/plans/rate-limits/

func DefaultRetryPolicy

func DefaultRetryPolicy() *RetryPolicy

DefaultRetryPolicy returns the documented default policy.

func NoRetry

func NoRetry() *RetryPolicy

NoRetry returns a policy that never retries.

func (*RetryPolicy) Delay

func (p *RetryPolicy) Delay(attempt int, retryAfter time.Duration) time.Duration

Delay computes the backoff before retry attempt n (1-based count of attempts already made). A server Retry-After hint wins and is capped.

type SlogAdapter

type SlogAdapter struct {
	Log interface {
		Debug(msg string, args ...any)
		Info(msg string, args ...any)
		Warn(msg string, args ...any)
		Error(msg string, args ...any)
	}
}

SlogAdapter wraps a *slog.Logger-compatible sink.

func (SlogAdapter) Debug

func (a SlogAdapter) Debug(msg string, args ...any)

Debug forwards a redacted debug message to the wrapped logger.

func (SlogAdapter) Error

func (a SlogAdapter) Error(msg string, args ...any)

Error forwards a redacted error message to the wrapped logger.

func (SlogAdapter) Info

func (a SlogAdapter) Info(msg string, args ...any)

Info forwards a redacted informational message to the wrapped logger.

func (SlogAdapter) Warn

func (a SlogAdapter) Warn(msg string, args ...any)

Warn forwards a redacted warning message to the wrapped logger.

type StaticTokenProvider

type StaticTokenProvider struct {
	// contains filtered or unexported fields
}

StaticTokenProvider returns a pre-minted access token.

func NewStaticTokenProvider

func NewStaticTokenProvider(token string) *StaticTokenProvider

NewStaticTokenProvider creates a provider for an already-issued access token.

func (*StaticTokenProvider) Refresh

func (p *StaticTokenProvider) Refresh(ctx context.Context) (string, error)

Refresh returns the same static token because static tokens cannot be refreshed by the SDK.

func (*StaticTokenProvider) Token

Token returns the configured access token or a configuration error when it is empty.

type SubProtocol

type SubProtocol string

SubProtocol selects the GraphQL-over-WebSocket subprotocol.

const (
	// SubProtocolGraphQLWS is the legacy Apollo protocol
	// (start/data/ka/stop frames).
	SubProtocolGraphQLWS SubProtocol = "graphql-ws"
	// SubProtocolGraphQLTransportWS is the graphql-ws library protocol
	// (subscribe/next/ping-pong/complete frames).
	SubProtocolGraphQLTransportWS SubProtocol = "graphql-transport-ws"
)

func (SubProtocol) DataType

func (p SubProtocol) DataType() string

DataType is the frame type carrying a result payload.

func (SubProtocol) KeepaliveType

func (p SubProtocol) KeepaliveType() string

KeepaliveType is the server's keepalive frame type.

func (SubProtocol) SubscribeType

func (p SubProtocol) SubscribeType() string

SubscribeType is the frame type used to start a subscription.

type TokenBucketRateLimiter

type TokenBucketRateLimiter struct {
	// contains filtered or unexported fields
}

TokenBucketRateLimiter is an in-process limiter for N requests per minute. Clock and sleep are injectable for tests.

func NewRateLimiter

func NewRateLimiter(rpm int) *TokenBucketRateLimiter

NewRateLimiter returns a token-bucket limiter allowing rpm requests per minute. rpm <= 0 disables limiting; the returned limiter is safe to pass to WithRateLimiter and behaves as a no-op.

func (*TokenBucketRateLimiter) Wait

Wait blocks until a token is available or ctx is cancelled.

type TokenProvider

type TokenProvider interface {
	Token(ctx context.Context) (string, error)
	// Refresh forces a fresh token (used after a 401).
	Refresh(ctx context.Context) (string, error)
}

TokenProvider supplies OAuth access tokens for HTTP Bearer auth and the WSS `token` URL parameter. Implementations must never leak tokens into errors or logs.

type WSConn

type WSConn interface {
	Read(ctx context.Context) (WSMessageType, []byte, error)
	Write(ctx context.Context, mt WSMessageType, data []byte) error
	// Close terminates the socket — the only way to end a Bitquery stream.
	Close(code uint32, reason string) error
}

WSConn abstracts a WebSocket connection so the subscription client can be tested without a network. Implementations must honour ctx on Read.

type WSMessageType

type WSMessageType int

WSMessageType is the WebSocket frame type.

const (
	// WSMessageText is a UTF-8 WebSocket text frame.
	WSMessageText WSMessageType = 1
	// WSMessageBinary is a binary WebSocket frame.
	WSMessageBinary WSMessageType = 2
)

WebSocket message types supported by WSConn.

Directories

Path Synopsis
examples
custom-endpoint command
Region, endpoint and transport configuration for an HTTP V2 client.
Region, endpoint and transport configuration for an HTTP V2 client.
http command
HTTP query against the V2 streaming GraphQL endpoint.
HTTP query against the V2 streaming GraphQL endpoint.
oauth command
OAuth2 client_credentials flow: mint + cache + auto-refresh tokens.
OAuth2 client_credentials flow: mint + cache + auto-refresh tokens.
subscription command
V2 WebSocket subscription — opt-in client, separate from the HTTP client.
V2 WebSocket subscription — opt-in client, separate from the HTTP client.
v1-historical command
V1 historical GraphQL with an explicit V1 client and deprecation signal.
V1 historical GraphQL with an explicit V1 client and deprecation signal.
v2-solana command
V2 Solana HTTP query for one token mint.
V2 Solana HTTP query for one token mint.
internal
redact
Package redact scrubs credentials from every observability path: Authorization headers, Bearer tokens, OAuth access_token / client_secret fields and the `token` URL query parameter used by the Bitquery WebSocket endpoint.
Package redact scrubs credentials from every observability path: Authorization headers, Bearer tokens, OAuth access_token / client_secret fields and the `token` URL query parameter used by the Bitquery WebSocket endpoint.
Package subscription provides the opt-in Bitquery V2 WebSocket subscription client.
Package subscription provides the opt-in Bitquery V2 WebSocket subscription client.
Package v1 provides the Bitquery V1 historical GraphQL client.
Package v1 provides the Bitquery V1 historical GraphQL client.
Package v2 provides the Bitquery V2 streaming GraphQL client (HTTPS).
Package v2 provides the Bitquery V2 streaming GraphQL client (HTTPS).

Jump to

Keyboard shortcuts

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