Project

erpc-sdk

0.0
The project is in a healthy, maintained state
Ruby client for ERPC Solana, Ethereum, and Avalanche RPC, REST, streams, subscriptions, and Cloud reads.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

>= 5.18, < 6
>= 13, < 14

Runtime

 Project Readme

ERPC SDK

ERPC — Global Edge Blockchain Infrastructure

CI npm crates.io PyPI Go Reference RubyGems license

ERPC Official Multi-Network Blockchain SDK
Built for Developers. Ready for AI Agents.

The current published 0.8.1 line includes the Cloudflare Workers fetch receiver fix. It does not include the unreleased native-USDC bridge or local unsigned builders; those remain source-checkout work under separate review.

With an eRPC API key, one client provides eRPC-backed access to Solana, Ethereum, Avalanche C/P/X-chain, price data, indexed data, leader and validator data, analytics, subscriptions, and account balance information. The source-checkout TypeScript client also exposes a Base read-only JSON-RPC facade with the verified default endpoint https://base.erpc.global; its baseEndpoint option overrides that authenticated endpoint, while baseRpc uses an exact caller-owned URL with scoped headers and no global eRPC API key. The other four language clients expose Base through the shared offline token catalog only. Direct RPC overrides introduced in 0.8.0 and offline token, DEX/pool, and ranking catalog reads do not require an eRPC API key.

Packages

Language Package Version availability
TypeScript @elsoul/erpc-sdk 0.8.1 release line
Rust erpc-sdk 0.8.1 release line
Python erpc-sdk 0.8.1 release line
Go github.com/elsoul/erpc-sdk/packages/go 0.8.1 release line
Ruby erpc-sdk 0.8.1 release line

The package registries expose live version badges for npm, crates.io, PyPI, Go, and RubyGems; the latest GitHub release is the shared release record.

The bounded token, DEX, pool, ranking, and reviewed EVM RPC-only quote APIs are the 0.7.0 history baseline. The direct RPC overrides, unsigned EVM swap preparation and simulation, and optional Mayan adapter are introduced in 0.8.0; install those APIs only when 0.8.0 is shown by the package registry badge and the latest GitHub release.

Install

TypeScript:

npm install @elsoul/erpc-sdk
# or: pnpm add @elsoul/erpc-sdk
# or: yarn add @elsoul/erpc-sdk
# or: bun add @elsoul/erpc-sdk

The TypeScript package includes ESM, CommonJS, and TypeScript declarations. Its runtime dependencies are @noble/curves and @noble/hashes.

Rust:

cargo add erpc-sdk

Python:

python -m pip install erpc-sdk

Go:

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

Ruby:

gem install erpc-sdk

See the package guides for TypeScript, Rust, Python, Go, and Ruby. Minimum versions are Rust 1.85, Python 3.11, Go 1.22, and Ruby 3.1.

Availability

The current published baseline is 0.8.1. It carries the Workers fetch receiver fix while the native-USDC bridge and local unsigned builders remain unreleased source-checkout work.

Capability 0.7.0 package 0.8.0 package
Offline token, DEX, and pool catalogs Included Included
Offline token rankings Included Included; see canonical metadata
Read-only reviewed EVM exact-input quotes (Ethereum Uniswap V2 and Avalanche LFJ legacy) Included Included
Caller-owned direct RPC overrides (solanaRpc, ethereumRpc, avalancheCRpc) Not included Introduced in 0.8.0; requires 0.8.0
Reviewed EVM exact-input preparation and RPC simulation Not included Introduced in 0.8.0; requires 0.8.0
Optional Mayan Swift v2 native EURC bridge Not included Introduced in 0.8.0; requires 0.8.0
Mayan Swift v2 native USDC bridge directions Not included Source addition pending publication; current 0.8.0 packages remain EURC-only
Solana CLMM quotes; multi-hop routing; SDK signing/sending Future work Future work

The 0.7.0 column records the published history baseline. The 0.8.0 column describes the version that introduced each API; live publication status follows the package registry badges and the latest GitHub release.

Direct RPC endpoints

The direct RPC configuration introduced in 0.8.0 lets a caller route selected chain JSON-RPC traffic to a dedicated node without an eRPC API key. A package consumer needs the current published 0.8.1 line for this API; source-checkout examples remain available for reviewed unreleased work.

