Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

chore(general): design fixes, import fixes #32

Merged
merged 3 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ The recommended way of initializing an `Ipc` provider is by using the [`on_ipc`]
```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 alloy::providers::{IpcConnect, Provider, ProviderBuilder};
use eyre::Result;

#[tokio::main]
async fn main() -> eyre::Result<()> {
// Set up the IPC transport which is consumed by the RPC client.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ The recommended way of initializing a `Ws` provider is by using the [`on_ws`](ht
```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 alloy::providers::{Provider, ProviderBuilder, WsConnect};
use eyre::Result;

#[tokio::main]
Expand Down
16 changes: 8 additions & 8 deletions src/getting-started/first-steps.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,21 @@ async fn main() -> Result<()> {
Next, add the following section to the body to create a provider with HTTP transport:

```rust,ignore
// Set up the HTTP transport which is consumed by the RPC client.
let rpc_url = "https://eth.merkle.io".parse()?;
// 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);
// Create a provider with the HTTP transport using the `reqwest` crate.
let provider = ProviderBuilder::new().on_http(rpc_url);
```

Finally we fetch the latest block number using the provider:

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

// Print the block number.
println!("Latest block number: {latest_block}");
// Print the block number.
println!("Latest block number: {latest_block}");
```

The complete and runnable example can be found [here](https://github.com/alloy-rs/examples/blob/main/examples/providers/examples/http.rs), one of the [many runnable examples of Alloy](https://github.com/alloy-rs/examples/blob/main/README.md#overview) to explore.
7 changes: 3 additions & 4 deletions src/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ After `alloy` as a dependency you can now import `alloy` as follows:

```rust,ignore
use alloy::{
network::{eip2718::Encodable2718, EthereumSigner, TransactionBuilder},
node_bindings::Anvil,
network::{eip2718::Encodable2718, EthereumWallet, TransactionBuilder},
primitives::U256,
providers::{Provider, ProviderBuilder},
rpc::types::eth::TransactionRequest,
signers::wallet::LocalWallet,
rpc::types::TransactionRequest,
signers::local::PrivateKeySigner,
};
```

Expand Down
128 changes: 64 additions & 64 deletions src/highlights/the-transaction-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ This article will walk you through the process of defining a transaction to send
Let's express our intent in the form of a [`TransactionRequest`](https://alloy-rs.github.io/alloy/alloy/rpc/types/eth/struct.TransactionRequest.html):

```rust,ignore
// Build a transaction to send 100 wei from Alice to Bob.
let tx = TransactionRequest::default()
.with_from(alice)
.with_to(bob)
.with_nonce(nonce)
.with_chain_id(chain_id)
.with_value(U256::from(100))
.with_gas_price(gas_price)
.with_gas_limit(gas_limit);
// Build a transaction to send 100 wei from Alice to Bob.
let tx = TransactionRequest::default()
.with_from(alice)
.with_to(bob)
.with_nonce(nonce)
.with_chain_id(chain_id)
.with_value(U256::from(100))
.with_gas_price(gas_price)
.with_gas_limit(gas_limit);
```

### Setup
Expand All @@ -24,45 +24,45 @@ We start by defining the RPC URL of our local Ethereum node [Anvil](https://gith
If you do not have `Anvil` installed see the [Foundry](https://github.com/foundry-rs/foundry) [installation instructions](https://book.getfoundry.sh/getting-started/installation).

```rust,ignore
// Spin up a local Anvil node.
// Ensure `anvil` is available in $PATH.
let anvil = Anvil::new().try_spawn()?;
// Spin up a local Anvil node.
// Ensure `anvil` is available in $PATH.
let anvil = Anvil::new().try_spawn()?;

// Get the RPC URL.
let rpc_url = anvil.endpoint().parse()?;
// Get the RPC URL.
let rpc_url = anvil.endpoint().parse()?;
```

```rust,ignore
// Alternatively you can use any valid RPC URL found on https://chainlist.org/
let rpc_url = "https://eth.merkle.io".parse()?;
// Alternatively you can use any valid RPC URL found on https://chainlist.org/
let rpc_url = "https://eth.merkle.io".parse()?;
```

Next let's define a `signer` for Alice. By default `Anvil` defines a mnemonic phrase: `"test test test test test test test test test test test junk"`. Make sure to not use this mnemonic phrase outside of testing environments. We register the signer in an [`EthereumWallet`](https://alloy-rs.github.io/alloy/alloy_network/struct.EthereumWallet.html) to be used in the `Provider` to sign our future transaction.

Derive the first key of the mnemonic phrase for `Alice`:

```rust,ignore
// Set up signer from the first default Anvil account (Alice).
let signer: PrivateKeySigner = anvil.keys()[0].clone().into();
let wallet = EthereumWallet::from(signer);
// Set up signer from the first default Anvil account (Alice).
let signer: PrivateKeySigner = anvil.keys()[0].clone().into();
let wallet = EthereumWallet::from(signer);
```

Next lets grab the address of our users `Alice` and `Bob`:

```rust,ignore
// Create two users, Alice and Bob.
let alice = anvil.addresses()[0];
let bob = anvil.addresses()[1];
// Create two users, Alice and Bob.
let alice = anvil.addresses()[0];
let bob = anvil.addresses()[1];
```

Next we can build the `Provider` using the `ProviderBuilder`.

```rust,ignore
// Create a provider with the wallet.
let provider = ProviderBuilder::new()
.with_recommended_fillers()
.wallet(wallet)
.on_http(rpc_url);
// Create a provider with the wallet.
let provider = ProviderBuilder::new()
.with_recommended_fillers()
.wallet(wallet)
.on_http(rpc_url);
```

Note that we use `.with_recommended_fillers()` method on the [ProviderBuilder](../building-with-alloy/connecting-to-a-blockchain/setting-up-a-provider.md) to automatically [fill fields](../building-with-alloy/understanding-fillers.md).
Expand All @@ -78,25 +78,25 @@ The `RecommendedFillers` includes the following fillers:
Because of we are using `RecommendedFillers` our `TransactionRequest` we only need a subset of the original fields:

```diff
// Build a transaction to send 100 wei from Alice to Bob.
let tx = TransactionRequest::default()
- .with_from(alice)
.with_to(bob)
- .with_nonce(nonce)
- .with_chain_id(chain_id)
.with_value(U256::from(100))
- .with_gas_price(gas_price)
- .with_gas_limit(gas_limit);
// Build a transaction to send 100 wei from Alice to Bob.
let tx = TransactionRequest::default()
- .with_from(alice)
.with_to(bob)
- .with_nonce(nonce)
- .with_chain_id(chain_id)
.with_value(U256::from(100))
- .with_gas_price(gas_price)
- .with_gas_limit(gas_limit);
```

Changes to:

```rust,ignore
// Build a transaction to send 100 wei from Alice to Bob.
// The `from` field is automatically filled to the first signer's address (Alice).
let tx = TransactionRequest::default()
.with_to(bob)
.with_value(U256::from(100));
// Build a transaction to send 100 wei from Alice to Bob.
// The `from` field is automatically filled to the first signer's address (Alice).
let tx = TransactionRequest::default()
.with_to(bob)
.with_value(U256::from(100));
```

Much better!
Expand All @@ -108,52 +108,52 @@ Given that we have configured a signer on our `Provider` we can sign the transac
There are three ways to listen for transaction inclusion after broadcasting the transaction, depending on your requirements:

```rust,ignore
// Send the transaction and listen for the transaction to be broadcasted.
let pending_tx = provider.send_transaction(tx).await?.register().await?;
// Send the transaction and listen for the transaction to be broadcasted.
let pending_tx = provider.send_transaction(tx).await?.register().await?;
```

```rust,ignore
// Send the transaction and listen for the transaction to be included.
let tx_hash = provider.send_transaction(tx).await?.watch().await?;
// Send the transaction and listen for the transaction to be included.
let tx_hash = provider.send_transaction(tx).await?.watch().await?;
```

```rust,ignore
// Send the transaction and fetch the receipt after the transaction was included.
let tx_receipt = provider.send_transaction(tx).await?.get_receipt().await?;
// Send the transaction and fetch the receipt after the transaction was included.
let tx_receipt = provider.send_transaction(tx).await?.get_receipt().await?;
```

Let's dive deeper into what we just did.

By calling:

```rust,ignore
let tx_builder = provider.send_transaction(tx).await?;
let tx_builder = provider.send_transaction(tx).await?;
```

The [`Provider::send_transaction`](https://alloy-rs.github.io/alloy/alloy_provider/provider/trait/trait.Provider.html#method.send_transaction) method returns a [`PendingTransactionBuilder`](https://alloy-rs.github.io/alloy/alloy_provider/heart/struct.PendingTransactionBuilder.html) for configuring the pending transaction watcher.

On it we can for example, set the [`required_confirmations`](https://alloy-rs.github.io/alloy/alloy_provider/heart/struct.PendingTransactionBuilder.html#method.set_required_confirmations) or set a [`timeout`](https://alloy-rs.github.io/alloy/alloy_provider/heart/struct.PendingTransactionBuilder.html#method.set_timeout):

```rust,ignore
// Configure the pending transaction.
let pending_tx_builder = provider.send_transaction(tx)
.await?
.with_required_confirmations(2)
.with_timeout(Some(std::time::Duration::from_secs(60)));
// Configure the pending transaction.
let pending_tx_builder = provider.send_transaction(tx)
.await?
.with_required_confirmations(2)
.with_timeout(Some(std::time::Duration::from_secs(60)));
```

By passing the `TransactionRequest`, we populate any missing fields. This involves filling in details such as the nonce, chain ID, gas price, and gas limit:

```diff
// Build a transaction to send 100 wei from Alice to Bob.
let tx = TransactionRequest::default()
.with_from(alice)
.with_to(bob)
+ .with_nonce(nonce)
+ .with_chain_id(chain_id)
.with_value(U256::from(100))
+ .with_gas_price(gas_price)
+ .with_gas_limit(gas_limit);
// Build a transaction to send 100 wei from Alice to Bob.
let tx = TransactionRequest::default()
+ .with_from(alice)
.with_to(bob)
+ .with_nonce(nonce)
+ .with_chain_id(chain_id)
.with_value(U256::from(100))
+ .with_gas_price(gas_price)
+ .with_gas_limit(gas_limit);
```

As part [Wallet's `fill` method](https://alloy-rs.github.io/alloy/alloy/providers/fillers/trait.TxFiller.html#tymethod.fill), registered on the `Provider`, we build a signed transaction from the populated `TransactionRequest` using our signer, Alice.
Expand All @@ -163,8 +163,8 @@ At this point, the `TransactionRequest` becomes a `TransactionEnvelope`, ready t
For instance:

```rust,ignore
// Send the transaction and fetch the receipt after the transaction was included.
let tx_receipt = provider.send_transaction(tx).await?.get_receipt().await?;
// Send the transaction and fetch the receipt after the transaction was included.
let tx_receipt = provider.send_transaction(tx).await?.get_receipt().await?;
```

The [`TransactionReceipt`](https://alloy-rs.github.io/alloy/alloy/rpc/types/struct.TransactionReceipt.html) provides a comprehensive record of the transaction's journey and outcome, including the transaction hash, block details, gas used, and addresses involved.
Expand Down