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)
}
Output:
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())
}
Output:
Index ¶
- Constants
- Variables
- func HTTPURL(version APIVersion, region Region, override string) (string, error)
- func IsRetryable(err error) bool
- func WebSocketURL(region Region, httpsOverride, wsOverride string) (string, error)
- type APIVersion
- type ClientCredentialsOption
- type ClientCredentialsProvider
- type Config
- type Dialer
- type Error
- type Executor
- type GraphQLError
- type Kind
- type Logger
- type Network
- type NopLogger
- type NopRateLimiter
- type Operation
- type Option
- func WithBaseURL(u string) Option
- func WithDialer(d Dialer) Option
- func WithHTTPClient(hc *http.Client) Option
- func WithLogger(l Logger) Option
- func WithRateLimiter(l RateLimiter) Option
- func WithRegion(r Region) Option
- func WithRetryPolicy(p *RetryPolicy) Option
- func WithStrict() Option
- func WithSubProtocol(p SubProtocol) Option
- func WithSubscriptionQueue(capacity int, policy string) Option
- func WithSubscriptionReconnect(n int) Option
- func WithTimeout(d time.Duration) Option
- func WithTokenEndpoint(u string) Option
- func WithTokenProvider(tp TokenProvider) Option
- func WithUserAgent(ua string) Option
- func WithWebSocketURL(u string) Option
- type RateLimiter
- type Region
- type Response
- type RetryPolicy
- type SlogAdapter
- type StaticTokenProvider
- type SubProtocol
- type TokenBucketRateLimiter
- type TokenProvider
- type WSConn
- type WSMessageType
Examples ¶
Constants ¶
const ( OverflowDropOldest = "drop_oldest" OverflowFail = "fail" )
Overflow policies for the subscription bounded queue.
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.
Variables ¶
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 ¶
IsRetryable reports whether err is a typed transient error a caller could safely retry beyond the built-in policy.
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.
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.
type Dialer ¶
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 ¶
Wrap builds an *Error of the given kind around cause — the exported constructor for subpackages and consumers extending the taxonomy.
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) Execute ¶
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 ¶
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.
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 ¶
WithBaseURL sets an explicit HTTPS endpoint override — wins over region.
func WithDialer ¶
WithDialer overrides the WebSocket dialer (tests/custom transport).
func WithHTTPClient ¶
WithHTTPClient supplies a caller-owned http.Client. The SDK will not mutate it; set your own timeout/transport there if needed.
func WithLogger ¶
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 ¶
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 ¶
WithSubscriptionQueue sets the bounded event-buffer capacity and overflow policy (OverflowDropOldest or OverflowFail).
func WithSubscriptionReconnect ¶
WithSubscriptionReconnect sets max reconnect attempts.
func WithTimeout ¶
WithTimeout sets the per-request timeout when no custom client is given.
func WithTokenEndpoint ¶
WithTokenEndpoint overrides the OAuth token endpoint.
func WithTokenProvider ¶
func WithTokenProvider(tp TokenProvider) Option
WithTokenProvider supplies the OAuth token source (required).
func WithWebSocketURL ¶
WithWebSocketURL sets an explicit WSS endpoint override for subscriptions.
type RateLimiter ¶
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 ¶
DecodeData unmarshals Data into v. Numbers inside interface{} targets decode as json.Number (never float64), preserving precision.
func (*Response) HasPartialData ¶
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.
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.
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.
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.
Source Files
¶
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). |