Config field Direct namespace(s)
solanaRpc erpc.solana.rpc, erpc.solana.das, erpc.solana.history, erpc.solana.leaders, erpc.solana.analytics, and erpc.solana.subscriptions
ethereumRpc erpc.ethereum.rpc, erpc.ethereum.subscriptions, and Ethereum EVM quote reads
avalancheCRpc erpc.avalanche.rpc, erpc.avalanche.subscriptions, and C-Chain EVM quote reads
baseRpc Source-checkout TypeScript erpc.base read-only JSON-RPC (endpoint, eth_chainId, eth_getBalance, and eth_call); unreleased

Extended Solana methods depend on the methods and limits supported by the chosen dedicated RPC provider.

import { createErpcClient } from '@elsoul/erpc-sdk'

const erpc = createErpcClient({
  solanaRpc: {
    httpUrl: 'https://solana.example/customer/path?region=eu',
  },
  ethereumRpc: {
    httpUrl: 'https://ethereum.example/rpc',
  },
  avalancheCRpc: {
    httpUrl: 'https://avalanche.example/rpc',
  },
})

const slot = await erpc.solana.rpc.getSlot().send()
const chainId = await erpc.ethereum.rpc.eth_chainId().send()
const avalancheChainId = await erpc.avalanche.rpc.eth_chainId().send()
console.log({ slot, chainId, avalancheChainId })
erpc.close()

Each supplied httpUrl is the complete final HTTP request target: its path and query are preserved exactly, no eRPC route or api-key is appended, and direct HTTP requests do not follow redirects.

An optional independent webSocketUrl enables subscriptions; it is never derived from httpUrl, and a missing URL does not fall back to eRPC. Scoped headers apply only to direct HTTP JSON-RPC requests and are not sent over WSS:

const subscribed = createErpcClient({
  ethereumRpc: {
    httpUrl: 'https://ethereum.example/rpc',
    webSocketUrl: 'wss://ethereum.example/socket',
    headers: { authorization: 'Bearer node-token' },
  },
})

In keyless mode, non-overridden chains and eRPC REST, native, and index services fail locally with ERPC_NOT_CONFIGURED before network I/O. A direct subscription without webSocketUrl also fails locally, even when an eRPC key is supplied. Add an eRPC API key when those non-overridden eRPC services are needed. Native AVAX, P/X, proposer VM, Info, and index services remain eRPC-backed when avalancheCRpc is used.

See the language-specific direct RPC guides for TypeScript, Rust, Python, Go, and Ruby.

Wallets and signing

The ERPC client has no wallet, privateKey, or signer configuration. It does not import keys or sign locally. sender, from, swapperAddress, and feePayer are public transaction addresses; they do not grant signing authority. Browser and hardware-wallet integrations keep keys inside the external signer. There is no walletSigner API in this SDK.

Item Owner and purpose Where it is sent
Wallet private key or signer The application and its external wallet; signs only after the caller reviews the unsigned envelope External wallet/signer only
ERPC API key Authentication for configured ERPC transports ERPC only
Direct-RPC headers Headers explicitly configured for a direct RPC override That caller-selected direct RPC endpoint only; no ERPC API key is inherited
Mayan builderApiKey Separate provider authentication for bridge builds Mayan /build only; never quote, Explorer, or ERPC
Public transaction addresses Route and transaction metadata The configured RPC or provider request as required

External signing and ERPC broadcast

The caller owns approval policy, chain selection, nonce and fee selection, fresh Solana blockhash handling, transaction review, signing, and confirmation. The SDK's prepareExactInputSwap and Mayan buildUnsigned operations return unsigned data. The handoff is:

unsigned envelope -> external wallet/signer -> signed serialized bytes -> configured ERPC RPC
Chain and unsigned source Caller-supplied signed bytes ERPC broadcast method
EVM: prepareExactInputSwap or Mayan buildUnsigned 0x-prefixed signed transaction hex erpc.ethereum.rpc.eth_sendRawTransaction(signedHex).send()
Solana v0: Mayan buildUnsigned Base64 serialized signed v0 transaction erpc.solana.rpc.sendTransaction(signedBase64, { encoding: 'base64' }).send()

The external signer must be initialized by the application; no wallet signing helper is supplied by the ERPC SDK. The ERPC .send() call makes the RPC request and does not perform cryptographic signing. An eth_signTransaction call, when exposed by an upstream RPC, is also an upstream RPC operation and does not prove that the node manages a wallet. A sign-only integration is required when the caller must retain ERPC broadcast routing; a sign-and-send integration may use the wallet's own RPC instead.

