Skip to content

Commit

Permalink
Merge pull request #3 from alloy-rs/provider_examples
Browse files Browse the repository at this point in the history
feat(provider): `provider` examples
  • Loading branch information
yash-atreya authored Mar 25, 2024
2 parents e329e7d + d443654 commit 78d6035
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 12 deletions.
Binary file added .DS_Store
Binary file not shown.
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ license = "MIT OR Apache-2.0"
homepage = "https://github.com/alloy-rs/examples"
repository = "https://github.com/alloy-rs/examples"
publish = false
exclude = ["examples/"]

[workspace.dependencies]
alloy = { git = "https://github.com/alloy-rs/alloy", rev = "fd8f065", features = [
Expand Down Expand Up @@ -43,17 +44,18 @@ alloy = { git = "https://github.com/alloy-rs/alloy", rev = "fd8f065", features =
# "signer-keystore",
"signer-mnemonic",
"signer-yubihsm",
# "transports",
"transports",
"transport-http",
# "transport-ipc",
# "transport-ws",
# "pubsub",
"transport-ipc",
"transport-ws",
"pubsub",
] }
# TODO: sol! macro somehow requires this to be present
alloy-sol-types = { version = "0.6.4", default-features = false, features = [
"std",
] }


# async
tokio = "1"

Expand Down
13 changes: 5 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,14 @@ cargo run --example mnemonic_signer
- [x] [Deploy from artifact](./examples/contracts/examples/deploy_from_artifact.rs)
- [x] [Deploy from contract](./examples/contracts/examples/deploy_from_contract.rs)
- [x] [Generate](./examples/contracts/examples/generate.rs)
- [x] Providers
- [x] [Builder](./examples/providers/examples/builder.rs)
- [x] [HTTP](./examples/providers/examples/http.rs)
- [x] [IPC](./examples/providers/examples/ipc.rs)
- [x] [WS](./examples/providers/examples/ws.rs)
- [x] Layers
- [x] [Nonce manager](./examples/layers/examples/nonce_layer.rs)
- [x] [Signature manager](./examples/layers/examples/signer_layer.rs)
- [ ] Providers
- [ ] Http
- [ ] IPC
- [ ] Mock
- [ ] Quorum
- [ ] Retry
- [ ] RW
- [ ] WS
- [x] Queries
- [x] [Contract storage](./examples/queries/examples/query_contract_storage.rs)
- [x] [Contract deployed bytecode](./examples/queries/examples/query_deployed_bytecode.rs)
Expand Down
Binary file added examples/.DS_Store
Binary file not shown.
28 changes: 28 additions & 0 deletions examples/providers/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "examples-providers"

publish.workspace = true
version.workspace = true
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true

[dev-dependencies]
alloy.workspace = true
# Temp dependency fix to enable relevant features - Ref: https://github.com/alloy-rs/examples/pull/3#discussion_r1537842062
alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "fd8f065", features = [
"pubsub",
] }
alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "fd8f065", features = [
"pubsub",
"ws",
] }


eyre.workspace = true
futures-util = "0.3"
reqwest.workspace = true
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
46 changes: 46 additions & 0 deletions examples/providers/examples/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//! Example of using the `ProviderBuilder` to create a provider with a signer and network.
use alloy::{
network::{EthereumSigner, TransactionBuilder},
node_bindings::Anvil,
primitives::U256,
providers::{Provider, ProviderBuilder, RootProvider},
rpc::{client::RpcClient, types::eth::TransactionRequest},
signers::wallet::Wallet,
};
use eyre::Result;

#[tokio::main]
async fn main() -> Result<()> {
// Setup the HTTP transport which is consumed by the RPC client
let anvil = Anvil::new().spawn();

let pk = &anvil.keys()[0];
let from = anvil.addresses()[0];
let signer = Wallet::from(pk.to_owned());

let rpc_client = RpcClient::new_http(anvil.endpoint().parse().unwrap());
let provider_with_signer = ProviderBuilder::new()
.signer(EthereumSigner::from(signer))
.provider(RootProvider::new(rpc_client));

let to = anvil.addresses()[1];

let mut tx_req = TransactionRequest::default()
.to(Some(to))
.value(U256::from(100))
.nonce(0)
.gas_limit(U256::from(21000));

tx_req.set_gas_price(U256::from(20e9));

let pending_tx = provider_with_signer.send_transaction(tx_req).await?;

println!("Pending transaction...{:?}", pending_tx.tx_hash());

let receipt = pending_tx.get_receipt().await?;

assert_eq!(receipt.from, from);

Ok(())
}
28 changes: 28 additions & 0 deletions examples/providers/examples/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! Example of using the HTTP provider to get the latest block number.
use alloy::{
network::Ethereum,
providers::{HttpProvider, Provider},
rpc::client::RpcClient,
};
use eyre::Result;

