Advanced Technical Topics: Token-2022, PDA, Multisig & Errors
Advanced technical guide covering transaction failures, Token-2022 specifics, PDA account management, hardware wallet integration, and error code interpretation.
#Why do transactions fail: technical reasons?
Even correctly formed transactions may not make it into a block. Understanding the reasons helps avoid wasting time and gas.
Solana Transaction Architecture
Each transaction in Solana has strict limits and time constraints:
- Maximum size: 1232 bytes (network packet MTU)
- Compute Units limit: 1,400,000 CU per transaction
- Lifetime: 150 slots (~60-90 seconds)
- Blockhash validity: Valid only for recent blocks
Transaction Expired: Most Common Error
What happened: Transaction contains reference to recent blockhash (block identifier). If more than 150 slots passed while waiting in queue, network rejects transaction as outdated.
Technical process:
- You form transaction with blockhash of block N
- Transaction waits for inclusion in block
- Network reaches block N+150
- Your blockhash is no longer in "recent blockhashes" list
- Validators reject transaction with "Blockhash not found" error
Why this happens:
Network congestion: During popular NFT mints or token hype, network receives millions of transactions. Priority Fee determines order.
Low Priority Fee: If you set minimum fee, validators will prioritize transactions with higher payment.
RPC problems: Public RPC nodes can be slow or lose connection.
Solution:
- ✅ Increase Priority Fee to "Medium" or "High" in wallet settings
- ✅ Retry after 1-2 minutes (blockhash updates automatically)
- ✅ Use private RPC endpoints (Helius, Triton) for stability
Important: Expired transaction doesn't deduct fee. Your funds are safe.
Account State Changed: Data Conflict
What happened: Between transaction formation and execution, account state changed.
Typical scenarios:
Scenario 1: Top-up during cleanup
- Scanner determined: account empty, balance = 0
- You form CloseAccount transaction
- Someone sends you 1 token to this account
- Transaction tries to close account with balance > 0
- Error: "Account has non-zero balance"
Scenario 2: Race condition with another transaction
- You sent token A swap on DEX
- Simultaneously sent token A account closing transaction
- Both transactions try to modify same account
- One passes, second rejected
Solution:
- ✅ Re-run scan - data will update
- ✅ Use tools with pre-flight simulation (check before sending)
- ✅ Avoid simultaneous operations with one token
Compute Budget Exceeded: Computation Limit Exceeded
What happened: Transaction tried to execute too complex operations, exceeding 1.4M Compute Units limit.
Causes:
- Too many instructions in batch: Trying to close 30-40 accounts at once
- Complex smart contracts: Some Token-2022 with extensions require more computation
- Nested program calls: Program A calls program B, which calls C
Solution:
- ✅ Reduce number of accounts in batch (close 15-20 instead of 25-30)
- ✅ Use tools that automatically optimize batch sizes
- ✅ Add
ComputeBudgetProgram.setComputeUnitLimit()instruction to increase limit
Technical detail: You can request up to 1,400,000 CU, but this requires proportionally higher Priority Fee:
Priority Fee = CU requested × Price per CU
Insufficient Lamports: Insufficient Funds
What happened: Insufficient SOL on balance to execute operation.
Non-obvious causes:
Rent-exempt minimum: If you try to transfer all SOL but have empty accounts open, wallet must preserve minimum to cover all accounts' rent.
Dynamic gas changes: During congestion, Priority Fee can grow 10-100x. Transaction formed with 0.000005 SOL gas calculation may require 0.0005 SOL.
Multiple transactions: You sent 5 transactions in a row, each reserves gas. Last one doesn't pass due to insufficient free funds.
Solution:
- ✅ Always keep minimum 0.01-0.02 SOL on balance
- ✅ Use "Advanced" mode in wallet to control gas reservation
- ✅ Send transactions sequentially, waiting for confirmation
#How does Token-2022 work and how to reclaim rent from it?
Token Extensions Program (Token-2022) is the evolution of classic SPL Token, launched in 2023.
Key Differences from SPL Token
SPL Token (classic):
- Program ID:
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - Fixed size: 165 bytes
- Basic functionality: transfer, mint, burn, approve
Token-2022:
- Program ID:
TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb - Variable size: 165-500+ bytes (depends on extensions)
- Extended functionality: 16+ additional capabilities
Main Extensions
Transfer Fee Extension:
Allows token creator to charge fee on each transfer.
Example:
Transfer 100 tokens
Fee: 2% = 2 tokens
Recipient receives: 98 tokens
Creator receives: 2 tokens fee
Impact on rent recovery: Accounts with Transfer Fee take more space → rent increases to ~0.0025 SOL.
Permanent Delegate:
Token creator appoints address that can transfer tokens from any wallet without owner consent.
Applications:
- Centralized stablecoins (USDC can freeze criminal funds)
- Game tokens (developer can confiscate on ban)
Risk: Creator has backdoor access to your funds.
Confidential Transfers:
Balance encryption using zero-knowledge proofs.
How it works:
- Only encrypted balance publicly visible
- Sender and receiver know real amounts
- Validators can verify correctness without disclosure
Account size: Up to 400 bytes → rent up to ~0.004 SOL
Non-Transferable Tokens:
Tokens that cannot be transferred (soulbound).
Applications:
- Certificates and diplomas
- Game achievements
- KYC tokens (identity verification)
Rent recovery specifics: Such tokens cannot be burned, but account can be closed if creator provided this function.
Why Old Tools Don't See Token-2022
Technical reason: Classic cleanup services use RPC method that returns only SPL tokens. Correct approach requires two separate queries for SPL and Token-2022 programs.
Token-2022 Rent Recovery
Recovery amounts (approximate):
- Basic Token-2022: ~0.00204 SOL (like SPL)
- With one extension: ~0.0025 SOL
- With two extensions: ~0.003 SOL
- With Confidential Transfers: ~0.004 SOL
Important: Actual amount depends on exact account size in bytes.
Closing process: Identical to SPL tokens - Burn remnants (if any), then CloseAccount instruction. Only difference: need to use correct Program ID when forming instruction.
#What are PDA accounts and can rent be recovered from them?
Program Derived Address (PDA) - accounts controlled by programs, not users.
What is PDA Technically
Regular account:
Private Key → Public Key (address)
Transaction signature = your private key
PDA:
Program ID + Seeds → Deterministic address
Transaction signature = program (via invoke_signed)
Key feature: PDA has no private key. Only program can sign operations on its behalf.
Where PDAs Are Used
Lending protocols (Solend, MarginFi):
When you deposit:
- Program creates PDA to store your collateral
- You're the owner but don't control directly
- Withdrawal only possible through program's withdraw() function
DEX (Raydium, Orca):
Open orders stored in PDAs - Order Book contains PDA of each open order. Cancel order = close PDA + return rent
Staking programs:
Your staked tokens sit in PDA - program controls unlock period, you cannot "steal" your own tokens before expiration
Can Rent Be Returned from PDA
Depends on program implementation.
If program provided Close Authority for user:
✅ You can close PDA and return rent
Examples: Outdated Serum DEX versions, old lending protocols
If program didn't provide:
❌ PDA remains open forever
Examples: Some staking programs create PDAs permanently
If funds still in use:
❌ Closing impossible until withdrawal
Example: Cannot close PDA with active loan in lending
How to Determine If You Can Return Rent
Step 1: Check Owner
Open account in Solscan and check if Owner is a known program (Raydium, Orca).
Step 2: Check Balance
If balance = only rent (no tokens/data), closing may be possible.
Step 3: Check Close Authority
Some explorers show Close Authority field. If it's your address - you can close.
Automatic Detection in Cleanup Tools
Quality services:
- Scan all accounts where you're Rent Payer
- Filter by programs with known logic
- Check balance and status via RPC
- Show only safe-to-close PDAs
Warning: Don't close PDAs manually without understanding. Can lose access to funds in protocol.
#How to use Ledger and hardware wallets for cleanup?
Hardware wallets provide maximum security but require additional steps for cleanup operations.
Why Ledger Blocks Complex Transactions
Screen limitation: Ledger Nano S/X has 128×64 pixel screen. It can show address (partially), transfer amount, and basic transaction info, but NOT details of 20 CloseAccount instructions, list of all affected accounts, or complex smart contract calls.
Protection mechanism: If Ledger cannot display transaction details, it rejects by default with error:
Condition of use not satisfied (0x6985)
What is Blind Signing
Blind Signing - mode where you allow Ledger to sign transactions without full detail display on screen.
How to enable:
- Connect Ledger to computer
- Open Solana app on device
- Press both buttons simultaneously to enter Settings
- Find "Blind signing" option
- Switch to "Enabled"
- Exit Settings
Important: This setting is inside Solana app on Ledger, not in Ledger Live on computer.
Blind Signing Risks
Loss of device verification: You don't see what you're signing. Theoretically, malicious site could send transaction transferring all SOL to hacker and closing your accounts - and you won't see this on Ledger screen.
How to minimize risks:
- ✅ Enable Blind Signing only for specific operation
- ✅ Use only verified services
- ✅ Check transaction simulation in Phantom/Solflare wallet (if using as interface)
- ✅ Disable Blind Signing immediately after use
Alternative Workflow Without Blind Signing
Method 1: Partial cleanup
Some simple operations don't require Blind Signing - closing 1-3 accounts per transaction, simple SPL tokens without extensions.
Method 2: Export via xpub
- Export extended public key from Ledger
- Import to hot wallet (watch-only)
- Do cleanup on hot wallet
- Send recovered SOL back to Ledger
Method 3: Create intermediate wallet
- Transfer funds to temporary hot wallet
- Do cleanup on hot wallet
- Return funds to Ledger
#How to reclaim rent from multisig wallets?
Multisignature wallets (Squads Protocol, Goki) use multiple keys to authorize transactions.
How Multisig Works in Solana
Structure:
Multisig Vault (PDA)
├── Signer 1: Alice (1/3 vote)
├── Signer 2: Bob (1/3 vote)
└── Signer 3: Charlie (1/3 vote)
Threshold: 2/3 (need signatures from two of three)
Transaction process:
- Alice creates Proposal: "Close 50 empty accounts"
- Bob reviews and Approves
- Threshold reached (2/3) → transaction executes automatically
- Charlie can Approve later (but unnecessary)
Why Regular Cleanup Tools Don't Work with Multisig
Problem: Standard services try to send transaction immediately after wallet connection. But in Multisig:
- One signature insufficient
- Need to create Proposal
- Wait for other signers
Technical moment: Multisig Vault is a PDA. Tokens stored not at signer addresses but in Vault. So scanning Alice's address shows 0 accounts, though Vault has hundreds.
Multisig Cleanup Workflow
Step 1: Scan Vault address
Find Multisig Vault address in Squads interface, paste into cleanup scanner (Read-Only).
Step 2: Export account list
Some advanced tools allow exporting list of token accounts to close.
Step 3: Create Proposal manually
In Squads interface:
- New Proposal → Custom Instruction
- Program: Token Program / Token-2022 Program
- Instruction: CloseAccount
- Account list: paste from export
- Create Proposal
Step 4: Collect signatures
Send Proposal link to other signers. After reaching threshold, transaction executes.
Automation for Multisig
Developers can create scripts using Squads SDK to automate proposal creation, signature collection, and execution. Cost includes gas for Proposal creation plus transaction execution gas.
#How to interpret common Solana error codes?
Solana uses numeric error codes that aren't always clear to users.
Common Error Codes During Cleanup
0x0 (Success): Not an error. Transaction executed successfully.
0x1 (Insufficient funds): Insufficient SOL for gas or rent-exempt minimum payment. Solution: Top up balance.
0x3 (Invalid account data): Account has incorrect data structure. Cause: Buggy token, corrupted metadata. Solution: Skip this account, close others.
0x7 (Account already in use): Another transaction simultaneously modifying this account. Solution: Wait 5-10 seconds, retry.
0xBB8 (3000 - Account not rent exempt): Attempt to create account without sufficient deposit. In cleanup context: Tool bug (rare error).
0x1771 (6001 - Custom program error): Error specific to particular program. Need to check error message details.
How to Get Error Details
In Phantom/Solflare:
After failed transaction appears:
Transaction failed
View in Explorer →
Click → opens Solscan with full log.
In Solscan:
- Find "Program Logs" section
- Look for lines with "Error:"
- Often has human-readable description
Example:
Program log: Error: Account has non-zero balance
Program TokenkegQf... failed: custom program error: 0x10
Interpretation: 0x10 = "Non-zero balance", cannot close account with tokens.