See the TypeScript signing and broadcast guide for fully initialized external-signer helpers and the language package guides for their corresponding unsigned envelopes. The optional ethers and @solana/web3.js examples are consumer integrations and are not ERPC runtime dependencies.

Mayan authentication layers

Mayan authentication has three separate layers. Official Mayan quote and swap documentation says the provider key is optional, and the pinned transaction builder README also describes x-api-key as optional for quote/build: Mayan API-key documentation and the pinned transaction-builder authentication section.

Layer SDK/documented behavior Bounded observation
Official Mayan provider contract Key optional according to the linked Mayan docs; provider policy can change No universal key-required claim is made
ERPC SDK local policy Default buildUnsigned without builderApiKey fails locally; allowUnauthenticatedBuild: true permits a keyless HTTP attempt at the configured endpoint, including the default endpoint Local default guard is separate from provider authorization
Current hosted service check Quotes remain keyless; provider build authorization is decided by Mayan At 2026-09-17T11:27:34.223Z, four EURC/USDC quotes returned HTTP 200, default builds made zero network requests, and explicit anonymous builds reached /build and returned HTTP 401 UNAUTHORIZED; no authenticated build or settlement evidence was captured

The published 0.8.1 bridge supports native EURC and includes the Workers fetch receiver fix. The reviewed native-USDC and local-builder additions remain unreleased. builderApiKey is a Mayan service key and is separate from wallet keys and the ERPC API key; it is sent only to Mayan /build.

Offline token catalog

The source checkout includes a bounded, source-backed token catalog across Ethereum, Solana, Avalanche C-Chain, and Base Mainnet. Catalog reads are local: they do not create a client, need an API key, or access a network.

The public TypeScript names use the chain-qualified constants below. Alias values are opaque deployment IDs; returned deployments keep their lifecycle status (active, legacy, winding-down, or retired) and native deployments use address: null.

import {
  findTokenDeploymentsBySymbol,
  getTokenDeployment,
  TOKEN_CHAIN_IDS,
  tokens,
} from '@elsoul/erpc-sdk'

const ethereumUsdc = getTokenDeployment(tokens.ethereum.USDC)
const solanaUsdc = getTokenDeployment(tokens.solana.USDC)
const avalancheUsdc = getTokenDeployment(tokens.avalancheC.USDC)
const baseEurc = getTokenDeployment(tokens.base.EURC)

const usdOnEthereum = findTokenDeploymentsBySymbol(
  TOKEN_CHAIN_IDS.ethereumMainnet,
  'USDC',
)
const eurOnSolana = findTokenDeploymentsBySymbol(
  TOKEN_CHAIN_IDS.solanaMainnet,
  'EURC',
)
const jpyOnAvalanche = findTokenDeploymentsBySymbol(
  TOKEN_CHAIN_IDS.avalancheCMainnet,
  'JPYC',
)

console.log({ ethereumUsdc, solanaUsdc, avalancheUsdc })
console.log({ baseEurc })
console.log({ usdOnEthereum, eurOnSolana, jpyOnAvalanche })

The stableCurrency filter maps USD to U.S. dollar, EUR to euro, and JPY to Japanese yen. These are straightforward catalog labels; the bounded catalog makes no claim of complete coverage, ranking, or market data. See the canonical registry guide and its source notes for fields, evidence, and lookup rules. All five SDKs expose the corresponding offline list/lookup APIs and catalog metadata; they do not call a runtime vendor service, RPC endpoint, or current clock for these reads.

The existing catalog and quote exports are included in the published 0.7.0 package; the Base additions described here remain source-checkout work pending release.

DEX catalog and RPC-only quotes

The published 0.7.0 packages include generated DEX, pool, native/wrapped, and alias records across the five SDKs. The reviewed seed quote tuples are Ethereum Uniswap V2 (WETH/USDC) and Avalanche LFJ legacy (WAVAX/USDC). Solana Orca Whirlpools and Raydium CLMM records use classic WSOL/EURC for lookup and pair discovery; they are not quote-enabled.

amountIn is a positive decimal string in the input token's base units.

import {
  createErpcClient,
  DEX_CHAIN_IDS,
  pools,
  tokens,
} from '@elsoul/erpc-sdk'

