Awesome
Ethers UserOp
An ether-rs middleware to craft UserOperations
Pre-requisites
Geth (tested with v1.12.2).
Use
To start a Silius bundler with user operation pool and JSON-RPC API with default config at 127.0.0.1:3000
on Geth Testnet
cargo run --bin ethuo bundler test
To generate a random key and address(generated key will be updated in config.json
)
cargo run --bin ethuo wallet new-key
To generate a counter-factual address(generated address will be updated in config.json
)
cargo run --bin ethuo wallet new-wallet-address
To use UserOpMiddleware
in your code, see example
use ethers::{
contract::abigen,
providers::{Http, Provider},
signers::Signer,
types::{Address, U256},
};
use ethers_userop::{
consts::{GETH_CHAIN_ID, GETH_ENTRY_POINT_ADDRESS, GETH_WETH_ADDRESS, SALT, SEED_PHRASE},
UserOpMiddleware,
};
use silius_primitives::Wallet as UoWallet;
use std::thread;
use std::time::Duration;
abigen!(WETH, "src/abi/WETH.json",);
#[tokio::main]
async fn main() -> anyhow::Result<()> {
env_logger::Builder::new()
.filter_level(log::LevelFilter::Info)
.init();
// Setup the environment
let eth_client_address = "http://localhost:8545".to_string();
let seed = SEED_PHRASE.to_string();
let provider = Provider::<Http>::try_from(eth_client_address.to_string())?;
let rpc_address = format!("http://{}", "127.0.0.1:3000");
let chain_id = GETH_CHAIN_ID; // Geth testnet
let uo_wallet = UoWallet::from_phrase(seed.as_str(), &U256::from(chain_id), false).unwrap();
let signer_wallet_address = uo_wallet.clone().signer.address();
let wallet_name = "simple-account-test";
// Instantiate a UserOpMiddleware
let mut uo_middleware: UserOpMiddleware<Provider<Http>> = UserOpMiddleware::new(
provider,
GETH_ENTRY_POINT_ADDRESS.parse::<Address>().unwrap(),
rpc_address,
uo_wallet.clone(),
);
// Deploy a smart contract wallet
let (uo_hash, scw_address) = uo_middleware
.deploy_scw(wallet_name.into(), 10u64, SALT)
.await?;
println!(
"Smart contract wallet deployed at {:x}
: {:?}",
scw_address, uo_hash
);
// Force to wait for the smart contract wallet to be deployed on the next block
thread::sleep(Duration::from_secs(12));
// Send Eth
let uo_hash = uo_middleware
.send_eth(scw_address, wallet_name, signer_wallet_address, 1u64)
.await?;
println!("Sent ETH to {}: {:?}", signer_wallet_address, uo_hash);
// Force to wait for the smart contract wallet to be deployed on the next block
thread::sleep(Duration::from_secs(12));
// Calling Weth contract to deposit Eth
let weth = WETH::new(
GETH_WETH_ADDRESS.parse::<Address>()?,
uo_middleware.clone().into(),
);
let mut deposit = weth.deposit().tx;
deposit.set_value(U256::from(100u64));
let uo_hash = uo_middleware
.call(wallet_name, scw_address, deposit)
.await?;
println!("Deposited ETH into WETH contract: {:?}", uo_hash);
Ok(())
}