From fac7b513386c8f74cddb8c8f9bc282572116c259 Mon Sep 17 00:00:00 2001 From: Akshay Date: Tue, 17 Dec 2024 08:00:55 +0000 Subject: [PATCH] enable native staking withdrawals using cli --- kalypso-cli/src/common_deps.rs | 65 +++++++++++++++++++++++++++++ kalypso-cli/src/config.json | 28 ++++++++++++- kalypso-cli/src/operations/mod.rs | 2 + kalypso-cli/src/operations/stake.rs | 59 ++++++++++++++++++++++++-- 4 files changed, 149 insertions(+), 5 deletions(-) diff --git a/kalypso-cli/src/common_deps.rs b/kalypso-cli/src/common_deps.rs index e53a601..01fe320 100644 --- a/kalypso-cli/src/common_deps.rs +++ b/kalypso-cli/src/common_deps.rs @@ -1599,3 +1599,68 @@ impl CommonDeps { }) } } + +pub struct RequestStakeWithdrawal { + pub private_key_signer: LocalWallet, + pub native_staking: + bindings::native_staking::NativeStaking, LocalWallet>>, + pub staking_token: bindings::ierc20::IERC20, LocalWallet>>, + pub staking_amount: U256, +} + +impl CommonDeps { + pub fn request_stake_withdrawal_info( + config: &std::collections::HashMap, + ) -> Result { + get_config_ref!(config, "private_key", private_key); + get_config_ref!(config, "rpc_url", rpc_url); + get_config_ref!(config, "native_staking", native_staking_address); + get_config_ref!(config, "chain_id", chain_id); + get_config_ref!(config, "staking_token", staking_token); + get_config_ref!(config, "staking_amount", staking_amount); + + let (staking_token, _) = + get_token_instance(private_key, chain_id, &staking_token, rpc_url)?; + + let (native_staking, private_key_signer) = + get_native_staking_instance(private_key, chain_id, native_staking_address, rpc_url)?; + + let staking_amount = U256::from_dec_str(staking_amount.as_str()) + .map_err(|e| format!("Invalid Unstaking Amount: {}", e))?; + + Ok(RequestStakeWithdrawal { + private_key_signer, + native_staking, + staking_token, + staking_amount, + }) + } +} + +pub struct NativeStakeWithdrawal { + pub private_key_signer: LocalWallet, + pub native_staking: + bindings::native_staking::NativeStaking, LocalWallet>>, + pub indexer_url: String, +} + +impl CommonDeps { + pub fn native_staking_withdrawal_info( + config: &std::collections::HashMap, + ) -> Result { + get_config_ref!(config, "private_key", private_key); + get_config_ref!(config, "rpc_url", rpc_url); + get_config_ref!(config, "native_staking", native_staking_address); + get_config_ref!(config, "chain_id", chain_id); + get_config_ref!(config, "indexer_url", indexer_url); + + let (native_staking, private_key_signer) = + get_native_staking_instance(private_key, chain_id, native_staking_address, rpc_url)?; + + Ok(NativeStakeWithdrawal { + private_key_signer, + native_staking, + indexer_url: indexer_url.to_string(), + }) + } +} diff --git a/kalypso-cli/src/config.json b/kalypso-cli/src/config.json index a1607f7..e5ed59f 100644 --- a/kalypso-cli/src/config.json +++ b/kalypso-cli/src/config.json @@ -116,7 +116,7 @@ }, { "field": "staking_amount", - "prompt": "Enter the amount to stake", + "prompt": "Enter the amount to stake (or) withdraw", "secret": false, "env_var": "STAKING_AMOUNT" }, @@ -659,7 +659,31 @@ "name": "Read Native Staking Pending Withdrawals", "description": "Reads Native Staking pending withdrawals", "required_prompts":[ - "indexer_url", "operator_address" + "indexer_url", + "operator_address" + ] + }, + { + "name": "Request Native Stake Withdrawal", + "description": "Create a withdrawal request on Native Staking Module", + "required_prompts": [ + "private_key", + "rpc_url", + "native_staking", + "chain_id", + "staking_token", + "staking_amount" + ] + }, + { + "name": "Process Withdrawal Requests", + "description": "Complete Withdrawal Request. Withdraws amount present in all withdrawal requests", + "required_prompts": [ + "private_key", + "rpc_url", + "native_staking", + "chain_id", + "indexer_url" ] } ] diff --git a/kalypso-cli/src/operations/mod.rs b/kalypso-cli/src/operations/mod.rs index 1b6b9f5..886f8ac 100644 --- a/kalypso-cli/src/operations/mod.rs +++ b/kalypso-cli/src/operations/mod.rs @@ -102,6 +102,8 @@ pub fn get_operation(name: &str) -> Option> { "Read Native Staking Pending Withdrawals" => { Some(Box::new(stake::ReadWithdrawalRequestIds)) } + "Request Native Stake Withdrawal" => Some(Box::new(stake::RequestNativeStakeWithdrawal)), + "Process Withdrawal Requests" => Some(Box::new(stake::ProcessWithdrawalRequests)), _ => unimplemented!(), } } diff --git a/kalypso-cli/src/operations/stake.rs b/kalypso-cli/src/operations/stake.rs index e737758..272cbf4 100644 --- a/kalypso-cli/src/operations/stake.rs +++ b/kalypso-cli/src/operations/stake.rs @@ -1,7 +1,10 @@ use std::{collections::HashMap, sync::Once}; use async_trait::async_trait; -use ethers::{signers::Signer, types::Address}; +use ethers::{ + signers::Signer, + types::{Address, U256}, +}; use serde::{Deserialize, Serialize}; use crate::common_deps::CommonDeps; @@ -13,7 +16,27 @@ pub struct RequestNativeStakeWithdrawal; #[async_trait] impl Operation for RequestNativeStakeWithdrawal { async fn execute(&self, config: HashMap) -> Result<(), String> { - unimplemented!() + let request_staking_withdrawal_info = CommonDeps::request_stake_withdrawal_info(&config)?; + + let native_unstaking_request_tx = CommonDeps::send_and_confirm( + request_staking_withdrawal_info + .native_staking + .request_stake_withdrawal( + request_staking_withdrawal_info.private_key_signer.address(), + request_staking_withdrawal_info.staking_token.address(), + request_staking_withdrawal_info.staking_amount, + ) + .send(), + ) + .await + .map_err(|e| format!("Native Unstaking Request Transaction failed: {}", e))?; + + println!( + "Native Unstaking Request Transaction: {}", + native_unstaking_request_tx + ); + + Ok(()) } } @@ -60,7 +83,37 @@ pub struct ProcessWithdrawalRequests; #[async_trait] impl Operation for ProcessWithdrawalRequests { async fn execute(&self, config: HashMap) -> Result<(), String> { - unimplemented!() + let request_staking_info = CommonDeps::native_staking_withdrawal_info(&config)?; + + let withdrawal_requests = read_staking_data( + &request_staking_info.private_key_signer.address(), + request_staking_info.indexer_url, + ) + .await + .map_err(|e| format!("Unable to read stake data from indexer: {}", e))?; + + let withdrawal_requests: Vec = withdrawal_requests + .iter() + .map(|a| U256::from_dec_str(a.index.as_ref()).unwrap()) + .collect(); + + let withdrawal_transaction_hash = CommonDeps::send_and_confirm( + request_staking_info + .native_staking + .withdraw_stake( + request_staking_info.private_key_signer.address(), + withdrawal_requests.into(), + ) + .send(), + ) + .await + .map_err(|e| format!("Native Staking Withdraw Transaction failed: {}", e))?; + + println!( + "Withdrawal Request Transaction: {}", + withdrawal_transaction_hash + ); + Ok(()) } }