const apiKey = process.env.ERPC_API_KEY
if (!apiKey) throw new Error('ERPC_API_KEY is required')

const erpc = createErpcClient({ apiKey })
const quote = await erpc.swap.quoteExactInput({
  chainId: DEX_CHAIN_IDS.ethereum,
  poolDefinitionId: pools.ethereum.UNISWAP_V2_USDC_WETH,
  inputTokenDeploymentId: tokens.ethereum.WETH,
  outputTokenDeploymentId: tokens.ethereum.USDC,
  amountIn: '1000000000000000000',
})

console.log(quote.amountOut)
erpc.close()

quoteExactInput is a composite async operation and is awaited directly; it does not have a .send() step. Low-level JSON-RPC methods remain pending requests and still use .send(). The quote reads the configured EVM RPC and calculates locally from one block snapshot. Native-to-wrapped definitions are metadata only; no automatic wrapping is performed. Reviewed unsigned preparation and RPC simulation for these two EVM routes are introduced in 0.8.0; Solana CLMM quotes, multi-hop routing, SDK signing, and SDK sending remain future work. Low-level JSON-RPC methods remain available through the chain clients.

Only the reviewed seed pool/token tuples receive quote capability. Discovery can record new pool and token facts for review, but it does not enable new swap execution or bridge support.

Reviewed EVM swap preparation and simulation (introduced in 0.8.0)

The 0.8.0 API adds prepareExactInputSwap and simulateExactInputSwap for both directions of the reviewed Ethereum Uniswap V2 WETH/USDC and Avalanche LFJ WAVAX/USDC tuples. A fresh configured-RPC quote drives local calldata construction, and the result is an unsigned neutral EVM envelope with an explicit allowance requirement. The SDK does not approve, sign, or send it; it does not wrap native assets, execute Solana CLMM routes, or select a multi-hop route.

Use separate client instances when read and execution preparation should use different dedicated RPC endpoints:

const readClient = createErpcClient({
  ethereumRpc: { httpUrl: 'https://read-node.example/rpc' },
})
const executionClient = createErpcClient({
  ethereumRpc: { httpUrl: 'https://execution-node.example/rpc' },
})

const quoteRequest = {
  chainId: DEX_CHAIN_IDS.ethereum,
  poolDefinitionId: pools.ethereum.UNISWAP_V2_USDC_WETH,
  inputTokenDeploymentId: tokens.ethereum.WETH,
  outputTokenDeploymentId: tokens.ethereum.USDC,
  amountIn: '1000000000000000000',
}
const quote = await readClient.swap.quoteExactInput(quoteRequest)

const preparationRequest = {
  ...quoteRequest,
  sender: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
  recipient: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
  slippageBps: 50,
  deadline: String(Math.floor(Date.now()/1000)+300),
}
const prepared = await executionClient.swap.prepareExactInputSwap(preparationRequest)
const simulation = await executionClient.swap.simulateExactInputSwap(preparationRequest)
console.log({ quote, prepared, simulation })
readClient.close()
executionClient.close()

Simulation is read-only and can fail when the caller's wallet has no balance or allowance. The caller's wallet owns allowance changes, fee and nonce fields, signing, and broadcasting. See the DEX and pool registry for the reviewed bindings and the five package guides for language-specific method names. The shared swap fixtures and parity verifier define the cross-language behavior contract; root's read-only preparation observations are recorded in the swap execution evidence packet.

Mayan Swift v2 bridge introduced in 0.8.0

The 0.8.0 API adds a standalone createMayanSwiftV2BridgeClient for native issued EURC between Ethereum and Solana. It exposes quoteExactInput, buildUnsigned, and getStatus for the two exact catalog directions. By default, quotes and builds use https://tx-builder.mayan.finance and indexed status uses https://explorer-api.mayan.finance/v3; set builderEndpoint and explorerEndpoint to customize those provider endpoints. The adapter uses Mayan's hosted quote, transaction-builder, source-swap, solver, relayer, Wormhole, and Explorer services. Its source-side USDC conversion and Solana-origin Jupiter v6 dependency are visible in returned data. This is the explicit bridge-only external-provider exception; normal SDK swaps remain configured RPC and local calculation.

The source checkout now contains reviewed native-USDC directions with deployment IDs deployment-0008 (Ethereum) and deployment-0010 (Solana). They use a direct source route with nullable router fields and no Jupiter/source-swap dependency. The USDC and local-builder additions are unreleased; the currently published 0.8.1 package remains EURC-only. The runnable example below therefore uses the current EURC API.

