Skip to content

Commit f8193c3

Browse files
NicolasRampoldientropidelictaturosatiuri-99JuArce
authored
feat: pay to batcher with keystore (#514)
Co-authored-by: Mariano Nicolini <mariano.nicolini.91@gmail.com> Co-authored-by: Santos Rosati <rosatisantos@gmail.com> Co-authored-by: Urix <43704209+uri-99@users.noreply.github.com> Co-authored-by: JuArce <52429267+JuArce@users.noreply.github.com> Co-authored-by: MauroFab <maurotoscano2@gmail.com>
1 parent 3106a3c commit f8193c3

2 files changed

Lines changed: 153 additions & 3 deletions

File tree

README_SEND_PROOFS.md

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,30 @@ This will create the ECDSA keystore file in `~/.aligned_keystore/keystore0`
3535

3636
- If you have the EigenLayer CLI installed, the keystore can be generated following [this](https://docs.eigenlayer.xyz/eigenlayer/operator-guides/operator-installation#import-keys) instructions. The key will be stored into `~/.eigenlayer/operator_keys`.
3737

38-
## SP1 proof
38+
## 2. Fund the batcher
39+
40+
To be able to send proofs to Aligned using the batcher, the user must fund its transactions. For this, there is a simple Batcher Payment System.
41+
42+
To use it you can use the `aligned` CLI, as shown with the following example:
43+
44+
```bash
45+
aligned deposit-to-batcher --keystore_path <keystore_path> --amount 0.1ether
46+
```
47+
48+
This commands also allows the usage of the flags:
49+
- `--batcher_addr` to specify the address of the Batcher Payment Service smart contract.
50+
- `--rpc` to specify the rpc url to be used.
51+
- `--chain` to specify the chain id to be used.
52+
- Note: `--amount` flag parameter must be with the shown format, followed by the `ether` keyword to specify how many ethers you wish to deposit to the batcher.
53+
54+
After depositing funds, you can verify the Service has correctly received them, executing the following command:
55+
```bash
56+
cast call <payment_service_smart_contract_address> "UserBalances(address)(uint256)" <address>
57+
```
58+
59+
## 3. Send your proof to the batcher
60+
61+
### SP1 proof
3962

4063
The SP1 proof needs the proof file and the vm program file.
4164

@@ -63,7 +86,7 @@ aligned submit \
6386
--keystore_path ~/.aligned_keystore/keystore0
6487
```
6588

66-
## Risc0 proof
89+
### Risc0 proof
6790

6891
The Risc0 proof needs the proof file and the vm program file (vm program file is the image id).
6992

@@ -91,7 +114,7 @@ aligned submit \
91114
--keystore_path ~/.aligned_keystore/keystore0
92115
```
93116

94-
## GnarkPlonkBn254, GnarkPlonkBls12_381 and Groth16Bn254
117+
### GnarkPlonkBn254, GnarkPlonkBls12_381 and Groth16Bn254
95118

96119
The GnarkPlonkBn254, GnarkPlonkBls12_381 and Groth16Bn254 proofs need the proof file, the public input file and the verification key file.
97120

batcher/aligned/src/main.rs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::str::FromStr;
77

88
use aligned_sdk::errors::{AlignedError, SubmitError};
99
use aligned_sdk::types::AlignedVerificationData;
10+
use aligned_sdk::types::Chain;
1011
use aligned_sdk::types::ProvingSystemId;
1112
use aligned_sdk::types::VerificationData;
1213
use clap::Parser;
@@ -20,7 +21,9 @@ use log::{error, info};
2021
use aligned_sdk::sdk::{get_verification_key_commitment, submit_multiple, verify_proof_onchain};
2122

2223
use ethers::utils::hex;
24+
use ethers::utils::parse_ether;
2325

26+
use crate::AlignedCommands::DepositToBatcher;
2427
use crate::AlignedCommands::GetVerificationKeyCommitment;
2528
use crate::AlignedCommands::Submit;
2629
use crate::AlignedCommands::VerifyProofOnchain;
@@ -45,6 +48,12 @@ pub enum AlignedCommands {
4548
name = "get-vk-commitment"
4649
)]
4750
GetVerificationKeyCommitment(GetVerificationKeyCommitmentArgs),
51+
// GetVericiationKey, command name is get-vk-commitment
52+
#[clap(
53+
about = "Deposits Ethereum in the batcher to pay for proofs",
54+
name = "deposit-to-batcher"
55+
)]
56+
DepositToBatcher(DepositToBatcherArgs),
4857
}
4958

5059
#[derive(Parser, Debug)]
@@ -90,6 +99,37 @@ pub struct SubmitArgs {
9099
private_key: Option<String>,
91100
}
92101

