erpc

package module
v0.4.0 Latest Latest
Warning

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

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

README

ERPC SDK for Go

Context-aware Go client for ERPC Solana and Ethereum JSON-RPC, indexed data, analytics, WebSocket subscriptions, price streams, account information, usage, and Cloud APIs.

Install

The first Go release is version v0.3.0 from the monorepo tag packages/go/v0.3.0.

go get github.com/elsoul/erpc-sdk/packages/go@v0.4.0

Go 1.22 or later is supported.

Quick start

package main

import (
	"context"
	"fmt"
	"os"

	erpc "github.com/elsoul/erpc-sdk/packages/go"
)

func main() {
	client, err := erpc.NewClient(erpc.Config{APIKey: os.Getenv("ERPC_API_KEY")})
	if err != nil {
		panic(err)
	}
	defer client.Close()

	slot, err := client.Solana.RPC.GetSlot(context.Background())
	if err != nil {
		panic(err)
	}
	chainID, err := client.Ethereum.RPC.ChainID(context.Background())
	if err != nil {
		panic(err)
	}
	fmt.Println(slot, chainID)
}

Every network method accepts context.Context. HTTP calls are attempted once; transaction submission and other state-changing calls are never retried.

Generic, typed, and batch requests

Typed common methods coexist with generic access to every method in the public catalog:

var health string
err := client.Solana.RPC.Raw(ctx, "getHealth", []any{}, &health)

request := erpc.NewRequest[uint64](client.Solana.RPC.RPCNamespace, "getSlot", []any{})
slot, err := request.Send(ctx)

A batch is sent as one intact request and results are returned in caller order:

results, err := client.Ethereum.RPC.Batch(ctx, []erpc.BatchCall{
	{Method: "eth_chainId", Params: []any{}},
	{Method: "eth_blockNumber", Params: []any{}},
})

The SDK rejects batches over 256 calls, mixed Solana heavy/standard batches, and leader-method batches locally.

Subscriptions and price streams

heads, err := client.Ethereum.Subscriptions.Subscribe(ctx, "newHeads")
if err != nil {
	return err
}
var header map[string]any
if err := heads.Next(ctx, &header); err != nil {
	return err
}
_, err = heads.Unsubscribe(ctx)

PriceClient.StreamPriceUpdates returns an SSE stream. Call Next for each event and Close when the stream is no longer needed.

Namespaces

Namespace Purpose
client.Solana.RPC Standard Solana JSON-RPC
client.Solana.DAS Indexed assets and tokens
client.Solana.History Address transactions and transfers
client.Solana.Leaders Leader slots and validator information
client.Solana.Analytics Epoch, slot, program, and TPS analytics
client.Solana.Subscriptions Enhanced WebSocket subscriptions
client.Ethereum.RPC Standard Ethereum JSON-RPC
client.Ethereum.Subscriptions Ethereum WebSocket subscriptions
client.Price Price metadata, updates, and streams
client.Account Token balance
client.Usage Masked monthly API-key usage

Create a separate CloudClient with a scoped access token for catalog, credit, resource, and usage APIs. Refresh credentials are not accepted or retained.

License

MIT

Documentation

Overview

Package erpc provides a context-aware Go client for ERPC JSON-RPC, REST, server-sent events, and WebSocket subscriptions.

Index

Constants

View Source
const (
	DefaultEndpoint        = "https://edge.erpc.global"
	DefaultAccountEndpoint = "https://solana-rpc.erpc.global"
	DefaultUserEndpoint    = "https://user-api.erpc.global"
	DefaultTimeout         = 30 * time.Second
)

Variables

