Skip to content

Commit

Permalink
Make ethcontract-generate curl dependency optional (#721)
Browse files Browse the repository at this point in the history
  • Loading branch information
vkgnosis authored Feb 17, 2022
1 parent 7f9a757 commit 5427c19
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 9 deletions.
6 changes: 5 additions & 1 deletion ethcontract-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ description = """
Proc macro for generating type-safe bindings to Ethereum smart contracts.
"""

[features]
default = ["http"]
http = ["ethcontract-generate/http"]

[lib]
proc-macro = true

[dependencies]
anyhow = "1.0"
ethcontract-common = { version = "0.16.0", path = "../ethcontract-common" }
ethcontract-generate = { version = "0.16.0", path = "../ethcontract-generate" }
ethcontract-generate = { version = "0.16.0", path = "../ethcontract-generate", default-features = false }
proc-macro2 = "1.0"
quote = "1.0"
syn = "1.0.12"
6 changes: 5 additions & 1 deletion ethcontract-generate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ description = """
Code generation for type-safe bindings to Ethereum smart contracts.
"""

[features]
default = ["http"]
http = ["curl"]

[dependencies]
anyhow = "1.0"
curl = "0.4"
curl = { version = "0.4", optional = true }
ethcontract-common = { version = "0.16.0", path = "../ethcontract-common" }
Inflector = "0.11"
proc-macro2 = "1.0"
Expand Down
21 changes: 21 additions & 0 deletions ethcontract-generate/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
//! .expect("failed to load an artifact");
//! ```
#[cfg(feature = "http")]
use crate::util;
use anyhow::{anyhow, Context, Error, Result};
#[cfg(feature = "http")]
use ethcontract_common::Address;
use std::borrow::Cow;
use std::env;
Expand All @@ -40,6 +42,7 @@ pub enum Source {
Local(PathBuf),

/// Resource in the internet, available via HTTP(S).
#[cfg(feature = "http")]
Http(Url),

/// An address of a mainnet contract, available via [Etherscan].
Expand All @@ -53,12 +56,14 @@ pub enum Source {
///
/// [Etherscan]: etherscan.io
/// [truffle loader]: ethcontract_common::artifact::truffle::TruffleLoader
#[cfg(feature = "http")]
Etherscan(Address),

/// The package identifier of an NPM package with a path to an artifact
/// or ABI to be retrieved from [unpkg].
///
/// [unpkg]: unpkg.io
#[cfg(feature = "http")]
Npm(String),
}

Expand Down Expand Up @@ -106,6 +111,7 @@ impl Source {

match url.scheme() {
"file" => Ok(Source::local(url.path())),
#[cfg(feature = "http")]
"http" | "https" => match url.host_str() {
Some("etherscan.io") => Source::etherscan(
url.path()
Expand All @@ -115,7 +121,9 @@ impl Source {
),
_ => Ok(Source::Http(url)),
},
#[cfg(feature = "http")]
"etherscan" => Source::etherscan(url.path()),
#[cfg(feature = "http")]
"npm" => Ok(Source::npm(url.path())),
_ => Err(anyhow!("unsupported URL '{}'", url)),
}
Expand All @@ -127,20 +135,23 @@ impl Source {
}

/// Creates an HTTP source from a URL.
#[cfg(feature = "http")]
pub fn http(url: &str) -> Result<Self> {
Ok(Source::Http(Url::parse(url)?))
}

/// Creates an [Etherscan] source from contract address on mainnet.
///
/// [Etherscan]: etherscan.io
#[cfg(feature = "http")]
pub fn etherscan(address: &str) -> Result<Self> {
util::parse_address(address)
.context("failed to parse address for Etherscan source")
.map(Source::Etherscan)
}

/// Creates an NPM source from a package path.
#[cfg(feature = "http")]
pub fn npm(package_path: impl Into<String>) -> Self {
Source::Npm(package_path.into())
}
Expand All @@ -157,8 +168,11 @@ impl Source {
pub fn artifact_json(&self) -> Result<String> {
match self {
Source::Local(path) => get_local_contract(path),
#[cfg(feature = "http")]
Source::Http(url) => get_http_contract(url),
#[cfg(feature = "http")]
Source::Etherscan(address) => get_etherscan_contract(*address),
#[cfg(feature = "http")]
Source::Npm(package) => get_npm_contract(package),
}
}
Expand Down Expand Up @@ -192,12 +206,14 @@ fn get_local_contract(path: &Path) -> Result<String> {
Ok(abi_or_artifact(json))
}

#[cfg(feature = "http")]
fn get_http_contract(url: &Url) -> Result<String> {
let json = util::http_get(url.as_str())
.with_context(|| format!("failed to retrieve JSON from {}", url))?;
Ok(abi_or_artifact(json))
}

#[cfg(feature = "http")]
fn get_etherscan_contract(address: Address) -> Result<String> {
// NOTE: We do not retrieve the bytecode since deploying contracts with the
// same bytecode is unreliable as the libraries have already linked and
Expand Down Expand Up @@ -225,6 +241,7 @@ fn get_etherscan_contract(address: Address) -> Result<String> {
Ok(json)
}

#[cfg(feature = "http")]
fn get_npm_contract(package: &str) -> Result<String> {
let unpkg_url = format!("https://unpkg.com/{}", package);
let json = util::http_get(&unpkg_url)
Expand Down Expand Up @@ -268,18 +285,22 @@ mod tests {
"/absolute/Contract.json",
Source::local("/absolute/Contract.json"),
),
#[cfg(feature = "http")]
(
"https://my.domain.eth/path/to/Contract.json",
Source::http("https://my.domain.eth/path/to/Contract.json").unwrap(),
),
#[cfg(feature = "http")]
(
"etherscan:0x0001020304050607080910111213141516171819",
Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(),
),
#[cfg(feature = "http")]
(
"https://etherscan.io/address/0x0001020304050607080910111213141516171819",
Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(),
),
#[cfg(feature = "http")]
(
"npm:@openzeppelin/[email protected]/build/contracts/IERC20.json",
Source::npm("@openzeppelin/[email protected]/build/contracts/IERC20.json"),
Expand Down
2 changes: 2 additions & 0 deletions ethcontract-generate/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use anyhow::{anyhow, Result};
#[cfg(feature = "http")]
use curl::easy::Easy;
use ethcontract_common::Address;
use inflector::Inflector;
Expand Down Expand Up @@ -54,6 +55,7 @@ where
}

/// Performs an HTTP GET request and return the contents of the response.
#[cfg(feature = "http")]
pub fn http_get(url: &str) -> Result<String> {
let mut buffer = Vec::new();
let mut handle = Easy::new();
Expand Down
6 changes: 3 additions & 3 deletions ethcontract-mock/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ Tools for mocking ethereum contracts.
"""

[dependencies]
ethcontract = { version = "0.16.0", path = "../ethcontract" }
ethcontract = { version = "0.16.0", path = "../ethcontract", default-features = false, features = ["derive"] }
hex = "0.4"
mockall = "0.11"
rlp = "0.5"
predicates = "2.0"

[dev-dependencies]
tokio = { version = "1.6", features = ["macros"] }
ethcontract-derive = { version = "0.16.0", path = "../ethcontract-derive" }
tokio = { version = "1.6", features = ["macros", "rt"] }
ethcontract-derive = { version = "0.16.0", path = "../ethcontract-derive", default-featuers = false }
5 changes: 3 additions & 2 deletions ethcontract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ to Ethereum smart contracts.
name = "ethcontract"

[features]
default = ["derive", "http-tls", "ws-tls-tokio"]
default = ["derive", "http-tls", "ws-tls-tokio", "derive-http"]
derive = ["ethcontract-derive"]
derive-http = ["ethcontract-derive/http"]
http = ["web3/http"]
http-tls = ["http", "web3/http-tls"]
http-native-tls = ["http", "web3/http-native-tls"]
Expand All @@ -32,7 +33,7 @@ ipc-tokio = ["web3/ipc-tokio"]
[dependencies]
arrayvec = "0.7"
ethcontract-common = { version = "0.16.0", path = "../ethcontract-common" }
ethcontract-derive = { version = "0.16.0", path = "../ethcontract-derive", optional = true}
ethcontract-derive = { version = "0.16.0", path = "../ethcontract-derive", optional = true, default-features = false }
futures = "0.3"
futures-timer = "3.0"
hex = "0.4"
Expand Down
2 changes: 1 addition & 1 deletion examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ license = "MIT OR Apache-2.0"
autobins = false

[dev-dependencies]
ethcontract = { path = "../ethcontract", features = ["derive"] }
ethcontract = { path = "../ethcontract" }
futures = "0.3"
tokio = { version = "1.6", features = ["macros"] }
2 changes: 1 addition & 1 deletion examples/generate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ futures = "0.3"
tokio = { version = "1.6", features = ["macros"] }

[build-dependencies]
ethcontract-generate = { path = "../../ethcontract-generate" }
ethcontract-generate = { path = "../../ethcontract-generate", default-features = false }

0 comments on commit 5427c19

Please sign in to comment.