How to get a Solana RPC endpoint for RWA (2026 guide)

TL;DR
The first time an RWA team tries to snapshot every holder of a tokenized treasury on Solana, they reach for getProgramAccounts filtered by mint — and the public endpoint either throttles it, truncates the response, or times out, because that one call is rate-limited harder than any other method on the network. There is no eth_getLogs to fall back on and no block-number to anchor a proof-of-reserves query, so the cap table you need for a record-date snapshot quietly comes back incomplete. This guide explains why holder enumeration is the hard part of real-world-asset (RWA) infrastructure on Solana, and how to get a private Solana RPC endpoint that can actually serve it.
What is a Solana RPC endpoint
A Solana RPC endpoint is the JSON-RPC (and WebSocket) interface your application uses to read account state, submit transactions, and subscribe to live updates on a Solana node. Solana looks superficially familiar to Ethereum developers — it speaks JSON-RPC over HTTPS — but the data model underneath is account-based, not contract-storage-based: everything on Solana, including a tokenized fund’s supply, every holder’s balance, and the compliance rules attached to a permissioned token, lives in discrete accounts owned by a program. For RWA workloads this is the whole story, because the questions you need to answer — who holds this asset, how much, and were they allowed to — are reads against many small accounts rather than a single contract call.
What depends on the endpoint, specifically on Solana:
- Reading individual account state with
getAccountInfo(a single holder’s token balance, mint supply, freeze authority) - Enumerating holders with
getProgramAccountsfiltered by mint — the basis of cap-table snapshots and proof of reserves - Submitting and simulating transactions (mint, transfer, redeem, freeze/thaw) with
sendTransactionandsimulateTransaction - Reconstructing activity history through
getSignaturesForAddressandgetTransaction, since there is no event-log query - Subscribing to live mint, burn, and transfer activity over WebSocket (
accountSubscribe,logsSubscribe) - Reading historical balances at a specific slot for audit and reserve attestation
You can review the full list of supported methods in the official Solana RPC documentation.
On Solana, endpoint quality shows up as a holder list that comes back short rather than as an outright error: a throttled or paginated getProgramAccounts can return a partial account set with a 200 OK, so a cap-table snapshot or reserve attestation looks like it succeeded when it silently missed accounts — the worst possible failure for a workload whose entire purpose is provable completeness.
How Solana RPC differs from EVM chains
If you are coming from Ethereum, Solana shares the JSON-RPC transport but almost nothing of the data model, and for RWA the gap is exactly where compliance and reporting live.
State is accounts, not contract storage. On Ethereum, a tokenized asset’s balances live in mapping slots inside one contract, and you read them through a view function or eth_getStorageAt. On Solana, each holder’s balance is its own token account, separate from the mint, separate from every other holder. There is no single contract to query for “all balances” — you enumerate the accounts. That makes getProgramAccounts, filtered to the token program and the specific mint, the canonical way to reconstruct a holder set, and it is the heaviest, most aggressively rate-limited call on the network.
There is no eth_getLogs. The single biggest adjustment for RWA developers: Solana has no event-log query primitive. You cannot scan a slot range for Transfer or ComplianceCheck events across accounts in one call. Transfer history is reconstructed from transaction signatures (getSignaturesForAddress) and decoded transactions, or streamed in real time over WebSocket or a Geyser gRPC plugin — a different model you provision and scale separately.
Compliance lives in the token program, not in your contract. Solana’s permissioned-asset standard is Token-2022 (Token Extensions). Instead of inheriting an ERC-3643-style base contract, an issuer attaches extensions to the mint: a transfer hook that fires a separate program on every transfer, a default-frozen account state that keeps wallets inert until KYC clears, and a permanent delegate for clawback. Reading and enforcing those rules means reading account state and the hook program’s accounts — more reads, against more accounts, on every transfer.
Time is measured in slots, not block numbers. Solana orders state by a monotonically increasing slot. For RWA audit trails this is workable — you can ask what an account held as of a past slot — but your historical queries are keyed on slot, and reconstructing state at an arbitrary past slot requires an archive node.
The practical takeaway: the data you need for RWA reporting is spread across many accounts and has no log-query shortcut, so the provider you choose has to sustain heavy getProgramAccounts fan-out, expose reliable WebSocket subscriptions, and serve historical slots — not just answer single-account reads quickly.
Solana RPC endpoint options
Public vs private Solana RPC endpoints
For RWA workloads the public-vs-private decision comes down to one method: can the endpoint serve getProgramAccounts at the size of your holder set, repeatedly, without truncating? A proof-of-reserves snapshot or a cap-table export is one heavy enumeration over every token account for a mint, and the public Solana endpoint is sized for exploration — it caps requests per IP and rate-limits the expensive enumeration calls hardest of all.
Official public endpoints:
- Mainnet:
https://api.mainnet-beta.solana.com - Devnet:
https://api.devnet.solana.com
⚠️ The public Solana endpoints allow roughly 100 requests per 10 seconds per IP, with
getProgramAccountsand other expensive calls throttled more aggressively still, and there is no SLA. A holder enumeration over a growing RWA mint can return a truncated or rate-limited result with no clean error, leaving a reserve snapshot silently incomplete. The Solana docs themselves recommend using professional RPC providers: the Solana clusters reference states the public endpoints “are not intended for production applications.”
| Factor | Public endpoint | Private endpoint |
|---|---|---|
| Access | Free and open | Restricted access |
| Resources | Shared infrastructure | Dedicated resources |
| Best use case | Development & testing | Production workloads |
| Rate limit | ~100 req / 10s per IP | No aggressive throttling |
getProgramAccounts (holder enumeration) | Throttled and truncated | Sustained, complete responses |
| Archive / historical-slot access | Not available | Available |
When a reserve attestation depends on enumerating every holder of a mint before a record date, an endpoint that quietly returns a partial account set is not a reliability inconvenience — it is a compliance failure you may not detect until an auditor does. That is the case for managed infrastructure on Solana RWA workloads.
📖 For a detailed comparison of Solana RPC providers, see Best Solana RPC providers in 2026.
Full node vs archive Solana node
For RWA on Solana, historical access is a compliance requirement rather than a convenience: proof of reserves and cap-table snapshots ask what a mint’s supply and holder balances were at a specific point in the past, which on Solana means reading account state as of a specific slot.
| Full node access | Archive node access |
|---|---|
| Current holder balances and mint supply | Holder balances reconstructed at any past slot |
| Live freeze-status and transfer-hook reads | Audit trail of supply and balance changes over time |
| Submitting mint, transfer, and redeem transactions | Proof-of-reserves snapshots at historical record dates |
Because Solana orders state by slot and full nodes prune older state, a Chainstack archive node is what lets you query an account’s balance as of any historical slot — the backbone of proof of reserves and the regulator-ready audit trail that tokenized-asset reporting depends on. Chainstack supports archive nodes for Solana.
HTTPS vs WebSockets
RWA reconciliation is where the transport choice bites: polling getProgramAccounts to detect new transfers is both expensive and laggy, so the moment you need to react to mints, burns, and transfers as they land, persistent subscriptions stop being optional. Solana exposes native WebSocket subscriptions alongside the HTTPS JSON-RPC interface, so you do not have to poll for events.
| Feature | HTTPS | WebSocket |
|---|---|---|
| Model | Request/response | Persistent connection |
| Complexity | Simple operationally | Requires reconnect/heartbeat logic |
| Best for | Holder enumeration, balance reads, tx submission, historical-slot queries | Streaming mint/burn/transfer activity for live compliance and reconciliation |
| Latency | Standard | Lower for frequent updates |
| Connection overhead | Per request | One-time handshake |
In practice, an RWA application uses both: HTTPS for the heavy getProgramAccounts snapshots and historical-slot reads, and WebSocket subscriptions (accountSubscribe, logsSubscribe) to feed compliance and reconciliation the instant a transfer lands instead of polling. For very high event volume, a Geyser gRPC stream is the higher-throughput alternative to standard WebSockets.
How to get a private Solana RPC endpoint with Chainstack