View Source
var EthereumRPCMethods = []string{
	"eth_accounts", "eth_baseFee", "eth_blobBaseFee", "eth_blockNumber", "eth_call", "eth_callMany",
	"eth_capabilities", "eth_chainId", "eth_createAccessList", "eth_estimateGas", "eth_feeHistory", "eth_gasPrice",
	"eth_getAccount", "eth_getBalance", "eth_getBlockByHash", "eth_getBlockByNumber", "eth_getBlockReceipts",
	"eth_getBlockTransactionCountByHash", "eth_getBlockTransactionCountByNumber", "eth_getCode",
	"eth_getFilterChanges", "eth_getFilterLogs", "eth_getLogs", "eth_getProof", "eth_getRawTransactionByHash",
	"eth_getStorageAt", "eth_getTransactionByBlockHashAndIndex", "eth_getTransactionByBlockNumberAndIndex",
	"eth_getTransactionByHash", "eth_getTransactionBySenderAndNonce", "eth_getTransactionCount",
	"eth_getTransactionReceipt", "eth_getUncleCountByBlockHash", "eth_getUncleCountByBlockNumber",
	"eth_maxPriorityFeePerGas", "eth_newBlockFilter", "eth_newFilter", "eth_newPendingTransactionFilter",
	"eth_sendRawTransaction", "eth_signTransaction", "eth_simulateV1", "eth_submitWork", "eth_syncing",
	"eth_uninstallFilter", "net_listening", "net_peerCount", "net_version", "txpool_content", "txpool_contentFrom",
	"txpool_inspect", "txpool_status", "web3_clientVersion", "web3_sha3",
}
View Source
var EthereumSubscriptionMethods = []string{"eth_subscribe", "eth_unsubscribe"}
View Source
var SolanaAnalyticsMethods = []string{"jetEpochSummary", "jetProgramStats", "jetSlotStats", "jetTopPrograms", "jetTpsTimeseries"}
View Source
var SolanaDASMethods = []string{
	"getAsset", "getAssetBatch", "getAssetProof", "getAssetProofBatch", "getAssetsByAuthority",
	"getAssetsByCreator", "getAssetsByGroup", "getAssetsByOwner", "getNftEditions", "getSignaturesForAsset",
	"getTokenAccounts", "getTokensByDelegate", "getTokensByOwner", "searchAssets",
}
View Source
var SolanaEnhancedSubscriptionMethods = []string{"accountSubscribe", "accountUnsubscribe", "transactionSubscribe", "transactionUnsubscribe"}
View Source
var SolanaHistoryMethods = []string{"getTransactionsForAddress", "getTransfersByAddress"}
View Source
var SolanaLeaderMethods = []string{"getLeaderSlots", "getValidatorsInformation"}
View Source
var SolanaRPCMethods = []string{
	"getAccountInfo", "getBalance", "getBlock", "getBlockCommitment", "getBlockHeight",
	"getBlockProduction", "getBlockTime", "getBlocks", "getBlocksWithLimit", "getClusterNodes",
	"getEpochInfo", "getEpochSchedule", "getFeeForMessage", "getFirstAvailableBlock", "getGenesisHash",
	"getHealth", "getHighestSnapshotSlot", "getIdentity", "getInflationGovernor", "getInflationRate",
	"getInflationReward", "getLargestAccounts", "getLatestBlockhash", "getLeaderSchedule", "getMaxRetransmitSlot",
	"getMaxShredInsertSlot", "getMinimumBalanceForRentExemption", "getMultipleAccounts", "getParsedTransaction",
	"getPriorityFeeEstimate", "getProgramAccounts", "getProgramAccountsV2", "getRecentPerformanceSamples",
	"getRecentPrioritizationFees", "getSignatureStatuses", "getSignaturesForAddress", "getSlot", "getSlotLeader",
	"getSlotLeaders", "getStakeMinimumDelegation", "getSupply", "getTokenAccountBalance",
	"getTokenAccountsByDelegate", "getTokenAccountsByOwner", "getTokenLargestAccounts", "getTokenSupply",
	"getTransaction", "getTransactionCount", "getVersion", "getVoteAccounts", "isBlockhashValid",
	"minimumLedgerSlot", "requestAirdrop", "sendTransaction", "simulateTransaction",
}

Method catalogs mirror the wire-compatible method names exposed by ERPC.

Functions

This section is empty.

Types

type AccountClient

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

AccountClient provides account and token-balance APIs.

func (*AccountClient) GetTokenBalance

func (c *AccountClient) GetTokenBalance(ctx context.Context) (TokenBalance, error)

type BatchCall

type BatchCall struct {
	Method string
	Params any
}