102+
#[derive(Parser, Debug)]
103+
#[command(version, about, long_about = None)]
104+
pub struct DepositToBatcherArgs {
105+
#[arg(
106+
name = "Batcher Eth Address",
107+
long = "batcher_addr",
108+
default_value = "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0"
109+
)]
110+
batcher_eth_address: String,
111+
#[arg(
112+
name = "Path to local keystore",
113+
long = "keystore_path",
114+
required = true
115+
)]
116+
keystore_path: Option<PathBuf>,
117+
#[arg(
118+
name = "Ethereum RPC provider address",
119+
long = "rpc",
120+
default_value = "http://localhost:8545"
121+
)]
122+
eth_rpc_url: String,
123+
#[arg(
124+
name = "The Ethereum network's name",
125+
long = "chain",
126+
default_value = "devnet"
127+
)]
128+
chain: ChainArg,
129+
#[arg(name = "Amount to deposit", long = "amount", required = true)]
130+
amount: String,
131+
}
132+
93133
#[derive(Parser, Debug)]
94134
#[command(version, about, long_about = None)]
95135
pub struct VerifyProofOnchainArgs {
@@ -283,6 +323,93 @@ async fn main() -> Result<(), AlignedError> {
283323
.map_err(|e| SubmitError::IoError(output_file.clone(), e))?;
284324
}
285325
}
326+
DepositToBatcher(deposit_to_batcher_args) => {
327+
if !deposit_to_batcher_args.amount.ends_with("ether") {
328+
error!("Amount should be in the format XX.XXether");
329+
return Ok(());
330+
}
331+
332+
let chain: aligned_sdk::types::Chain = deposit_to_batcher_args.chain.into();
333+
334+
let amount = deposit_to_batcher_args.amount.replace("ether", "");
335+
336+
let eth_rpc_url = deposit_to_batcher_args.eth_rpc_url;
337+
338+
let eth_rpc_provider = Provider::<Http>::try_from(eth_rpc_url).map_err(|e| {
339+
SubmitError::EthError(format!("Error while connecting to Ethereum: {}", e))
340+
})?;
341+
342+
let keystore_path = &deposit_to_batcher_args.keystore_path;
343+
344+
let mut wallet = if let Some(keystore_path) = keystore_path {
345+
let password = rpassword::prompt_password("Please enter your keystore password:")
346+
.map_err(|e| SubmitError::GenericError(e.to_string()))?;
347+
Wallet::decrypt_keystore(keystore_path, password)
348+
.map_err(|e| SubmitError::GenericError(e.to_string()))?
349+
} else {
350+
warn!("Missing keystore used for payment.");
351+
return Ok(());
352+
};
353+
354+
match chain {
355+
Chain::Devnet => wallet = wallet.with_chain_id(31337u64),
356+
Chain::Holesky => wallet = wallet.with_chain_id(17000u64),
357+
}
358+
359+
let client = SignerMiddleware::new(eth_rpc_provider.clone(), wallet.clone());
360+
361+
let balance = client
362+
.get_balance(wallet.address(), None)
363+
.await
364+
.map_err(|e| {
365+
SubmitError::EthError(format!("Error while getting balance: {}", e))
366+
})?;
367+
368+
let amount_ether = parse_ether(&amount)
369+
.map_err(|e| SubmitError::EthError(format!("Error while parsing amount: {}", e)))?;
370+
371+
if amount_ether <= U256::from(0) {
372+
error!("Amount should be greater than 0");
373+
return Ok(());
374+
}
375+
376+
if balance < amount_ether {
377+
error!("Insufficient funds to pay to the batcher. Please deposit some Ether in your wallet.");
378+
return Ok(());
379+
}
380+
381+
let batcher_addr = Address::from_str(&deposit_to_batcher_args.batcher_eth_address)
382+
.map_err(|e| {
383+
SubmitError::EthError(format!("Error while parsing batcher address: {}", e))
384+
})?;
385+
386+
let tx = TransactionRequest::new()
387+
.to(batcher_addr)
388+
.value(amount_ether)
389+
.from(wallet.address());
390+
391+
info!("Sending {} ether to the batcher", amount);
392+
393+
let tx = client
394+
.send_transaction(tx, None)
395+
.await
396+
.map_err(|e| {
397+
SubmitError::EthError(format!("Error while sending transaction: {}", e))
398+
})?
399+
.await
400+
.map_err(|e| {
401+
SubmitError::EthError(format!("Error while sending transaction: {}", e))
402+
})?;
403+
404+
if let Some(tx) = tx {
405+
info!(
406+
"Payment sent to the batcher successfully. Tx: 0x{:x}",
407+
tx.transaction_hash
408+
);
409+
} else {
410+
error!("Transaction failed");
411+
}
412+
}
286413
}
287414

288415
Ok(())

0 commit comments

Comments
 (0)