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}