@@ -31,12 +31,12 @@ pub(crate) struct MintInfo {
31
31
}
32
32
33
33
pub ( crate ) struct Config < ' a > {
34
- pub ( crate ) default_signer : Arc < dyn Signer > ,
34
+ pub ( crate ) default_signer : Option < Arc < dyn Signer > > ,
35
35
pub ( crate ) rpc_client : Arc < RpcClient > ,
36
36
pub ( crate ) program_client : Arc < dyn ProgramClient < ProgramRpcClientSendTransaction > > ,
37
37
pub ( crate ) websocket_url : String ,
38
38
pub ( crate ) output_format : OutputFormat ,
39
- pub ( crate ) fee_payer : Arc < dyn Signer > ,
39
+ pub ( crate ) fee_payer : Option < Arc < dyn Signer > > ,
40
40
pub ( crate ) nonce_account : Option < Pubkey > ,
41
41
pub ( crate ) nonce_authority : Option < Pubkey > ,
42
42
pub ( crate ) sign_only : bool ,
@@ -134,9 +134,10 @@ impl<'a> Config<'a> {
134
134
135
135
let default_keypair = cli_config. keypair_path . clone ( ) ;
136
136
137
- let default_signer: Arc < dyn Signer > = {
137
+ let default_signer: Option < Arc < dyn Signer > > = {
138
138
if let Some ( owner_path) = matches. value_of ( "owner" ) {
139
139
signer_from_path_with_config ( matches, owner_path, "owner" , wallet_manager, & config)
140
+ . ok ( )
140
141
} else {
141
142
signer_from_path_with_config (
142
143
matches,
@@ -145,23 +146,32 @@ impl<'a> Config<'a> {
145
146
wallet_manager,
146
147
& config,
147
148
)
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 ( )
148
158
}
149
159
}
150
- . map ( Arc :: from)
151
- . unwrap_or_else ( |e| {
152
- eprintln ! ( "error: {}" , e) ;
153
- exit ( 1 ) ;
154
- } ) ;
160
+ . map ( Arc :: from) ;
155
161
156
- let fee_payer = matches
162
+ let fee_payer: Option < Arc < dyn Signer > > = matches
157
163
. 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
+ )
160
173
} )
161
- . unwrap_or_else ( |e| {
162
- eprintln ! ( "error: {}" , e) ;
163
- exit ( 1 ) ;
164
- } ) ;
174
+ . or_else ( || default_signer. clone ( ) ) ;
165
175
166
176
let verbose = matches. is_present ( "verbose" ) ;
167
177
let output_format = matches
@@ -253,14 +263,38 @@ impl<'a> Config<'a> {
253
263
}
254
264
}
255
265
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
+
256
290
// Check if an explicit token account address was provided, otherwise
257
291
// return the associated token address for the default address.
258
292
pub ( crate ) async fn associated_token_address_or_override (
259
293
& self ,
260
294
arg_matches : & ArgMatches < ' _ > ,
261
295
override_name : & str ,
262
296
wallet_manager : & mut Option < Arc < RemoteWalletManager > > ,
263
- ) -> Pubkey {
297
+ ) -> Result < Pubkey , Error > {
264
298
let token = pubkey_of_signer ( arg_matches, "token" , wallet_manager) . unwrap ( ) ;
265
299
self . associated_token_address_for_token_or_override (
266
300
arg_matches,
@@ -279,42 +313,42 @@ impl<'a> Config<'a> {
279
313
override_name : & str ,
280
314
wallet_manager : & mut Option < Arc < RemoteWalletManager > > ,
281
315
token : Option < Pubkey > ,
282
- ) -> Pubkey {
316
+ ) -> Result < Pubkey , Error > {
283
317
if let Some ( address) = pubkey_of_signer ( arg_matches, override_name, wallet_manager) . unwrap ( )
284
318
{
285
- return address;
319
+ return Ok ( address) ;
286
320
}
287
321
288
322
let token = token. unwrap ( ) ;
289
323
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)
291
326
}
292
327
293
328
pub ( crate ) fn associated_token_address_for_token_and_program (
294
329
& self ,
295
330
token : & Pubkey ,
331
+ owner : & Pubkey ,
296
332
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
+ ) )
300
337
}
301
338
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
303
340
pub ( crate ) fn pubkey_or_default (
304
341
& self ,
305
- arg_matches : & ArgMatches ,
342
+ arg_matches : & ArgMatches < ' _ > ,
306
343
address_name : & str ,
307
344
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) ;
315
349
}
316
350
317
- self . default_signer . pubkey ( )
351
+ Ok ( self . default_signer ( ) ? . pubkey ( ) )
318
352
}
319
353
320
354
// Checks if an explicit signer was provided, otherwise return the default signer.
@@ -329,7 +363,7 @@ impl<'a> Config<'a> {
329
363
let config = SignerFromPathConfig {
330
364
allow_null_signer : !self . multisigner_pubkeys . is_empty ( ) ,
331
365
} ;
332
- let mut load_authority = move || -> Result < Arc < dyn Signer > , _ > {
366
+ let mut load_authority = move || -> Result < Arc < dyn Signer > , Error > {
333
367
if authority_name != "owner" {
334
368
if let Some ( keypair_path) = arg_matches. value_of ( authority_name) {
335
369
return signer_from_path_with_config (
@@ -339,11 +373,12 @@ impl<'a> Config<'a> {
339
373
wallet_manager,
340
374
& config,
341
375
)
342
- . map ( Arc :: from) ;
376
+ . map ( Arc :: from)
377
+ . map_err ( |e| e. to_string ( ) . into ( ) ) ;
343
378
}
344
379
}
345
380
346
- Ok ( self . default_signer . clone ( ) )
381
+ self . default_signer ( )
347
382
} ;
348
383
349
384
let authority = load_authority ( ) . unwrap_or_else ( |e| {
0 commit comments