simplify provider type declaration
This commit is contained in:
parent
cd4914d37f
commit
1c6b067bb9
|
@ -1,6 +1,6 @@
|
||||||
//! Minimal HTTP JSON-RPC 2.0 Client
|
//! Minimal HTTP JSON-RPC 2.0 Client
|
||||||
//! The request/response code is taken from [here](https://github.com/althea-net/guac_rs/blob/master/web3/src/jsonrpc)
|
//! The request/response code is taken from [here](https://github.com/althea-net/guac_rs/blob/master/web3/src/jsonrpc)
|
||||||
use crate::JsonRpcClient;
|
use crate::{provider::ProviderError, JsonRpcClient};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use reqwest::{Client, Error as ReqwestError};
|
use reqwest::{Client, Error as ReqwestError};
|
||||||
|
@ -29,6 +29,12 @@ pub enum ClientError {
|
||||||
JsonRpcError(#[from] JsonRpcError),
|
JsonRpcError(#[from] JsonRpcError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ClientError> for ProviderError {
|
||||||
|
fn from(src: ClientError) -> Self {
|
||||||
|
ProviderError::JsonRpcClientError(Box::new(src))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl JsonRpcClient for Provider {
|
impl JsonRpcClient for Provider {
|
||||||
type Error = ClientError;
|
type Error = ClientError;
|
||||||
|
|
|
@ -10,10 +10,10 @@ use async_trait::async_trait;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{error::Error, fmt::Debug};
|
use std::{error::Error, fmt::Debug};
|
||||||
|
|
||||||
pub use provider::Provider;
|
pub use provider::{Provider, ProviderError};
|
||||||
|
|
||||||
/// An HTTP provider for interacting with an Ethereum-compatible blockchain
|
/// An HTTP provider for interacting with an Ethereum-compatible blockchain
|
||||||
pub type HttpProvider<N> = Provider<http::Provider, N>;
|
pub type HttpProvider = Provider<http::Provider>;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
/// Trait which must be implemented by data transports to be used with the Ethereum
|
/// Trait which must be implemented by data transports to be used with the Ethereum
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
use crate::{ens, http::Provider as HttpProvider, networks::Network, JsonRpcClient};
|
use crate::{
|
||||||
|
ens,
|
||||||
|
http::Provider as HttpProvider,
|
||||||
|
networks::{Mainnet, Network},
|
||||||
|
JsonRpcClient,
|
||||||
|
};
|
||||||
|
|
||||||
use ethers_core::{
|
use ethers_core::{
|
||||||
abi::{self, Detokenize, ParamType},
|
abi::{self, Detokenize, ParamType},
|
||||||
|
@ -10,93 +15,116 @@ use ethers_core::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use thiserror::Error;
|
||||||
use url::{ParseError, Url};
|
use url::{ParseError, Url};
|
||||||
|
|
||||||
use std::{convert::TryFrom, fmt::Debug, marker::PhantomData};
|
use std::{convert::TryFrom, fmt::Debug};
|
||||||
|
|
||||||
/// An abstract provider for interacting with the [Ethereum JSON RPC
|
/// An abstract provider for interacting with the [Ethereum JSON RPC
|
||||||
/// API](https://github.com/ethereum/wiki/wiki/JSON-RPC). Must be instantiated
|
/// API](https://github.com/ethereum/wiki/wiki/JSON-RPC). Must be instantiated
|
||||||
/// with a [`Network`](networks/trait.Network.html) and a data transport
|
/// with a [`Network`](networks/trait.Network.html) and a data transport
|
||||||
/// (e.g. HTTP, Websockets etc.)
|
/// (e.g. HTTP, Websockets etc.)
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Provider<P, N>(P, PhantomData<N>, Option<Address>);
|
pub struct Provider<P>(P, Option<Address>);
|
||||||
|
|
||||||
|
#[derive(Debug, Error)]
|
||||||
|
/// An error thrown when making a call to the provider
|
||||||
|
pub enum ProviderError {
|
||||||
|
#[error(transparent)]
|
||||||
|
// dyn dispatch the error to avoid generic return types
|
||||||
|
JsonRpcClientError(#[from] Box<dyn std::error::Error>),
|
||||||
|
#[error("ens name not found: {0}")]
|
||||||
|
EnsError(String),
|
||||||
|
}
|
||||||
|
|
||||||
// JSON RPC bindings
|
// JSON RPC bindings
|
||||||
impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
impl<P> Provider<P>
|
||||||
|
where
|
||||||
|
P: JsonRpcClient,
|
||||||
|
ProviderError: From<<P as JsonRpcClient>::Error> + 'static,
|
||||||
|
{
|
||||||
////// Blockchain Status
|
////// Blockchain Status
|
||||||
//
|
//
|
||||||
// Functions for querying the state of the blockchain
|
// Functions for querying the state of the blockchain
|
||||||
|
|
||||||
/// Gets the latest block number via the `eth_BlockNumber` API
|
/// Gets the latest block number via the `eth_BlockNumber` API
|
||||||
pub async fn get_block_number(&self) -> Result<U256, P::Error> {
|
pub async fn get_block_number(&self) -> Result<U256, ProviderError> {
|
||||||
self.0.request("eth_blockNumber", None::<()>).await
|
Ok(self.0.request("eth_blockNumber", None::<()>).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the block at `block_hash_or_number` (transaction hashes only)
|
/// Gets the block at `block_hash_or_number` (transaction hashes only)
|
||||||
pub async fn get_block(
|
pub async fn get_block(
|
||||||
&self,
|
&self,
|
||||||
block_hash_or_number: impl Into<BlockId>,
|
block_hash_or_number: impl Into<BlockId>,
|
||||||
) -> Result<Block<TxHash>, P::Error> {
|
) -> Result<Block<TxHash>, ProviderError> {
|
||||||
self.get_block_gen(block_hash_or_number.into(), false).await
|
Ok(self
|
||||||
|
.get_block_gen(block_hash_or_number.into(), false)
|
||||||
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the block at `block_hash_or_number` (full transactions included)
|
/// Gets the block at `block_hash_or_number` (full transactions included)
|
||||||
pub async fn get_block_with_txs(
|
pub async fn get_block_with_txs(
|
||||||
&self,
|
&self,
|
||||||
block_hash_or_number: impl Into<BlockId>,
|
block_hash_or_number: impl Into<BlockId>,
|
||||||
) -> Result<Block<Transaction>, P::Error> {
|
) -> Result<Block<Transaction>, ProviderError> {
|
||||||
self.get_block_gen(block_hash_or_number.into(), true).await
|
Ok(self
|
||||||
|
.get_block_gen(block_hash_or_number.into(), true)
|
||||||
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_block_gen<Tx: for<'a> Deserialize<'a>>(
|
async fn get_block_gen<Tx: for<'a> Deserialize<'a>>(
|
||||||
&self,
|
&self,
|
||||||
id: BlockId,
|
id: BlockId,
|
||||||
include_txs: bool,
|
include_txs: bool,
|
||||||
) -> Result<Block<Tx>, P::Error> {
|
) -> Result<Block<Tx>, ProviderError> {
|
||||||
let include_txs = utils::serialize(&include_txs);
|
let include_txs = utils::serialize(&include_txs);
|
||||||
|
|
||||||
match id {
|
Ok(match id {
|
||||||
BlockId::Hash(hash) => {
|
BlockId::Hash(hash) => {
|
||||||
let hash = utils::serialize(&hash);
|
let hash = utils::serialize(&hash);
|
||||||
let args = vec![hash, include_txs];
|
let args = vec![hash, include_txs];
|
||||||
self.0.request("eth_getBlockByHash", Some(args)).await
|
self.0.request("eth_getBlockByHash", Some(args)).await?
|
||||||
}
|
}
|
||||||
BlockId::Number(num) => {
|
BlockId::Number(num) => {
|
||||||
let num = utils::serialize(&num);
|
let num = utils::serialize(&num);
|
||||||
let args = vec![num, include_txs];
|
let args = vec![num, include_txs];
|
||||||
self.0.request("eth_getBlockByNumber", Some(args)).await
|
self.0.request("eth_getBlockByNumber", Some(args)).await?
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the transaction with `transaction_hash`
|
/// Gets the transaction with `transaction_hash`
|
||||||
pub async fn get_transaction<T: Send + Sync + Into<TxHash>>(
|
pub async fn get_transaction<T: Send + Sync + Into<TxHash>>(
|
||||||
&self,
|
&self,
|
||||||
transaction_hash: T,
|
transaction_hash: T,
|
||||||
) -> Result<Transaction, P::Error> {
|
) -> Result<Transaction, ProviderError> {
|
||||||
let hash = transaction_hash.into();
|
let hash = transaction_hash.into();
|
||||||
self.0.request("eth_getTransactionByHash", Some(hash)).await
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_getTransactionByHash", Some(hash))
|
||||||
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the transaction receipt with `transaction_hash`
|
/// Gets the transaction receipt with `transaction_hash`
|
||||||
pub async fn get_transaction_receipt<T: Send + Sync + Into<TxHash>>(
|
pub async fn get_transaction_receipt<T: Send + Sync + Into<TxHash>>(
|
||||||
&self,
|
&self,
|
||||||
transaction_hash: T,
|
transaction_hash: T,
|
||||||
) -> Result<TransactionReceipt, P::Error> {
|
) -> Result<TransactionReceipt, ProviderError> {
|
||||||
let hash = transaction_hash.into();
|
let hash = transaction_hash.into();
|
||||||
self.0
|
Ok(self
|
||||||
|
.0
|
||||||
.request("eth_getTransactionReceipt", Some(hash))
|
.request("eth_getTransactionReceipt", Some(hash))
|
||||||
.await
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the current gas price as estimated by the node
|
/// Gets the current gas price as estimated by the node
|
||||||
pub async fn get_gas_price(&self) -> Result<U256, P::Error> {
|
pub async fn get_gas_price(&self) -> Result<U256, ProviderError> {
|
||||||
self.0.request("eth_gasPrice", None::<()>).await
|
Ok(self.0.request("eth_gasPrice", None::<()>).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the accounts on the node
|
/// Gets the accounts on the node
|
||||||
pub async fn get_accounts(&self) -> Result<Vec<Address>, P::Error> {
|
pub async fn get_accounts(&self) -> Result<Vec<Address>, ProviderError> {
|
||||||
self.0.request("eth_accounts", None::<()>).await
|
Ok(self.0.request("eth_accounts", None::<()>).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the nonce of the address
|
/// Returns the nonce of the address
|
||||||
|
@ -104,12 +132,13 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
&self,
|
&self,
|
||||||
from: Address,
|
from: Address,
|
||||||
block: Option<BlockNumber>,
|
block: Option<BlockNumber>,
|
||||||
) -> Result<U256, P::Error> {
|
) -> Result<U256, ProviderError> {
|
||||||
let from = utils::serialize(&from);
|
let from = utils::serialize(&from);
|
||||||
let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
|
let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
|
||||||
self.0
|
Ok(self
|
||||||
|
.0
|
||||||
.request("eth_getTransactionCount", Some(&[from, block]))
|
.request("eth_getTransactionCount", Some(&[from, block]))
|
||||||
.await
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the account's balance
|
/// Returns the account's balance
|
||||||
|
@ -117,16 +146,19 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
&self,
|
&self,
|
||||||
from: Address,
|
from: Address,
|
||||||
block: Option<BlockNumber>,
|
block: Option<BlockNumber>,
|
||||||
) -> Result<U256, P::Error> {
|
) -> Result<U256, ProviderError> {
|
||||||
let from = utils::serialize(&from);
|
let from = utils::serialize(&from);
|
||||||
let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
|
let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
|
||||||
self.0.request("eth_getBalance", Some(&[from, block])).await
|
Ok(self
|
||||||
|
.0
|
||||||
|
.request("eth_getBalance", Some(&[from, block]))
|
||||||
|
.await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the currently configured chain id, a value used in replay-protected
|
/// Returns the currently configured chain id, a value used in replay-protected
|
||||||
/// transaction signing as introduced by EIP-155.
|
/// transaction signing as introduced by EIP-155.
|
||||||
pub async fn get_chainid(&self) -> Result<U256, P::Error> {
|
pub async fn get_chainid(&self) -> Result<U256, ProviderError> {
|
||||||
self.0.request("eth_chainId", None::<()>).await
|
Ok(self.0.request("eth_chainId", None::<()>).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
////// Contract Execution
|
////// Contract Execution
|
||||||
|
@ -139,10 +171,10 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
&self,
|
&self,
|
||||||
tx: TransactionRequest,
|
tx: TransactionRequest,
|
||||||
block: Option<BlockNumber>,
|
block: Option<BlockNumber>,
|
||||||
) -> Result<Bytes, P::Error> {
|
) -> Result<Bytes, ProviderError> {
|
||||||
let tx = utils::serialize(&tx);
|
let tx = utils::serialize(&tx);
|
||||||
let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
|
let block = utils::serialize(&block.unwrap_or(BlockNumber::Latest));
|
||||||
self.0.request("eth_call", Some(vec![tx, block])).await
|
Ok(self.0.request("eth_call", Some(vec![tx, block])).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a transaction to a single Ethereum node and return the estimated amount of gas required (as a U256) to send it
|
/// Send a transaction to a single Ethereum node and return the estimated amount of gas required (as a U256) to send it
|
||||||
|
@ -152,7 +184,7 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
&self,
|
&self,
|
||||||
tx: &TransactionRequest,
|
tx: &TransactionRequest,
|
||||||
block: Option<BlockNumber>,
|
block: Option<BlockNumber>,
|
||||||
) -> Result<U256, P::Error> {
|
) -> Result<U256, ProviderError> {
|
||||||
let tx = utils::serialize(tx);
|
let tx = utils::serialize(tx);
|
||||||
|
|
||||||
let args = match block {
|
let args = match block {
|
||||||
|
@ -160,37 +192,43 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
None => vec![tx],
|
None => vec![tx],
|
||||||
};
|
};
|
||||||
|
|
||||||
self.0.request("eth_estimateGas", Some(args)).await
|
Ok(self.0.request("eth_estimateGas", Some(args)).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send the transaction to the entire Ethereum network and returns the transaction's hash
|
/// Send the transaction to the entire Ethereum network and returns the transaction's hash
|
||||||
/// This will consume gas from the account that signed the transaction.
|
/// This will consume gas from the account that signed the transaction.
|
||||||
pub async fn send_transaction(&self, mut tx: TransactionRequest) -> Result<TxHash, P::Error> {
|
pub async fn send_transaction(
|
||||||
|
&self,
|
||||||
|
mut tx: TransactionRequest,
|
||||||
|
) -> Result<TxHash, ProviderError> {
|
||||||
if let Some(ref to) = tx.to {
|
if let Some(ref to) = tx.to {
|
||||||
if let NameOrAddress::Name(ens_name) = to {
|
if let NameOrAddress::Name(ens_name) = to {
|
||||||
|
// resolve to an address
|
||||||
let addr = self
|
let addr = self
|
||||||
.resolve_name(&ens_name)
|
.resolve_name(&ens_name)
|
||||||
.await?
|
.await?
|
||||||
.expect("TODO: Handle ENS name not found");
|
.ok_or(ProviderError::EnsError(ens_name.to_owned()))?;
|
||||||
|
|
||||||
|
// set the value
|
||||||
tx.to = Some(addr.into())
|
tx.to = Some(addr.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.0.request("eth_sendTransaction", Some(tx)).await
|
Ok(self.0.request("eth_sendTransaction", Some(tx)).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send the raw RLP encoded transaction to the entire Ethereum network and returns the transaction's hash
|
/// Send the raw RLP encoded transaction to the entire Ethereum network and returns the transaction's hash
|
||||||
/// This will consume gas from the account that signed the transaction.
|
/// This will consume gas from the account that signed the transaction.
|
||||||
pub async fn send_raw_transaction(&self, tx: &Transaction) -> Result<TxHash, P::Error> {
|
pub async fn send_raw_transaction(&self, tx: &Transaction) -> Result<TxHash, ProviderError> {
|
||||||
let rlp = utils::serialize(&tx.rlp());
|
let rlp = utils::serialize(&tx.rlp());
|
||||||
self.0.request("eth_sendRawTransaction", Some(rlp)).await
|
Ok(self.0.request("eth_sendRawTransaction", Some(rlp)).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
////// Contract state
|
////// Contract state
|
||||||
|
|
||||||
/// Returns an array (possibly empty) of logs that match the filter
|
/// Returns an array (possibly empty) of logs that match the filter
|
||||||
pub async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>, P::Error> {
|
pub async fn get_logs(&self, filter: &Filter) -> Result<Vec<Log>, ProviderError> {
|
||||||
self.0.request("eth_getLogs", Some(filter)).await
|
Ok(self.0.request("eth_getLogs", Some(filter)).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: get_code, get_storage_at
|
// TODO: get_code, get_storage_at
|
||||||
|
@ -208,7 +246,7 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
///
|
///
|
||||||
/// If the bytes returned from the ENS registrar/resolver cannot be interpreted as
|
/// If the bytes returned from the ENS registrar/resolver cannot be interpreted as
|
||||||
/// an address. This should theoretically never happen.
|
/// an address. This should theoretically never happen.
|
||||||
pub async fn resolve_name(&self, ens_name: &str) -> Result<Option<Address>, P::Error> {
|
pub async fn resolve_name(&self, ens_name: &str) -> Result<Option<Address>, ProviderError> {
|
||||||
self.query_resolver(ParamType::Address, ens_name, ens::ADDR_SELECTOR)
|
self.query_resolver(ParamType::Address, ens_name, ens::ADDR_SELECTOR)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -218,7 +256,7 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
///
|
///
|
||||||
/// If the bytes returned from the ENS registrar/resolver cannot be interpreted as
|
/// If the bytes returned from the ENS registrar/resolver cannot be interpreted as
|
||||||
/// a string. This should theoretically never happen.
|
/// a string. This should theoretically never happen.
|
||||||
pub async fn lookup_address(&self, address: Address) -> Result<Option<String>, P::Error> {
|
pub async fn lookup_address(&self, address: Address) -> Result<Option<String>, ProviderError> {
|
||||||
let ens_name = ens::reverse_address(address);
|
let ens_name = ens::reverse_address(address);
|
||||||
self.query_resolver(ParamType::String, &ens_name, ens::NAME_SELECTOR)
|
self.query_resolver(ParamType::String, &ens_name, ens::NAME_SELECTOR)
|
||||||
.await
|
.await
|
||||||
|
@ -229,11 +267,11 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
param: ParamType,
|
param: ParamType,
|
||||||
ens_name: &str,
|
ens_name: &str,
|
||||||
selector: Selector,
|
selector: Selector,
|
||||||
) -> Result<Option<T>, P::Error> {
|
) -> Result<Option<T>, ProviderError> {
|
||||||
// Get the ENS address, prioritize the local override variable
|
// Get the ENS address, prioritize the local override variable
|
||||||
let ens_addr = match self.2 {
|
let ens_addr = match self.1 {
|
||||||
Some(ens_addr) => ens_addr,
|
Some(ens_addr) => ens_addr,
|
||||||
None => match N::ENS_ADDRESS {
|
None => match Mainnet::ENS_ADDRESS {
|
||||||
Some(ens_addr) => ens_addr,
|
Some(ens_addr) => ens_addr,
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
},
|
},
|
||||||
|
@ -260,7 +298,7 @@ impl<P: JsonRpcClient, N: Network> Provider<P, N> {
|
||||||
|
|
||||||
/// Overrides the default ENS address set by the provider's `Network` type.
|
/// Overrides the default ENS address set by the provider's `Network` type.
|
||||||
pub fn ens<T: Into<Address>>(mut self, ens: T) -> Self {
|
pub fn ens<T: Into<Address>>(mut self, ens: T) -> Self {
|
||||||
self.2 = Some(ens.into());
|
self.1 = Some(ens.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,27 +314,22 @@ fn decode_bytes<T: Detokenize>(param: ParamType, bytes: Bytes) -> T {
|
||||||
T::from_tokens(tokens).expect("could not parse tokens as address")
|
T::from_tokens(tokens).expect("could not parse tokens as address")
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Network> TryFrom<&str> for Provider<HttpProvider, N> {
|
impl TryFrom<&str> for Provider<HttpProvider> {
|
||||||
type Error = ParseError;
|
type Error = ParseError;
|
||||||
|
|
||||||
fn try_from(src: &str) -> Result<Self, Self::Error> {
|
fn try_from(src: &str) -> Result<Self, Self::Error> {
|
||||||
Ok(Provider(
|
Ok(Provider(HttpProvider::new(Url::parse(src)?), None))
|
||||||
HttpProvider::new(Url::parse(src)?),
|
|
||||||
PhantomData,
|
|
||||||
None,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod ens_tests {
|
mod ens_tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::networks::Mainnet;
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
// Test vector from: https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#id2
|
// Test vector from: https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#id2
|
||||||
async fn mainnet_resolve_name() {
|
async fn mainnet_resolve_name() {
|
||||||
let provider = Provider::<HttpProvider, Mainnet>::try_from(
|
let provider = Provider::<HttpProvider>::try_from(
|
||||||
"https://mainnet.infura.io/v3/9408f47dedf04716a03ef994182cf150",
|
"https://mainnet.infura.io/v3/9408f47dedf04716a03ef994182cf150",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -325,7 +358,7 @@ mod ens_tests {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
// Test vector from: https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#id2
|
// Test vector from: https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#id2
|
||||||
async fn mainnet_lookup_address() {
|
async fn mainnet_lookup_address() {
|
||||||
let provider = Provider::<HttpProvider, Mainnet>::try_from(
|
let provider = Provider::<HttpProvider>::try_from(
|
||||||
"https://mainnet.infura.io/v3/9408f47dedf04716a03ef994182cf150",
|
"https://mainnet.infura.io/v3/9408f47dedf04716a03ef994182cf150",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
Loading…
Reference in New Issue