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

Commit 81c90f5

Browse files
MarkSackerbergjoncinqueMark Sackerberg
authored
Allow GC to close empty associated accounts (#2554)
* Allow GC to close empty associated accounts Empty associated accounts will only be closed in case the new flag del_associated_accounts is set. Otherwise behaviour is as before. Useage: spl-token gc --del_associated_accounts * use kebab-case Co-authored-by: Jon Cinque <[email protected]> * align coding style Thank you jon! * Add sanity check * correcting amount check before closing * formatting correcly using cargo fmt * changing sanity check to assert! Co-authored-by: Sack <none> Co-authored-by: Jon Cinque <[email protected]> Co-authored-by: Mark Sackerberg <Contact@Discord>
1 parent fcbc0d3 commit 81c90f5

File tree

1 file changed

+33
-6
lines changed

1 file changed

+33
-6
lines changed

token/cli/src/main.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,7 +1214,11 @@ fn command_multisig(config: &Config, address: Pubkey) -> CommandResult {
12141214
Ok(None)
12151215
}
12161216

1217-
fn command_gc(config: &Config, owner: Pubkey) -> CommandResult {
1217+
fn command_gc(
1218+
config: &Config,
1219+
owner: Pubkey,
1220+
close_empty_associated_accounts: bool,
1221+
) -> CommandResult {
12181222
println_display(config, "Fetching token accounts".to_string());
12191223
let accounts = config
12201224
.rpc_client
@@ -1295,9 +1299,18 @@ fn command_gc(config: &Config, owner: Pubkey) -> CommandResult {
12951299
}
12961300

12971301
for (address, (amount, decimals, frozen, close_authority)) in accounts {
1298-
if address == associated_token_account {
1299-
// leave the associated token account alone
1300-
continue;
1302+
match (
1303+
address == associated_token_account,
1304+
close_empty_associated_accounts,
1305+
total_balance > 0,
1306+
) {
1307+
(true, _, true) => continue, // don't ever close associated token account with amount
1308+
(true, false, _) => continue, // don't close associated token account if close_empty_associated_accounts isn't set
1309+
(true, true, false) => println_display(
1310+
config,
1311+
format!("Closing Account {}", associated_token_account),
1312+
),
1313+
_ => {}
13011314
}
13021315

13031316
if frozen {
@@ -1307,8 +1320,12 @@ fn command_gc(config: &Config, owner: Pubkey) -> CommandResult {
13071320

13081321
let mut account_instructions = vec![];
13091322

1310-
// Transfer the account balance into the associated token account
1323+
// Sanity check!
1324+
// we shouldn't ever be here, but if we are here, abort!
1325+
assert!(amount == 0 || address != associated_token_account);
1326+
13111327
if amount > 0 {
1328+
// Transfer the account balance into the associated token account
13121329
account_instructions.push(transfer_checked(
13131330
&spl_token::id(),
13141331
&address,
@@ -2128,6 +2145,12 @@ fn main() {
21282145
SubCommand::with_name("gc")
21292146
.about("Cleanup unnecessary token accounts")
21302147
.arg(owner_keypair_arg())
2148+
.arg(
2149+
Arg::with_name("close_empty_associated_accounts")
2150+
.long("close-empty-associated-accounts")
2151+
.takes_value(false)
2152+
.help("close all empty associated token accounts (to get SOL back)")
2153+
)
21312154
)
21322155
.subcommand(
21332156
SubCommand::with_name("sync-native")
@@ -2609,11 +2632,15 @@ fn main() {
26092632
}
26102633
_ => {}
26112634
}
2635+
2636+
let close_empty_associated_accounts =
2637+
matches.is_present("close_empty_associated_accounts");
2638+
26122639
let (owner_signer, owner_address) =
26132640
config.signer_or_default(arg_matches, "owner", &mut wallet_manager);
26142641
bulk_signers.push(owner_signer);
26152642

2616-
command_gc(&config, owner_address)
2643+
command_gc(&config, owner_address, close_empty_associated_accounts)
26172644
}
26182645
("sync-native", Some(arg_matches)) => {
26192646
let address = config.associated_token_address_for_token_or_override(

0 commit comments

Comments
 (0)