Docs
How Sweepra works, what it touches, and how to do the same thing without it.
What is rent?
Every account on Solana must hold a minimum balance of SOL so the network can store its data. This is called rent exemption. It is not a fee that is spent — it is a deposit held inside the account.
A standard SPL token account is 165 bytes, which requires 2,039,280 lamports (0.00203928 SOL). Token-2022 accounts that use extensions are larger and require a little more.
Why empty accounts lock SOL
Receiving a token creates a token account for it. Selling or sending the full balance leaves the account open with a zero balance, and the deposit stays locked inside until the account is closed. Closing it returns the full lamport balance to the destination you choose.
What Sweepra closes, burns and revokes
- Close — token accounts with a zero balance. The rent goes to your own wallet.
- Burn + close — tokens you explicitly select, or that fall under your dust threshold. The tokens are destroyed, then the account is closed.
- Revoke — removes a delegate approval so another address can no longer spend from that account.
- Unwrap — a wrapped SOL account is closed and its SOL returns to your wallet.
What Sweepra never does
- It never holds your keys or funds and never signs on your behalf.
- It never charges a fee. Only the standard Solana network fee (and optional priority fee) is paid.
- It never touches accounts classified as Keep unless you select them yourself, and it asks you to confirm any burn.
- It cannot close frozen accounts or accounts blocked by Token-2022 extensions, and it tells you why.
Verifying every transaction
Each batch shows its signature as soon as it is sent. Open it on Solscan and check the instructions: you should only see CloseAccount, Burn or Revoke instructions from your wallet, with your wallet as the destination for closed accounts. Your wallet also shows a simulation before you approve.
Close empty accounts without Sweepra
A standalone TypeScript script using @solana/web3.js and @solana/spl-token. Run it with a keypair you control.
import { Connection, Keypair, PublicKey, Transaction, sendAndConfirmTransaction } from '@solana/web3.js'
import { createCloseAccountInstruction, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID } from '@solana/spl-token'
const connection = new Connection('https://api.mainnet-beta.solana.com', 'confirmed')
const owner = Keypair.fromSecretKey(/* your secret key bytes */)
async function closeEmptyAccounts() {
for (const programId of [TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID]) {
const { value } = await connection.getParsedTokenAccountsByOwner(owner.publicKey, { programId })
const empty = value.filter((a) => a.account.data.parsed.info.tokenAmount.amount === '0')
for (let i = 0; i < empty.length; i += 20) {
const tx = new Transaction()
for (const acc of empty.slice(i, i + 20)) {
tx.add(createCloseAccountInstruction(acc.pubkey, owner.publicKey, owner.publicKey, [], programId))
}
const sig = await sendAndConfirmTransaction(connection, tx, [owner])
console.log('closed', Math.min(20, empty.length - i), 'accounts:', sig)
}
}
}
closeEmptyAccounts()