use crate::command::{CliConfig, ProcessResult};
use solana_clap_utils::keypair::DefaultSigner;
use solana_cli_config::{Config, ConfigInput};
use solana_cli_output::OutputFormat;
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use solana_remote_wallet::remote_wallet::RemoteWalletManager;
use solana_sdk::commitment_config::{CommitmentConfig, CommitmentLevel};
use std::any::Any;
use std::borrow::BorrowMut;
use std::sync::Arc;
use std::time::Duration;
pub struct CommonCli {
cli_config: CliConfig,
program_id: Pubkey,
}
pub trait Matche {
fn as_any(&self) -> &dyn Any;
fn get_config_file(&self) -> &str;
fn get_owner(&self) -> &str;
}
impl CommonCli {
pub fn new(program_id: Pubkey) -> CommonCli {
CommonCli {
cli_config: CliConfig {
signers: vec![],
json_rpc_url: "".to_string(),
rpc_timeout: Default::default(),
commitment: Default::default(),
confirm_transaction_initial_timeout: Default::default(),
output_format: OutputFormat::Display,
config: Config::default(),
},
program_id,
}
}
pub fn parse_args(mut self, app: Box<dyn Matche>) -> Self {
let config_file = app.get_config_file();
let config = if config_file.is_empty() {
Config::default()
} else {
Config::load(config_file).unwrap_or_default()
};
let json_rpc_url = config.json_rpc_url.clone();
let rpc_timeout = Duration::from_secs(20);
let commitment = CommitmentConfig {
commitment: CommitmentLevel::Finalized,
};
let confirm_transaction_initial_timeout = Duration::from_secs(10);
let default_signer_arg_name = "keypair".to_string();
let (_, default_signer_path) =
ConfigInput::compute_keypair_path_setting(app.get_owner(), &config.keypair_path);
let default_signer = DefaultSigner::new(default_signer_arg_name, &default_signer_path);
let mut wallet_manager: Option<Arc<RemoteWalletManager>> = None;
let k = default_signer.signer_from_path(&Default::default(), &mut wallet_manager);
self.cli_config.signers = vec![k.unwrap()];
self.cli_config.json_rpc_url = json_rpc_url;
self.cli_config.rpc_timeout = rpc_timeout;
self.cli_config.commitment = commitment;
self.cli_config.confirm_transaction_initial_timeout = confirm_transaction_initial_timeout;
self.cli_config.output_format = OutputFormat::Display;
self.cli_config.config = config;
self
}
pub fn process_command(
mut self,
process_command: fn(
config: &mut CliConfig,
rpc_client: RpcClient,
app: Box<dyn Matche>,
) -> ProcessResult,
app: Box<dyn Matche>,
) {
let rpc_client = RpcClient::new_with_timeouts_and_commitment(
self.cli_config.json_rpc_url.to_string(),
self.cli_config.rpc_timeout,
self.cli_config.commitment,
self.cli_config.confirm_transaction_initial_timeout,
);
let result = process_command(self.cli_config.borrow_mut(), rpc_client, app);
match result {
Err(err) => println!("err: {}", err),
Ok(sig) => println!("{}", sig),
};
}
pub fn get_pubkey_for_program_with_seeds(self, seeds: &[&[u8]]) -> (Pubkey, u8) {
Pubkey::find_program_address(seeds, &self.program_id)
}
}