Skip to main content

Production-grade Solana RPC client with rate limiting, circuit breaking, and provider rotation.

Project description

solana-rpc-resilient

production-grade solana rpc client that handles the real world.

rate limiting. circuit breaking. provider rotation. retry on 429. zero config.



extracted from a production solana trading system. battle-tested with millions of rpc calls.

๐Ÿ›ก๏ธ Why this library?

every solana dev hits the same problems:

  • 429 rate limits โ€” your rpc provider throttles you and your app crashes
  • dead providers โ€” your single rpc endpoint goes down and everything stops
  • no failover โ€” you hardcode one url and pray

this library solves all three with zero config:

from solana_rpc_resilient import ResilientRPCClient

client = ResilientRPCClient([
    {"name": "helius", "url": "https://mainnet.helius-rpc.com/?api-key=YOUR_KEY", "weight": 3},
    {"name": "quicknode", "url": "https://your-quicknode-url.com", "weight": 2},
    {"name": "public", "url": "https://api.mainnet-beta.solana.com", "weight": 1},
])

async with client:
    balance = await client.get_balance("So11111111111111111111111111111111111111112")
    print(balance)  # Ok(489293423) โ€” balance in lamports

if helius returns 429 โ†’ automatically rotates to quicknode. if quicknode is down โ†’ circuit breaker opens, falls back to public. if all providers are down โ†’ auto-recovers the healthiest one after 10s.

you never think about rpc reliability again.

๐Ÿ“ฆ Install

pip install solana-rpc-resilient

requires python 3.11+

You need your own RPC endpoints. Get a free key from Helius, QuickNode, or any Solana RPC provider. The public endpoint (api.mainnet-beta.solana.com) works but is heavily rate-limited.

โšก Features

feature description
adaptive rate limiter token bucket that self-tunes. backs off on 429, climbs back after stable success.
circuit breaker CLOSED โ†’ OPEN โ†’ HALF_OPEN state machine. stops hammering dead endpoints.
provider rotation weighted random selection from healthy providers. auto-failover on 429.
auto-recovery unhealthy providers are re-probed after configurable timeout. never permanently locked out.
request dedup concurrent calls for the same data share one in-flight request.
ttl cache configurable per-method caching to reduce unnecessary calls.
bypass mode emergency calls skip circuit breaker (e.g., checking balance during a sell).

๐Ÿ”ง Components

Rate Limiter

from solana_rpc_resilient import TokenBucketRateLimiter

limiter = TokenBucketRateLimiter(rate=10.0, burst=20.0)

result = await limiter.acquire(timeout=5.0)
if result.is_ok:
    # make your api call
    limiter.record_success()
else:
    # timed out waiting for a token
    pass

# on 429 response:
limiter.record_rate_limit(retry_after=2.0)
# rate automatically decreases. cooldown kicks in.

Circuit Breaker

from solana_rpc_resilient import CircuitBreaker

breaker = CircuitBreaker(
    name="helius",
    failure_threshold=5,    # open after 5 failures
    recovery_seconds=60.0,  # try again after 60s
)

result = await breaker.call(
    my_rpc_function,
    is_retriable=lambda err: err.code == "RATE_LIMITED",  # 429s don't trip the breaker
)

Full Client

from solana_rpc_resilient import ResilientRPCClient

client = ResilientRPCClient(
    providers=[
        {"name": "primary", "url": "https://...", "weight": 3, "tier": "paid"},
        {"name": "backup", "url": "https://...", "weight": 1, "tier": "free"},
    ],
    rate_limit=10.0,       # requests/second
    burst=20.0,            # burst capacity
    failure_threshold=5,   # circuit breaker threshold
    recovery_seconds=60.0, # circuit breaker recovery
)

async with client:
    # all standard solana rpc methods
    balance = await client.get_balance(address)
    info = await client.get_account_info(address)
    sig = await client.send_transaction(tx_bytes, skip_preflight=True)
    statuses = await client.get_signature_statuses(signatures)
    accounts = await client.get_token_accounts(owner)
    slot = await client.get_slot()

    # helius enhanced (falls back to standard if unavailable)
    fees = await client.get_priority_fee_estimate(
        account_keys=["JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB"],
        priority_level="High",
    )

๐ŸŽฏ Result Type

all methods return Result[T, RPCError] โ€” no exceptions to catch:

result = await client.get_balance(address)

if result.is_ok:
    lamports = result.unwrap()
    print(f"balance: {lamports / 1e9:.4f} SOL")
else:
    error = result.unwrap_err()
    print(f"failed: {error.code} โ€” {error.message}")

๐Ÿ—๏ธ Architecture

  your code
     โ”‚
     โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ResilientRPCClient  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  ResponseCache       โ”‚ โ† dedup + TTL
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  TokenBucketLimiter  โ”‚ โ† adaptive rate control
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  CircuitBreaker      โ”‚ โ† failure isolation
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  ProviderRotator     โ”‚ โ† weighted failover
โ”‚    โ”œโ”€ provider A โœ…   โ”‚
โ”‚    โ”œโ”€ provider B โœ…   โ”‚
โ”‚    โ””โ”€ provider C โŒ   โ”‚ โ† auto-recovers
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ†š Comparison

solana-rpc-resilient raw httpx / aiohttp solana-py
Rate limiting โœ… adaptive token bucket โŒ manual โŒ none
Circuit breaker โœ… automatic โŒ manual โŒ none
Provider failover โœ… weighted rotation โŒ single endpoint โŒ single endpoint
429 recovery โœ… backoff + rotate โŒ crash โŒ crash
Request dedup โœ… built-in โŒ manual โŒ none
Result type โœ… Ok / Err โŒ exceptions โŒ exceptions
Async โœ… native โœ… โš ๏ธ sync default

License

MIT


๐Ÿ“ฆ Also by JinUltimate1995

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

solana_rpc_resilient-0.1.0.tar.gz (18.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

solana_rpc_resilient-0.1.0-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

Details for the file solana_rpc_resilient-0.1.0.tar.gz.

File metadata

  • Download URL: solana_rpc_resilient-0.1.0.tar.gz
  • Upload date:
  • Size: 18.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for solana_rpc_resilient-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b393da285d6a062d7cf6185bacff3a191ca810bba8dc5993eed4d6b2bd6d6126
MD5 9d22e83f6948a9be41e63ddea762642c
BLAKE2b-256 e0a469c1bc73874f100ecbc8d9a76caf88d345bb872551a69a7f8e0a1caec28c

See more details on using hashes here.

File details

Details for the file solana_rpc_resilient-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for solana_rpc_resilient-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d54f8168bc43f4199a1d6a7efb16943e690b7d982a55f409ba73a7ddd2cf3b8e
MD5 f808d0efb1777a05a4d739bd05f3cf2e
BLAKE2b-256 f6f5c0a8f26db4757ce09d4b8bf052d7e5443b8c4336a754e9637b173714c3a8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page