I am happy to announce a first alpha version of the ic-alloy
EVM RPC support library, a fork of Alloy with ICP support.
Alloy is the next generation of Ethereum support libraries, written in Rust and designed for scalability and performance. Alloy is a rewrite of ethers-rs from the ground up. Alloy includes built in support for transports like HTTP, WebSockets and IPC.
And now … Alloy also works with ICP.
I have added ICP as an Alloy transport layer and signer. This makes it possible to use the full feature set (almost) of Alloy from ICP canisters:
- Getting blocks, balances and addresses, one by one or in batches
- Sending ETH and ERC-20 tokens using fillers for nonce, gas estimation etc
- Interacting with EVM contract functions
- Watching for blocks and EVM events (logs), that is, subscribing to them on a timed basis
- Signing messages and transactions
- etc
I haven’t deployed the library to crates.io yet, I’d like to wait a bit and hopefully receive some feedback first. ic-alloy
should make it significantly simpler to interact with the EVM from Rust based canisters.
Try it, let me know what you think and any issues you encounter.
Resources:
- Live demo
ic-alloy-toolkit
(Code for above demo)ic-alloy
(The Rust library)
Example, get the balance of an address
#[ic_cdk::update]
async fn get_balance(address: String) -> Result<String, String> {
let address = address.parse::<Address>().map_err(|e| e.to_string())?;
let rpc_service = RpcService::EthSepolia(EthSepoliaService::Alchemy);
let config = IcpConfig::new(rpc_service);
let provider = ProviderBuilder::new().on_icp(config);
let result = provider.get_balance(address).await;
match result {
Ok(balance) => Ok(balance.to_string()),
Err(e) => Err(e.to_string()),
}
}
Example, sign a message
#[ic_cdk::update]
async fn sign_message(message: String) -> Result<String, String> {
let ecdsa_key_name = "key_1".to_string();
let chain_id = 11155111;
IcpSigner::new(vec![], &ecdsa_key_name, Some(chain_id)).await.unwrap();
let signature = signer.sign_message(message.as_bytes()).await.unwrap();
Ok(format!("{:?}", signature))
}