2 unstable releases

0.2.0 May 15, 2023
0.1.0 Apr 20, 2023

#4 in #walletd

32 downloads per month
Used in walletd

MIT/Apache

210KB
2.5K SLoC

WalletD Ethereum

For "local" examples, the examples require an instance of Ganache-CLI to be running. For "remote" examples, the examples expect a .env file with "INFURA_KEY" to be set. (this is still todo. See issue #74)

To get all examples to line up with ganache-cli, instantiate ganache-cli with the following command:

ganache-cli -b 3 -m "mandate rude write gather vivid inform leg swift usual early bamboo element"

To run examples, you can run all of them

cargo test --examples

You can also run specific examples by name

cargo run --example get_accounts_and_balances

lib.rs:

WalletD Ethereum Library

Provides a wallet implementation for Ethereum and blockchain-specific functionality.

Quickstart Guide

Use the [EthereumWallet] struct as a good starting point to access the functionalities for Ethereum that walletD provides.

Each [EthereumWallet] is associated with one public address. An [EthereumWallet] could be instantiated without a [EthereumPrivateKey] affiliated with it, but it would not be able to sign transactions. If an [EthereumWallet] is created with an [EthereumPublicKey] but no [EthereumPrivateKey], it will be able to verify signatures but not sign or send transactions.

Import from Seed

Here's how you can import an Ethereum wallet based on a master [HDKey]. We will use the mut keyword to make the [ethereum wallet][EthereumWallet] mutable so that we can modify ethereum_wallet later. By importing the ethereum_wallet fom a master_hd_key will both the [EthereumPrivateKey] and the [EthereumPublicKey] will be provided to the ethereum_wallet.

use walletd_ethereum::prelude::*;
use walletd_hd_key::prelude::*;

let master_seed = Seed::from_str("a2fd9c0522d84d52ee4c8533dc02d4b69b4df9b6255e1af20c9f1d4d691689f2a38637eb1ec778972bf845c32d5ae83c7536999b5666397ac32021b21e0accee")?;
let master_hd_key = HDKey::new_master(master_seed, HDNetworkType::TestNet)?;
let mut ethereum_wallet = EthereumWallet::builder().master_hd_key(master_hd_key).build()?;
let public_address = ethereum_wallet.public_address();
println!("ethereum wallet public address: {}", public_address);

Default Derivation Path

Deriving an [EthereumWallet] is simple and uses some default settings under the hood. We can inspect our ethereum_wallet to see that a child derived_hd_key was derived from the master master_hd_key and see the derivation path [HDPath] that was used by default.

let derived_hd_key = ethereum_wallet.derived_hd_key()?;
let address_derivation_path = derived_hd_key.derivation_path;
println!("address derivation path: {}", address_derivation_path);

We see that by default the Ethereum wallet uses the derivation path "m/44'/60'/0'/0/" corresponding to BIP44 for the purpose value and 60' corresponding to the coin type for Ethereum.

We need to add a [blockchain connector][BlockchainConnector] to our [ethereum wallet][EthereumWallet] to be able to interact with the Ethereum blockchain.

Adding a Blockchain Connector

Here's an example of how to add an instance of [EthClient] to our ethereum_wallet. [EthClient] currently supports any Ethereum endpoint that conforms to the Ethereum JSON-RPC standard for accessing Ethereum blockchain data. We recommend using Infura, or Alchemy. Both services provide generous free plans that you can use. Note that the url used to connect needs to match the network type being used (pay attention to the difference between testnet networks (used for testing and development purposes) and the mainnet network (where coins have actual value).

 let ethclient_url = "https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161";
 let eth_client = EthClient::new(ethclient_url)?;
 ethereum_wallet.set_blockchain_client(eth_client);

Using EthClient to Access Blockchain Data

The blockchain client ethclient can be used separately from the ethereum_wallet to access blockchain data such as details of a transaction given a tx hash, the current block number, or the current gas price.

let tx_hash = "0xe4216d69bf935587b82243e68189de7ade0aa5b6f70dd0de8636b8d643431c0b";
let tx = eth_client.transaction_data_from_hash(tx_hash).await?;
let block_number = eth_client.current_block_number().await;
let gas_price = eth_client.gas_price().await;
println!("transaction data: {:?}", tx);

Balance of Ethereum Wallet on Blockchain

When the ethereum_wallet is connected to the blockchain, we can find the balance of the wallet.

let balance = ethereum_wallet.balance().await?;
println!("ethereum wallet balance: {} ETH, ({} wei)", balance.eth(), balance.wei());

Dependencies

~17–26MB
~349K SLoC