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.
Try It Now
Clone and run — fetches real Solana blocks, prints every non-vote transaction:
&&
You'll see:
slot=300000000 txs=2541 time=Some(1730981797)
tx=24Bx6JCtMat... fee=5000 success=true
tx=5RrkdQfeNNW... fee=5000 success=true
...
slot=300000001 txs=1907 time=Some(1730981798)
...
Try the other examples:
Use in Your Project
Two Approaches to Data
1. Custom Extraction — parse raw JSON yourself
Use on_raw to get the full JSON-RPC response. Extract whatever you need — inner instructions, program-specific data, rewards, address lookups, anything.
on_raw is the same hook name across all chains (Solana, Ethereum, etc.).
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. Both together
on_raw fires first with raw JSON. Then extraction fires on_block, on_transaction, etc.
Use solana::extract_block() inside on_raw if you want the framework's structured data as a starting point alongside your own parsing.
How It Works
┌──────────────────────────────────────────────────────┐
│ CascadeRunner │
│ │
│ Fetch (parallel) ──▶ on_raw(slot, &raw_json) │
│ + retry ↓ your custom extraction │
│ forever ──────────────────────────── │
│ Built-in extraction (optional) │
│ ↓ on_block() │
│ ↓ on_transaction() │
│ ↓ on_token_transfer() │
│ ↓ on_account_activity() │
│ ↓ │
│ Cursor (atomic, crash-safe) │
└──────────────────────────────────────────────────────┘
Slots always arrive in order. Kill the process, restart, picks up where it left off.
Examples
| Example | Run | What you'll see |
|---|---|---|
| solana_backfill | cargo run --release --example solana_backfill |
Block summaries + transaction details |
| custom_extraction | cargo run --release --example custom_extraction |
Inner instruction counts + top 5 programs per slot |
| crash_recovery_test | cargo run --release --example crash_recovery_test |
Two-stage backfill proving zero-duplicate cursor resume |
Running Modes
// Backfill a slot range
solana_mainnet
.backfill
.concurrency
.with_plugin
.run
// Follow the chain tip in real-time
solana_mainnet
.live
.with_plugin
.run
// Follow from a specific slot
solana_mainnet
.live_from
.with_plugin
.run
All Options
solana_mainnet // or ::solana_devnet() or ::chain("name")
.auth_token // JWT for Cascade API
.concurrency // parallel workers (default: 10)
.encoding // "json" (structured) or raw
.cursor_file // resume support (default: cursor.json)
.tip_buffer // slots behind tip for live mode
.source_url // override endpoint
.with_plugin // register 1+ plugins
.run // blocks until done or Ctrl-C
Plugin Hooks
All hooks default to no-op. Override only what you need.
Convenience import: use quicknode_cascade::solana::prelude::*;
Data Types
| Type | Fields |
|---|---|
BlockData |
slot, blockhash, parent_slot, block_time, block_height, transaction_count, raw |
TransactionData |
slot, tx_index, signature, success, fee, compute_units, is_vote, balances, logs, raw |
TokenTransferData |
slot, tx_index, signature, mint, owner, pre/post_amount, decimals |
AccountActivityData |
slot, tx_index, signature, account, pre/post_balance, balance_change, is_signer, is_fee_payer |
Types with raw carry the full JSON so you can parse anything the framework doesn't extract.
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 | 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 with chain-specific types — same on_raw hook everywhere:
use ; // now
// use quicknode_cascade::ethereum::{Plugin, BlockData}; // future
License
Apache-2.0