BatchCall is one call in a caller-defined, unsplit JSON-RPC batch.

type BinaryUpdate

type BinaryUpdate struct {
	Data     []string `json:"data"`
	Encoding string   `json:"encoding"`
}

type Client

type Client struct {
	Solana   *SolanaClient
	Ethereum *EthereumClient
	Price    *PriceClient
	Account  *AccountClient
	Usage    *UsageClient
}

Client groups all API namespaces backed by one API key.

func NewClient

func NewClient(config Config) (*Client, error)

NewClient validates config and creates an inert client. It performs no network I/O until a method is called.

func (*Client) Close

func (c *Client) Close() error

Close closes subscription connections. HTTP requests require no close.

type CloudCatalogClient

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

func (*CloudCatalogClient) List

type CloudClient

type CloudClient struct {
	Catalog   *CloudCatalogClient
	Credit    *CloudCreditClient
	Resources *CloudResourcesClient
	Usage     *UsageClient
}

CloudClient uses a scoped access token and never accepts refresh credentials.

func NewCloudClient

func NewCloudClient(config CloudConfig) (*CloudClient, error)

type CloudConfig

type CloudConfig struct {
	AccessToken string
	Endpoint    string
	Headers     http.Header
	Timeout     time.Duration
	HTTPClient  *http.Client
}

type CloudCredit

type CloudCredit struct {
	AlertLevel           string   `json:"alertLevel"`
	BalanceCents         int64    `json:"balanceCents"`
	BurnRateCentsPerHour uint64   `json:"burnRateCentsPerHour"`
	QuoteExpiresAt       string   `json:"quoteExpiresAt"`
	QuoteTimestamp       string   `json:"quoteTimestamp"`
	TimeToZeroHours      *float64 `json:"timeToZeroHours"`
}

type CloudCreditClient

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

func (*CloudCreditClient) Get

type CloudOffering

type CloudOffering struct {
	Billing      *CloudOfferingBilling `json:"billing,omitempty"`
	Capabilities []string              `json:"capabilities"`
	Compute      map[string]string     `json:"compute,omitempty"`
	Description  string                `json:"description"`
	ID           string                `json:"id"`
	Kind         string                `json:"kind"`
	Mode         string                `json:"mode,omitempty"`
	Name         string                `json:"name"`
	Regions      []string              `json:"regions"`
	Solana       map[string]string     `json:"solana,omitempty"`
}

type CloudOfferingBilling

type CloudOfferingBilling struct {
	AmountCents uint64 `json:"amountCents"`
	Unit        string `json:"unit"`
}

type CloudResource

type CloudResource struct {
	CreatedAt *string `json:"createdAt"`
	ID        string  `json:"id"`
	Kind      string  `json:"kind"`
	Mode      string  `json:"mode,omitempty"`
	Name      *string `json:"name"`
	Region    *string `json:"region"`
	Status    string  `json:"status"`
}

type CloudResourceStatus

type CloudResourceStatus struct {
	Billing *CloudResourceStatusBilling `json:"billing,omitempty"`
	ID      string                      `json:"id"`
	Status  string                      `json:"status"`
}

type CloudResourceStatusBilling

type CloudResourceStatusBilling struct {
	GraceEndsAt   *string  `json:"graceEndsAt"`
	HourlyCredits *float64 `json:"hourlyCredits"`
	NextChargeAt  *string  `json:"nextChargeAt"`
	Status        string   `json:"status"`
}

type CloudResourcesClient

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

func (*CloudResourcesClient) Get

func (c *CloudResourcesClient) Get(ctx context.Context, resourceID string) (CloudResource, error)

func (*CloudResourcesClient) GetStatus

func (c *CloudResourcesClient) GetStatus(ctx context.Context, resourceID string) (CloudResourceStatus, error)

func (*CloudResourcesClient) List

type Config

type Config struct {
	APIKey          string
	Endpoint        string
	AccountEndpoint string
	UserEndpoint    string
	Headers         http.Header
	Timeout         time.Duration
	HTTPClient      *http.Client
}

Config configures Client. APIKey is retained in memory but never returned by Endpoint methods or SDK errors.

type Error

