substreams_ethereum/
lib.rs

1pub use substreams_ethereum_core::scalar;
2pub use substreams_ethereum_core::{block_view, pb, rpc, Event, Function, NULL_ADDRESS};
3pub use substreams_ethereum_derive::EthabiContract;
4
5// Those are dependencies that needs to be exported for `substreams-abigen` to work. Must not
6// be removed.
7pub use substreams_ethereum_core::IndexedDynamicValue;
8
9#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
10pub use getrandom;
11
12/// Builder struct for generating type-safe bindings Rust code directly in your project from a contract's ABI.
13/// This is equivalent to code generated by macro [use_contract].
14///
15/// # Example
16///
17/// Running the code below will generate a file called `erc721.rs` containing the
18/// bindings inside, which exports an `erc` struct, along with all its events. Put into a
19/// `build.rs` file this will generate the bindings during `cargo build`.
20///
21/// ```no_run
22///     use anyhow::{Ok, Result};
23///     use substreams_ethereum::Abigen;
24///
25///     fn main() -> Result<(), anyhow::Error> {
26///         Abigen::new("ERC721", "abi/erc721.json")?
27///             .generate()?
28///             .write_to_file("src/abi/erc721.rs")?;
29///
30///         Ok(())
31///     }
32/// ```
33pub use substreams_ethereum_abigen::build::Abigen;
34
35/// This macro can be used to import an Ethereum ABI file in JSON format and generate all the
36/// required bindings for ABI decoding/encoding in Rust, targetting `substreams` developer
37/// experience. You prefer to have the code generated directly, check out [Abigen].
38///
39/// ```no_run
40///     use substreams_ethereum::use_contract;
41///
42///     use_contract!(erc721, "./examples/abi/erc721.json");
43/// ```
44///
45/// This invocation will generate the following code (signatures only for consiscness):
46///
47/// ```rust
48/// mod erc721 {
49///     pub mod events {
50///         #[derive(Debug, Clone, PartialEq)]
51///         pub struct Transfer {
52///             pub from: Vec<u8>,
53///             pub to: Vec<u8>,
54///             pub token_id: ethabi::Uint,
55///         }
56///
57///         impl Transfer {
58///             pub fn match_log(log: &substreams_ethereum::pb::eth::v2::Log) -> bool {
59///                // ...
60///                # todo!()
61///             }
62///
63///             pub fn decode(log: &substreams_ethereum::pb::eth::v2::Log) -> Result<Transfer, String> {
64///                // ...
65///                # todo!()
66///             }
67///         }
68///
69///         // ... Other events ...
70///     }
71/// }
72/// ```
73#[macro_export]
74macro_rules! use_contract {
75    ($module: ident, $path: expr) => {
76        #[allow(dead_code)]
77        #[allow(missing_docs)]
78        #[allow(unused_imports)]
79        #[allow(unused_mut)]
80        #[allow(unused_variables)]
81        pub mod $module {
82            #[derive(substreams_ethereum::EthabiContract)]
83            #[ethabi_contract_options(path = $path)]
84            struct _Dummy;
85        }
86    };
87}
88
89/// The `init` macro registers a custom get random function in the system which is required
90/// because `ethabi` that we rely on for ABI decoding/encoding primitives use it somewhere in
91/// its transitive set of dependencies and causes problem in `wasm32-unknown-unknown` target.
92///
93/// This macro must be invoked in the root crate so you must have the `substreams_ethereum::init!()`
94/// call in your `lib.rs` of your Substreams.
95///
96/// In addition, you need to have `getrandom = { version = "0.2", features = ["custom"] }` dependency
97/// in your Substreams `Cargo.toml` file:
98///
99/// ```toml
100/// # Required so that ethabi > ethereum-types build correctly under wasm32-unknown-unknown
101/// [target.wasm32-unknown-unknown.dependencies]
102/// getrandom = { version = "0.2", features = ["custom"] }
103///```
104#[macro_export]
105macro_rules! init {
106    () => {
107        #[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
108        $crate::getrandom::register_custom_getrandom!($crate::getrandom_unavailable);
109    };
110}
111
112#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
113const GETRANDOM_UNVAILABLE_IN_SUBSTREAMS: u32 = getrandom::Error::CUSTOM_START + 5545;
114
115#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
116pub fn getrandom_unavailable(_buf: &mut [u8]) -> Result<(), getrandom::Error> {
117    let code = std::num::NonZeroU32::new(GETRANDOM_UNVAILABLE_IN_SUBSTREAMS).unwrap();
118    Err(getrandom::Error::from(code))
119}