All Blog Posts
Multi-network RPC backends for wallets

Multi-network RPC backends for wallets

By Elias Faltin 8min read

Your wallet's indexer can exhaust the RPC capacity its balance API needs. A Base backfill and Ethereum balance reads share throughput when both use the same Dwellir account limit. A second API key does not increase that limit.

If your wallet uses public or free RPCs on user devices, start with the services you operate. An indexer still needs to backfill records, follow new blocks, and recover from interruptions. Those backend workloads are the focus here.

For initial wallet integration, see connecting a dApp to Ethereum and BSC. For provider throughput ceilings, see RPC rate limits compared.

Use Dwellir for wallet indexing and balance services

Dwellir's standard requests-per-second (RPS) limit applies to the account. All API keys share it. Choosing another network or creating another key does not create a separate RPS allowance. See the rate-limit documentation.

A Dwellir Unlimited Node add-on gives one endpoint its own RPS limit, outside the shared account limit. Usage on that endpoint is unmetered up to the selected limit. It does not consume the plan's API credits.

For example, an Unlimited add-on on your Base indexing endpoint separates its RPS budget from Ethereum balance reads on the standard plan. The add-on covers that endpoint, not every endpoint on Base. Other endpoints remain on the account's shared limit unless they have their own Unlimited add-on.

WorkloadCapacity choiceWhat it changes
Initial integration or intermittent readsStandard account planAll keys share the account's RPS limit and credit allowance
Sustained indexing on one endpointUnlimited add-on for that endpointSeparate RPS limit and unmetered usage up to that limit
Backfill and live reads on the same Unlimited endpointApplication request budgetsBoth share that endpoint's purchased RPS limit

Use the add-on where sustained traffic makes a fixed monthly bill useful. Choose its RPS tier from peak demand, including recovery after downtime. The tier remains a rate limit; it does not reserve hardware or guarantee throughput.

Limit backfill concurrency so it leaves room for live reads on the same endpoint. A separate limit protects other endpoints from that workload's RPS consumption. It does not prioritize requests within the covered endpoint.

Dwellir standard plans share one account RPS limit across keys. An Unlimited add-on gives one endpoint a separate limit and unmetered usage.

Verify chainId when selecting an endpoint

A request sent to the wrong network can return valid JSON. The account might have another balance there, or its transaction receipt might be null. An HTTP success response cannot detect that configuration error.

Maintain a configured endpoint pool for each chain ID. Call eth_chainId when connecting, switching networks, or selecting a failover endpoint. Reject HTTP errors, JSON-RPC errors, malformed results, and unexpected chain IDs before sending wallet requests.

BASH
curl -sS https://api-base-mainnet-archive.n.dwellir.com/YOUR_API_KEY \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'

Base Mainnet should return 0x2105, the hexadecimal representation of 8453. Compare against your configured value, rather than accepting whichever network the endpoint reports.

ChainDecimal chain IDExpected eth_chainId
Ethereum10x1
BNB Smart Chain560x38
Base84530x2105
Arbitrum One421610xa4b1
Optimism100xa

Before broadcasting, also check the signed transaction's chain ID. EIP-155 binds replay-protected legacy signatures to a chain ID. Current typed transactions also include one. A wrong endpoint should reject a transaction signed for another chain, but reads can still return misleading data.

A matching chain ID detects routing mistakes. It does not prove that an untrusted endpoint reports honest data. Use trusted providers and keep API keys out of client logs.

Record the selected provider, expected chain ID, and method in telemetry. Remove mismatched endpoints from that chain's pool. If no verified endpoint remains, report the network as unavailable instead of selecting a default chain.

Check eth_chainId when connecting, switching networks, or failing over. Reject endpoints that return another chain ID.

Separate read retries from transaction recovery

Balance and block queries can move to another verified endpoint after a transport failure. A transaction submission needs more care because a timeout does not reveal whether the node accepted it.

FailureRead handlingTransaction handling
Rate limitHonor retry delays; use bounded backoffApply the same limits and preserve the pending submission
Timeout or server errorRetry against a verified endpoint for that chainCheck the transaction hash before deciding to rebroadcast
Chain ID mismatchRemove the endpointReject it before broadcast
Stale headCompare block progress and choose a current endpointReconcile known transactions before changing nonce state
Different pending nonce valuesLabel pending balances as provisionalUse a durable nonce record and known transaction hashes

Keep transaction submission and pending nonce reads on a consistent backend where the provider supports it. A load-balanced hostname can still route requests to different nodes. Dwellir's sticky-session documentation explains how to preserve backend affinity.

If your backend signs transactions, affinity alone does not coordinate concurrent workers. Store nonce reservations durably and serialize allocation for each sending account. For user-signed transactions, the signing wallet controls nonce selection; your indexer tracks the submitted transaction. See the nonce and mempool guides for the underlying transaction behavior.

After a broadcast timeout:

  1. Retain the signed bytes, transaction hash, chain ID, and reserved nonce.
  2. Look up the transaction and its receipt on a verified endpoint. A null result on one node does not prove that no node accepted it.
  3. If recovery requires another broadcast, submit the same signed bytes. They identify the same transaction.
  4. Create a replacement only through an explicit replacement policy. Do not allocate a new nonce and create another payment automatically.
  5. Reconcile receipts and account nonce state before releasing reservations or reporting the payment complete.

Give reads a deadline and a bounded number of endpoint attempts. Retry transport and rate-limit failures, while returning invalid-parameter errors to the caller. A generic retry wrapper around arbitrary wallet operations can repeat actions that should require reconciliation.

Wallet failover rules distinguish read retries from transaction reconciliation after a broadcast timeout.

Alert on wallet failures by chain and method

Set thresholds from the wallet's service targets and observed traffic. The following signals identify different failures and need different responses.

SignalWhat it can revealResponse
Rate-limit responsesBackground jobs consuming shared capacityReduce background concurrency and inspect the account or Unlimited endpoint limit
Chain ID mismatchMisconfigured endpoint or routingRemove the endpoint and investigate the configuration
Repeated failoversUnstable provider or unsuitable retry policyInspect each failure reason and bound retries
Broadcast success rateSubmission failuresTrack receipt outcomes separately from accepted broadcasts
Balance block ageStale readsLabel cached balances with their block and freshness
Nonce errors after failoverConflicting pending views or local reservationsReconcile transaction hashes and nonce records

A successful broadcast does not mean the transaction executed. Track acceptance, inclusion, execution status, and your required confirmation level separately. Explain the current state in the wallet instead of showing a generic success message.

Test the failover policy before adding networks

Exercise a rate limit, a timed-out broadcast, and a backup with the wrong chain ID. Confirm that reads stay on the selected chain. Confirm that a lost broadcast response cannot create a duplicate payment.

Then test provider recovery. A restored primary should not reset pending nonce reservations or erase transactions submitted through the backup.

Create a Dwellir account to connect your backend to the networks it indexes. Measure live reads and backfills before choosing capacity.

For sustained traffic, compare an Unlimited add-on for the busy endpoint with your metered usage. Contact the Dwellir team with the endpoint, peak RPS, and recovery workload to size it.

read another blog post