type Error struct {
	Kind    ErrorKind
	Message string
	Status  int
	Code    int
	Data    json.RawMessage
}

Error is the credential-safe error returned by the SDK.

func (*Error) Error

func (e *Error) Error() string

type ErrorKind

type ErrorKind string

ErrorKind identifies an SDK failure without exposing request credentials.

const (
	ErrorConfig          ErrorKind = "config"
	ErrorTransport       ErrorKind = "transport"
	ErrorHTTP            ErrorKind = "http"
	ErrorRPC             ErrorKind = "rpc"
	ErrorInvalidResponse ErrorKind = "invalid_response"
	ErrorBatchPolicy     ErrorKind = "batch_policy"
)

type EthereumClient

type EthereumClient struct {
	RPC           *EthereumRPCClient
	Subscriptions *EthereumSubscriptions
}

EthereumClient groups standard RPC and subscriptions.

type EthereumRPCClient

type EthereumRPCClient struct{ *RPCNamespace }

EthereumRPCClient provides Ethereum JSON-RPC and typed common methods.

func (*EthereumRPCClient) BlockNumber

func (c *EthereumRPCClient) BlockNumber(ctx context.Context) (string, error)

func (*EthereumRPCClient) Call

func (c *EthereumRPCClient) Call(ctx context.Context, transaction any, block string) (string, error)

func (*EthereumRPCClient) ChainID

func (c *EthereumRPCClient) ChainID(ctx context.Context) (string, error)

func (*EthereumRPCClient) GetBalance

func (c *EthereumRPCClient) GetBalance(ctx context.Context, address, block string) (string, error)

func (*EthereumRPCClient) GetBlockByNumber

func (c *EthereumRPCClient) GetBlockByNumber(ctx context.Context, block string, fullTransactions bool) (json.RawMessage, error)

func (*EthereumRPCClient) SendRawTransaction

func (c *EthereumRPCClient) SendRawTransaction(ctx context.Context, transaction string) (string, error)

SendRawTransaction is attempted exactly once. The SDK never retries it.

type EthereumSubscriptions

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

func (*EthereumSubscriptions) Endpoint

func (c *EthereumSubscriptions) Endpoint() string

func (*EthereumSubscriptions) Raw

func (c *EthereumSubscriptions) Raw(ctx context.Context, method string, params, result any) error

func (*EthereumSubscriptions) Subscribe

func (c *EthereumSubscriptions) Subscribe(ctx context.Context, subscription string, options ...any) (*Subscription, error)

type MonthlyAPIKeyChainUsage

type MonthlyAPIKeyChainUsage struct {
	Chain     string                     `json:"chain"`
	Count     float64                    `json:"count"`
	Credits   float64                    `json:"credits"`
	Methods   []MonthlyAPIKeyMethodUsage `json:"methods"`
	UpdatedAt *string                    `json:"updatedAt"`
}

type MonthlyAPIKeyMethodUsage

type MonthlyAPIKeyMethodUsage struct {
	Count      float64 `json:"count"`
	CreditCost float64 `json:"creditCost"`
	Credits    float64 `json:"credits"`
	Method     string  `json:"method"`
	UpdatedAt  *string `json:"updatedAt"`
}

type MonthlyAPIKeyUsage

type MonthlyAPIKeyUsage struct {
	APIKeys          []MonthlyAPIKeyUsageEntry `json:"apiKeys"`
	Chains           []MonthlyAPIKeyChainUsage `json:"chains"`
	HasStrandedUsage bool                      `json:"hasStrandedUsage"`
	KeyCount         float64                   `json:"keyCount"`
	TotalCount       float64                   `json:"totalCount"`
	TotalCredits     float64                   `json:"totalCredits"`
	UpdatedAt        *string                   `json:"updatedAt"`
	YearMonth        string                    `json:"yearMonth"`
}

type MonthlyAPIKeyUsageEntry

type MonthlyAPIKeyUsageEntry struct {
	APIKeyLast4  string                    `json:"apiKeyLast4"`
	APIKeyLength float64                   `json:"apiKeyLength"`
	Chains       []MonthlyAPIKeyChainUsage `json:"chains"`
	Count        float64                   `json:"count"`
	Credits      float64                   `json:"credits"`
	KeyID        *float64                  `json:"keyId"`
	UpdatedAt    *string                   `json:"updatedAt"`
}

