A comprehensive Substreams package for monitoring and processing Cypher Protocol events and calls on Ethereum networks. This project provides foundational modules for extracting, filtering, and processing blockchain data with a specific focus on the Cypher Protocol ecosystem.
This Substreams package is designed to monitor and process events from the Cypher Protocol smart contracts, including:
all_events
: Extracts all events from successful transactionsall_calls
: Extracts all calls including internal callsindex_events
: Creates searchable indexes for eventsindex_calls
: Creates searchable indexes for callsindex_events_and_calls
: Combined indexing for both events and callsfiltered_events
: Filter events by address and signaturefiltered_calls
: Filter calls by contract, caller, and methodfiltered_transactions
: Filter complete transactionsfiltered_events_and_calls
: Combined filtering of events and callsfilter_cypher_events
: Enhanced processor with configurable contract addressesrustup target add wasm32-unknown-unknown
# Build the WASM module
cargo build --target wasm32-unknown-unknown --release
# The compiled module will be available at:
# target/wasm32-unknown-unknown/release/cypher_protocol.wasm
The package uses configurable contract addresses that can be set via parameters:
# Example parameter format for filter_cypher_events:
"query_string|contract_addresses_string"
# Where contract_addresses_string is:
"voting_escrow:0xaddr1,election:0xaddr2,cypher_token:0xaddr3,reward_distributor:0xaddr4,distribution_module:0xaddr5,airdrop:0xaddr6"
# Filter events by address and signature
substreams run substreams.yaml filtered_events \
--param='(evt_addr:0x1234... || evt_addr:0x5678...) && evt_sig:0xdeadbeef...'
# Filter calls by contract and method
substreams run substreams.yaml filtered_calls \
--param='call_method:0xa9059cbb && call_to:0xdac17f958d2ee523a2206206994597c13d831ec7'
# Process Cypher Protocol events with configurable addresses
substreams run substreams.yaml filter_cypher_events \
--param='(call_to:0x3cb7367ac1e6a439da1f1717f8055f02e3c9d56e || call_to:0xcccd218a58b53c67fc17d8c87cb90d83614e35fd)|voting_escrow:0xf65e1e90269373a60b2abdaf2dc52b2a5a8fdb5c,election:0x0c132c3841b9cdbb3a305275ee02d571a551ce70,cypher_token:0xd36f05bc341b3286c1fd15a809d3315741796f26,reward_distributor:0x7f91980325a294b2affaac6f26e1644864160d41,distribution_module:0x636bdc02170e04c917204f858fa110ce9a5bf05f,airdrop:0xfcbebe31e067a8c460563bcb1d7458fae1949f29'
CreateLock
: User creates new lock positionDepositFor
: Add tokens to existing lockWithdraw
: Withdraw expired lockIncreaseUnlockTime
: Extend lock durationLockIndefinite
: Convert to indefinite lockUnlockIndefinite
: Convert back to timed lockMerge
: Merge two lock positionsTransfer
: NFT Transfer (ERC-721)Approval
: NFT Approval (ERC-721)Vote
: User votes for candidateBribeClaimed
: User claims bribe rewardBribeAdded
: Bribe added for candidateCandidateEnabled
: Candidate enabled for votingCandidateDisabled
: Candidate disabledBribeTokenEnabled
: Token approved for bribesBribeTokenDisabled
: Token disabled for bribesTransfer
: ERC-20 TransferApproval
: ERC-20 ApprovalRootAdded
: New merkle root addedClaimed
: User claimed rewardTokensEmitted
: Tokens emitted to recipientEmissionAddressUpdated
: Emission address changedCypherTokenClaimed
: CypherToken claimedVeCypherNftClaimed
: VeCypherNft claimedThe package supports a powerful query language for filtering events and calls:
||
: Logical OR&&
: Logical AND()
: Parentheses for groupingevt_addr:0x...
: Filter by event contract addressevt_sig:0x...
: Filter by event signaturecall_to:0x...
: Filter by called contract addresscall_from:0x...
: Filter by caller addresscall_method:0x...
: Filter by method signature (4 bytes)# Complex event filtering
'(evt_addr:0x1234... || evt_addr:0x5678...) && evt_sig:0xdeadbeef...'
# Combined event and call filtering
'evt_sig:0x9bb8f83800000000000000000000000000000000000000000000000000000000 || (call_method:0xa9059cbb && call_to:0xdac17f958d2ee523a2206206994597c13d831ec7)'
The filter_cypher_events
module outputs structured data:
message ProcessedEvents {
repeated TransferEvent transfer_events = 1;
repeated ContractEvent contract_events = 2;
Clock clock = 3;
}
message TransferEvent {
string from = 1;
string to = 2;
string value = 3;
string token_id = 4;
string hash = 5;
uint64 block_number = 6;
uint64 timestamp = 7;
}
message ContractEvent {
string contract_name = 1;
string event_name = 2;
map<string, string> event_data = 3;
uint64 block_number = 4;
string transaction_hash = 5;
uint64 timestamp = 6;
string contract_address = 7;
}
The package includes comprehensive error handling and logging:
src/
├── calls.rs # Call processing modules
├── events.rs # Event processing modules
├── combined.rs # Combined processing and Cypher Protocol specific logic
├── lib.rs # Module exports and initialization
└── pb/ # Generated protobuf bindings
# Run unit tests
cargo test
# Run with verbose output
cargo test -- --nocapture
To add support for new event types:
combined.rs
extract_event_data()
process_contract_event()
substreams
: Core Substreams frameworksubstreams-ethereum
: Ethereum-specific functionalitynum-bigint
: Big integer arithmetic for token amountshex
: Hexadecimal encoding/decodingethabi
: Ethereum ABI parsinganyhow
: Error handlingThis project is part of the Substreams foundational modules ecosystem.
For issues and questions:
all_events
gives you all the events in a block (from successful transactions), with basic block hash/number/timestamp and transaction hash
substreams gui cypher-protocol@v0.0.4 all_events
all_calls
gives you all the calls in a block (including internal calls), with basic block hash/number/timestamp and transaction hash
substreams gui cypher-protocol@v0.0.4 all_calls
filtered_events
reads from all_events
and applies a filter on the event addresses and signatures.
Supported operators are: logical or ||
, logical and &&
and parenthesis: ()
Addresses to match must be written as 0x-prefixed hexadecimal, lowercase, prefixed by evt_addr:
and signatures by evt_sig:
.
Example: (evt_addr:0x1234... || evt_addr:0x5678...) && evt_sig:0xdeadbeef...
substreams gui cypher-protocol@v0.0.4 filtered_events
filtered_calls
reads from all_calls
and applies a filter on the called contract, the caller and the method 4-bytes signature
Supported operators are: logical or ||
, logical and &&
and parenthesis: ()
Addresses to match must be written as 0x-prefixed hexadecimal, lowercase, prefixed by call_to:
or call_from:
, methods by call_method:
.
Example: (call_to:0x1234... || call_from:0x1234...) && call_method:0xdeadbeef...
substreams gui cypher-protocol@v0.0.4 filtered_calls
filtered_transactions
reads from ethereum blocks and applies a filter on the events (addresses and signatures) as well as calls (from, to and method).
Supported operators are: logical or ||
, logical and &&
and parenthesis: ()
Addresses and signatures to match must be written as 0x-prefixed hexadecimal, lowercase, prefixed by evt_addr:
, evt_sig:
, call_to:
, call_from:
or call_method:
.
Example: ((evt_addr:0x1234... || evt_addr:0x5678...) && evt_sig:0xdeadbeef...) || call_to:0x01010101...
substreams gui cypher-protocol@v0.0.4 filtered_transactions
filtered_events_and_calls
reads from all_calls
and all_events
, then applies a filter to extract the items that interest you, based on called contract, caller, call method, event address and event signature.
Supported operators are: logical or ||
, logical and &&
and parenthesis: ()
Addresses and signatures to match must be written as 0x-prefixed hexadecimal, lowercase, prefixed by evt_addr:
, evt_sig:
, call_to:
, call_from:
or call_method:
.
Example: evt_sig:0x9bb8f83800000000000000000000000000000000000000000000000000000000 || (call_method:0xa9059cbb && call_to:0xdac17f958d2ee523a2206206994597c13d831ec7)
substreams gui cypher-protocol@v0.0.4 filtered_events_and_calls
filter_cypher_events
is an enhanced version that accepts configurable contract addresses.
Parameter format: "query_string|contract_addresses_string"
Where query_string is the same as unified_events_and_calls_processor
And contract_addresses_string is: "voting_escrow:0xaddr1,election:0xaddr2,cypher_token:0xaddr3,reward_distributor:0xaddr4,distribution_module:0xaddr5,airdrop:0xaddr6"
This allows dynamic configuration of Cypher Protocol contract addresses without code changes.
Processing behavior is identical to unified_events_and_calls_processor but uses configurable addresses.
substreams gui cypher-protocol@v0.0.4 filter_cypher_events
index_events
sets the following keys on the block:
substreams gui cypher-protocol@v0.0.4 index_events
index_calls
sets the following keys on the block:
substreams gui cypher-protocol@v0.0.4 index_calls
index_events_and_calls
sets the following keys on the block:
substreams gui cypher-protocol@v0.0.4 index_events_and_calls