The source checkout also defines additive local unsigned construction for all four reviewed routes. prepareSourceSwap accepts a normalized quote, public source and destination addresses, and a caller-supplied 16-byte order nonce; buildLocalUnsigned then requires the matching explicitly configured source RPC. EURC source swaps use the bounded Mayan source route, while direct USDC uses no source-swap request. Local construction never falls back to hosted /build, reads provider keys, signs, approves, or broadcasts. See the local construction contract, local fixture, and reference evidence.

import { createMayanSwiftV2BridgeClient, TOKEN_CHAIN_IDS } from '@elsoul/erpc-sdk'

const mayanQuoteClient = createMayanSwiftV2BridgeClient({
  builderEndpoint: 'https://tx-builder.mayan.finance',
  explorerEndpoint: 'https://explorer-api.mayan.finance/v3',
})
const quotes = await mayanQuoteClient.quoteExactInput({
  sourceChainId: TOKEN_CHAIN_IDS.ethereumMainnet,
  destinationChainId: TOKEN_CHAIN_IDS.solanaMainnet,
  sourceTokenDeploymentId: 'deployment-0011',
  destinationTokenDeploymentId: 'deployment-0013',
  amountIn: '1000000',
  slippageBps: 50,
})
mayanQuoteClient.close()
const mayanBuilderApiKey = process.env.MAYAN_BUILDER_API_KEY
if (!mayanBuilderApiKey) throw new Error('MAYAN_BUILDER_API_KEY is required for a keyed build')
const mayanBuildClient = createMayanSwiftV2BridgeClient({
  builderEndpoint: 'https://tx-builder.mayan.finance',
  explorerEndpoint: 'https://explorer-api.mayan.finance/v3',
  builderApiKey: mayanBuilderApiKey,
})
const built = await mayanBuildClient.buildUnsigned({
  quote: quotes[0],
  swapperAddress: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
  destinationAddress: 'So11111111111111111111111111111111111111112',
})
const sourceTransactionHash = process.env.MAYAN_SOURCE_TRANSACTION_HASH
if (!sourceTransactionHash) throw new Error('MAYAN_SOURCE_TRANSACTION_HASH is required for status')
const status = await mayanBuildClient.getStatus({
  sourceChainId: TOKEN_CHAIN_IDS.ethereumMainnet,
  sourceTransactionHash: sourceTransactionHash,
})
console.log({ built, status })
mayanBuildClient.close()

builderApiKey is sent only to /build; quote and status calls work without it and never receive an eRPC key or ambient credentials. A keyless build attempt at any configured endpoint, including the default endpoint, requires the explicit allowUnauthenticatedBuild opt-in; this does not override Mayan's provider authorization policy. Provider signatures, transaction semantics, and settlement are structurally checked and remain locally unverified. The returned transaction is unsigned; the consumer wallet decides whether to approve, sign, and send. Do not vendor or self-host the upstream transaction-builder repository, whose licensing is unresolved. See the bridge registry and the package guides for language-specific constructors and error names. Cross-language bridge behavior is captured by the shared fixture registry and parity verifier; CI and independent review records remain the source of gate status.

Offline token rankings

The published 0.7.0 packages expose an offline ranking snapshot and its metadata. The ranking metric is total supply multiplied by the direct native pool price, in exact rational native atomic units. It is not circulating market capitalization. Coverage is explicit; partial coverage and unranked reasons remain visible in the snapshot. The optional global USD market-cap metric is rights-gated and disabled by default.

Ranking lookups use exact chain IDs and read no network, vendor API, current time, or client configuration. Generated records and metadata are immutable in each SDK. The canonical ranking artifact and ranking configuration carry the current metric, observation time, status, coverage, digest, and unranked reasons. See the ranking implementation and the package entry-point documentation for the language-specific list API.

Source-checkout maintenance

The source checkout has bounded, read-only RPC discovery for Ethereum factory pairs, Avalanche factory pairs, and Solana program accounts. Verified address facts are replayed from the configured endpoints in registry/discovery.mjs using registry/discovery-config.json. Newly observed tokens use unclassified address-only names and symbols, with stableCurrency, underlyingAssetId, and economicReferenceAssetId set to null until reviewed.

