From 91cd6ccce8c71c82f462d8a8838a94087565623a Mon Sep 17 00:00:00 2001 From: Genysys Date: Mon, 19 Dec 2022 19:54:24 +0400 Subject: [PATCH] feat: adds bscscan as abi source (#1955) --- CHANGELOG.md | 2 +- .../ethers-contract-abigen/src/source.rs | 38 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b157dc5..88e51cc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## ethers-core ### Unreleased - +- - Graceful handling of WebSocket transport errors [#1889](https://github.com/gakonst/ethers-rs/issues/1889) [#1815](https://github.com/gakonst/ethers-rs/issues/1815) - `MiddlewareBuilder` trait to instantiate a `Provider` as `Middleware` layers. - An `Event` builder can be instantiated specifying the event filter type, without the need to instantiate a contract. diff --git a/ethers-contract/ethers-contract-abigen/src/source.rs b/ethers-contract/ethers-contract-abigen/src/source.rs index a1189cf3..2cedae73 100644 --- a/ethers-contract/ethers-contract-abigen/src/source.rs +++ b/ethers-contract/ethers-contract-abigen/src/source.rs @@ -20,6 +20,9 @@ pub enum Source { /// An ABI to be retrieved over HTTP(S). Http(Url), + /// An address of a mainnet contract that has been verified on Bscscan.com. + Bscscan(Address), + /// An address of a mainnet contract that has been verified on Etherscan.io. Etherscan(Address), @@ -54,7 +57,12 @@ impl Source { /// /// - `etherscan:0xXX..XX` or `https://etherscan.io/address/0xXX..XX`: a address or URL of a /// verified contract on Etherscan. - /// + /// - `bscscan:0xXX..XX` or `https://bscscan.io/address/0xXX..XX`: a address or URL of a + /// verified contract on Bscscan. + /// - `polygonscan:0xXX..XX` or `https://polygonscan.io/address/0xXX..XX`: a address or URL of a + /// verified contract on Polygonscan. + /// - `snowtrace:0xXX..XX` or `https://snowtrace.io/address/0xXX..XX`: a address or URL of a + /// verified contract on Snowtrace. /// - `npm:@org/package@1.0.0/path/to/contract.json` an npmjs package with an optional version /// and path (defaulting to the latest version and `index.js`). The contract ABI will be /// retrieved through `unpkg.io`. @@ -99,6 +107,12 @@ impl Source { match url.scheme() { "file" => Ok(Source::local(source)), "http" | "https" => match url.host_str() { + Some("bscscan.com") => Source::etherscan( + url.path() + .rsplit('/') + .next() + .ok_or_else(|| eyre!("HTTP URL does not have a path"))?, + ), Some("etherscan.io") => Source::etherscan( url.path() .rsplit('/') @@ -119,6 +133,7 @@ impl Source { ), _ => Ok(Source::Http(url)), }, + "bscscan" => Source::bscscan(url.path()), "etherscan" => Source::etherscan(url.path()), "polygonscan" => Source::polygonscan(url.path()), "snowtrace" => Source::snowtrace(url.path()), @@ -140,6 +155,16 @@ impl Source { Ok(Source::Http(Url::parse(url.as_ref())?)) } + /// Creates an Bscscan source from an address string. + pub fn bscscan(address: S) -> Result + where + S: AsRef, + { + let address = + util::parse_address(address).context("failed to parse address for Bscscan source")?; + Ok(Source::Bscscan(address)) + } + /// Creates an Etherscan source from an address string. pub fn etherscan(address: S) -> Result where @@ -187,6 +212,7 @@ impl Source { match self { Source::Local(path) => get_local_contract(path), Source::Http(_) => panic!("Http abi location are not supported for wasm"), + Source::Bscscan(_) => panic!("Bscscan abi location are not supported for wasm"), Source::Etherscan(_) => panic!("Etherscan abi location are not supported for wasm"), Source::Polygonscan(_) => panic!("Polygonscan abi location are not supported for wasm"), Source::Snowtrace(_) => panic!("Snowtrace abi location are not supported for wasm"), @@ -197,6 +223,7 @@ impl Source { match self { Source::Local(path) => get_local_contract(path), Source::Http(url) => get_http_contract(url), + Source::Bscscan(address) => get_etherscan_contract(*address, "bscscan.com"), Source::Etherscan(address) => get_etherscan_contract(*address, "etherscan.io"), Source::Polygonscan(address) => get_etherscan_contract(*address, "polygonscan.com"), Source::Snowtrace(address) => get_etherscan_contract(*address, "snowtrace.io"), @@ -261,6 +288,7 @@ fn get_etherscan_contract(address: Address, domain: &str) -> Result { // probably don't reference anything when deploying on other networks. let api_key = { let key_res = match domain { + "bscscan.com" => env::var("BSCSCAN_API_KEY").ok(), "etherscan.io" => env::var("ETHERSCAN_API_KEY").ok(), "polygonscan.com" => env::var("POLYGONSCAN_API_KEY").ok(), "snowtrace.io" => env::var("SNOWTRACE_API_KEY").ok(), @@ -311,6 +339,10 @@ mod tests { "https://my.domain.eth/path/to/Contract.json", Source::http("https://my.domain.eth/path/to/Contract.json").unwrap(), ), + ( + "bscscan:0x0001020304050607080910111213141516171819", + Source::bscscan("0x0001020304050607080910111213141516171819").unwrap(), + ), ( "etherscan:0x0001020304050607080910111213141516171819", Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(), @@ -323,6 +355,10 @@ mod tests { "snowtrace:0x0001020304050607080910111213141516171819", Source::snowtrace("0x0001020304050607080910111213141516171819").unwrap(), ), + ( + "https://bscscan.io/address/0x0001020304050607080910111213141516171819", + Source::bscscan("0x0001020304050607080910111213141516171819").unwrap(), + ), ( "https://etherscan.io/address/0x0001020304050607080910111213141516171819", Source::etherscan("0x0001020304050607080910111213141516171819").unwrap(),