You can deploy a private Solana RPC node on Chainstack in a few steps:
- Log in to the Chainstack console (or create an account)
- Create a new project
- Select Solana as your blockchain protocol
- Choose network: Solana Mainnet or Solana Devnet
- Deploy the node
- Open Access and credentials and copy your HTTPS and WebSocket endpoints
- Run a quick connectivity check before wiring it into production code
Once you have the endpoint, connect with the current Solana SDK, @solana/kit, and read an account balance — the same primitive an RWA app uses to check a single holder before fanning out to the full set:
import { createSolanaRpc, address } from "@solana/kit";
// Point the client at your Chainstack HTTPS endpoint
const rpc = createSolanaRpc("YOUR_CHAINSTACK_ENDPOINT");
// Single-account read; .send() dispatches the JSON-RPC request
const balance = await rpc
.getBalance(address("23dQfKhhsZ9RA5AAn12KGk21MB784PmTB3gfKRwdBNHr"))
.send();
console.log(balance);
📖 For the full integration guide, see the Chainstack Solana tooling documentation.
You can also access Chainstack Solana RPC directly from Claude, Cursor, Codex, Gemini, or Windsurf using Chainstack MCP. Learn more about Chainstack MCP.
Chainlist is EVM-only and does not apply to Solana — there is no Chainlist entry to point a wallet at a Solana endpoint.
Chainstack pricing for Solana RPC
Chainstack bills on request units instead of opaque compute credits, which makes an RWA workload straightforward to model: a reserve snapshot is a known number of getProgramAccounts and account reads, so you can forecast cost from how often you re-snapshot holders. See the full Chainstack pricing page for plan details and overage rates.
| Plan | Cost | Requests/Month | RPS | Overage (per 1M extra) |
|---|---|---|---|---|
| Developer | $0 | 3M RU | 25 | $20 |
| Growth | $49 | 20M RU | 250 | $15 |
| Pro | $199 | 80M RU | 400 | $12.50 |
| Business | $499 | 200M RU | 600 | $10 |
| Enterprise | from $990 | 400M+ RU | Unlimited | $5 |
Advanced options relevant to Solana RWA workloads:
- Archive node access — archive requests consume 2 RU each versus 1 RU for full-node requests; essential for proof-of-reserves and historical-slot balance reads. See Chainstack archive data.
- Unlimited Node — flat monthly fee with RPS-tiered throughput, useful when frequent holder enumeration drives high, steady read volume.
- Dedicated Nodes — isolated infrastructure from $0.50/hour per node plus storage, for institutional RWA platforms that need throughput guarantees and can add a Geyser gRPC stream for real-time event delivery.
How to estimate monthly cost
- Estimate baseline reads per minute (single-holder balance lookups, dashboard refreshes, freeze-status checks)
- Add transaction submissions (mints, transfers, redemptions) per minute
- Add your real-time subscription load and any Geyser stream
- Map the total against the plan tiers above, leaving headroom for overage
- The Solana-specific multiplier: a
getProgramAccountssnapshot over a mint with thousands of holders is one very expensive call, and if you run it on every record date or reconciliation cycle it can dwarf your steady-state read volume. Size for the snapshot cadence, not the average request rate.
Production readiness checklist
- Primary + fallback RPC provider configured
- Request timeout policy set
- Retry logic with exponential backoff implemented
- Credentials stored in env/secret manager (never hardcoded)
- Monitoring for latency, error rate, and throttling
- Alerts for sustained degradation
getProgramAccountsresponses validated for completeness (verify account counts; never assume a200means the full holder set) and paginated withdataSlice/filters where possible- Archive endpoint confirmed for historical-slot proof-of-reserves reads before any reserve attestation goes live
- WebSocket reconnect plus missed-event backfill from
getSignaturesForAddress, so a dropped subscription does not leave a gap in the compliance feed
Benchmark candidate endpoints against the Chainstack performance dashboard before committing reserve-critical traffic to a provider.
Troubleshooting common Solana RPC issues
| Issue | Cause | How to fix |
|---|---|---|
429 Too Many Requests | Public endpoint per-IP cap hit | Move to a managed endpoint with dedicated throughput |
| Holder enumeration returns a partial set | getProgramAccounts throttled or truncated on a shared endpoint | Use a private endpoint, add mint/dataSlice filters, and validate the returned account count against expected supply |
getProgramAccounts times out | Mint has too many holders for one unbounded call | Narrow with memcmp filters, request only needed fields via dataSlice, and run on dedicated infrastructure |
| Reconstructing transfer history fails | Looking for an eth_getLogs equivalent that does not exist | Use getSignaturesForAddress + getTransaction, or stream events over WebSocket / Geyser gRPC |
| Historical balance query returns nothing | Full node has pruned the target slot | Query an archive node, which retains account state at any past slot |
| Transfer reverts on a permissioned token | Token-2022 transfer hook or default-frozen account state rejected it | Confirm both wallets are thawed/KYC-cleared and the hook program’s required accounts are passed in the transaction |
Conclusion
The failure that catches Solana RWA teams is not a crash — it is a getProgramAccounts snapshot that comes back short and returns 200 OK anyway. You enumerate the holders of a tokenized treasury for a record-date reserve attestation, the public endpoint silently truncates the response under load, and you publish a proof of reserves that is missing accounts. There is no eth_getLogs to cross-check it against and no block number to re-anchor the query, so the gap is invisible until someone reconciles against the real supply. For a workload whose entire value proposition is provable completeness, a partial-but-successful-looking read is the most dangerous outcome there is.
The pattern that works: run holder enumeration on a private endpoint from day one, validate every getProgramAccounts response against expected supply before you trust it, and provision an archive node before you write a single line of proof-of-reserves code — historical-slot balance reads are non-negotiable for RWA attestation on Solana. Drive live compliance and reconciliation from WebSocket or Geyser subscriptions, not from polling, and keep a signature-based backfill ready so a dropped connection never leaves a hole in the audit trail.
Start free, then move reserve-critical and compliance traffic to dedicated infrastructure as your asset under tokenization grows.
FAQ
Why does getProgramAccounts matter so much for RWA on Solana? Because Solana has no single contract holding all balances and no eth_getLogs to scan transfers, the only way to reconstruct who holds a tokenized asset is to enumerate every token account for the mint — and that is what getProgramAccounts does. It is the most expensive, most aggressively rate-limited call on the network, so cap-table snapshots and proof-of-reserves attestations live or die on whether your endpoint can serve it completely. On a public endpoint it gets throttled or truncated; a private endpoint with dedicated resources serves the full set.
How do I prove reserves at a past date on Solana? You read account balances as of the slot that corresponds to your record date, which requires an archive node — full nodes prune older state. Chainstack supports archive nodes for Solana; archive requests consume 2 RU each. Pair the historical enumeration with a current one to show supply and holder balances reconciled at the attestation point.
How does Token-2022 change my RPC requirements compared to a normal SPL token? Token-2022 (Token Extensions) pushes compliance into the token program itself: transfer hooks fire a separate program on every transfer, accounts can default to frozen until KYC clears, and a permanent delegate enables clawback. Each of those means extra account reads — you have to read the hook program’s accounts and the holder’s frozen/thawed state — so a permissioned RWA mint generates meaningfully more read volume per transfer than a plain SPL token, which is another reason holder-scale enumeration needs managed throughput.
Do I need WebSockets, or can I just poll for transfers? Polling getProgramAccounts to detect transfers is both expensive and laggy, and it will miss activity between polls. For live compliance and reconciliation, subscribe over WebSocket (accountSubscribe, logsSubscribe) so mints, burns, and transfers reach your stack the moment they land; for very high event volume, a Geyser gRPC stream is the higher-throughput option. Always keep a getSignaturesForAddress backfill ready to close gaps after a reconnect.
Which SDKs work with a Solana RPC endpoint? The current official client is @solana/kit (the successor to @solana/web3.js v1, which is now in maintenance mode), and Anchor is the standard framework for program development. Point any of them at your private endpoint’s HTTPS URL instead of the public cluster. EVM libraries like ethers.js and web3.js do not work with Solana.
Is the public Solana endpoint enough for production RWA? No. The public endpoints cap requests per IP, throttle getProgramAccounts hardest of all, and carry no SLA — so a holder enumeration for a reserve snapshot can come back truncated with no error. The Solana documentation itself states the public endpoints are not intended for production. RWA reporting needs a private endpoint with dedicated throughput and archive access.
Additional resources
- Solana: Create a token and vesting program — hands-on SPL token and on-chain vesting tutorial on Chainstack docs
- Chainstack Solana tooling documentation
- Solana RPC API reference — official Solana developer documentation
- Blockchain infrastructure for RWA — proof of reserves, cap tables, and audit-trail node requirements for tokenized assets
- Top 7 RWA token data tools for developers in 2026 — including the open-source Chainstack rwa-sdk
- More Solana tutorials and articles on the Chainstack Blog