Skip to content

Commit

Permalink
feat(connecting-to-a-blockchain): Add providers (#17)
Browse files Browse the repository at this point in the history
* fix command

* fix paths, clarify shorthands

* fix docs

* lift up copy

* add back link to glossary
  • Loading branch information
zerosnacks authored May 6, 2024
1 parent 87f8c27 commit d051d8f
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 3 deletions.
9 changes: 7 additions & 2 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
- [Common conversions](./building-with-alloy/basic-building-blocks/common-conversions.md)
- [Creating instances](./building-with-alloy/basic-building-blocks/creating-instances.md)
- [Comparisons and equivalence](./building-with-alloy/basic-building-blocks/comparisons-and-equivalence.md)
- [Connecting to a blockchain](./building-with-alloy/connecting-to-a-blockchain/setting-up-a-provider.md)
- [Setting up a Provider](./building-with-alloy/connecting-to-a-blockchain/setting-up-a-provider.md)
- [HTTP provider](./building-with-alloy/connecting-to-a-blockchain/http-provider.md)
- [WS provider](./building-with-alloy/connecting-to-a-blockchain/ws-provider.md)
- [IPC provider](./building-with-alloy/connecting-to-a-blockchain/ipc-provider.md)

# Examples

Expand Down Expand Up @@ -52,9 +57,9 @@
- [Builder](./examples/providers/builder.md)
- [Builtin](./examples/providers/builtin.md)
- [HTTP](./examples/providers/http.md)
- [WS](./examples/providers/ws.md)
- [WS with authentication](./examples/providers/ws_with_auth.md)
- [IPC](./examples/providers/ipc.md)
- [WebSocket](./examples/providers/ws.md)
- [WebSocket with authentication](./examples/providers/ws_with_auth.md)
- [Queries](./examples/queries/query_contract_storage.md)
- [Query contract storage](./examples/queries/query_contract_storage.md)
- [Query contract deployed bytecode](./examples/queries/query_deployed_bytecode.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
### Http Provider

The `Http` provider establishes an HTTP connection with a node, allowing you to send JSON-RPC requests to the node to fetch data, simulate calls, send transactions and much more.

#### Initializing an Http Provider

The recommended way of initializing a `Http` provider is by using the [`on_http`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html#method.on_http) method on the [`ProviderBuilder`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html).

```rust,ignore
//! Example of creating an HTTP provider using the `on_http` method on the `ProviderBuilder`.
use alloy::providers::{Provider, ProviderBuilder};
use eyre::Result;
#[tokio::main]
async fn main() -> eyre::Result<()> {
// Set up the HTTP transport which is consumed by the RPC client.
let rpc_url = "https://eth.merkle.io".parse()?;
// Create a provider with the HTTP transport using the `reqwest` crate.
let provider = ProviderBuilder::new().on_http(rpc_url);
Ok(())
}
```

An alternative way of initializing is to use the [`on_builtin`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html#method.on_builtin) method on the [`ProviderBuilder`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html). This method will automatically determine the connection type (`Http`, `Ws` or `Ipc`) depending on the format of the URL. This method is particularly useful if you need a boxed transport.

```rust,ignore
//! Example of creating an HTTP provider using the `on_builtin` method on the `ProviderBuilder`.
use alloy::providers::{Provider, ProviderBuilder};
use eyre::Result;
#[tokio::main]
async fn main() -> eyre::Result<()> {
// Create a provider with the HTTP transport using the `reqwest` crate.
let provider = ProviderBuilder::new().on_builtin("https://eth.merkle.io").await?;
Ok(())
}
```

{{#include ../../examples/providers/http.md}}
49 changes: 49 additions & 0 deletions src/building-with-alloy/connecting-to-a-blockchain/ipc-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
### IPC Provider

The [IPC (Inter-Process Communication)](https://en.wikipedia.org/wiki/Inter-process_communication) transport allows our program to communicate with a node over a local [Unix domain socket](https://en.wikipedia.org/wiki/Unix_domain_socket) or [Windows named pipe](https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipes).

Using the IPC transport allows the ethers library to send JSON-RPC requests to the Ethereum client and receive responses, without the need for a network connection or HTTP server. This can be useful for interacting with a local Ethereum node that is running on the same network. Using IPC [is faster than RPC](https://github.com/0xKitsune/geth-ipc-rpc-bench), however you will need to have a local node that you can connect to.

#### Initializing an `Ipc` Provider

The recommended way of initializing an `Ipc` provider is by using the [`on_ipc`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html#method.on_ipc) method on the [`ProviderBuilder`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html) with an [`IpcConnect`](https://alloy-rs.github.io/alloy/alloy/rpc/client/struct.IpcConnect.html) configuration.

```rust,ignore
//! Example of creating an IPC provider using the `on_ipc` method on the `ProviderBuilder`.
use alloy::{
providers::{Provider, ProviderBuilder},
rpc::client::IpcConnect,
};
use eyre::Result;
#[tokio::main]
async fn main() -> eyre::Result<()> {
// Set up the IPC transport which is consumed by the RPC client.
let ipc_path = "/tmp/reth.ipc";
// Create the provider.
let ipc = IpcConnect::new(ipc_path.to_string());
let provider = ProviderBuilder::new().on_ipc(ipc).await?;
Ok(())
}
```

An alternative way of initializing is to use the [`on_builtin`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html#method.on_builtin) method on the [`ProviderBuilder`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html). This method will automatically determine the connection type (`Http`, `Ws` or `Ipc`) depending on the format of the URL. This method is particularly useful if you need a boxed transport.

```rust,ignore
//! Example of creating an IPC provider using the `on_builtin` method on the `ProviderBuilder`.
use alloy::providers::{Provider, ProviderBuilder};
use eyre::Result;
#[tokio::main]
async fn main() -> eyre::Result<()> {
// Create a provider with the IPC transport.
let provider = ProviderBuilder::new().on_builtin("/tmp/reth.ipc").await?;
Ok(())
}
```

{{#include ../../examples/providers/ipc.md}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
## Setting up a Provider

A [`Provider`](https://alloy-rs.github.io/alloy/alloy_provider/provider/trait/trait.Provider.html) is an abstraction of a connection to the Ethereum network, providing a concise, consistent interface to standard Ethereum node functionality.

### Builder

The correct way of creating a [`Provider`](https://alloy-rs.github.io/alloy/alloy_provider/provider/trait/trait.Provider.html) is through the [`ProviderBuilder`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html), a [builder](https://rust-unofficial.github.io/patterns/patterns/creational/builder.html).

Alloy provides concrete transport implementations for [`HTTP`](./http-provider.md), [`WS` (WebSockets)](./ws-provider.md) and [`IPC` (Inter-Process Communication)](./ipc-provider.md), as well as higher level transports which wrap a single or multiple transports.

```rust,ignore
//! Example of using the HTTP provider using the `on_http` method.
use alloy::providers::{Provider, ProviderBuilder};
use eyre::Result;
#[tokio::main]
async fn main() -> eyre::Result<()> {
// Set up the HTTP transport which is consumed by the RPC client.
let rpc_url = "https://eth.merkle.io".parse()?;
// Create a provider with the HTTP transport using the `reqwest` crate.
let provider = ProviderBuilder::new().on_http(rpc_url);
Ok(())
}
```

### Fillers

[Fillers](https://alloy-rs.github.io/alloy/alloy_provider/fillers/index.html) decorate a [`Provider`](https://alloy-rs.github.io/alloy/alloy_provider/provider/trait/trait.Provider.html), filling transaction details before they are sent to the network. Fillers are used to set the nonce, gas price, gas limit, and other transaction details, and are called before any other layer.

```rust,ignore
//! Example of using the `.with_recommended_fillers()` method in the provider.
use alloy::{
network::EthereumSigner, node_bindings::Anvil, providers::ProviderBuilder,
signers::wallet::LocalWallet,
};
use eyre::Result;
#[tokio::main]
async fn main() -> Result<()> {
// Spin up a local Anvil node.
// Ensure `anvil` is available in $PATH.
let anvil = Anvil::new().try_spawn()?;
// Set up signer from the first default Anvil account (Alice).
let signer: LocalWallet = anvil.keys()[0].clone().into();
// Create a provider with the signer.
let rpc_url = anvil.endpoint().parse()?;
let provider = ProviderBuilder::new()
// Adds the `ChainIdFiller`, `GasFiller` and the `NonceFiller` layers.
.with_recommended_fillers()
.signer(EthereumSigner::from(signer))
.on_http(rpc_url);
// ...
Ok(())
}
```
53 changes: 53 additions & 0 deletions src/building-with-alloy/connecting-to-a-blockchain/ws-provider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
### WebSocket Provider

The `Ws` provider establishes an WebSocket connection with a node, allowing you to send JSON-RPC requests to the node to fetch data, simulate calls, send transactions and much more. The `Ws` provider can be used with any Ethereum node that supports WebSocket connections. This allows programs to interact with the network in real-time without the need for HTTP polling for things like new block headers and filter logs.

#### Initializing a `Ws` Provider

The recommended way of initializing a `Ws` provider is by using the [`on_ws`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html#method.on_ws) method on the [`ProviderBuilder`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html) with a [`WsConnect`](https://alloy-rs.github.io/alloy/alloy/rpc/client/struct.WsConnect.html) configuration.

```rust,ignore
//! Example of creating an WS provider using the `on_ws` method on the `ProviderBuilder`.
use alloy::{
providers::{Provider, ProviderBuilder},
rpc::client::WsConnect,
};
use eyre::Result;
#[tokio::main]
async fn main() -> eyre::Result<()> {
// Set up the WS transport which is consumed by the RPC client.
let rpc_url = "wss://eth-mainnet.g.alchemy.com/v2/your-api-key";
// Create the provider.
let ws = WsConnect::new(rpc_url);
let provider = ProviderBuilder::new().on_ws(ws).await?;
Ok(())
}
```

An alternative way of initializing is to use the [`on_builtin`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html#method.on_builtin) method on the [`ProviderBuilder`](https://alloy-rs.github.io/alloy/alloy_provider/builder/struct.ProviderBuilder.html). This method will automatically determine the connection type (`Http`, `Ws` or `Ipc`) depending on the format of the URL. This method is particularly useful if you need a boxed transport.

```rust,ignore
//! Example of creating an WS provider using the `on_builtin` method on the `ProviderBuilder`.
use alloy::providers::{Provider, ProviderBuilder};
use eyre::Result;
#[tokio::main]
async fn main() -> eyre::Result<()> {
// Create a provider with the WS transport.
let provider = ProviderBuilder::new().on_builtin("wss://eth-mainnet.g.alchemy.com/v2/your-api-key").await?;
Ok(())
}
```

Similar to the other providers, you can also establish an authorized connection with a node via websockets.

{{#include ../../examples/providers/ws.md}}


{{#include ../../examples/providers/ws_with_auth.md}}
2 changes: 2 additions & 0 deletions src/getting-started/first-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ After [installing](./installation.md) `alloy` let's create an example of using t
Install [`tokio`](https://crates.io/crates/tokio) and [`eyre`](https://crates.io/crates/eyre) as dependencies and define the body as follows:

```rust,ignore
//! Example of creating an HTTP provider using the `on_http` method on the `ProviderBuilder`.
use alloy::providers::{Provider, ProviderBuilder};
use eyre::Result;
Expand Down
2 changes: 1 addition & 1 deletion src/migrating-from-ethers/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ let x = B256::from(u256);
// `B256` => `U256`
let x: U256 = b256.into();
let x = U256::from_be_bytes(b256.to_be_bytes())
let x = U256::from_be_bytes(b256.into())
```

#### RPC
Expand Down

0 comments on commit d051d8f

Please sign in to comment.