diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 795bd4b22..bb5c01356 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -43,6 +43,7 @@ url = "2.1.0" [dev-dependencies] solana-core = { path = "../core", version = "0.21.0" } solana-budget-program = { path = "../programs/budget_program", version = "0.21.0" } +tempfile = "3.1.0" [[bin]] name = "solana" diff --git a/cli/src/cli.rs b/cli/src/cli.rs index c7a1681f2..c8b4754d8 100644 --- a/cli/src/cli.rs +++ b/cli/src/cli.rs @@ -64,7 +64,7 @@ pub enum CliCommand { Deploy(String), // Stake Commands CreateStakeAccount { - stake_account_pubkey: Pubkey, + stake_account: Keypair, staker: Option, withdrawer: Option, lockup: Lockup, @@ -85,7 +85,7 @@ pub enum CliCommand { // Storage Commands CreateStorageAccount { account_owner: Pubkey, - storage_account_pubkey: Pubkey, + storage_account: Keypair, account_type: StorageAccountType, }, ClaimStorageReward { @@ -102,7 +102,7 @@ pub enum CliCommand { }, // Vote Commands CreateVoteAccount { - vote_account_pubkey: Pubkey, + vote_account: Keypair, node_pubkey: Pubkey, authorized_voter: Option, authorized_withdrawer: Option, @@ -840,7 +840,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult { // Create stake account CliCommand::CreateStakeAccount { - stake_account_pubkey, + stake_account, staker, withdrawer, lockup, @@ -848,7 +848,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult { } => process_create_stake_account( &rpc_client, config, - &stake_account_pubkey, + stake_account, staker, withdrawer, lockup, @@ -914,13 +914,13 @@ pub fn process_command(config: &CliConfig) -> ProcessResult { // Create storage account CliCommand::CreateStorageAccount { account_owner, - storage_account_pubkey, + storage_account, account_type, } => process_create_storage_account( &rpc_client, config, &account_owner, - &storage_account_pubkey, + storage_account, *account_type, ), CliCommand::ClaimStorageReward { @@ -959,7 +959,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult { // Create vote account CliCommand::CreateVoteAccount { - vote_account_pubkey, + vote_account, node_pubkey, authorized_voter, authorized_withdrawer, @@ -967,7 +967,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult { } => process_create_vote_account( &rpc_client, config, - &vote_account_pubkey, + vote_account, &node_pubkey, authorized_voter, authorized_withdrawer, @@ -1782,10 +1782,11 @@ mod tests { config.command = CliCommand::Confirm(good_signature); assert_eq!(process_command(&config).unwrap(), "Confirmed"); - let bob_pubkey = Pubkey::new_rand(); + let bob_keypair = Keypair::new(); + let bob_pubkey = bob_keypair.pubkey(); let node_pubkey = Pubkey::new_rand(); config.command = CliCommand::CreateVoteAccount { - vote_account_pubkey: bob_pubkey, + vote_account: bob_keypair, node_pubkey, authorized_voter: Some(bob_pubkey), authorized_withdrawer: Some(bob_pubkey), @@ -1800,10 +1801,11 @@ mod tests { let signature = process_command(&config); assert_eq!(signature.unwrap(), SIGNATURE.to_string()); - let bob_pubkey = Pubkey::new_rand(); + let bob_keypair = Keypair::new(); + let bob_pubkey = bob_keypair.pubkey(); let custodian = Pubkey::new_rand(); config.command = CliCommand::CreateStakeAccount { - stake_account_pubkey: bob_pubkey, + stake_account: bob_keypair, staker: None, withdrawer: None, lockup: Lockup { slot: 0, custodian }, @@ -1947,8 +1949,9 @@ mod tests { }; assert!(process_command(&config).is_err()); + let bob_keypair = Keypair::new(); config.command = CliCommand::CreateVoteAccount { - vote_account_pubkey: bob_pubkey, + vote_account: bob_keypair, node_pubkey, authorized_voter: Some(bob_pubkey), authorized_withdrawer: Some(bob_pubkey), diff --git a/cli/src/stake.rs b/cli/src/stake.rs index 8b2193554..37f4daf9a 100644 --- a/cli/src/stake.rs +++ b/cli/src/stake.rs @@ -10,6 +10,7 @@ use crate::{ use clap::{App, Arg, ArgMatches, SubCommand}; use console::style; use solana_client::rpc_client::RpcClient; +use solana_sdk::signature::Keypair; use solana_sdk::{ account_utils::State, pubkey::Pubkey, @@ -21,9 +22,10 @@ use solana_sdk::{ }, transaction::Transaction, }; +use solana_stake_api::stake_state::Meta; use solana_stake_api::{ stake_instruction::{self, StakeError}, - stake_state::{Authorized, Lockup, Meta, StakeAuthorize, StakeState}, + stake_state::{Authorized, Lockup, StakeAuthorize, StakeState}, }; use solana_vote_api::vote_state::VoteState; use std::ops::Deref; @@ -38,13 +40,13 @@ impl StakeSubCommands for App<'_, '_> { SubCommand::with_name("create-stake-account") .about("Create a stake account") .arg( - Arg::with_name("stake_account_pubkey") + Arg::with_name("stake_account") .index(1) .value_name("STAKE ACCOUNT") .takes_value(true) .required(true) - .validator(is_pubkey_or_keypair) - .help("Address of the stake account to fund (pubkey or keypair)") + .validator(is_keypair) + .help("Keypair of the stake account to fund") ) .arg( Arg::with_name("amount") @@ -272,7 +274,7 @@ impl StakeSubCommands for App<'_, '_> { } pub fn parse_stake_create_account(matches: &ArgMatches<'_>) -> Result { - let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap(); + let stake_account = keypair_of(matches, "stake_account").unwrap(); let slot = value_of(&matches, "lockup").unwrap_or(0); let custodian = pubkey_of(matches, "custodian").unwrap_or_default(); let staker = pubkey_of(matches, "authorized_staker"); @@ -281,7 +283,7 @@ pub fn parse_stake_create_account(matches: &ArgMatches<'_>) -> Result) -> Result, withdrawer: &Option, lockup: &Lockup, lamports: u64, ) -> ProcessResult { + let stake_account_pubkey = stake_account.pubkey(); check_unique_pubkeys( (&config.keypair.pubkey(), "cli keypair".to_string()), - (stake_account_pubkey, "stake_account_pubkey".to_string()), + (&stake_account_pubkey, "stake_account_pubkey".to_string()), )?; if rpc_client.get_account(&stake_account_pubkey).is_ok() { @@ -412,7 +415,7 @@ pub fn process_create_stake_account( let ixs = stake_instruction::create_stake_account_with_lockup( &config.keypair.pubkey(), - stake_account_pubkey, + &stake_account_pubkey, &authorized, lockup, lamports, @@ -709,36 +712,54 @@ pub fn process_delegate_stake( mod tests { use super::*; use crate::cli::{app, parse_command}; + use solana_sdk::signature::write_keypair; + use tempfile::NamedTempFile; + + fn make_tmp_file() -> (String, NamedTempFile) { + let tmp_file = NamedTempFile::new().unwrap(); + (String::from(tmp_file.path().to_str().unwrap()), tmp_file) + } #[test] fn test_parse_command() { let test_commands = app("test", "desc", "version"); - let pubkey = Pubkey::new_rand(); - let pubkey_string = format!("{}", pubkey); + let (keypair_file, mut tmp_file) = make_tmp_file(); + let stake_account_keypair = Keypair::new(); + write_keypair(&stake_account_keypair, tmp_file.as_file_mut()).unwrap(); + let stake_account_pubkey = stake_account_keypair.pubkey(); + let stake_account_string = stake_account_pubkey.to_string(); let test_authorize_staker = test_commands.clone().get_matches_from(vec![ "test", "stake-authorize-staker", - &pubkey_string, - &pubkey_string, + &stake_account_string, + &stake_account_string, ]); assert_eq!( parse_command(&test_authorize_staker).unwrap(), CliCommandInfo { - command: CliCommand::StakeAuthorize(pubkey, pubkey, StakeAuthorize::Staker), + command: CliCommand::StakeAuthorize( + stake_account_pubkey, + stake_account_pubkey, + StakeAuthorize::Staker + ), require_keypair: true } ); let test_authorize_withdrawer = test_commands.clone().get_matches_from(vec![ "test", "stake-authorize-withdrawer", - &pubkey_string, - &pubkey_string, + &stake_account_string, + &stake_account_string, ]); assert_eq!( parse_command(&test_authorize_withdrawer).unwrap(), CliCommandInfo { - command: CliCommand::StakeAuthorize(pubkey, pubkey, StakeAuthorize::Withdrawer), + command: CliCommand::StakeAuthorize( + stake_account_pubkey, + stake_account_pubkey, + StakeAuthorize::Withdrawer + ), require_keypair: true } ); @@ -751,7 +772,7 @@ mod tests { let test_create_stake_account = test_commands.clone().get_matches_from(vec![ "test", "create-stake-account", - &pubkey_string, + &keypair_file, "50", "--authorized-staker", &authorized_string, @@ -767,7 +788,7 @@ mod tests { parse_command(&test_create_stake_account).unwrap(), CliCommandInfo { command: CliCommand::CreateStakeAccount { - stake_account_pubkey: pubkey, + stake_account: stake_account_keypair, staker: Some(authorized), withdrawer: Some(authorized), lockup: Lockup { @@ -779,18 +800,26 @@ mod tests { require_keypair: true } ); + + let (keypair_file, mut tmp_file) = make_tmp_file(); + let stake_account_keypair = Keypair::new(); + write_keypair(&stake_account_keypair, tmp_file.as_file_mut()).unwrap(); + let stake_account_pubkey = stake_account_keypair.pubkey(); + let stake_account_string = stake_account_pubkey.to_string(); + let test_create_stake_account2 = test_commands.clone().get_matches_from(vec![ "test", "create-stake-account", - &pubkey_string, + &keypair_file, "50", "lamports", ]); + assert_eq!( parse_command(&test_create_stake_account2).unwrap(), CliCommandInfo { command: CliCommand::CreateStakeAccount { - stake_account_pubkey: pubkey, + stake_account: stake_account_keypair, staker: None, withdrawer: None, lockup: Lockup { @@ -810,12 +839,12 @@ mod tests { "test", "delegate-stake", &stake_pubkey_string, - &pubkey_string, + &stake_account_string, ]); assert_eq!( parse_command(&test_delegate_stake).unwrap(), CliCommandInfo { - command: CliCommand::DelegateStake(stake_pubkey, pubkey, false), + command: CliCommand::DelegateStake(stake_pubkey, stake_account_pubkey, false), require_keypair: true } ); @@ -825,12 +854,12 @@ mod tests { "delegate-stake", "--force", &stake_pubkey_string, - &pubkey_string, + &stake_account_string, ]); assert_eq!( parse_command(&test_delegate_stake).unwrap(), CliCommandInfo { - command: CliCommand::DelegateStake(stake_pubkey, pubkey, true), + command: CliCommand::DelegateStake(stake_pubkey, stake_account_pubkey, true), require_keypair: true } ); @@ -840,7 +869,7 @@ mod tests { "test", "withdraw-stake", &stake_pubkey_string, - &pubkey_string, + &stake_account_string, "42", "lamports", ]); @@ -848,7 +877,7 @@ mod tests { assert_eq!( parse_command(&test_withdraw_stake).unwrap(), CliCommandInfo { - command: CliCommand::WithdrawStake(stake_pubkey, pubkey, 42), + command: CliCommand::WithdrawStake(stake_pubkey, stake_account_pubkey, 42), require_keypair: true } ); diff --git a/cli/src/storage.rs b/cli/src/storage.rs index ae3055984..db22e6084 100644 --- a/cli/src/storage.rs +++ b/cli/src/storage.rs @@ -8,6 +8,7 @@ use crate::{ }; use clap::{App, Arg, ArgMatches, SubCommand}; use solana_client::rpc_client::RpcClient; +use solana_sdk::signature::Keypair; use solana_sdk::{ account_utils::State, message::Message, pubkey::Pubkey, signature::KeypairUtil, system_instruction::SystemError, transaction::Transaction, @@ -32,12 +33,12 @@ impl StorageSubCommands for App<'_, '_> { .validator(is_pubkey_or_keypair), ) .arg( - Arg::with_name("storage_account_pubkey") + Arg::with_name("storage_account") .index(2) - .value_name("STORAGE ACCOUNT PUBKEY") + .value_name("STORAGE ACCOUNT") .takes_value(true) .required(true) - .validator(is_pubkey_or_keypair), + .validator(is_keypair), ), ) .subcommand( @@ -52,12 +53,12 @@ impl StorageSubCommands for App<'_, '_> { .validator(is_pubkey_or_keypair), ) .arg( - Arg::with_name("storage_account_pubkey") + Arg::with_name("storage_account") .index(2) - .value_name("STORAGE ACCOUNT PUBKEY") + .value_name("STORAGE ACCOUNT") .takes_value(true) .required(true) - .validator(is_pubkey_or_keypair), + .validator(is_keypair), ), ) .subcommand( @@ -102,11 +103,11 @@ pub fn parse_storage_create_archiver_account( matches: &ArgMatches<'_>, ) -> Result { let account_owner = pubkey_of(matches, "storage_account_owner").unwrap(); - let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap(); + let storage_account = keypair_of(matches, "storage_account").unwrap(); Ok(CliCommandInfo { command: CliCommand::CreateStorageAccount { account_owner, - storage_account_pubkey, + storage_account, account_type: StorageAccountType::Archiver, }, require_keypair: true, @@ -117,11 +118,11 @@ pub fn parse_storage_create_validator_account( matches: &ArgMatches<'_>, ) -> Result { let account_owner = pubkey_of(matches, "storage_account_owner").unwrap(); - let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap(); + let storage_account = keypair_of(matches, "storage_account").unwrap(); Ok(CliCommandInfo { command: CliCommand::CreateStorageAccount { account_owner, - storage_account_pubkey, + storage_account, account_type: StorageAccountType::Validator, }, require_keypair: true, @@ -154,9 +155,10 @@ pub fn process_create_storage_account( rpc_client: &RpcClient, config: &CliConfig, account_owner: &Pubkey, - storage_account_pubkey: &Pubkey, + storage_account: &Keypair, account_type: StorageAccountType, ) -> ProcessResult { + let storage_account_pubkey = storage_account.pubkey(); check_unique_pubkeys( (&config.keypair.pubkey(), "cli keypair".to_string()), ( @@ -168,7 +170,7 @@ pub fn process_create_storage_account( let ixs = storage_instruction::create_storage_account( &config.keypair.pubkey(), &account_owner, - storage_account_pubkey, + &storage_account_pubkey, 1, account_type, ); @@ -226,45 +228,60 @@ pub fn process_show_storage_account( mod tests { use super::*; use crate::cli::{app, parse_command}; + use solana_sdk::signature::write_keypair; + use tempfile::NamedTempFile; + + fn make_tmp_file() -> (String, NamedTempFile) { + let tmp_file = NamedTempFile::new().unwrap(); + (String::from(tmp_file.path().to_str().unwrap()), tmp_file) + } #[test] fn test_parse_command() { let test_commands = app("test", "desc", "version"); let pubkey = Pubkey::new_rand(); let pubkey_string = pubkey.to_string(); - let storage_account_pubkey = Pubkey::new_rand(); - let storage_account_string = storage_account_pubkey.to_string(); + + let (keypair_file, mut tmp_file) = make_tmp_file(); + let storage_account_keypair = Keypair::new(); + write_keypair(&storage_account_keypair, tmp_file.as_file_mut()).unwrap(); let test_create_archiver_storage_account = test_commands.clone().get_matches_from(vec![ "test", "create-archiver-storage-account", &pubkey_string, - &storage_account_string, + &keypair_file, ]); assert_eq!( parse_command(&test_create_archiver_storage_account).unwrap(), CliCommandInfo { command: CliCommand::CreateStorageAccount { account_owner: pubkey, - storage_account_pubkey, + storage_account: storage_account_keypair, account_type: StorageAccountType::Archiver, }, require_keypair: true } ); + let (keypair_file, mut tmp_file) = make_tmp_file(); + let storage_account_keypair = Keypair::new(); + write_keypair(&storage_account_keypair, tmp_file.as_file_mut()).unwrap(); + let storage_account_pubkey = storage_account_keypair.pubkey(); + let storage_account_string = storage_account_pubkey.to_string(); + let test_create_validator_storage_account = test_commands.clone().get_matches_from(vec![ "test", "create-validator-storage-account", &pubkey_string, - &storage_account_string, + &keypair_file, ]); assert_eq!( parse_command(&test_create_validator_storage_account).unwrap(), CliCommandInfo { command: CliCommand::CreateStorageAccount { account_owner: pubkey, - storage_account_pubkey, + storage_account: storage_account_keypair, account_type: StorageAccountType::Validator, }, require_keypair: true diff --git a/cli/src/vote.rs b/cli/src/vote.rs index 82a5230ca..789d569ec 100644 --- a/cli/src/vote.rs +++ b/cli/src/vote.rs @@ -9,6 +9,7 @@ use crate::{ }; use clap::{value_t_or_exit, App, Arg, ArgMatches, SubCommand}; use solana_client::rpc_client::RpcClient; +use solana_sdk::signature::Keypair; use solana_sdk::{ account::Account, pubkey::Pubkey, signature::KeypairUtil, system_instruction::SystemError, transaction::Transaction, @@ -28,13 +29,13 @@ impl VoteSubCommands for App<'_, '_> { SubCommand::with_name("create-vote-account") .about("Create a vote account") .arg( - Arg::with_name("vote_account_pubkey") + Arg::with_name("vote_account") .index(1) - .value_name("VOTE ACCOUNT PUBKEY") + .value_name("VOTE ACCOUNT KEYPAIR") .takes_value(true) .required(true) - .validator(is_pubkey_or_keypair) - .help("Vote account address to fund"), + .validator(is_keypair) + .help("Vote account keypair to fund"), ) .arg( Arg::with_name("node_pubkey") @@ -161,7 +162,7 @@ impl VoteSubCommands for App<'_, '_> { } pub fn parse_vote_create_account(matches: &ArgMatches<'_>) -> Result { - let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap(); + let vote_account = keypair_of(matches, "vote_account").unwrap(); let node_pubkey = pubkey_of(matches, "node_pubkey").unwrap(); let commission = value_of(&matches, "commission").unwrap_or(0); let authorized_voter = pubkey_of(matches, "authorized_voter"); @@ -169,7 +170,7 @@ pub fn parse_vote_create_account(matches: &ArgMatches<'_>) -> Result) -> Result, authorized_withdrawer: &Option, commission: u8, ) -> ProcessResult { + let vote_account_pubkey = vote_account.pubkey(); check_unique_pubkeys( - (vote_account_pubkey, "vote_account_pubkey".to_string()), + (&vote_account_pubkey, "vote_account_pubkey".to_string()), (&node_pubkey, "node_pubkey".to_string()), )?; check_unique_pubkeys( (&config.keypair.pubkey(), "cli keypair".to_string()), - (vote_account_pubkey, "vote_account_pubkey".to_string()), + (&vote_account_pubkey, "vote_account_pubkey".to_string()), )?; let required_balance = rpc_client.get_minimum_balance_for_rent_exemption(VoteState::size_of())?; @@ -254,13 +256,13 @@ pub fn process_create_vote_account( }; let vote_init = VoteInit { node_pubkey: *node_pubkey, - authorized_voter: authorized_voter.unwrap_or(*vote_account_pubkey), + authorized_voter: authorized_voter.unwrap_or(vote_account_pubkey), authorized_withdrawer: authorized_withdrawer.unwrap_or(config.keypair.pubkey()), commission, }; let ixs = vote_instruction::create_account( &config.keypair.pubkey(), - vote_account_pubkey, + &vote_account_pubkey, &vote_init, lamports, ); @@ -430,11 +432,19 @@ pub fn process_uptime( mod tests { use super::*; use crate::cli::{app, parse_command}; + use solana_sdk::signature::write_keypair; + use tempfile::NamedTempFile; + + fn make_tmp_file() -> (String, NamedTempFile) { + let tmp_file = NamedTempFile::new().unwrap(); + (String::from(tmp_file.path().to_str().unwrap()), tmp_file) + } #[test] fn test_parse_command() { let test_commands = app("test", "desc", "version"); - let pubkey = Pubkey::new_rand(); + let keypair = Keypair::new(); + let pubkey = keypair.pubkey(); let pubkey_string = pubkey.to_string(); let test_authorize_voter = test_commands.clone().get_matches_from(vec![ @@ -451,13 +461,16 @@ mod tests { } ); + let (keypair_file, mut tmp_file) = make_tmp_file(); + let keypair = Keypair::new(); + write_keypair(&keypair, tmp_file.as_file_mut()).unwrap(); // Test CreateVoteAccount SubCommand let node_pubkey = Pubkey::new_rand(); let node_pubkey_string = format!("{}", node_pubkey); let test_create_vote_account = test_commands.clone().get_matches_from(vec![ "test", "create-vote-account", - &pubkey_string, + &keypair_file, &node_pubkey_string, "--commission", "10", @@ -466,7 +479,7 @@ mod tests { parse_command(&test_create_vote_account).unwrap(), CliCommandInfo { command: CliCommand::CreateVoteAccount { - vote_account_pubkey: pubkey, + vote_account: keypair, node_pubkey, authorized_voter: None, authorized_withdrawer: None, @@ -475,17 +488,22 @@ mod tests { require_keypair: true } ); + + let (keypair_file, mut tmp_file) = make_tmp_file(); + let keypair = Keypair::new(); + write_keypair(&keypair, tmp_file.as_file_mut()).unwrap(); + let test_create_vote_account2 = test_commands.clone().get_matches_from(vec![ "test", "create-vote-account", - &pubkey_string, + &keypair_file, &node_pubkey_string, ]); assert_eq!( parse_command(&test_create_vote_account2).unwrap(), CliCommandInfo { command: CliCommand::CreateVoteAccount { - vote_account_pubkey: pubkey, + vote_account: keypair, node_pubkey, authorized_voter: None, authorized_withdrawer: None, @@ -494,12 +512,17 @@ mod tests { require_keypair: true } ); + // test init with an authed voter let authed = Pubkey::new_rand(); + let (keypair_file, mut tmp_file) = make_tmp_file(); + let keypair = Keypair::new(); + write_keypair(&keypair, tmp_file.as_file_mut()).unwrap(); + let test_create_vote_account3 = test_commands.clone().get_matches_from(vec![ "test", "create-vote-account", - &pubkey_string, + &keypair_file, &node_pubkey_string, "--authorized-voter", &authed.to_string(), @@ -508,7 +531,7 @@ mod tests { parse_command(&test_create_vote_account3).unwrap(), CliCommandInfo { command: CliCommand::CreateVoteAccount { - vote_account_pubkey: pubkey, + vote_account: keypair, node_pubkey, authorized_voter: Some(authed), authorized_withdrawer: None, @@ -517,11 +540,15 @@ mod tests { require_keypair: true } ); + + let (keypair_file, mut tmp_file) = make_tmp_file(); + let keypair = Keypair::new(); + write_keypair(&keypair, tmp_file.as_file_mut()).unwrap(); // test init with an authed withdrawer let test_create_vote_account4 = test_commands.clone().get_matches_from(vec![ "test", "create-vote-account", - &pubkey_string, + &keypair_file, &node_pubkey_string, "--authorized-withdrawer", &authed.to_string(), @@ -530,7 +557,7 @@ mod tests { parse_command(&test_create_vote_account4).unwrap(), CliCommandInfo { command: CliCommand::CreateVoteAccount { - vote_account_pubkey: pubkey, + vote_account: keypair, node_pubkey, authorized_voter: None, authorized_withdrawer: Some(authed), diff --git a/multinode-demo/archiver.sh b/multinode-demo/archiver.sh index 4fca08fa9..9fa5df946 100755 --- a/multinode-demo/archiver.sh +++ b/multinode-demo/archiver.sh @@ -68,10 +68,9 @@ identity_pubkey=$($solana_keygen pubkey "$identity_keypair") if [[ ! -r $storage_keypair ]]; then $solana_keygen new -o "$storage_keypair" - storage_pubkey=$($solana_keygen pubkey "$storage_keypair") $solana_cli --keypair "$identity_keypair" --url "$rpc_url" \ - create-archiver-storage-account "$identity_pubkey" "$storage_pubkey" + create-archiver-storage-account "$identity_pubkey" "$storage_keypair" fi default_arg --entrypoint "$entrypoint"