Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit a7f6f88

Browse files
authored
token-cli: Only require default signer for commands which use it (#3293)
1 parent 6e81794 commit a7f6f88

File tree

3 files changed

+245
-117
lines changed

3 files changed

+245
-117
lines changed

token/cli/src/bench.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ async fn command_create_accounts(
302302
messages.push(Message::new(
303303
&[
304304
system_instruction::create_account_with_seed(
305-
&config.fee_payer.pubkey(),
305+
&config.fee_payer()?.pubkey(),
306306
address,
307307
owner,
308308
seed,
@@ -312,7 +312,7 @@ async fn command_create_accounts(
312312
),
313313
instruction::initialize_account(&program_id, address, token, owner)?,
314314
],
315-
Some(&config.fee_payer.pubkey()),
315+
Some(&config.fee_payer()?.pubkey()),
316316
));
317317
}
318318
}
@@ -358,7 +358,7 @@ async fn command_close_accounts(
358358
owner,
359359
&[],
360360
)?],
361-
Some(&config.fee_payer.pubkey()),
361+
Some(&config.fee_payer()?.pubkey()),
362362
));
363363
}
364364
}
@@ -415,7 +415,7 @@ async fn command_deposit_into_or_withdraw_from(
415415
amount,
416416
mint_info.decimals,
417417
)?],
418-
Some(&config.fee_payer.pubkey()),
418+
Some(&config.fee_payer()?.pubkey()),
419419
));
420420
} else {
421421
eprintln!("Token account does not exist: {}", address)

token/cli/src/config.rs

Lines changed: 70 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ pub(crate) struct MintInfo {
3131
}
3232

3333
pub(crate) struct Config<'a> {
34-
pub(crate) default_signer: Arc<dyn Signer>,
34+
pub(crate) default_signer: Option<Arc<dyn Signer>>,
3535
pub(crate) rpc_client: Arc<RpcClient>,
3636
pub(crate) program_client: Arc<dyn ProgramClient<ProgramRpcClientSendTransaction>>,
3737
pub(crate) websocket_url: String,
3838
pub(crate) output_format: OutputFormat,
39-
pub(crate) fee_payer: Arc<dyn Signer>,
39+
pub(crate) fee_payer: Option<Arc<dyn Signer>>,
4040
pub(crate) nonce_account: Option<Pubkey>,
4141
pub(crate) nonce_authority: Option<Pubkey>,
4242
pub(crate) sign_only: bool,
@@ -134,9 +134,10 @@ impl<'a> Config<'a> {
134134

135135
let default_keypair = cli_config.keypair_path.clone();
136136

137-
let default_signer: Arc<dyn Signer> = {
137+
let default_signer: Option<Arc<dyn Signer>> = {
138138
if let Some(owner_path) = matches.value_of("owner") {
139139
signer_from_path_with_config(matches, owner_path, "owner", wallet_manager, &config)
140+
.ok()
140141
} else {
141142
signer_from_path_with_config(
142143
matches,
@@ -145,23 +146,32 @@ impl<'a> Config<'a> {
145146
wallet_manager,
146147
&config,
147148
)
149+
.map_err(|e| {
150+
if std::fs::metadata(&default_keypair).is_ok() {
151+
eprintln!("error: {}", e);
152+
exit(1);
153+
} else {
154+
e
155+
}
156+
})
157+
.ok()
148158
}
149159
}
150-
.map(Arc::from)
151-
.unwrap_or_else(|e| {
152-
eprintln!("error: {}", e);
153-
exit(1);
154-
});
160+
.map(Arc::from);
155161

156-
let fee_payer = matches
162+
let fee_payer: Option<Arc<dyn Signer>> = matches
157163
.value_of("fee_payer")
158-
.map_or(Ok(default_signer.clone()), |path| {
159-
signer_from_path(matches, path, "fee_payer", wallet_manager).map(Arc::from)
164+
.map(|path| {
165+
Arc::from(
166+
signer_from_path(matches, path, "fee_payer", wallet_manager).unwrap_or_else(
167+
|e| {
168+
eprintln!("error: {}", e);
169+
exit(1);
170+
},
171+
),
172+
)
160173
})
161-
.unwrap_or_else(|e| {
162-
eprintln!("error: {}", e);
163-
exit(1);
164-
});
174+
.or_else(|| default_signer.clone());
165175

166176
let verbose = matches.is_present("verbose");
167177
let output_format = matches
@@ -253,14 +263,38 @@ impl<'a> Config<'a> {
253263
}
254264
}
255265

266+
// Returns Ok(default signer), or Err if there is no default signer configured
267+
pub(crate) fn default_signer(&self) -> Result<Arc<dyn Signer>, Error> {
268+
if let Some(default_signer) = &self.default_signer {
269+
Ok(default_signer.clone())
270+
} else {
271+
Err("default signer is required, please specify a valid default signer by identifying a \
272+
valid configuration file using the --config-file argument, or by creating a valid \
273+
config at the default location of ~/.config/solana/cli/config.yml using the solana \
274+
config command".to_string().into())
275+
}
276+
}
277+
278+
// Returns Ok(fee payer), or Err if there is no fee payer configured
279+
pub(crate) fn fee_payer(&self) -> Result<Arc<dyn Signer>, Error> {
280+
if let Some(fee_payer) = &self.fee_payer {
281+
Ok(fee_payer.clone())
282+
} else {
283+
Err("fee payer is required, please specify a valid fee payer using the --fee_payer argument, \
284+
or by identifying a valid configuration file using the --config-file argument, or by \
285+
creating a valid config at the default location of ~/.config/solana/cli/config.yml using \
286+
the solana config command".to_string().into())
287+
}
288+
}
289+
256290
// Check if an explicit token account address was provided, otherwise
257291
// return the associated token address for the default address.
258292
pub(crate) async fn associated_token_address_or_override(
259293
&self,
260294
arg_matches: &ArgMatches<'_>,
261295
override_name: &str,
262296
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
263-
) -> Pubkey {
297+
) -> Result<Pubkey, Error> {
264298
let token = pubkey_of_signer(arg_matches, "token", wallet_manager).unwrap();
265299
self.associated_token_address_for_token_or_override(
266300
arg_matches,
@@ -279,42 +313,42 @@ impl<'a> Config<'a> {
279313
override_name: &str,
280314
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
281315
token: Option<Pubkey>,
282-
) -> Pubkey {
316+
) -> Result<Pubkey, Error> {
283317
if let Some(address) = pubkey_of_signer(arg_matches, override_name, wallet_manager).unwrap()
284318
{
285-
return address;
319+
return Ok(address);
286320
}
287321

288322
let token = token.unwrap();
289323
let program_id = self.get_mint_info(&token, None).await.unwrap().program_id;
290-
self.associated_token_address_for_token_and_program(&token, &program_id)
324+
let owner = self.pubkey_or_default(arg_matches, "owner", wallet_manager)?;
325+
self.associated_token_address_for_token_and_program(&token, &owner, &program_id)
291326
}
292327

293328
pub(crate) fn associated_token_address_for_token_and_program(
294329
&self,
295330
token: &Pubkey,
331+
owner: &Pubkey,
296332
program_id: &Pubkey,
297-
) -> Pubkey {
298-
let owner = self.default_signer.pubkey();
299-
get_associated_token_address_with_program_id(&owner, token, program_id)
333+
) -> Result<Pubkey, Error> {
334+
Ok(get_associated_token_address_with_program_id(
335+
owner, token, program_id,
336+
))
300337
}
301338

302-
// Checks if an explicit address was provided, otherwise return the default address.
339+
// Checks if an explicit address was provided, otherwise return the default address if there is one
303340
pub(crate) fn pubkey_or_default(
304341
&self,
305-
arg_matches: &ArgMatches,
342+
arg_matches: &ArgMatches<'_>,
306343
address_name: &str,
307344
wallet_manager: &mut Option<Arc<RemoteWalletManager>>,
308-
) -> Pubkey {
309-
if address_name != "owner" {
310-
if let Some(address) =
311-
pubkey_of_signer(arg_matches, address_name, wallet_manager).unwrap()
312-
{
313-
return address;
314-
}
345+
) -> Result<Pubkey, Error> {
346+
if let Some(address) = pubkey_of_signer(arg_matches, address_name, wallet_manager).unwrap()
347+
{
348+
return Ok(address);
315349
}
316350

317-
self.default_signer.pubkey()
351+
Ok(self.default_signer()?.pubkey())
318352
}
319353

320354
// Checks if an explicit signer was provided, otherwise return the default signer.
@@ -329,7 +363,7 @@ impl<'a> Config<'a> {
329363
let config = SignerFromPathConfig {
330364
allow_null_signer: !self.multisigner_pubkeys.is_empty(),
331365
};
332-
let mut load_authority = move || -> Result<Arc<dyn Signer>, _> {
366+
let mut load_authority = move || -> Result<Arc<dyn Signer>, Error> {
333367
if authority_name != "owner" {
334368
if let Some(keypair_path) = arg_matches.value_of(authority_name) {
335369
return signer_from_path_with_config(
@@ -339,11 +373,12 @@ impl<'a> Config<'a> {
339373
wallet_manager,
340374
&config,
341375
)
342-
.map(Arc::from);
376+
.map(Arc::from)
377+
.map_err(|e| e.to_string().into());
343378
}
344379
}
345380

346-
Ok(self.default_signer.clone())
381+
self.default_signer()
347382
};
348383

349384
let authority = load_authority().unwrap_or_else(|e| {

0 commit comments

Comments
 (0)