Skip to content

Commit 3419a50

Browse files
committed
feat: unlock and withdraw funds in sdk
1 parent 9f3d613 commit 3419a50

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed

crates/cli/src/main.rs

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ use aligned_sdk::verification_layer::estimate_fee;
1919
use aligned_sdk::verification_layer::get_chain_id;
2020
use aligned_sdk::verification_layer::get_nonce_from_batcher;
2121
use aligned_sdk::verification_layer::get_nonce_from_ethereum;
22+
use aligned_sdk::verification_layer::unlock_balance_in_aligned;
23+
use aligned_sdk::verification_layer::withdraw_balance_from_aligned;
2224
use aligned_sdk::verification_layer::{deposit_to_aligned, get_balance_in_aligned};
2325
use aligned_sdk::verification_layer::{get_vk_commitment, save_response, submit_multiple};
2426
use clap::Args;
@@ -42,7 +44,9 @@ use crate::AlignedCommands::GetUserNonce;
4244
use crate::AlignedCommands::GetUserNonceFromEthereum;
4345
use crate::AlignedCommands::GetVkCommitment;
4446
use crate::AlignedCommands::Submit;
47+
use crate::AlignedCommands::UnlockFunds;
4548
use crate::AlignedCommands::VerifyProofOnchain;
49+
use crate::AlignedCommands::WithdrawFunds;
4650

4751
#[derive(Parser, Debug)]
4852
#[command(version, about, long_about = None)]
@@ -65,6 +69,10 @@ pub enum AlignedCommands {
6569
name = "deposit-to-batcher"
6670
)]
6771
DepositToBatcher(DepositToBatcherArgs),
72+
#[clap(about = "Unlocks funds from the batcher", name = "unlock-funds")]
73+
UnlockFunds(UnlockFundsArgs),
74+
#[clap(about = "Withdraw funds from the batcher", name = "withdraw-funds")]
75+
WithdrawFunds(WithdrawFundsArgs),
6876
#[clap(about = "Get user balance from the batcher", name = "get-user-balance")]
6977
GetUserBalance(GetUserBalanceArgs),
7078
#[clap(
@@ -208,6 +216,38 @@ pub struct DepositToBatcherArgs {
208216
amount: String,
209217
}
210218

