@@ -29,6 +29,7 @@ use solana_sdk::{
29
29
instruction:: Instruction ,
30
30
message:: Message ,
31
31
native_token:: * ,
32
+ program_option:: COption ,
32
33
program_pack:: Pack ,
33
34
pubkey:: Pubkey ,
34
35
signature:: { Keypair , Signer } ,
@@ -365,18 +366,67 @@ fn command_authorize(
365
366
account : Pubkey ,
366
367
authority_type : AuthorityType ,
367
368
new_owner : Option < Pubkey > ,
369
+ force_authorize : bool ,
368
370
) -> CommandResult {
369
371
let auth_str = match authority_type {
370
372
AuthorityType :: MintTokens => "mint authority" ,
371
373
AuthorityType :: FreezeAccount => "freeze authority" ,
372
374
AuthorityType :: AccountOwner => "owner" ,
373
375
AuthorityType :: CloseAccount => "close authority" ,
374
376
} ;
377
+ let target_account = config. rpc_client . get_account ( & account) ?;
378
+ let previous_authority = if let Ok ( mint) = Mint :: unpack ( & target_account. data ) {
379
+ match authority_type {
380
+ AuthorityType :: AccountOwner | AuthorityType :: CloseAccount => Err ( format ! (
381
+ "Authority type `{}` not supported for SPL Token mints" ,
382
+ auth_str
383
+ ) ) ,
384
+ AuthorityType :: MintTokens => Ok ( mint. mint_authority ) ,
385
+ AuthorityType :: FreezeAccount => Ok ( mint. freeze_authority ) ,
386
+ }
387
+ } else if let Ok ( token_account) = Account :: unpack ( & target_account. data ) {
388
+ let check_associated_token_account = || -> Result < ( ) , Error > {
389
+ let maybe_associated_token_account =
390
+ get_associated_token_address ( & config. owner , & token_account. mint ) ;
391
+ if account == maybe_associated_token_account
392
+ && !force_authorize
393
+ && Some ( config. owner ) != new_owner
394
+ {
395
+ Err (
396
+ format ! ( "Error: attempting to change the `{}` of an associated token account of `--owner`" , auth_str)
397
+ . into ( ) ,
398
+ )
399
+ } else {
400
+ Ok ( ( ) )
401
+ }
402
+ } ;
403
+
404
+ match authority_type {
405
+ AuthorityType :: MintTokens | AuthorityType :: FreezeAccount => Err ( format ! (
406
+ "Authority type `{}` not supported for SPL Token accounts" ,
407
+ auth_str
408
+ ) ) ,
409
+ AuthorityType :: AccountOwner => {
410
+ check_associated_token_account ( ) ?;
411
+ Ok ( COption :: Some ( token_account. owner ) )
412
+ }
413
+ AuthorityType :: CloseAccount => {
414
+ check_associated_token_account ( ) ?;
415
+ Ok ( COption :: Some (
416
+ token_account. close_authority . unwrap_or ( token_account. owner ) ,
417
+ ) )
418
+ }
419
+ }
420
+ } else {
421
+ Err ( "Unsupported account data format" . to_string ( ) )
422
+ } ?;
375
423
println ! (
376
424
"Updating {}\n Current {}: {}\n New {}: {}" ,
377
425
account,
378
426
auth_str,
379
- config. owner,
427
+ previous_authority
428
+ . map( |pubkey| pubkey. to_string( ) )
429
+ . unwrap_or_else( || "disabled" . to_string( ) ) ,
380
430
auth_str,
381
431
new_owner
382
432
. map( |pubkey| pubkey. to_string( ) )
@@ -1319,6 +1369,12 @@ fn main() {
1319
1369
. conflicts_with ( "new_authority" )
1320
1370
. help ( "Disable mint, freeze, or close functionality by setting authority to None." )
1321
1371
)
1372
+ . arg (
1373
+ Arg :: with_name ( "force" )
1374
+ . long ( "force" )
1375
+ . hidden ( true )
1376
+ . help ( "Force re-authorize the wallet's associate token account. Don't use this flag" ) ,
1377
+ )
1322
1378
. arg ( multisig_signer_arg ( ) )
1323
1379
. nonce_args ( true )
1324
1380
. offline_args ( ) ,
@@ -1862,7 +1918,14 @@ fn main() {
1862
1918
} ;
1863
1919
let new_authority =
1864
1920
pubkey_of_signer ( arg_matches, "new_authority" , & mut wallet_manager) . unwrap ( ) ;
1865
- command_authorize ( & config, address, authority_type, new_authority)
1921
+ let force_authorize = arg_matches. is_present ( "force" ) ;
1922
+ command_authorize (
1923
+ & config,
1924
+ address,
1925
+ authority_type,
1926
+ new_authority,
1927
+ force_authorize,
1928
+ )
1866
1929
}
1867
1930
( "transfer" , Some ( arg_matches) ) => {
1868
1931
let sender = pubkey_of_signer ( arg_matches, "sender" , & mut wallet_manager)
0 commit comments