#[tokio::main]
async fn main() -> Result<()> {
// Setup the HTTP transport which is consumed by the RPC client
let rpc_url = "https://eth.llamarpc.com".parse().unwrap();

// Create the RPC client
let rpc_client = RpcClient::new_http(rpc_url);

// Provider can then be instantiated using the RPC client, HttpProvider is an alias
// RootProvider. RootProvider requires two generics N: Network and T: Transport
let provider = HttpProvider::<Ethereum>::new(rpc_client);

// Get latest block number
let latest_block = provider.get_block_number().await?;

println!("Latest block number: {}", latest_block);

Ok(())
}
29 changes: 29 additions & 0 deletions examples/providers/examples/ipc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//! Example of using the IPC provider to get the latest block number.
use alloy::{
network::Ethereum,
providers::{Provider, RootProvider},
transports::ipc::IpcConnect,
};
use alloy_rpc_client::RpcClient;
use eyre::Result;

#[tokio::main]
async fn main() -> Result<()> {
// Setup the IPC transport which is consumed by the RPC client
let ipc_path = "/tmp/reth.ipc";

// IPC transport
let ipc = IpcConnect::new(ipc_path.to_string());

// RPC client using IPC transport
let ipc_client = RpcClient::connect_pubsub(ipc).await?;

let provider = RootProvider::<Ethereum, _>::new(ipc_client);

let latest_block = provider.get_block_number().await?;

println!("Latest block: {}", latest_block);

Ok(())
}
39 changes: 39 additions & 0 deletions examples/providers/examples/ws.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! Example of using the WS provider to subscribe to new blocks.
use alloy::network::Ethereum;
// Temp Fix
use alloy_provider::{Provider, RootProvider};
use alloy_rpc_client::{RpcClient, WsConnect};
//
use eyre::Result;
use futures_util::StreamExt;

#[tokio::main]
async fn main() -> Result<()> {
let rpc_url = "wss://eth-mainnet.g.alchemy.com/v2/your-api-key";

let ws_transport = WsConnect::new(rpc_url);

let rpc_client = RpcClient::connect_pubsub(ws_transport).await?;

let provider = RootProvider::<Ethereum, _>::new(rpc_client);

let sub = provider.subscribe_blocks().await?;

let mut stream = sub.into_stream().take(4);
println!("Awaiting blocks...");

while let Some(block) = stream.next().await {
println!("{:?}", block.header.number);
}

let handle = tokio::spawn(async move {
while let Some(block) = stream.next().await {
println!("{:?}", block.header.number);
}
});

handle.await?;

Ok(())
}
56 changes: 56 additions & 0 deletions examples/providers/examples/ws_with_auth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//! Example of using the WS provider with auth to subscribe to new blocks.
use alloy::{network::Ethereum, transports::Authorization};
// Temp Fix
use alloy_provider::{Provider, RootProvider};
use alloy_rpc_client::{RpcClient, WsConnect};
//
use eyre::Result;
use futures_util::StreamExt;

#[tokio::main]
async fn main() -> Result<()> {
let rpc_url = "wss://your-ws-endpoint.com/";

let auth = Authorization::basic("username", "password");
let auth_bearer = Authorization::bearer("bearer-token");

let ws_transport_basic = WsConnect::with_auth(rpc_url, Some(auth));

let ws_transport_bearer = WsConnect::with_auth(rpc_url, Some(auth_bearer));

let rpc_client_basic = RpcClient::connect_pubsub(ws_transport_basic).await?;

let rpc_client_bearer = RpcClient::connect_pubsub(ws_transport_bearer).await?;

let provider_basic = RootProvider::<Ethereum, _>::new(rpc_client_basic);

let provider_bearer = RootProvider::<Ethereum, _>::new(rpc_client_bearer);

let sub_basic = provider_basic.subscribe_blocks();
let sub_bearer = provider_bearer.subscribe_blocks();

let mut stream_basic = sub_basic.await?.into_stream().take(4);
let mut stream_bearer = sub_bearer.await?.into_stream().take(4);

println!("Awaiting blocks...");

// Spawning the block processing for basic auth as a new task
let basic_handle = tokio::spawn(async move {
while let Some(block) = stream_basic.next().await {
println!("From basic {:?}", block.header.number);
}
});

// Similarly for bearer auth
let bearer_handle = tokio::spawn(async move {
while let Some(block) = stream_bearer.next().await {
println!("From bearer {:?}", block.header.number);
}
});

// Wait for both tasks to complete
let _ = tokio::try_join!(basic_handle, bearer_handle)?;

Ok(())
}

0 comments on commit 78d6035

Please sign in to comment.