Admission is capped at 8 tokens and 8 pools per run. Current catalog records, source evidence, and metadata are maintained in the canonical token catalog, DEX and pool catalog, and ranking artifact. Direct reviewed native pools use WETH, WAVAX, or classic WSOL and native liquidity floors of 10 ETH, 100 AVAX, or 100 SOL in chain-native atomic units. Discovery state is bounded and resumable; cap- or dependency-deferred candidates are revalidated from fresh verified receipts before they can be reconsidered. IDs and aliases are append-only, and an RPC outage does not retire an existing record.

The installed schedules are daily discovery/ranking maintenance at 03:17 UTC, an hourly read-only pool monitor at minute 13 with a persisted rotating batch of 32, and Thursday release preparation at 03:47 UTC. Automatic data merge and automatic release are opt-in through ERPC_ENABLE_AUTOMATIC_DATA_MERGE and ERPC_ENABLE_AUTOMATIC_RELEASE; both are currently OFF. Eligible additive data can merge only after exact CI and applicable branch protection. A later baseline-to-data merge followed by a version-only PR can produce the paired root and Go tags in the release workflow, followed by an explicit publisher dispatch when the opt-in policies and protections are enabled. Source, schema, adapter, and API changes, including the initial 0.7.0 feature release, require manual review. These schedules prepare reviewable work; the local integration evidence is not Actions promotion provenance, and these schedules do not establish that a live scheduled run has succeeded.

Quick starts

TypeScript

import { createErpcClient } from '@elsoul/erpc-sdk'

const apiKey = process.env.ERPC_API_KEY
if (!apiKey) throw new Error('ERPC_API_KEY is required')

const erpc = createErpcClient({ apiKey })

const slot = await erpc.solana.rpc.getSlot().send()
const chainId = await erpc.ethereum.rpc.eth_chainId().send()
const avalancheChainId = await erpc.avalanche.rpc.eth_chainId().send()

console.log({ slot, chainId, avalancheChainId })
erpc.close()

HTTP JSON-RPC methods return a pending request. Calling .send() performs the request, so request construction stays explicit and future middleware can be added without changing method signatures.

Rust

use erpc_sdk::{ErpcClient, ErpcClientConfig};

let erpc = ErpcClient::new(ErpcClientConfig::new(api_key))?;
let slot = erpc.solana.rpc.get_slot(Vec::<serde_json::Value>::new())?
    .send()
    .await?;
let chain_id = erpc.ethereum.rpc.eth_chain_id().send().await?;
let avalanche_chain_id = erpc.avalanche.rpc.eth_chain_id().send().await?;

Python

from erpc_sdk import ErpcClient, ErpcClientConfig

async with ErpcClient(ErpcClientConfig(api_key)) as erpc:
    slot = await erpc.solana.rpc.get_slot().send()
    chain_id = await erpc.ethereum.rpc.eth_chain_id().send()
    avalanche_chain_id = await erpc.avalanche.rpc.eth_chain_id().send()

Go

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

client, err := erpc.NewClient(erpc.Config{APIKey: apiKey})
if err != nil {
	return err
}
defer client.Close()

slot, err := client.Solana.RPC.GetSlot(ctx)
chainID, err := client.Ethereum.RPC.ChainID(ctx)
avalancheChainID, err := client.Avalanche.RPC.ChainID(ctx)

Ruby

require "erpc_sdk"

begin
  erpc = ERPC::Client.new(ERPC::ClientConfig.new(api_key: api_key))
  slot = erpc.solana.rpc.get_slot.send
  chain_id = erpc.ethereum.rpc.eth_chain_id.send
  avalanche_chain_id = erpc.avalanche.rpc.eth_chain_id.send
ensure
  erpc&.close
end

API overview

Namespace Purpose
erpc.solana.rpc Solana JSON-RPC
erpc.solana.das Indexed assets and tokens
erpc.solana.history Address transactions and transfers
erpc.solana.leaders Leader slots and validator information
erpc.solana.analytics Epoch, slot, program, and TPS analytics
erpc.solana.subscriptions Enhanced WebSocket subscriptions
erpc.ethereum.rpc Ethereum JSON-RPC
erpc.ethereum.subscriptions Ethereum WebSocket subscriptions
erpc.avalanche.rpc Avalanche C-Chain EVM-compatible JSON-RPC
erpc.avalanche.subscriptions Avalanche C-Chain WebSocket subscriptions
erpc.avalanche.avax C-Chain AVAX atomic transaction API
erpc.avalanche.xChain X-Chain (avm.*) API
erpc.avalanche.pChain P-Chain (platform.*) API
erpc.avalanche.proposerVm P-Chain proposer VM API
erpc.avalanche.info Avalanche network upgrade information
erpc.avalanche.index C/P/X block and X transaction indexes
erpc.price Price metadata, updates, and streams
erpc.account ERPC token balance
erpc.usage Masked monthly API-key usage
cloud.catalog Provider-neutral Cloud capabilities
cloud.credit Read-only credit and burn-rate snapshot
cloud.resources Credential-free Cloud resource inventory

