quicknode-cascade
Stream Solana data at insane speed. One crate. Parallel. Consistent. Crash-safe.
Powered by QuickNode Cascade — edge-cached block archive, 300+ PoPs, sub-50ms latency worldwide.
30-Second Start
That fetches real Solana blocks and prints every non-vote transaction. No config, no setup.
Add to Your Project
Two Approaches
You choose how to consume the data. Use one or both.
1. Custom Extraction — Parse Raw JSON Yourself
Implement on_slot and get the full raw getBlock JSON-RPC response. Parse it however you need — inner instructions, program-specific data, rewards, address lookups, anything.
use ;
;
2. Built-in Extraction — Let the Framework Do It
Implement on_block, on_transaction, etc. The framework extracts structured data and calls your hooks.
use ;
;
3. Combine Both
on_slot fires first with raw JSON. Then the built-in extraction fires on_block, on_transaction, etc. Use solana::extract_block() as a utility if you want structured data alongside your custom parsing.
How It Works
┌─────────────────────────────────────────────────────────┐
│ CascadeRunner │
│ │
│ ┌──────────┐ ┌───────────────────────────────────┐ │
│ │ Fetch │───▶│ on_slot(slot, &raw_json) │ │
│ │ parallel │ │ ↓ your custom extraction │ │
│ │ + retry │ ├───────────────────────────────────┤ │
│ │ forever │ │ Built-in extraction (optional) │ │
│ │ │ │ ↓ on_block() │ │
│ └──────────┘ │ ↓ on_transaction() │ │
│ │ │ ↓ on_token_transfer() │ │
│ │ │ ↓ on_account_activity() │ │
│ │ └───────────────────────────────────┘ │
│ │ │ │
│ └─────────────────────────▼───────────────────┐ │
│ ┌──────────────────┐ │ │
│ │ Cursor (atomic) │ │ │
│ │ crash-safe resume │ │ │
│ └──────────────────┘ │ │
└─────────────────────────────────────────────────────────┘
Slots always arrive in order. Cursor saves after every batch. Kill the process, restart, picks up where it left off.
Examples
| Example | What it does | Run it |
|---|---|---|
solana_backfill |
Built-in extraction: blocks + transactions | cargo run --release --example solana_backfill |
custom_extraction |
Custom extraction: inner instructions + program stats | cargo run --release --example custom_extraction |
crash_recovery_test |
Two-stage backfill proving cursor resume | cargo run --release --example crash_recovery_test |
Running Modes
// Backfill a range of slots
solana_mainnet
.backfill
.concurrency
.run
// Follow the chain tip in real-time
solana_mainnet
.live
.run
// Follow from a specific slot
solana_mainnet
.live_from
.run
Configuration
solana_mainnet
.auth_token // JWT for Cascade API
.concurrency // parallel workers (default: 10)
.encoding // "json" (structured) or raw
.cursor_file // resume support
.tip_buffer // slots behind tip (live mode)
.source_url // override endpoint
.with_plugin // register plugins
.run
Plugin Hooks
All hooks default to no-op. Override only what you need.
Extraction Utility
solana::extract_block() is public — call it from on_slot if you want the framework's structured data as a starting point:
let extracted = extract_block;
// extracted.block, extracted.transactions, extracted.token_transfers, extracted.account_activity
Reliability
| What happens | What the framework does |
|---|---|
| Network error / timeout / 5xx | Retry forever, exponential backoff |
| HTTP 429 | Wait 5s, retry forever |
| Skipped slot | on_skipped_slot(), cursor advances |
| Plugin error | Log it, keep going |
on_load error |
Fail fast, clean up loaded plugins |
| Ctrl-C / SIGTERM | on_exit() all plugins, save cursor |
| SIGKILL (crash) | Cursor up to 1 batch stale, replay is safe |
Delivery guarantee: at-least-once. Design your plugins for idempotent writes.
Multi-Chain
Solana types live under quicknode_cascade::solana. When new chains ship, they get their own modules:
use ; // now
// use quicknode_cascade::ethereum::{Plugin, BlockData}; // future
CascadeRunner::chain("solana-mainnet") maps to https://solana-mainnet-cascade.quiknode.io. Same pattern for any chain.
License
Apache-2.0