use super::*;
use alloy::primitives::{Address, U256};
use clap::Subcommand;
use color_eyre::{eyre::eyre, Result};
use evmlib::Network;
use sn_testnet_deploy::{
funding::FundingOptions, get_anvil_node_data_hardcoded, get_environment_details,
inventory::DeploymentInventoryService, CloudProvider, EvmNetwork, TestnetDeployBuilder,
};
use std::str::FromStr;
#[derive(Subcommand, Debug)]
pub enum FundsCommand {
Deposit {
#[clap(long)]
funding_wallet_secret_key: Option<String>,
#[arg(long)]
gas_to_transfer: Option<U256>,
#[arg(short = 'n', long)]
name: String,
#[clap(long, value_parser = parse_provider, verbatim_doc_comment, default_value_t = CloudProvider::DigitalOcean)]
provider: CloudProvider,
#[arg(long)]
tokens_to_transfer: Option<U256>,
},
Drain {
#[arg(short = 'n', long)]
name: String,
#[clap(long, value_parser = parse_provider, verbatim_doc_comment, default_value_t = CloudProvider::DigitalOcean)]
provider: CloudProvider,
#[clap(long)]
to_address: Option<String>,
},
}
pub async fn handle_funds_command(cmd: FundsCommand) -> Result<()> {
match cmd {
FundsCommand::Deposit {
funding_wallet_secret_key,
gas_to_transfer,
name,
provider,
tokens_to_transfer,
} => {
let testnet_deployer = TestnetDeployBuilder::default()
.environment_name(&name)
.provider(provider)
.build()?;
let inventory_services = DeploymentInventoryService::from(&testnet_deployer);
inventory_services
.generate_or_retrieve_inventory(&name, true, None)
.await?;
let environment_details =
get_environment_details(&name, &inventory_services.s3_repository).await?;
let funding_wallet_secret_key = if funding_wallet_secret_key.is_none()
&& environment_details.evm_details.network == EvmNetwork::Anvil
{
let anvil_node_data = get_anvil_node_data_hardcoded(
&testnet_deployer.ansible_provisioner.ansible_runner,
)?;
Some(anvil_node_data.deployer_wallet_private_key)
} else {
funding_wallet_secret_key
};
let options = FundingOptions {
evm_data_payments_address: environment_details.evm_details.data_payments_address,
evm_merkle_payments_address: environment_details
.evm_details
.merkle_payments_address,
evm_payment_token_address: environment_details.evm_details.payment_token_address,
evm_rpc_url: environment_details.evm_details.rpc_url,
evm_network: environment_details.evm_details.network,
funding_wallet_secret_key,
gas_amount: gas_to_transfer,
token_amount: tokens_to_transfer,
uploaders_count: None,
};
testnet_deployer
.ansible_provisioner
.deposit_funds_to_clients(&options)
.await?;
Ok(())
}
FundsCommand::Drain {
name,
provider,
to_address,
} => {
let testnet_deployer = TestnetDeployBuilder::default()
.environment_name(&name)
.provider(provider)
.build()?;
let inventory_services = DeploymentInventoryService::from(&testnet_deployer);
inventory_services
.generate_or_retrieve_inventory(&name, true, None)
.await?;
let environment_details =
get_environment_details(&name, &inventory_services.s3_repository).await?;
let to_address = if let Some(to_address) = to_address {
Address::from_str(&to_address)?
} else if let Some(to_address) = environment_details.funding_wallet_address {
Address::from_str(&to_address)?
} else {
return Err(eyre!(
"No to-address was provided and no funding wallet address was found in the environment details"
));
};
let network = match environment_details.evm_details.network {
EvmNetwork::Anvil => {
return Err(eyre!(
"Draining funds from ANT instances is not supported for an Anvil network"
));
}
EvmNetwork::ArbitrumOne => Network::ArbitrumOne,
EvmNetwork::ArbitrumSepoliaTest => Network::ArbitrumSepoliaTest,
EvmNetwork::Custom => {
if let (
Some(emv_data_payments_address),
Some(evm_merkle_payments_address),
Some(evm_payment_token_address),
Some(evm_rpc_url),
) = (
environment_details
.evm_details
.data_payments_address
.as_ref(),
environment_details
.evm_details
.merkle_payments_address
.as_ref(),
environment_details
.evm_details
.payment_token_address
.as_ref(),
environment_details.evm_details.rpc_url.as_ref(),
) {
Network::new_custom(
evm_rpc_url,
evm_payment_token_address,
emv_data_payments_address,
Some(evm_merkle_payments_address),
)
} else {
return Err(eyre!(
"Custom EVM details not found in the environment details"
));
}
}
};
testnet_deployer
.ansible_provisioner
.drain_funds_from_ant_instances(to_address, network)
.await?;
Ok(())
}
}
}