complete refactor
This commit is contained in:
parent
28dc014ae3
commit
c46442dd12
|
@ -1,5 +1,10 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.31"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
@ -165,6 +170,23 @@ dependencies = [
|
||||||
"uint 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"uint 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ethers"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ethers-abi 0.1.0",
|
||||||
|
"ethers-contract 0.1.0",
|
||||||
|
"ethers-providers 0.1.0",
|
||||||
|
"ethers-signers 0.1.0",
|
||||||
|
"ethers-types 0.1.0",
|
||||||
|
"ethers-utils 0.1.0",
|
||||||
|
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde_json 1.0.53 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-abi"
|
name = "ethers-abi"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1076,6 +1098,17 @@ dependencies = [
|
||||||
"mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pin-project-lite 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syn 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1326,6 +1359,7 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
"checksum anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f"
|
||||||
"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||||
"checksum async-trait 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "26c4f3195085c36ea8d24d32b2f828d23296a9370a28aa39d111f6f16bef9f3b"
|
"checksum async-trait 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "26c4f3195085c36ea8d24d32b2f828d23296a9370a28aa39d111f6f16bef9f3b"
|
||||||
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||||
|
@ -1444,6 +1478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
"checksum tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2"
|
"checksum tiny-keccak 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2"
|
||||||
"checksum tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
"checksum tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||||
"checksum tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58"
|
"checksum tokio 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58"
|
||||||
|
"checksum tokio-macros 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
|
||||||
"checksum tokio-rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "15cb62a0d2770787abc96e99c1cd98fcf17f94959f3af63ca85bdfb203f051b4"
|
"checksum tokio-rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "15cb62a0d2770787abc96e99c1cd98fcf17f94959f3af63ca85bdfb203f051b4"
|
||||||
"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
|
"checksum tokio-util 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499"
|
||||||
"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
|
"checksum tower-service 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
|
||||||
|
|
34
Cargo.toml
34
Cargo.toml
|
@ -1,7 +1,7 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
|
|
||||||
members = [
|
members = [
|
||||||
# "./crates/ethers",
|
"./crates/ethers",
|
||||||
"./crates/ethers-abi",
|
"./crates/ethers-abi",
|
||||||
"./crates/ethers-contract",
|
"./crates/ethers-contract",
|
||||||
# "./crates/ethers-derive",
|
# "./crates/ethers-derive",
|
||||||
|
@ -10,35 +10,3 @@ members = [
|
||||||
"./crates/ethers-types",
|
"./crates/ethers-types",
|
||||||
"./crates/ethers-utils",
|
"./crates/ethers-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
# [dependencies]
|
|
||||||
# ethers-derive = { path = "ethers-derive", optional = true }
|
|
||||||
#
|
|
||||||
# ethereum-types = { version = "0.9.2", default-features = false, features = ["serialize"] }
|
|
||||||
# url = { version = "2.1.1", default-features = false }
|
|
||||||
# async-trait = { version = "0.1.31", default-features = false }
|
|
||||||
# reqwest = { version = "0.10.4", default-features = false, features = ["json", "rustls-tls"] }
|
|
||||||
# serde = { version = "1.0.110", default-features = false, features = ["derive"] }
|
|
||||||
# serde_json = { version = "1.0.53", default-features = false }
|
|
||||||
# thiserror = { version = "1.0.19", default-features = false }
|
|
||||||
# rustc-hex = { version = "2.1.0", default-features = false }
|
|
||||||
# rand = { version = "0.5.1", default-features = false } # this should be the same rand crate version as the one in secp
|
|
||||||
# secp256k1 = { version = "0.17.2", default-features = false, features = ["std", "recovery", "rand"] }
|
|
||||||
# zeroize = { version = "1.1.0", default-features = false }
|
|
||||||
# tiny-keccak = { version = "2.0.2", default-features = false }
|
|
||||||
#
|
|
||||||
# solc = { git = "https://github.com/paritytech/rust_solc", optional = true }
|
|
||||||
# rlp = "0.4.5"
|
|
||||||
# ethabi = "12.0.0"
|
|
||||||
# bincode = "1.2.1"
|
|
||||||
# arrayvec = "0.5.1"
|
|
||||||
#
|
|
||||||
# [dev-dependencies]
|
|
||||||
# tokio = { version = "0.2.21", features = ["macros"] }
|
|
||||||
# failure = "0.1.8"
|
|
||||||
# rand = { version = "0.5.1" }
|
|
||||||
#
|
|
||||||
# [features]
|
|
||||||
# default = ["derive"]
|
|
||||||
# derive = ["ethers-derive"]
|
|
||||||
#
|
|
||||||
|
|
33
README.md
33
README.md
|
@ -6,12 +6,15 @@ Complete Ethereum wallet implementation and utilities in Rust (with WASM and FFI
|
||||||
|
|
||||||
- [x] User friendly transaction APIs
|
- [x] User friendly transaction APIs
|
||||||
- [x] Type-safe EIP-155 transactions
|
- [x] Type-safe EIP-155 transactions
|
||||||
|
- [x] Querying past events
|
||||||
- [ ] Event Monitoring
|
- [ ] Event Monitoring
|
||||||
- [ ] Deploy and interact with smart contracts
|
- [ ] Deploy and interact with smart contracts
|
||||||
- [ ] Type safe smart contract bindings
|
- [ ] Type safe smart contract bindings
|
||||||
- [ ] Hardware wallet support
|
- [ ] Hardware wallet support
|
||||||
- [ ] ...
|
- [ ] ...
|
||||||
|
|
||||||
|
## Directory Structure
|
||||||
|
|
||||||
## Acknowledgements
|
## Acknowledgements
|
||||||
|
|
||||||
This library would not have been possibly without the great work of the creators of [`rust-web3`]() and [`ethcontract-rs`]()
|
This library would not have been possibly without the great work of the creators of [`rust-web3`]() and [`ethcontract-rs`]()
|
||||||
|
@ -19,33 +22,3 @@ This library would not have been possibly without the great work of the creators
|
||||||
A lot of the code was inspired and adapted from them, to a unified and opinionated interface.
|
A lot of the code was inspired and adapted from them, to a unified and opinionated interface.
|
||||||
That said, Rust-web3 is ~9k LoC (tests included) and ethcontract-rs is 11k lines,
|
That said, Rust-web3 is ~9k LoC (tests included) and ethcontract-rs is 11k lines,
|
||||||
so in total about 20k lines of code with tests. This library is xxx LoC.
|
so in total about 20k lines of code with tests. This library is xxx LoC.
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
### Sending a transaction with an offline key
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use ethers::{types::TransactionRequest, HttpProvider, MainnetWallet};
|
|
||||||
use std::convert::TryFrom;
|
|
||||||
|
|
||||||
// connect to the network
|
|
||||||
let provider = HttpProvider::try_from("http://localhost:8545")?;
|
|
||||||
|
|
||||||
// create a wallet and connect it to the provider
|
|
||||||
let client = "15c42bf2987d5a8a73804a8ea72fb4149f88adf73e98fc3f8a8ce9f24fcb7774"
|
|
||||||
.parse::<MainnetWallet>()?
|
|
||||||
.connect(&provider);
|
|
||||||
|
|
||||||
// craft the transaction using the builder pattern
|
|
||||||
let tx = TransactionRequest::new()
|
|
||||||
.send_to_str("986eE0C8B91A58e490Ee59718Cca41056Cf55f24")?
|
|
||||||
.value(10000);
|
|
||||||
|
|
||||||
// send it!
|
|
||||||
let tx = client.sign_and_send_transaction(tx, None).await?;
|
|
||||||
|
|
||||||
// get the mined tx
|
|
||||||
let tx = client.get_transaction(tx.hash).await?;
|
|
||||||
|
|
||||||
println!("{}", serde_json::to_string(&tx)?);
|
|
||||||
```
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub use ethabi::Contract as Abi;
|
||||||
pub use ethabi::*;
|
pub use ethabi::*;
|
||||||
|
|
||||||
mod tokens;
|
mod tokens;
|
||||||
pub use tokens::{Detokenize, Tokenizable, TokenizableItem, Tokenize};
|
pub use tokens::{Detokenize, InvalidOutputType, Tokenizable, TokenizableItem, Tokenize};
|
||||||
|
|
||||||
/// Extension trait for `ethabi::Function`.
|
/// Extension trait for `ethabi::Function`.
|
||||||
pub trait FunctionExt {
|
pub trait FunctionExt {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Contract Functions Output types.
|
//! Contract Functions Output types.
|
||||||
//! Adapted from: https://github.com/tomusdrw/rust-web3/blob/master/src/contract/tokens.rs
|
//! Adapted from: https://github.com/tomusdrw/rust-web3/blob/master/src/contract/tokens.rs
|
||||||
|
#[allow(clippy::all)]
|
||||||
use crate::Token;
|
use crate::Token;
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
|
|
|
@ -4,8 +4,35 @@ version = "0.1.0"
|
||||||
authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
|
authors = ["Georgios Konstantopoulos <me@gakonst.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
[features]
|
||||||
|
default = ["full"]
|
||||||
|
full = [
|
||||||
|
"abi",
|
||||||
|
"contract",
|
||||||
|
"providers",
|
||||||
|
"signers",
|
||||||
|
"types",
|
||||||
|
"utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
abi = ["ethers-abi"]
|
||||||
|
contract = ["ethers-contract"]
|
||||||
|
providers = ["ethers-providers"]
|
||||||
|
signers = ["ethers-signers"]
|
||||||
|
types = ["ethers-types"]
|
||||||
|
utils = ["ethers-utils"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
ethers-abi = { path = "../ethers-abi", optional = true }
|
||||||
|
ethers-contract = { path = "../ethers-contract", optional = true }
|
||||||
|
ethers-providers = { path = "../ethers-providers", optional = true }
|
||||||
|
ethers-signers = { path = "../ethers-signers", optional = true }
|
||||||
|
ethers-types = { path = "../ethers-types", optional = true }
|
||||||
|
ethers-utils = { path = "../ethers-utils", optional = true }
|
||||||
|
|
||||||
# TODO: Make this have features for each available module
|
[dev-dependencies]
|
||||||
|
anyhow = "1.0.31"
|
||||||
|
tokio = { version = "0.2.21", features = ["macros"] }
|
||||||
|
serde_json = "1.0.53"
|
||||||
|
rand = "0.5.1" # note: when passing RNGs, they must be with version 0.5.1
|
||||||
|
serde = { version = "1.0.110", features = ["derive"] }
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
use ethabi::Token;
|
|
||||||
use ethers::{
|
use ethers::{
|
||||||
contract::{Contract, Detokenize},
|
abi::{Detokenize, InvalidOutputType, Token},
|
||||||
|
contract::Contract,
|
||||||
|
providers::HttpProvider,
|
||||||
|
signers::MainnetWallet,
|
||||||
types::Address,
|
types::Address,
|
||||||
HttpProvider, MainnetWallet,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
@ -18,9 +21,7 @@ struct ValueChanged {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Detokenize for ValueChanged {
|
impl Detokenize for ValueChanged {
|
||||||
fn from_tokens(
|
fn from_tokens(tokens: Vec<Token>) -> Result<ValueChanged, InvalidOutputType> {
|
||||||
tokens: Vec<Token>,
|
|
||||||
) -> Result<ValueChanged, ethers::contract::InvalidOutputType> {
|
|
||||||
let author: Address = tokens[0].clone().to_address().unwrap();
|
let author: Address = tokens[0].clone().to_address().unwrap();
|
||||||
let old_value = tokens[1].clone().to_string().unwrap();
|
let old_value = tokens[1].clone().to_string().unwrap();
|
||||||
let new_value = tokens[2].clone().to_string().unwrap();
|
let new_value = tokens[2].clone().to_string().unwrap();
|
||||||
|
@ -34,7 +35,7 @@ impl Detokenize for ValueChanged {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), failure::Error> {
|
async fn main() -> Result<()> {
|
||||||
// connect to the network
|
// connect to the network
|
||||||
let provider = HttpProvider::try_from("http://localhost:8545")?;
|
let provider = HttpProvider::try_from("http://localhost:8545")?;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
use anyhow::Result;
|
||||||
use ethers::{
|
use ethers::{
|
||||||
|
providers::HttpProvider,
|
||||||
types::{Address, Filter},
|
types::{Address, Filter},
|
||||||
HttpProvider,
|
|
||||||
};
|
};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), failure::Error> {
|
async fn main() -> Result<()> {
|
||||||
// connect to the network
|
// connect to the network
|
||||||
let provider = HttpProvider::try_from("http://localhost:8545")?;
|
let provider = HttpProvider::try_from("http://localhost:8545")?;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use ethers::{types::TransactionRequest, HttpProvider, MainnetWallet};
|
use anyhow::Result;
|
||||||
|
use ethers::{providers::HttpProvider, signers::MainnetWallet, types::TransactionRequest};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), failure::Error> {
|
async fn main() -> Result<()> {
|
||||||
// connect to the network
|
// connect to the network
|
||||||
let provider = HttpProvider::try_from("http://localhost:8545")?;
|
let provider = HttpProvider::try_from("http://localhost:8545")?;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use ethers::{MainnetWallet as Wallet, Signer};
|
use ethers::signers::{MainnetWallet as Wallet, Signer};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let message = "Some data";
|
let message = "Some data";
|
|
@ -1,11 +1,12 @@
|
||||||
|
use anyhow::Result;
|
||||||
use ethers::{
|
use ethers::{
|
||||||
|
providers::HttpProvider,
|
||||||
types::{BlockNumber, TransactionRequest},
|
types::{BlockNumber, TransactionRequest},
|
||||||
HttpProvider,
|
|
||||||
};
|
};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), failure::Error> {
|
async fn main() -> Result<()> {
|
||||||
// connect to the network
|
// connect to the network
|
||||||
let provider = HttpProvider::try_from("http://localhost:8545")?;
|
let provider = HttpProvider::try_from("http://localhost:8545")?;
|
||||||
let accounts = provider.get_accounts().await?;
|
let accounts = provider.get_accounts().await?;
|
|
@ -15,23 +15,32 @@
|
||||||
//! More examples can be found in the [`examples` directory of the
|
//! More examples can be found in the [`examples` directory of the
|
||||||
//! repositry](https://github.com/gakonst/ethers-rs)
|
//! repositry](https://github.com/gakonst/ethers-rs)
|
||||||
|
|
||||||
pub mod providers;
|
#[cfg(feature = "abi")]
|
||||||
pub use providers::HttpProvider;
|
pub mod abi {
|
||||||
|
pub use ethers_abi::*;
|
||||||
|
}
|
||||||
|
|
||||||
pub mod contract;
|
#[cfg(feature = "contract")]
|
||||||
pub use contract::Contract;
|
pub mod contract {
|
||||||
|
pub use ethers_contract::*;
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) mod signers;
|
#[cfg(feature = "providers")]
|
||||||
pub use signers::{AnyWallet, MainnetWallet, Signer};
|
pub mod providers {
|
||||||
|
pub use ethers_providers::*;
|
||||||
|
}
|
||||||
|
|
||||||
/// Ethereum related datatypes
|
#[cfg(feature = "signers")]
|
||||||
pub mod types;
|
pub mod signers {
|
||||||
|
pub use ethers_signers::*;
|
||||||
|
}
|
||||||
|
|
||||||
/// Re-export solc for convenience
|
#[cfg(feature = "types")]
|
||||||
pub use solc;
|
pub mod types {
|
||||||
|
pub use ethers_types::*;
|
||||||
|
}
|
||||||
|
|
||||||
/// Various utilities
|
#[cfg(feature = "utils")]
|
||||||
pub mod utils;
|
pub mod utils {
|
||||||
|
pub use ethers_utils::*;
|
||||||
/// ABI utilities
|
}
|
||||||
pub mod abi;
|
|
||||||
|
|
Loading…
Reference in New Issue