The Solana Common Modules Substreams contains a set of modules that allow you to easily retrieve basic information from the Solana blockchain, such as transactions or instructions.
The substreams-v0.3.0.yaml
file defines all the different modules available, and also provides you with documentation about the usage of every module.
In your substreams.yaml,
imports:
sol: https://spkg.io/streamingfast/solana-common-v0.3.0.spkg
Replace any source: sf.solana.type.v1.Block
input with map: sol:blocks_without_votes
(you will be getting the same protobuf object, but with some vote-related transactions already pruned)
Add block filtering to your "entry modules" (any module reading blocks or transactions before emitting your custom types):
If you know the instruction program ID
of all transactions that you want, use the program_ids_without_votes
index like this:
blockFilter:
module: sol:program_ids_without_votes
query:
string: "program:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy || program:Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD"
If you also need to get transactions based on the instruction's accounts
, use the (bigger) index like this:
blockFilter:
module: sol:program_ids_and_accounts_without_votes
query:
string: "program:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy || account:Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD"
In your substreams.yaml,
imports:
sol: https://spkg.io/streamingfast/solana-common-v0.3.0.spkg
transactions_by_programid_without_votes
or transactions_by_programid_and_account_without_votes
(along with source: sf.substreams.v1.Clock
if you need slot number/ID/timestamp) as your module input, ex: - name: my_cool_module
kind: map
inputs:
- source: sf.substreams.v1.Clock
- map: sol:transactions_by_programid_without_votes
sol:transactions_by_programid_without_votes
or transactions_by_programid_and_account_without_votes
module to match the data that you want to be fed to your module:params:
sol:transactions_by_programid_without_votes: "program:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy"
sol:transactions_by_programid_and_account_without_votes: "program:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy || (account:Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD && program:FsJ3A3u2vn5cTVofAjvy6y5kwABJAqYWpe4975bi2epH)"
substreams protogen
against your substreams.yaml to create the rust bindings of the protobuf definition inside the substreams. (If you are using the substreams-solana
rust crate, follow the instructions to write a buf.gen.yaml
that will bind things correctly: https://github.com/streamingfast/substreams-solana, )blocks_without_votes
(map)Vote111111111111111111111111111111111111111
instructions) from the 'transactions' array.program_ids_without_votes
(index)program:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
, program:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy
Use it to only get blocks that contain instructions matching the programID/accounts that you need, ex:
- name: my_module
...
blockFilter:
module: program_ids_without_votes
query:
string: (program:4vMsoUT2BWatFweudnQM1xedRLfJgJ7hswhcpz4xgBTy || program:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)
program_ids_and_accounts_without_votes
(index)account:Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD
, program:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
Use it to only get blocks that contain instructions matching the programID/accounts that you need, ex:
- name: my_module
...
blockFilter:
module: program_ids_and_accounts_without_votes
query:
string: (account:Gnt27xtC473ZT2Mw5u8wZ68Z3gULkSTb5DuxJy7eJotD && program:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA)
transactions_by_programid_without_votes
(map)program_ids_without_votes
index to only process blocks that contain matching instructions.transactions_by_programid_and_account_without_votes
(map)program_ids_and_accounts_without_votes
index to only process blocks that contain matching instructions.substreams gui solana-common@v0.3.0 blocks_without_votes
substreams gui solana-common@v0.3.0 transactions_by_programid_without_votes
substreams gui solana-common@v0.3.0 transactions_by_programid_and_account_without_votes
blocks_without_votes
allows you to consume a full Solana Block without Vote instructions (Vote111111111111111111111111111111111111111
).
If you consume it on HISTORICAL data (+1000 blocks from HEAD), you will be reading from the StreamingFast cache, thus saving costs on the amount of TB read.
substreams gui solana-common@v0.3.0 v020:blocks_without_votes
filtered_transactions_without_votes
allows you to consume transactions containing instructions from specific program_id based on a filter string.
Supported operators are: logical or ||
, logical and &&
and parenthesis: ()
.
Example: to only consume TRANSACTIONS containing Token or ComputeBudget instructions: program:TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA || program:ComputeBudget111111111111111111111111111111
.
Transactions containing Vote111111111111111111111111111111111111111
are always excluded.
substreams gui solana-common@v0.3.0 v020:filtered_transactions_without_votes
substreams gui solana-common@v0.3.0 program_ids_without_votes
substreams gui solana-common@v0.3.0 program_ids_and_accounts_without_votes
program_ids_without_votes
creates a cache to efficiently retrieve instructions based on the program ID.
For example, the following sets keys for the Token program:
substreams gui solana-common@v0.3.0 v020:program_ids_without_votes