219+
#[derive(Parser, Debug)]
220+
#[command(version, about, long_about = None)]
221+
pub struct UnlockFundsArgs {
222+
#[command(flatten)]
223+
private_key_type: PrivateKeyType,
224+
#[arg(
225+
name = "Ethereum RPC provider address",
226+
long = "rpc_url",
227+
default_value = "http://localhost:8545"
228+
)]
229+
eth_rpc_url: String,
230+
#[clap(flatten)]
231+
network: NetworkArg,
232+
}
233+
234+
#[derive(Parser, Debug)]
235+
#[command(version, about, long_about = None)]
236+
pub struct WithdrawFundsArgs {
237+
#[command(flatten)]
238+
private_key_type: PrivateKeyType,
239+
#[arg(
240+
name = "Ethereum RPC provider address",
241+
long = "rpc_url",
242+
default_value = "http://localhost:8545"
243+
)]
244+
eth_rpc_url: String,
245+
#[clap(flatten)]
246+
network: NetworkArg,
247+
#[arg(name = "Amount to withdraw", long = "amount", required = true)]
248+
amount: String,
249+
}
250+
211251
#[derive(Parser, Debug)]
212252
#[command(version, about, long_about = None)]
213253
pub struct VerifyProofOnchainArgs {
@@ -752,6 +792,105 @@ async fn main() -> Result<(), AlignedError> {
752792
}
753793
}
754794
}
795+
UnlockFunds(args) => {
796+
let eth_rpc_url = args.eth_rpc_url;
797+
let eth_rpc_provider =
798+
Provider::<Http>::try_from(eth_rpc_url.clone()).map_err(|e| {
799+
SubmitError::EthereumProviderError(format!(
800+
"Error while connecting to Ethereum: {}",
801+
e
802+
))
803+
})?;
804+
805+
let keystore_path = &args.private_key_type.keystore_path;
806+
let private_key = &args.private_key_type.private_key;
807+
808+
let mut wallet = if let Some(keystore_path) = keystore_path {
809+
let password = rpassword::prompt_password("Please enter your keystore password:")
810+
.map_err(|e| SubmitError::GenericError(e.to_string()))?;
811+
Wallet::decrypt_keystore(keystore_path, password)
812+
.map_err(|e| SubmitError::GenericError(e.to_string()))?
813+
} else if let Some(private_key) = private_key {
814+
private_key
815+
.parse::<LocalWallet>()
816+
.map_err(|e| SubmitError::GenericError(e.to_string()))?
817+
} else {
818+
warn!("Missing keystore or private key used for payment.");
819+
return Ok(());
820+
};
821+
822+
let chain_id = get_chain_id(eth_rpc_url.as_str()).await?;
823+
wallet = wallet.with_chain_id(chain_id);
824+
825+
let client = SignerMiddleware::new(eth_rpc_provider, wallet);
826+
827+
match unlock_balance_in_aligned(&client, args.network.into()).await {
828+
Ok(receipt) => {
829+
info!(
830+
"Funds in batcher unlocked successfully. Receipt: 0x{:x}",
831+
receipt.transaction_hash
832+
);
833+
}
834+
Err(e) => {
835+
error!("Transaction failed: {:?}", e);
836+
}
837+
}
838+
}
839+
WithdrawFunds(args) => {
840+
if !args.amount.ends_with("ether") {
841+
error!("Amount should be in the format XX.XXether");
842+
return Ok(());
843+
}
844+
845+
let amount_ether = args.amount.replace("ether", "");
846+
847+
let amount_wei = parse_ether(&amount_ether).map_err(|e| {
848+
SubmitError::EthereumProviderError(format!("Error while parsing amount: {}", e))
849+
})?;
850+
851+
let eth_rpc_url = args.eth_rpc_url;
852+
let eth_rpc_provider =
853+
Provider::<Http>::try_from(eth_rpc_url.clone()).map_err(|e| {
854+
SubmitError::EthereumProviderError(format!(
855+
"Error while connecting to Ethereum: {}",
856+
e
857+
))
858+
})?;
859+
860+
let keystore_path = &args.private_key_type.keystore_path;
861+
let private_key = &args.private_key_type.private_key;
862+
863+
let mut wallet = if let Some(keystore_path) = keystore_path {
864+
let password = rpassword::prompt_password("Please enter your keystore password:")
865+
.map_err(|e| SubmitError::GenericError(e.to_string()))?;
866+
Wallet::decrypt_keystore(keystore_path, password)
867+
.map_err(|e| SubmitError::GenericError(e.to_string()))?
868+
} else if let Some(private_key) = private_key {
869+
private_key
870+
.parse::<LocalWallet>()
871+
.map_err(|e| SubmitError::GenericError(e.to_string()))?
872+
} else {
873+
warn!("Missing keystore or private key used for payment.");
874+
return Ok(());
875+
};
876+
877+
let chain_id = get_chain_id(eth_rpc_url.as_str()).await?;
878+
wallet = wallet.with_chain_id(chain_id);
879+
880+
let client = SignerMiddleware::new(eth_rpc_provider, wallet);
881+
882+
match withdraw_balance_from_aligned(&client, args.network.into(), amount_wei).await {
883+
Ok(receipt) => {
884+
info!(
885+
"Balance withdraw from batcher successfully. Receipt: 0x{:x}",
886+
receipt.transaction_hash
887+
);
888+
}
889+
Err(e) => {
890+
error!("Transaction failed: {:?}", e);
891+
}
892+
}
893+
}
755894
GetUserBalance(get_user_balance_args) => {
756895
let user_address = H160::from_str(&get_user_balance_args.user_address).unwrap();
757896
match get_balance_in_aligned(

0 commit comments

Comments
 (0)