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.1.tar.gz (18.9 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.1-py3-none-any.whl (19.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: solana_rpc_resilient-0.1.1.tar.gz
  • Upload date:
  • Size: 18.9 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.1.tar.gz
Algorithm Hash digest
SHA256 5de81e86721d4e41de60e7cf7487a7b2077c8ea7ad7d50131588a2f7f50c9968
MD5 fce39b48e31542b7b8535fd127b640f4
BLAKE2b-256 415d0a8fbc07a8cf84a4265124308290e0455d544668069e03b9e84c1de614d4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for solana_rpc_resilient-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c2c480b50a35b635f34c4de0d0c01c6779ec66ee54f5c94e18876bf4d7ae8b94
MD5 eb8d2d3a174f749c02de94cddd37b047
BLAKE2b-256 158bd90c104145eefbbd0e771bbb697f8f7274387560b21f4cc9f6cb66034513

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