See method availability for the complete supported catalog and the server-dependent capabilities planned for later releases.

Solana examples

const balance = await erpc.solana.rpc.getBalance(address).send()
const asset = await erpc.solana.das.getAsset({ id: assetId }).send()
const leaders = await erpc.solana.leaders.getLeaderSlots(slot).send()

const transactions = await erpc.solana.history
  .getTransactionsForAddress(address, { limit: 20 })
  .send()

const programs = await erpc.solana.analytics
  .jetTopPrograms({ limit: 10 })
  .send()

Solana transaction v1

Solana v1 and its 4096-byte transaction-size support were activated on the network on 2026-09-15; v0 and legacy transactions remain unchanged. See the official larger transaction sizes note. For generic RPC pass-through, pass maxSupportedTransactionVersion: 1 when the caller supports v1, and pass a serialized payload with encoding: 'base64' when sending or simulating a larger transaction. The SDK forwards these options and payloads unchanged; the caller supplies the signed transaction, and the SDK does not build, sign, or decode it. A server JSON-RPC error such as -32015 remains an ErpcJsonRpcError with its numeric code and optional data preserved. The Mayan bridge adapter has a separate provider envelope contract: it accepts only v0 framing at or below 1232 bytes and rejects v1 until a provider-specific v1 contract is reviewed. See the Solana transaction v1 guide.

const transaction = await erpc.solana.rpc
  .getTransaction(signature, { maxSupportedTransactionVersion: 1 })
  .send()
const sent = await erpc.solana.rpc
  .sendTransaction(serializedBase64, { encoding: 'base64' })
  .send()

Ethereum examples

const block = await erpc.ethereum.rpc
  .eth_getBlockByNumber('latest', false)
  .send()

const balance = await erpc.ethereum.rpc
  .eth_getBalance(address, 'latest')
  .send()

Avalanche examples

Avalanche C-Chain EVM calls continue to use the Ethereum-compatible catalog. Native AVAX, X-Chain, P-Chain, proposer VM, and information methods use named parameters on /ava. Index calls use their required explicit C/P/X routes.

const chainId = await erpc.avalanche.rpc.eth_chainId().send()
const block = await erpc.avalanche.rpc
  .eth_getBlockByNumber('latest', false)
  .send()

const pHeight = await erpc.avalanche.pChain.getHeight().send()
const xHeight = await erpc.avalanche.xChain.getHeight().send()
const validators = await erpc.avalanche.pChain
  .getCurrentValidators({})
  .send()
const indexedTransaction = await erpc.avalanche.index.xChainTransactions
  .getContainerByID({ id: transactionId })
  .send()

const accepted = await erpc.avalanche.subscriptions.subscribe(
  'newAcceptedTransactions',
  (transaction) => console.log(transaction),
)

await accepted.unsubscribe()

Native and Index API namespaces do not support JSON-RPC batches; the SDK rejects non-empty batches before network I/O. Every namespace retains raw access for forward-compatible exact wire method names.

Price data

const latest = await erpc.price.getLatestPriceUpdates({
  ids: [feedId],
  parsed: true,
})

for await (const event of erpc.price.streamPriceUpdates({ ids: [feedId] })) {
  console.log(event.data)
}

Price and confidence values are strings to preserve protocol precision.

Account balance

const tokenBalance = await erpc.account.getTokenBalance()
console.log(tokenBalance.remaining_tokens)

Monthly API-key usage

The regular API-key client can read the current month or a specific calendar month. Results contain only the key length and last four characters; the SDK also projects the response onto the documented fields so unexpected credential fields are never returned to application code.

const usage = await erpc.usage.getMonthlyApiKeyUsage()
const august = await erpc.usage.getMonthlyApiKeyUsage({
  yearMonth: '2026-08',
})

