Substreams for Solana Developers

Substreams allows you to easily extract data from the the Solana blockchain. With Substreams, you can retrieve transactions, instructions or accounts, taking advantage of its powerful streaming technology. It's super fast!

Getting Started

First, you must consider whether you want to develop your own Substreams or consume a ready-to-use Substreams. It is possible that someone has already built a Substreams package to extract the data you want; you can explore Substreams packages in the Substreams Registry.
If you have found a Substreams package that fits your needs, then explore the Consume Substreams section. At the most basic level you should cover:
If you can't find a Substreams package that fits your needs, then you can go ahead and develop your own Substreams. The Develop Substreams section of the documentation covers everything you need to know about building a Substreams from scratch. At the most basic level, you should cover:


If you want to deep dive into the code, you can follow one or several of the Solana Tutorials available in the documentation.

The Solana Data Model

A Substreams module is, essentially, a Rust function that extracts data from the blockchain. In order to specify which data you want to retrieve, Substreams gives you access to the abstraction of a full Solana block.
In the following example, a Solana block (solana::Block) is passed as a parameter. Then, a custom object defined by the user, BlockMeta, is emitted as output, containing some relevant fields (slot, hash, parent_hash):
fn map_block_meta(block: solana::Block) -> Result<BlockMeta, substreams::errors::Error> {
Ok(BlockMeta {
slot: blk.slot,
hash: blk.blockhash,
parent_hash: blk.previous_blockhash,
The Block object holds other important data, such as:

The Account Address Tables

In Solana, the account concept plays a very important role. However, the original Solana data model imposes a restriction on the number of accounts that a single transaction can have. The Account Address Tables is a way to overcome this restriction, allowing developers to increase the number of accounts per transaction.
The resolved_accounts() method of the ConfirmedTransaction object includes a ready-to-use array of accounts, including accounts from the Lookup Table.