@@ -555,6 +555,43 @@ fn command_revoke(config: &Config, account: Pubkey) -> CommandResult {
555
555
Ok ( Some ( transaction) )
556
556
}
557
557
558
+ fn command_close ( config : & Config , account : Pubkey , destination : Pubkey ) -> CommandResult {
559
+ let source_account = config
560
+ . rpc_client
561
+ . get_token_account_with_commitment ( & account, config. commitment_config ) ?
562
+ . value
563
+ . ok_or_else ( || format ! ( "Could not find token account {}" , account) ) ?;
564
+
565
+ if !source_account. is_native && source_account. token_amount . ui_amount > 0.0 {
566
+ return Err ( format ! (
567
+ "Account {} still has {} tokens; empty the account in order to close it." ,
568
+ account, source_account. token_amount. ui_amount
569
+ )
570
+ . into ( ) ) ;
571
+ }
572
+
573
+ let mut transaction = Transaction :: new_with_payer (
574
+ & [ close_account (
575
+ & spl_token:: id ( ) ,
576
+ & account,
577
+ & destination,
578
+ & config. owner . pubkey ( ) ,
579
+ & [ ] ,
580
+ ) ?] ,
581
+ Some ( & config. fee_payer . pubkey ( ) ) ,
582
+ ) ;
583
+
584
+ let ( recent_blockhash, fee_calculator) = config. rpc_client . get_recent_blockhash ( ) ?;
585
+ check_fee_payer_balance (
586
+ config,
587
+ fee_calculator. calculate_fee ( & transaction. message ( ) , None ) ,
588
+ ) ?;
589
+ let mut signers = vec ! [ config. fee_payer. as_ref( ) , config. owner. as_ref( ) ] ;
590
+ unique_signers ! ( signers) ;
591
+ transaction. sign ( & signers, recent_blockhash) ;
592
+ Ok ( Some ( transaction) )
593
+ }
594
+
558
595
fn command_balance ( config : & Config , address : Pubkey ) -> CommandResult {
559
596
let balance = config
560
597
. rpc_client
@@ -1089,6 +1126,28 @@ fn main() {
1089
1126
. help ( "The address of the token account" ) ,
1090
1127
) ,
1091
1128
)
1129
+ . subcommand (
1130
+ SubCommand :: with_name ( "close" )
1131
+ . about ( "Close a token account" )
1132
+ . arg (
1133
+ Arg :: with_name ( "account" )
1134
+ . validator ( is_pubkey_or_keypair)
1135
+ . value_name ( "TOKEN_ACCOUNT_ADDRESS" )
1136
+ . takes_value ( true )
1137
+ . index ( 1 )
1138
+ . required ( true )
1139
+ . help ( "The address of the token account to close" ) ,
1140
+ )
1141
+ . arg (
1142
+ Arg :: with_name ( "destination" )
1143
+ . validator ( is_pubkey_or_keypair)
1144
+ . value_name ( "TOKEN_ACCOUNT_ADDRESS" )
1145
+ . takes_value ( true )
1146
+ . index ( 2 )
1147
+ . required ( true )
1148
+ . help ( "The address of the account to receive remaining SOL" ) ,
1149
+ ) ,
1150
+ )
1092
1151
. get_matches ( ) ;
1093
1152
1094
1153
let mut wallet_manager = None ;
@@ -1241,6 +1300,11 @@ fn main() {
1241
1300
let account = pubkey_of ( arg_matches, "account" ) . unwrap ( ) ;
1242
1301
command_revoke ( & config, account)
1243
1302
}
1303
+ ( "close" , Some ( arg_matches) ) => {
1304
+ let account = pubkey_of ( arg_matches, "account" ) . unwrap ( ) ;
1305
+ let destination = pubkey_of ( arg_matches, "destination" ) . unwrap ( ) ;
1306
+ command_close ( & config, account, destination)
1307
+ }
1244
1308
( "balance" , Some ( arg_matches) ) => {
1245
1309
let address = pubkey_of ( arg_matches, "address" ) . unwrap ( ) ;
1246
1310
command_balance ( & config, address)
0 commit comments