From 9fae9aabb5f847faed4842d4a7704275188e2ee8 Mon Sep 17 00:00:00 2001 From: kbizikav <132550763+kbizikav@users.noreply.github.com> Date: Tue, 21 Oct 2025 00:32:53 +0700 Subject: [PATCH] feat: add clear cache command --- Cargo.lock | 2 +- Cargo.toml | 3 +-- src/cli/accounts_status.rs | 12 +++++++----- src/cli/interactive.rs | 4 +++- src/cli/mod.rs | 10 ++++++++++ src/cli/mode_selection.rs | 6 ++++++ src/external_api/intmax/circulation.rs | 7 ++++--- src/external_api/intmax/gnark.rs | 14 ++++++++------ src/external_api/intmax/withdrawal.rs | 10 ++-------- src/state/mode.rs | 2 ++ src/utils/cache.rs | 18 ++++++++++++++++++ src/utils/mod.rs | 1 + 12 files changed, 63 insertions(+), 26 deletions(-) create mode 100644 src/utils/cache.rs diff --git a/Cargo.lock b/Cargo.lock index 6edbdb7..f39cd1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2716,7 +2716,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mining-cli" -version = "1.3.3" +version = "1.3.4" dependencies = [ "aes-gcm", "alloy", diff --git a/Cargo.toml b/Cargo.toml index e969ee7..86dd040 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mining-cli" -version = "1.3.3" +version = "1.3.4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -46,4 +46,3 @@ serde_with = "3.12.0" tower = "0.5.2" serde_qs = "0.15.0" env_logger = "0.11.8" - diff --git a/src/cli/accounts_status.rs b/src/cli/accounts_status.rs index 06a8644..9b1ed47 100644 --- a/src/cli/accounts_status.rs +++ b/src/cli/accounts_status.rs @@ -1,8 +1,11 @@ -use alloy::{primitives::{B256, U256}, providers::Provider as _}; +use alloy::{ + primitives::{B256, U256}, + providers::Provider as _, +}; use crate::{ external_api::{ - contracts::utils::get_address_from_private_key, intmax::circulation::get_circulation + contracts::utils::get_address_from_private_key, intmax::circulation::get_circulation, }, services::utils::{is_address_used, pretty_format_u256}, state::{key::Key, state::State}, @@ -39,7 +42,7 @@ pub async fn accounts_status( let mut total_long_term_claimable_amount = U256::default(); loop { let key = Key::new(withdrawal_private_key, key_number); - if !is_address_used(&state.provider,key.deposit_address).await? { + if !is_address_used(&state.provider, key.deposit_address).await? { println!( "Total short term claimable amount: {} ITX", pretty_format_u256(total_short_term_claimable_amount) @@ -54,7 +57,7 @@ pub async fn accounts_status( let is_qualified = !get_circulation(key.deposit_address).await?.is_excluded; let deposit_balance = state.provider.get_balance(key.deposit_address).await?; println!( - "Deposit address #{}: {:?} {} ETH. Qualified: {}. Deposits: {}/{}. Claimable Short: {} ITX, Claimable Long: {} ITX", + "Deposit address #{}: {:?} {} ETH. Qualified: {}. Deposits: {}/{}. Claimable Short: {} ITX, Claimable Long: {} ITX", key_number, key.deposit_address, pretty_format_u256(deposit_balance), @@ -63,7 +66,6 @@ pub async fn accounts_status( mining_times, pretty_format_u256( assets_status.short_term_claimable_amount - ), pretty_format_u256( assets_status.long_term_claimable_amount diff --git a/src/cli/interactive.rs b/src/cli/interactive.rs index 0221e2d..18b8b2d 100644 --- a/src/cli/interactive.rs +++ b/src/cli/interactive.rs @@ -27,7 +27,9 @@ fn address_duplication_check() -> anyhow::Result<()> { for network in Network::iter() { for config_index in EnvConfig::get_existing_indices(network) { let config = EnvConfig::load_from_file(network, config_index)?; - if let std::collections::hash_map::Entry::Vacant(e) = address_to_network.entry(config.withdrawal_address) { + if let std::collections::hash_map::Entry::Vacant(e) = + address_to_network.entry(config.withdrawal_address) + { e.insert((network, config_index)); } else { let (duplicated_network, duplicated_index) = diff --git a/src/cli/mod.rs b/src/cli/mod.rs index a54c8d6..81c2cef 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -12,6 +12,7 @@ use crate::{ services::{claim_loop, exit_loop, legacy_claim_loop, mining_loop}, state::{mode::RunMode, state::State}, utils::{ + cache::clear_github_cache, env_config::EnvConfig, env_validation::validate_env_config, network::{get_network, is_legacy, Network}, @@ -127,6 +128,15 @@ async fn mode_loop( update::update()?; press_enter_to_continue(); } + RunMode::ClearCache => { + let cache_removed = clear_github_cache()?; + if cache_removed { + println!("GitHub cache directory removed."); + } else { + println!("GitHub cache directory does not exist."); + } + press_enter_to_continue(); + } }; if !is_interactive { // if not in interactive mode, we only run once diff --git a/src/cli/mode_selection.rs b/src/cli/mode_selection.rs index 9e7e435..d300877 100644 --- a/src/cli/mode_selection.rs +++ b/src/cli/mode_selection.rs @@ -25,6 +25,11 @@ pub fn legacy_select_mode() -> anyhow::Result { style("Check Update:").bold(), style("check for updates of this CLI").dim() ), + format!( + "{} {}", + style("Clear Cache:").bold(), + style("remove cached GitHub responses for tree data").dim() + ), ]; let term = Term::stdout(); term.clear_screen()?; @@ -38,6 +43,7 @@ pub fn legacy_select_mode() -> anyhow::Result { 1 => RunMode::Exit, 2 => RunMode::Export, 3 => RunMode::CheckUpdate, + 4 => RunMode::ClearCache, _ => unreachable!(), }; Ok(mode) diff --git a/src/external_api/intmax/circulation.rs b/src/external_api/intmax/circulation.rs index c27fb2c..59466cd 100644 --- a/src/external_api/intmax/circulation.rs +++ b/src/external_api/intmax/circulation.rs @@ -37,9 +37,10 @@ pub async fn get_circulation(address: Address) -> Result Ok(success), CirculationResponse::Error(error) => Err(IntmaxError::ServerError(error)), diff --git a/src/external_api/intmax/gnark.rs b/src/external_api/intmax/gnark.rs index 3f91468..bf5fd5c 100644 --- a/src/external_api/intmax/gnark.rs +++ b/src/external_api/intmax/gnark.rs @@ -97,9 +97,10 @@ pub async fn gnark_start_prove( }) .await .map_err(|_| IntmaxError::NetworkError("failed to request gnark server".to_string()))?; - let output: GnarkStartProofResponse = response.json().await.map_err(|e| { - IntmaxError::SerializeError(format!("failed to parse response: {}", e)) - })?; + let output: GnarkStartProofResponse = response + .json() + .await + .map_err(|e| IntmaxError::SerializeError(format!("failed to parse response: {}", e)))?; match output { GnarkStartProofResponse::Success(success) => Ok(success), GnarkStartProofResponse::Error(error) => Err(IntmaxError::ServerError(error)), @@ -120,9 +121,10 @@ pub async fn gnark_get_proof( }) .await .map_err(|_| IntmaxError::NetworkError("failed to request gnark server".to_string()))?; - let output: GnarkGetProofResponse = response.json().await.map_err(|e| { - IntmaxError::SerializeError(format!("failed to parse response: {}", e)) - })?; + let output: GnarkGetProofResponse = response + .json() + .await + .map_err(|e| IntmaxError::SerializeError(format!("failed to parse response: {}", e)))?; match output { GnarkGetProofResponse::Success(success) => Ok(success), GnarkGetProofResponse::Error(error) => Err(IntmaxError::ServerError(error)), diff --git a/src/external_api/intmax/withdrawal.rs b/src/external_api/intmax/withdrawal.rs index 11d311f..6c51ee7 100644 --- a/src/external_api/intmax/withdrawal.rs +++ b/src/external_api/intmax/withdrawal.rs @@ -73,10 +73,7 @@ async fn start_withdrawal( .await .map_err(|_| IntmaxError::NetworkError("failed to request withdrawal server".to_string()))?; let response: Value = response.json().await.map_err(|e| { - IntmaxError::SerializeError(format!( - "failed to parse response as json: {}", - e - )) + IntmaxError::SerializeError(format!("failed to parse response as json: {}", e)) })?; let response: SubmitWithdrawalResponse = serde_json::from_value(response.clone()).map_err(|_| { @@ -105,10 +102,7 @@ async fn query_withdrawal(withdrawal_id: &str) -> Result write!(f, "Exit"), RunMode::Export => write!(f, "Export"), RunMode::CheckUpdate => write!(f, "CheckUpdate"), + RunMode::ClearCache => write!(f, "ClearCache"), } } } diff --git a/src/utils/cache.rs b/src/utils/cache.rs new file mode 100644 index 0000000..e7227b9 --- /dev/null +++ b/src/utils/cache.rs @@ -0,0 +1,18 @@ +use std::fs; + +use anyhow::Context as _; + +use super::file::get_data_path; + +/// Removes the cached GitHub responses stored under `~/.mining-cli/github_cache`. +/// Returns `Ok(true)` when the cache directory existed and was removed. +pub fn clear_github_cache() -> anyhow::Result { + let cache_dir = get_data_path()?.join("github_cache"); + if cache_dir.exists() { + fs::remove_dir_all(&cache_dir) + .with_context(|| format!("failed to remove cache directory: {:?}", cache_dir))?; + Ok(true) + } else { + Ok(false) + } +} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index c08f31f..d50363a 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,4 +1,5 @@ pub mod bin_parser; +pub mod cache; pub mod config; pub mod deposit_hash_tree; pub mod derive_key;