diff --git a/cli/src/stake.rs b/cli/src/stake.rs index bced64474..9b40e6491 100644 --- a/cli/src/stake.rs +++ b/cli/src/stake.rs @@ -672,16 +672,6 @@ pub fn process_create_stake_account( fee_payer: Option<&dyn Signer>, from: Option<&dyn Signer>, ) -> ProcessResult { - // Offline derived address creation currently is not possible - // https://github.com/solana-labs/solana/pull/8252 - if seed.is_some() && sign_only { - return Err(CliError::BadParameter( - "Offline stake account creation with derived addresses are not yet supported" - .to_string(), - ) - .into()); - } - let stake_account_address = if let Some(seed) = seed { create_address_with_seed(&stake_account.pubkey(), &seed, &solana_stake_program::id())? } else { diff --git a/cli/tests/stake.rs b/cli/tests/stake.rs index 5c2188270..526cb4b0e 100644 --- a/cli/tests/stake.rs +++ b/cli/tests/stake.rs @@ -1380,10 +1380,19 @@ fn test_offline_nonced_create_stake_account_and_withdraw() { process_command(&config).unwrap(); check_balance(42, &rpc_client, &recipient_pubkey); - // Test that offline derived addresses fail + // Fetch nonce hash + let account = rpc_client.get_account(&nonce_account.pubkey()).unwrap(); + let nonce_state: NonceState = account.state().unwrap(); + let nonce_hash = match nonce_state { + NonceState::Initialized(_meta, hash) => hash, + _ => panic!("Nonce is not initialized"), + }; + + // Create another stake account. This time with seed + let seed = "seedy"; config_offline.command = CliCommand::CreateStakeAccount { stake_account: Rc::new(Box::new(read_keypair_file(&stake_keypair_file).unwrap())), - seed: Some("fail".to_string()), + seed: Some(seed.to_string()), staker: None, withdrawer: None, lockup: Lockup::default(), @@ -1395,7 +1404,28 @@ fn test_offline_nonced_create_stake_account_and_withdraw() { fee_payer: None, from: None, }; - process_command(&config_offline).unwrap_err(); + let sig_response = process_command(&config_offline).unwrap(); + let (blockhash, signers) = parse_sign_only_reply_string(&sig_response); + let offline_presigner = presigner_from_pubkey_sigs(&offline_pubkey, &signers).unwrap(); + let stake_presigner = presigner_from_pubkey_sigs(&stake_pubkey, &signers).unwrap(); + config.command = CliCommand::CreateStakeAccount { + stake_account: Rc::new(stake_presigner.into()), + seed: Some(seed.to_string()), + staker: Some(offline_pubkey.into()), + withdrawer: Some(offline_pubkey.into()), + lockup: Lockup::default(), + lamports: 50_000, + sign_only: false, + blockhash_query: BlockhashQuery::FeeCalculator(blockhash), + nonce_account: Some(nonce_pubkey), + nonce_authority: Some(offline_presigner.clone().into()), + fee_payer: Some(offline_presigner.clone().into()), + from: Some(offline_presigner.clone().into()), + }; + process_command(&config).unwrap(); + let seed_address = + create_address_with_seed(&stake_pubkey, seed, &solana_stake_program::id()).unwrap(); + check_balance(50_000, &rpc_client, &seed_address); server.close().unwrap(); remove_dir_all(ledger_path).unwrap();