console.log(usage.totalCredits, august.apiKeys[0]?.apiKeyLast4)

Cloud read client

Applications that already have a scoped ERPC Cloud OAuth access token can use the separate Cloud client. It does not accept or retain a refresh credential.

import { createErpcCloudClient } from '@elsoul/erpc-sdk'

const cloud = createErpcCloudClient({ accessToken })
const catalog = await cloud.catalog.list()
const credit = await cloud.credit.get()
const resources = await cloud.resources.list()
const usage = await cloud.usage.getMonthlyApiKeyUsage()

const first = resources[0]
const resource = first ? await cloud.resources.get(first.id) : undefined
const status = first
  ? await cloud.resources.getStatus(first.id)
  : undefined

Cloud resource responses deliberately exclude usernames, passwords, hosts, and internal product or subscription identifiers. The Cloud OAuth and resource routes are enabled as a coordinated server rollout; see the roadmap for rollout status. Catalog entries omit prices and availability that the service cannot verify. Credit snapshots use integer cents and include their quote validity window. The CLI owns interactive Device Authorization and keychain storage.

Batch requests

const [slot, blockHeight] = await erpc.solana.rpc
  .batch([
    { method: 'getSlot', params: [] },
    { method: 'getBlockHeight', params: [] },
  ])
  .send()

The SDK preserves server batch boundaries. It rejects unsupported mixed Solana batches locally, accepts at most 256 calls in one batch, and never silently splits a batch.

WebSocket subscriptions

const heads = await erpc.ethereum.subscriptions.subscribe(
  'newHeads',
  (header) => console.log(header),
)

const accounts = await erpc.solana.subscriptions.accountSubscribe(
  address,
  (account) => console.log(account),
)

await heads.unsubscribe()
await accounts.unsubscribe()
erpc.close()

Browsers and modern Node.js releases can use their global WebSocket implementation. Other runtimes can pass a compatible constructor with the webSocket client option.

Error handling

import {
  ErpcHttpError,
  ErpcJsonRpcError,
  ErpcTimeoutError,
} from '@elsoul/erpc-sdk'

try {
  await erpc.solana.rpc.getSlot().send()
} catch (error) {
  if (error instanceof ErpcJsonRpcError) {
    console.error(error.rpcCode, error.message, error.data)
  }
  else if (error instanceof ErpcHttpError) console.error(error.status)
  else if (error instanceof ErpcTimeoutError) console.error('Timed out')
  else throw error
}

Error URLs redact the API key. Requests are not retried automatically, which avoids unexpectedly repeating state-changing calls.

Raw methods

Typed catalogs cover every method currently exposed by ERPC. New server methods can be called before the next SDK release through the raw escape hatch:

const result = await erpc.solana.rpc
  .raw<MyResult>('futureMethod', [{ enabled: true }])
  .send()

Configuration

const erpc = createErpcClient({
  apiKey,
  endpoint: 'https://edge.erpc.global',
  avalancheEndpoint: 'https://ava-rpc.erpc.global',
  accountEndpoint: 'https://solana-rpc.erpc.global',
  userEndpoint: 'https://user-api.erpc.global',
  timeoutMs: 30_000,
  fetch: customFetch,
  webSocket: CustomWebSocket,
})

apiKey is required for default eRPC connections. The 0.8.0 direct-node settings above (solanaRpc, ethereumRpc, or avalancheCRpc) allow keyless selected RPC access; legacy endpoint and avalancheEndpoint remain eRPC base URLs, not full dedicated-node overrides. Default endpoints and timeout values are exported for applications that need to inspect them.

Development

corepack pnpm install --frozen-lockfile
corepack pnpm check
corepack pnpm test
corepack pnpm build
corepack pnpm pack:check
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo test --workspace --locked
cargo package --package erpc-sdk
cd packages/ruby
bundle install
bundle exec rake
bundle exec rake package

Live smoke tests are opt-in and require a real ERPC key:

ERPC_API_KEY=your_key corepack pnpm --filter @elsoul/erpc-sdk test:live

Prefer loading the key from a protected local environment file so it does not enter shell history. Never commit credentials.

Documentation

Release model

Publishing is initiated by a human-pushed version tag. The release workflow is configured for registry Trusted Publishing and provenance. Merging a change never publishes a package. See the release process for initial setup and release steps.

License

MIT