Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/chain/chain_type.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::str::FromStr;
use std::{fmt::Display, str::FromStr};

use serde::{Deserialize, Serialize};

Expand All @@ -22,14 +22,17 @@ impl ChainType {
}
}

impl ToString for ChainType {
fn to_string(&self) -> String {
match self {
Self::Evm => "evm",
Self::Solana => "sol",
Self::Ton => "ton",
}
.to_string()
impl Display for ChainType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Evm => "evm",
Self::Solana => "sol",
Self::Ton => "ton",
}
)
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/chain/evm_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl EvmChain {
.json::<EthCallResponse>()
.await
.ok()
.and_then(|x| Some(x.result)),
.map(|x| x.result),
seconds,
)
}
Expand Down Expand Up @@ -111,9 +111,7 @@ impl ChainOps for EvmChain {
"latest"
]);
let decimals_hex = self.rpc_call("eth_call", params, rpc_index).await.0?;
BigUint::parse_bytes(&decimals_hex.as_bytes()[2..], 16)?
.to_usize()
.into()
BigUint::parse_bytes(&decimals_hex.as_bytes()[2..], 16)?.to_usize()
}
async fn scan_for_tokens(
&self,
Expand All @@ -130,7 +128,7 @@ impl ChainOps for EvmChain {
if address.len() != 40 {
return None;
}
if !address.chars().all(|c| c.is_digit(16)) {
if !address.chars().all(|c| c.is_ascii_hexdigit()) {
return None;
}
let mut hasher = Keccak256::new();
Expand Down
2 changes: 1 addition & 1 deletion src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub trait ChainOps {
async fn get_token_decimals(&self, token_address: &str, rpc_index: usize) -> Option<usize>;
async fn get_token_symbol(&self, token_address: &str, _rpc_index: usize) -> Option<String> {
let pairs = dexscreener::pairs::get_pairs(vec![token_address]).await?;
(pairs.len() != 0).then(|| pairs[0].base_token.symbol.clone())
(!pairs.is_empty()).then(|| pairs[0].base_token.symbol.clone())
}
async fn get_holdings_balance(
&self,
Expand Down
2 changes: 1 addition & 1 deletion src/chain/sol_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl ChainOps for SolChain {
let (balances, wait_time) = self
.rpc_call::<SolGetTokenBalanceResponse>("getTokenAccountsByOwner", params, rpc_index)
.await;
if balances.is_some() && balances.clone().unwrap().token_amounts.len() == 0 {
if balances.is_some() && balances.clone().unwrap().token_amounts.is_empty() {
return (Some(BigUint::ZERO), wait_time);
}
(
Expand Down
4 changes: 2 additions & 2 deletions src/chain/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl Token {
let symbol = chain.get_token_symbol(address, 0).await?;
Some(Self {
symbol,
address: chain.parse_token_address(&address)?,
address: chain.parse_token_address(address)?,
decimals,
})
}
Expand All @@ -33,7 +33,7 @@ impl Token {
if mag > 0 {
value.insert(mag as usize, '.');
} else {
value = format!("0.{}{value}", "0".repeat(mag.abs() as usize));
value = format!("0.{}{value}", "0".repeat(mag.unsigned_abs()));
}
value.parse().unwrap()
}
Expand Down
21 changes: 6 additions & 15 deletions src/chain/ton_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,7 @@ impl TonChain {
route: String,
query_pairs: Vec<(&str, &str)>,
) -> (Option<T>, Option<f32>) {
let mut url = Url::parse(&format!(
"{}/{}",
self.properties.rpc_urls[0].to_string(),
route
))
.unwrap();
let mut url = Url::parse(&format!("{}/{}", self.properties.rpc_urls[0], route)).unwrap();
url.query_pairs_mut().extend_pairs(query_pairs);
let response = match self
.http_client
Expand All @@ -105,10 +100,7 @@ impl ChainOps for TonChain {
let (balance, wait_time) = self
.api_call::<TonGetAccountResponse>(format!("accounts/{address}"), vec![])
.await;
(
balance.and_then(|b| Some(BigUint::from(b.balance))),
wait_time,
)
(balance.map(|b| BigUint::from(b.balance)), wait_time)
}
async fn get_token_balance(
&self,
Expand All @@ -132,9 +124,9 @@ impl ChainOps for TonChain {
address: &str,
_rpc_index: usize,
) -> SupportOption<Vec<(String, BigUint)>> {
let address = self.parse_wallet_address(&address).to_supported()?;
let address = self.parse_wallet_address(address).to_supported()?;
self.api_call::<TonGetAccountJettonsBalancesResponse>(
format!("accounts/{}/jettons", address),
format!("accounts/{address}/jettons"),
vec![],
)
.await
Expand All @@ -161,12 +153,11 @@ impl ChainOps for TonChain {
.decimals,
)
.ok()
.into()
}
async fn scan_for_tokens(&self, address: &str, _rpc_index: usize) -> SupportOption<Vec<Token>> {
let address = self.parse_wallet_address(&address).to_supported()?;
let address = self.parse_wallet_address(address).to_supported()?;
self.api_call::<TonGetAccountJettonsBalancesResponse>(
format!("accounts/{}/jettons", address),
format!("accounts/{address}/jettons"),
vec![],
)
.await
Expand Down
2 changes: 1 addition & 1 deletion src/dexscreener/pairs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ where
let pairs = stream::iter(tokens.clone())
.map(async |t| {
let url = Url::from_str(
format!("https://api.dexscreener.com/latest/dex/tokens/{}", t).as_str(),
format!("https://api.dexscreener.com/latest/dex/tokens/{t}").as_str(),
)
.unwrap();
let task = async |_rpc_index| (get_pairs_request(url.clone()).await, None);
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ async fn main() {
}
}
if let Err(err) = Repl::default().run().await {
eprintln!("Error: {}", err);
eprintln!("Error: {err}");
}
}
2 changes: 1 addition & 1 deletion src/repl/data_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub fn data_file_exists() -> Result<bool, String> {
pub fn read_data_file() -> Result<Vec<u8>, String> {
match std::fs::read(get_data_file_path()?) {
Ok(x) => Ok(x),
_ => return Err("Could not read data file".to_string()),
_ => Err("Could not read data file".to_string()),
}
}

Expand Down
56 changes: 26 additions & 30 deletions src/repl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ impl Repl {
{
Some(x) => Ok(x),
None => Err(format!(
"There is no available chain with name {:?}",
chain_name
"There is no available chain with name {chain_name:?}",
)),
}
}
Expand All @@ -138,18 +137,18 @@ impl Repl {
.iter()
.find_map(|(chain_type, address, alias)| {
(account == address || alias.clone().is_some_and(|alias| alias == account))
.then(|| (chain_type, address))
.then_some((chain_type, address))
}) {
Some(x) => Ok(x),
_ => Err(format!("Found no account corresponding to {:?}", account)),
_ => Err(format!("Found no account corresponding to {account:?}")),
}
}
fn format_address(a: &str) -> String {
let first = &a[..if a.starts_with("0x") { 7 } else { 5 }].to_string();
let last = &a[a.len() - 5..].to_string();
format!("{first}..{last}")
}
fn format_account(address: &String, alias: &Option<String>) -> String {
fn format_account(address: &str, alias: &Option<String>) -> String {
if alias.is_some() {
return alias.clone().unwrap();
}
Expand Down Expand Up @@ -293,7 +292,7 @@ can use the same command to set an authentication token for the API.
let chain_name = self.find_chain(arg)?.properties.name.clone();
self.config.rpcs.remove_entry(arg);
self.store_config_to_data_file()?;
println!("{} chain set back to default state", chain_name);
println!("{chain_name} chain set back to default state");
Ok(())
}
"toggle" => {
Expand Down Expand Up @@ -340,7 +339,7 @@ can use the same command to set an authentication token for the API.
let arg = command_parts[2];
let chain = self.find_chain(chain_id)?;
if chain.chain_type != ChainType::Ton && Url::from_str(arg).is_err() {
return Err(format!("{:?} is not a valid url", arg));
return Err(format!("{arg:?} is not a valid url"));
}
self.config
.rpcs
Expand Down Expand Up @@ -374,7 +373,7 @@ alias, if set.
])
})
.collect::<Vec<_>>();
if rows.len() == 0 {
if rows.is_empty() {
continue;
}
rows.insert(
Expand Down Expand Up @@ -450,7 +449,7 @@ alias, if set.
Vec::from([t.symbol.clone(), t.address.clone(), t.decimals.to_string()])
})
.collect::<Vec<_>>();
if tokens.len() == 0 {
if tokens.is_empty() {
continue;
}
tokens.insert(
Expand Down Expand Up @@ -483,14 +482,13 @@ alias, if set.
))
}
};
let token = match Token::new(&token_address, &chain).await {
let token = match Token::new(&token_address, chain).await {
Some(x) => x,
None => return Err("Could not fetch token info".to_string()),
};
if self
.tokens_of_chain(chain)
.find(|(_, t)| t.address == token.address)
.is_some()
.any(|(_, t)| t.address == token.address)
{
return Err("Token already added".to_string());
}
Expand All @@ -516,8 +514,7 @@ alias, if set.
Some(x) => self.config.tokens.remove(x),
None => {
return Err(format!(
"Could not find token with address {:?}",
token_address
"Could not find token with address {token_address:?}",
))
}
};
Expand All @@ -542,10 +539,10 @@ alias, if set.
let new_tokens = tokens_found
.into_iter()
.filter_map(|t| {
self.tokens_of_chain(chain)
.find(|(_, ct)| ct.address == t.address)
.is_none()
.then(|| (chain_id.to_string(), t))
(!self
.tokens_of_chain(chain)
.any(|(_, ct)| ct.address == t.address))
.then(|| (chain_id.to_string(), t))
})
.collect::<Vec<_>>();
let new_tokens_len = new_tokens.len();
Expand All @@ -554,7 +551,7 @@ alias, if set.
if new_tokens_len == 0 {
println!("Found no new tokens");
} else {
println!("{} new tokens added", new_tokens_len);
println!("{new_tokens_len} new tokens added");
}
Ok(())
}
Expand All @@ -577,15 +574,15 @@ alias, if set.
.accounts
.iter()
.flat_map(|(chain_type, address, alias)| {
self.enabled_chains_of_type(&chain_type)
self.enabled_chains_of_type(chain_type)
.map(move |chain| (chain, address, alias))
})
.partition(|(chain, _, _)| chain.chain_type == ChainType::Ton);

let accounts_not_supported = accounts_not_supported
.iter()
.flat_map(|(chain, address, alias)| {
self.tokens_of_chain(&chain)
self.tokens_of_chain(chain)
.map(move |(_, token)| (chain, token.clone(), address, alias))
})
.collect::<Vec<_>>();
Expand Down Expand Up @@ -688,11 +685,8 @@ alias, if set.
account_holdings
.iter()
.filter_map(move |(token_address, balance)| {
let Some((_, token)) =
tokens_of_chain.find(|(_, t)| t.address == *token_address)
else {
return None;
};
let (_, token) =
tokens_of_chain.find(|(_, t)| t.address == *token_address)?;
(*balance != BigUint::ZERO).then(|| ReplBalanceEntry {
account: account_label.clone(),
chain: chain.properties.name.clone(),
Expand Down Expand Up @@ -721,7 +715,7 @@ alias, if set.
.await
{
Some(x) => x,
None => return Err(format!("Could not fetch tokens price")),
None => return Err("Could not fetch tokens price".to_string()),
}
.iter()
.filter_map(|p| {
Expand All @@ -732,8 +726,7 @@ alias, if set.

self.spinner.stop();

for i in 0..balances.len() {
let balance = &mut balances[i];
for balance in &mut balances {
if let Some((_, price)) =
pairs.iter().find(|pair| pair.0 == balance.token.address)
{
Expand Down Expand Up @@ -795,7 +788,10 @@ alias, if set.
"chain" => self.handle_chain(command_parts),
"account" => self.handle_account(command_parts),
"config" => self.handle_config(command_parts),
"help" | "?" => Ok(Self::display_help()),
"help" | "?" => {
Self::display_help();
Ok(())
}
"exit" | "quit" => std::process::exit(0),
x => Err(format!("Unknown command: {x:?}")),
} {
Expand Down
4 changes: 1 addition & 3 deletions src/utils/spinner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ impl Spinner {
let output = format!(
"\r{}{}{}{}",
FRAMES[i].to_colored(),
extra_msg
.and_then(|s| Some(format!(" {s}")))
.unwrap_or_default(),
extra_msg.map(|s| format!(" {s}")).unwrap_or_default(),
if show_progress {
format!(
" {}/{}",
Expand Down
6 changes: 3 additions & 3 deletions src/utils/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl Default for Table {

impl Display for Table {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.rows.len() == 0 {
if self.rows.is_empty() {
return write!(f, "");
}
if self.title != String::default() {
Expand All @@ -43,8 +43,8 @@ impl Display for Table {
let col_count = self.rows[0].len();
let mut col_widths: Vec<usize> = vec![0; col_count];
for i in 0..row_count {
for j in 0..col_count {
col_widths[j] = (self.rows[i][j].len() + self.spacing).max(col_widths[j]);
for (j, col_width) in col_widths.iter_mut().enumerate().take(col_count) {
*col_width = (self.rows[i][j].len() + self.spacing).max(*col_width);
}
}
for i in 0..row_count {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub trait StylizedText {

impl StylizedText for &str {
fn to_colored(&self) -> String {
format!("\x1b[32m{}\x1b[0m", self)
format!("\x1b[32m{self}\x1b[0m")
}
fn to_title(&self) -> String {
format!("{}\n{}", self, "=".repeat(self.len()))
Expand Down