ERPC SDK
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-sdkThe TypeScript package includes ESM, CommonJS, and TypeScript declarations. Its
runtime dependencies are @noble/curves and @noble/hashes.
Rust:
cargo add erpc-sdkPython:
python -m pip install erpc-sdkGo:
go get github.com/elsoul/erpc-sdk/packages/go@v0.8.1Ruby:
gem install erpc-sdkSee 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
endAPI 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)
: undefinedCloud 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 packageLive smoke tests are opt-in and require a real ERPC key:
ERPC_API_KEY=your_key corepack pnpm --filter @elsoul/erpc-sdk test:livePrefer loading the key from a protected local environment file so it does not enter shell history. Never commit credentials.
Documentation
- Method availability
- DEX and pool catalog
- Bridge capability registry
- Registry roadmap
- Maintenance runbook
- Solana transaction v1 guide
- Changelog
- Roadmap
- Release process
- Contributing
- Security policy
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.