ci: run examples in CI (#421)
* ci: run examples in CI * fix(ens): set the resolved ens addr for gas estimation * fix(contract-examples): use legacy sends with ganache * fix(ens-example): ensure test runs when forking from mainnet * fix(watch-blocks-example): run our own provider with preset blocktime
This commit is contained in:
parent
824bedbd42
commit
b5909d05b0
|
@ -158,4 +158,45 @@ jobs:
|
|||
- name: Wasm-pack test chrome
|
||||
run: |
|
||||
cd examples/ethers-wasm
|
||||
wasm-pack test --headless --chrome
|
||||
wasm-pack test --headless --chrome
|
||||
|
||||
examples:
|
||||
name: Examples
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
uses: actions/checkout@v2
|
||||
- name: Install ganache-cli
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 10
|
||||
- name: Install ganache
|
||||
run: npm install -g ganache-cli
|
||||
- name: Install Solc
|
||||
run: |
|
||||
mkdir -p "$HOME/bin"
|
||||
wget -q https://github.com/ethereum/solidity/releases/download/v0.6.6/solc-static-linux -O $HOME/bin/solc
|
||||
chmod u+x "$HOME/bin/solc"
|
||||
export PATH=$HOME/bin:$PATH
|
||||
solc --version
|
||||
|
||||
- name: Install geth
|
||||
run: |
|
||||
mkdir -p "$HOME/bin"
|
||||
wget -q https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.23-8c2f2715.tar.gz
|
||||
tar -xvf geth-linux-amd64-1.9.23-8c2f2715.tar.gz
|
||||
mv geth-linux-amd64-1.9.23-8c2f2715/geth $HOME/bin/geth
|
||||
chmod u+x "$HOME/bin/geth"
|
||||
export PATH=$HOME/bin:$PATH
|
||||
geth version
|
||||
- name: Install stable toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: cargo test
|
||||
run: |
|
||||
export PATH=$HOME/bin:$PATH
|
||||
./scripts/examples.sh
|
||||
|
|
|
@ -10,6 +10,8 @@ Extensive documentation and examples are available [here](https://docs.rs/ethers
|
|||
|
||||
Alternatively, you may clone the repository and run `cd ethers/ && cargo doc --open`
|
||||
|
||||
You can also run any of the examples by executing: `cargo run -p ethers --example <name>`
|
||||
|
||||
## Add ethers-rs to your repository
|
||||
|
||||
```toml
|
||||
|
|
|
@ -215,7 +215,7 @@ pub trait Middleware: Sync + Send + Debug {
|
|||
tx: &mut TypedTransaction,
|
||||
block: Option<BlockId>,
|
||||
) -> Result<(), Self::Error> {
|
||||
let tx_clone = tx.clone();
|
||||
let mut tx_clone = tx.clone();
|
||||
|
||||
// TODO: Maybe deduplicate the code in a nice way
|
||||
match tx {
|
||||
|
@ -223,6 +223,7 @@ pub trait Middleware: Sync + Send + Debug {
|
|||
if let Some(NameOrAddress::Name(ref ens_name)) = inner.to {
|
||||
let addr = self.resolve_name(ens_name).await?;
|
||||
inner.to = Some(addr.into());
|
||||
tx_clone.set_to(addr);
|
||||
};
|
||||
|
||||
if inner.from.is_none() {
|
||||
|
@ -244,6 +245,7 @@ pub trait Middleware: Sync + Send + Debug {
|
|||
if let Some(NameOrAddress::Name(ref ens_name)) = inner.tx.to {
|
||||
let addr = self.resolve_name(ens_name).await?;
|
||||
inner.tx.to = Some(addr.into());
|
||||
tx_clone.set_to(addr);
|
||||
};
|
||||
|
||||
if inner.tx.from.is_none() {
|
||||
|
@ -265,6 +267,7 @@ pub trait Middleware: Sync + Send + Debug {
|
|||
if let Some(NameOrAddress::Name(ref ens_name)) = inner.to {
|
||||
let addr = self.resolve_name(ens_name).await?;
|
||||
inner.to = Some(addr.into());
|
||||
tx_clone.set_to(addr);
|
||||
};
|
||||
|
||||
if inner.from.is_none() {
|
||||
|
|
|
@ -4,8 +4,8 @@ fn main() -> anyhow::Result<()> {
|
|||
let mut args = std::env::args();
|
||||
args.next().unwrap(); // skip program name
|
||||
|
||||
let contract_name = args.next().unwrap();
|
||||
let contract: String = args.next().unwrap();
|
||||
let contract_name = args.next().unwrap_or("SimpleStorage".to_owned());
|
||||
let contract: String = args.next().unwrap_or("examples/contract.sol".to_owned());
|
||||
|
||||
println!("Generating bindings for {}\n", contract);
|
||||
|
||||
|
|
|
@ -45,7 +45,11 @@ async fn main() -> Result<()> {
|
|||
);
|
||||
|
||||
// 6. deploy it with the constructor arguments
|
||||
let contract = factory.deploy("initial value".to_string())?.send().await?;
|
||||
let contract = factory
|
||||
.deploy("initial value".to_string())?
|
||||
.legacy()
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
// 7. get the contract's address
|
||||
let addr = contract.address();
|
||||
|
@ -55,7 +59,12 @@ async fn main() -> Result<()> {
|
|||
|
||||
// 9. call the `setValue` method
|
||||
// (first `await` returns a PendingTransaction, second one waits for it to be mined)
|
||||
let _receipt = contract.set_value("hi".to_owned()).send().await?.await?;
|
||||
let _receipt = contract
|
||||
.set_value("hi".to_owned())
|
||||
.legacy()
|
||||
.send()
|
||||
.await?
|
||||
.await?;
|
||||
|
||||
// 10. get all events
|
||||
let logs = contract
|
||||
|
|
|
@ -43,7 +43,11 @@ async fn main() -> Result<()> {
|
|||
);
|
||||
|
||||
// 6. deploy it with the constructor arguments
|
||||
let contract = factory.deploy("initial value".to_string())?.send().await?;
|
||||
let contract = factory
|
||||
.deploy("initial value".to_string())?
|
||||
.legacy()
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
// 7. get the contract's address
|
||||
let addr = contract.address();
|
||||
|
@ -53,7 +57,12 @@ async fn main() -> Result<()> {
|
|||
|
||||
// 9. call the `setValue` method
|
||||
// (first `await` returns a PendingTransaction, second one waits for it to be mined)
|
||||
let _receipt = contract.set_value("hi".to_owned()).send().await?.await?;
|
||||
let _receipt = contract
|
||||
.set_value("hi".to_owned())
|
||||
.legacy()
|
||||
.send()
|
||||
.await?
|
||||
.await?;
|
||||
|
||||
// 10. get all events
|
||||
let logs = contract
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
use anyhow::Result;
|
||||
use ethers::prelude::*;
|
||||
use ethers::{prelude::*, utils::Ganache};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
// fork mainnet
|
||||
let ganache = Ganache::new()
|
||||
.fork("https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27")
|
||||
.spawn();
|
||||
let from = ganache.addresses()[0].clone();
|
||||
// connect to the network
|
||||
let provider = Provider::<Http>::try_from(
|
||||
"https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
|
||||
)?;
|
||||
|
||||
// create a wallet and connect it to the provider
|
||||
let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"
|
||||
.parse::<LocalWallet>()?;
|
||||
let client = SignerMiddleware::new(provider, wallet);
|
||||
let provider = Provider::<Http>::try_from(ganache.endpoint())
|
||||
.unwrap()
|
||||
.with_sender(from);
|
||||
|
||||
// craft the transaction
|
||||
let tx = TransactionRequest::new().to("vitalik.eth").value(100_000);
|
||||
|
||||
// send it!
|
||||
let receipt = client
|
||||
let receipt = provider
|
||||
.send_transaction(tx, None)
|
||||
.await?
|
||||
.await?
|
||||
.ok_or_else(|| anyhow::format_err!("tx dropped from mempool"))?;
|
||||
let tx = client.get_transaction(receipt.transaction_hash).await?;
|
||||
let tx = provider.get_transaction(receipt.transaction_hash).await?;
|
||||
|
||||
println!("{}", serde_json::to_string(&tx)?);
|
||||
println!("{}", serde_json::to_string(&receipt)?);
|
||||
|
|
|
@ -2,6 +2,7 @@ use ethers::prelude::*;
|
|||
use std::time::Duration;
|
||||
|
||||
#[tokio::main]
|
||||
#[cfg(feature = "ipc")]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let provider = Provider::connect_ipc("~/.ethereum/geth.ipc")
|
||||
.await?
|
||||
|
@ -15,3 +16,6 @@ async fn main() -> anyhow::Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "ipc"))]
|
||||
fn main() {}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use ethers::prelude::*;
|
||||
use ethers::{prelude::*, utils::Ganache};
|
||||
use std::time::Duration;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let ws = Ws::connect("ws://localhost:8546").await?;
|
||||
let ganache = Ganache::new().block_time(1u64).spawn();
|
||||
let ws = Ws::connect(ganache.ws_endpoint()).await?;
|
||||
let provider = Provider::new(ws).interval(Duration::from_millis(2000));
|
||||
let mut stream = provider.watch_blocks().await?.stream();
|
||||
let mut stream = provider.watch_blocks().await?.take(5);
|
||||
while let Some(block) = stream.next().await {
|
||||
dbg!(block);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# run all examples
|
||||
for file in examples/*.rs; do
|
||||
name=`echo $file | cut -f 1 -d '.'`
|
||||
cargo r -p ethers --example `basename $name`
|
||||
done
|
Loading…
Reference in New Issue