MonthlyAPIKeyUsageEntry only contains the last four API-key characters.

type ParsedPriceUpdate

type ParsedPriceUpdate struct {
	EMAPrice PricePoint       `json:"ema_price"`
	ID       string           `json:"id"`
	Metadata *json.RawMessage `json:"metadata,omitempty"`
	Price    PricePoint       `json:"price"`
}

type PendingRequest

type PendingRequest[T any] struct {
	// contains filtered or unexported fields
}

PendingRequest is an inert typed request. I/O starts when Send is called.

func NewRequest

func NewRequest[T any](namespace *RPCNamespace, method string, params any) *PendingRequest[T]

NewRequest creates a typed pending JSON-RPC request.

func (*PendingRequest[T]) Send

func (r *PendingRequest[T]) Send(ctx context.Context) (T, error)

Send performs the pending request.

type PriceClient

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

func (*PriceClient) GetLatestPriceUpdates

func (c *PriceClient) GetLatestPriceUpdates(ctx context.Context, options PriceUpdateOptions) (PriceUpdateResponse, error)

func (*PriceClient) GetPriceFeeds

func (c *PriceClient) GetPriceFeeds(ctx context.Context, queryText, assetType string) ([]PriceFeedMetadata, error)

func (*PriceClient) GetPriceUpdatesAtTimestamp

func (c *PriceClient) GetPriceUpdatesAtTimestamp(ctx context.Context, publishTime int64, options PriceUpdateOptions) (PriceUpdateResponse, error)

func (*PriceClient) StreamPriceUpdates

func (c *PriceClient) StreamPriceUpdates(ctx context.Context, options PriceStreamOptions) (*PriceStream, error)

type PriceFeedMetadata

type PriceFeedMetadata struct {
	Attributes map[string]string `json:"attributes,omitempty"`
	ID         string            `json:"id"`
}

type PricePoint

type PricePoint struct {
	Conf        string `json:"conf"`
	Expo        int32  `json:"expo"`
	Price       string `json:"price"`
	PublishTime int64  `json:"publish_time"`
}

type PriceStream

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

PriceStream is a streaming SSE response. Call Close when abandoning it.

func (*PriceStream) Close

func (s *PriceStream) Close() error

func (*PriceStream) Next

func (s *PriceStream) Next() (PriceStreamEvent, error)

Next blocks until the next data-bearing SSE event.

type PriceStreamEvent

type PriceStreamEvent struct {
	Data  PriceUpdateResponse
	Event string
	ID    string
}

type PriceStreamOptions

type PriceStreamOptions struct {
	PriceUpdateOptions
	AllowUnordered *bool
	BenchmarksOnly *bool
}

type PriceUpdateOptions

type PriceUpdateOptions struct {
	Encoding              string
	IDs                   []string
	IgnoreInvalidPriceIDs *bool
	Parsed                *bool
}

type PriceUpdateResponse

type PriceUpdateResponse struct {
	Binary BinaryUpdate        `json:"binary"`
	Parsed []ParsedPriceUpdate `json:"parsed,omitempty"`
}

type RPCNamespace

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

RPCNamespace provides generic and batch JSON-RPC access.

func (*RPCNamespace) Batch

func (n *RPCNamespace) Batch(ctx context.Context, calls []BatchCall) ([]json.RawMessage, error)

Batch sends exactly one JSON-RPC batch and returns results in caller order. The transport never silently splits a batch.

func (*RPCNamespace) Endpoint

func (n *RPCNamespace) Endpoint() string

Endpoint returns the public endpoint without credentials, query, or fragment.

func (*RPCNamespace) Raw

func (n *RPCNamespace) Raw(ctx context.Context, method string, params any, result any) error

Raw is an alias for Request for forward-compatible methods.

func (*RPCNamespace) Request

func (n *RPCNamespace) Request(ctx context.Context, method string, params any, result any) error

Request executes one JSON-RPC call and decodes its result into result.

type SolanaClient

