From 775adadd1e92832d65ef0ac593b364d0a14146c9 Mon Sep 17 00:00:00 2001 From: scx1332 Date: Thu, 14 Mar 2024 22:27:04 +0100 Subject: [PATCH] f --- src/actions.rs | 1 + src/actions/transfer.rs | 141 ++++++++++++++++++++++++++++++++++++++++ src/main.rs | 129 +++--------------------------------- 3 files changed, 150 insertions(+), 121 deletions(-) create mode 100644 src/actions/transfer.rs diff --git a/src/actions.rs b/src/actions.rs index 04981680..5fce744f 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -5,6 +5,7 @@ use web3::types::Address; pub mod check_rpc; pub mod deposit; pub mod scan_chain; +pub mod transfer; pub fn check_address_name(n: &str) -> Result { match n { diff --git a/src/actions/transfer.rs b/src/actions/transfer.rs new file mode 100644 index 00000000..5c598ecc --- /dev/null +++ b/src/actions/transfer.rs @@ -0,0 +1,141 @@ +use std::str::FromStr; +use rust_decimal::Decimal; +use sqlx::SqlitePool; +use web3::types::Address; +use erc20_payment_lib::config::Config; +use erc20_payment_lib::runtime::get_token_balance; +use erc20_payment_lib::setup::PaymentSetup; +use erc20_payment_lib_common::{err_custom_create, err_from}; +use erc20_payment_lib_common::error::PaymentError; +use erc20_payment_lib_common::model::TokenTransferDbObj; +use erc20_payment_lib_common::ops::{insert_token_transfer_with_deposit_check, update_token_transfer}; +use erc20_payment_lib_common::utils::{DecimalConvExt, StringConvExt}; +use crate::actions::check_address_name; +use crate::options::TransferOptions; +use erc20_payment_lib_common::error::ErrorBag; + +pub async fn transfer_local( + conn: SqlitePool, + single_transfer_options: TransferOptions, + config: Config, + public_addrs: &[Address], +) -> Result<(), PaymentError> { + log::info!("Adding single transfer..."); + let chain_cfg = config + .chain + .get(&single_transfer_options.chain_name) + .ok_or(err_custom_create!( + "Chain {} not found in config file", + single_transfer_options.chain_name + ))?; + + #[allow(clippy::if_same_then_else)] + let token = if single_transfer_options.token == "glm" { + Some(format!("{:#x}", chain_cfg.token.address)) + } else if single_transfer_options.token == "eth" { + None + } else if single_transfer_options.token == "matic" { + //matic is the same as eth + None + } else { + return Err(err_custom_create!( + "Unknown token: {}", + single_transfer_options.token + )); + }; + + let recipient = check_address_name(&single_transfer_options.recipient).unwrap(); + + let public_addr = if let Some(address) = single_transfer_options.address { + address + } else if let Some(account_no) = single_transfer_options.account_no { + *public_addrs + .get(account_no) + .expect("No public adss found with specified account_no") + } else { + *public_addrs.first().expect("No public address found") + }; + //let mut db_transaction = conn.clone().unwrap().begin().await.unwrap(); + + let amount_str = if let Some(amount) = single_transfer_options.amount { + amount.to_u256_from_eth().unwrap().to_string() + } else if single_transfer_options.all { + let payment_setup = PaymentSetup::new_empty(&config)?; + { + #[allow(clippy::if_same_then_else)] + if single_transfer_options.token == "glm" { + get_token_balance( + payment_setup.get_provider(chain_cfg.chain_id)?, + chain_cfg.token.address, + public_addr, + None, + ) + .await? + .to_string() + } else if single_transfer_options.token == "eth" + || single_transfer_options.token == "matic" + { + let val = payment_setup + .get_provider(chain_cfg.chain_id)? + .eth_balance(public_addr, None) + .await + .map_err(err_from!())?; + let gas_val = Decimal::from_str(&chain_cfg.max_fee_per_gas.to_string()) + .map_err(|e| err_custom_create!("Failed to convert {e}"))? + * Decimal::from(21500); //leave some room for rounding error + let gas_val = gas_val.to_u256_from_gwei().map_err(err_from!())?; + if gas_val > val { + return Err(err_custom_create!( + "Not enough eth to pay for gas, required: {}, available: {}", + gas_val, + val + )); + } + (val - gas_val).to_string() + } else { + return Err(err_custom_create!( + "Unknown token: {}", + single_transfer_options.token + )); + } + } + } else { + return Err(err_custom_create!("No amount specified")); + }; + let amount_decimal = amount_str.to_eth().unwrap(); + + let mut tt = insert_token_transfer_with_deposit_check( + &conn.clone(), + &TokenTransferDbObj { + id: 0, + payment_id: None, + from_addr: format!("{:#x}", public_addr), + receiver_addr: format!("{:#x}", recipient), + chain_id: chain_cfg.chain_id, + token_addr: token, + token_amount: amount_str, + deposit_id: single_transfer_options.deposit_id, + deposit_finish: 0, + create_date: Default::default(), + tx_id: None, + paid_date: None, + fee_paid: None, + error: None, + }, + ) + .await + .unwrap(); + + let payment_id = format!("{}_transfer_{}", single_transfer_options.token, tt.id); + tt.payment_id = Some(payment_id.clone()); + update_token_transfer(&conn.clone(), &tt) + .await + .unwrap(); + + log::info!( + "Transfer added to db amount: {}, payment id: {}", + amount_decimal, + payment_id + ); + Ok(()) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 5987e977..f207098a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,6 @@ use erc20_payment_lib_common::create_sqlite_connection; use erc20_payment_lib_common::error::*; use erc20_payment_lib_common::ops::{ get_next_transactions_to_process, insert_token_transfer, - insert_token_transfer_with_deposit_check, update_token_transfer, }; use erc20_payment_lib_common::*; @@ -25,7 +24,6 @@ use erc20_payment_lib::{ use std::env; use std::str::FromStr; -use crate::actions::check_address_name; use crate::actions::check_rpc::check_rpc_local; use crate::actions::deposit::close::close_deposit_local; use crate::actions::deposit::create::make_deposit_local; @@ -35,19 +33,19 @@ use crate::stats::{export_stats, run_stats}; use erc20_payment_lib::faucet_client::faucet_donate; use erc20_payment_lib::misc::gen_private_keys; use erc20_payment_lib::runtime::{ - get_token_balance, mint_golem_token, remove_last_unsent_transactions, remove_transaction_force, + mint_golem_token, remove_last_unsent_transactions, remove_transaction_force, PaymentRuntimeArgs, }; use erc20_payment_lib::server::web::{runtime_web_scope, ServerData}; use erc20_payment_lib::setup::PaymentSetup; use erc20_payment_lib_common::init_metrics; use erc20_payment_lib_common::model::TokenTransferDbObj; -use erc20_payment_lib_common::utils::{DecimalConvExt, StringConvExt}; use erc20_payment_lib_extra::{account_balance, generate_test_payments}; use rust_decimal::Decimal; use std::sync::Arc; use structopt::StructOpt; use tokio::sync::{broadcast, Mutex}; +use crate::actions::transfer::transfer_local; async fn main_internal() -> Result<(), PaymentError> { dotenv::dotenv().ok(); @@ -407,123 +405,12 @@ async fn main_internal() -> Result<(), PaymentError> { PaymentCommands::Transfer { single_transfer_options, } => { - log::info!("Adding single transfer..."); - let chain_cfg = config - .chain - .get(&single_transfer_options.chain_name) - .ok_or(err_custom_create!( - "Chain {} not found in config file", - single_transfer_options.chain_name - ))?; - - #[allow(clippy::if_same_then_else)] - let token = if single_transfer_options.token == "glm" { - Some(format!("{:#x}", chain_cfg.token.address)) - } else if single_transfer_options.token == "eth" { - None - } else if single_transfer_options.token == "matic" { - //matic is the same as eth - None - } else { - return Err(err_custom_create!( - "Unknown token: {}", - single_transfer_options.token - )); - }; - - let recipient = check_address_name(&single_transfer_options.recipient).unwrap(); - - let public_addr = if let Some(address) = single_transfer_options.address { - address - } else if let Some(account_no) = single_transfer_options.account_no { - *public_addrs - .get(account_no) - .expect("No public adss found with specified account_no") - } else { - *public_addrs.first().expect("No public address found") - }; - //let mut db_transaction = conn.clone().unwrap().begin().await.unwrap(); - - let amount_str = if let Some(amount) = single_transfer_options.amount { - amount.to_u256_from_eth().unwrap().to_string() - } else if single_transfer_options.all { - let payment_setup = PaymentSetup::new_empty(&config)?; - { - #[allow(clippy::if_same_then_else)] - if single_transfer_options.token == "glm" { - get_token_balance( - payment_setup.get_provider(chain_cfg.chain_id)?, - chain_cfg.token.address, - public_addr, - None, - ) - .await? - .to_string() - } else if single_transfer_options.token == "eth" - || single_transfer_options.token == "matic" - { - let val = payment_setup - .get_provider(chain_cfg.chain_id)? - .eth_balance(public_addr, None) - .await - .map_err(err_from!())?; - let gas_val = Decimal::from_str(&chain_cfg.max_fee_per_gas.to_string()) - .map_err(|e| err_custom_create!("Failed to convert {e}"))? - * Decimal::from(21500); //leave some room for rounding error - let gas_val = gas_val.to_u256_from_gwei().map_err(err_from!())?; - if gas_val > val { - return Err(err_custom_create!( - "Not enough eth to pay for gas, required: {}, available: {}", - gas_val, - val - )); - } - (val - gas_val).to_string() - } else { - return Err(err_custom_create!( - "Unknown token: {}", - single_transfer_options.token - )); - } - } - } else { - return Err(err_custom_create!("No amount specified")); - }; - let amount_decimal = amount_str.to_eth().unwrap(); - - let mut tt = insert_token_transfer_with_deposit_check( - &conn.clone().unwrap(), - &TokenTransferDbObj { - id: 0, - payment_id: None, - from_addr: format!("{:#x}", public_addr), - receiver_addr: format!("{:#x}", recipient), - chain_id: chain_cfg.chain_id, - token_addr: token, - token_amount: amount_str, - deposit_id: single_transfer_options.deposit_id, - deposit_finish: 0, - create_date: Default::default(), - tx_id: None, - paid_date: None, - fee_paid: None, - error: None, - }, - ) - .await - .unwrap(); - - let payment_id = format!("{}_transfer_{}", single_transfer_options.token, tt.id); - tt.payment_id = Some(payment_id.clone()); - update_token_transfer(&conn.clone().unwrap(), &tt) - .await - .unwrap(); - - log::info!( - "Transfer added to db amount: {}, payment id: {}", - amount_decimal, - payment_id - ); + transfer_local( + conn.clone().unwrap(), + single_transfer_options, + config, + &public_addrs, + ).await?; } PaymentCommands::Balance { account_balance_options,