type SolanaClient struct {
	RPC           *SolanaRPCClient
	DAS           *RPCNamespace
	History       *RPCNamespace
	Leaders       *RPCNamespace
	Analytics     *RPCNamespace
	Subscriptions *SolanaSubscriptions
}

SolanaClient groups standard and extended Solana APIs.

type SolanaContext

type SolanaContext struct {
	APIVersion string `json:"apiVersion,omitempty"`
	Slot       uint64 `json:"slot"`
}

SolanaContext is standard response context metadata.

type SolanaContextResult

type SolanaContextResult[T any] struct {
	Context SolanaContext `json:"context"`
	Value   T             `json:"value"`
}

SolanaContextResult wraps a value with standard response context metadata.

type SolanaRPCClient

type SolanaRPCClient struct{ *RPCNamespace }

SolanaRPCClient provides standard Solana JSON-RPC and typed common methods.

func (*SolanaRPCClient) GetAccountInfo

func (c *SolanaRPCClient) GetAccountInfo(ctx context.Context, address string, options ...any) (SolanaContextResult[json.RawMessage], error)

func (*SolanaRPCClient) GetBalance

func (c *SolanaRPCClient) GetBalance(ctx context.Context, address string, options ...any) (SolanaContextResult[uint64], error)

func (*SolanaRPCClient) GetLatestBlockhash

func (c *SolanaRPCClient) GetLatestBlockhash(ctx context.Context, options ...any) (json.RawMessage, error)

func (*SolanaRPCClient) GetSlot

func (c *SolanaRPCClient) GetSlot(ctx context.Context, params ...any) (uint64, error)

func (*SolanaRPCClient) GetTransaction

func (c *SolanaRPCClient) GetTransaction(ctx context.Context, signature string, options ...any) (json.RawMessage, error)

func (*SolanaRPCClient) SendTransaction

func (c *SolanaRPCClient) SendTransaction(ctx context.Context, transaction string, options ...any) (string, error)

SendTransaction is attempted exactly once. The SDK never retries a state-changing request automatically.

func (*SolanaRPCClient) SimulateTransaction

func (c *SolanaRPCClient) SimulateTransaction(ctx context.Context, transaction string, options ...any) (json.RawMessage, error)

type SolanaSubscriptions

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

func (*SolanaSubscriptions) AccountSubscribe

func (c *SolanaSubscriptions) AccountSubscribe(ctx context.Context, address string, options ...any) (*Subscription, error)

func (*SolanaSubscriptions) Endpoint

func (c *SolanaSubscriptions) Endpoint() string

func (*SolanaSubscriptions) Raw

func (c *SolanaSubscriptions) Raw(ctx context.Context, method string, params, result any) error

func (*SolanaSubscriptions) RawSubscribe

func (c *SolanaSubscriptions) RawSubscribe(ctx context.Context, method string, params any, unsubscribeMethod string) (*Subscription, error)

func (*SolanaSubscriptions) TransactionSubscribe

func (c *SolanaSubscriptions) TransactionSubscribe(ctx context.Context, filter any, options ...any) (*Subscription, error)

type Subscription

type Subscription struct {
	ID json.RawMessage
	// contains filtered or unexported fields
}

Subscription is an active JSON-RPC subscription.

func (*Subscription) Next

func (s *Subscription) Next(ctx context.Context, result any) error

func (*Subscription) Unsubscribe

func (s *Subscription) Unsubscribe(ctx context.Context) (bool, error)

Unsubscribe is idempotent after a successful server response.

type TokenBalance

type TokenBalance struct {
	MaxTokens       uint64  `json:"max_tokens"`
	NextRefillAt    *string `json:"next_refill_at"`
	Plan            string  `json:"plan"`
	RemainingTokens uint64  `json:"remaining_tokens"`
}

TokenBalance is the current account token balance.

type UsageClient

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

func (*UsageClient) GetMonthlyAPIKeyUsage

func (c *UsageClient) GetMonthlyAPIKeyUsage(ctx context.Context, yearMonth string) (MonthlyAPIKeyUsage, error)

Directories

Path Synopsis
examples
basic command

Jump to

Keyboard shortcuts

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