'How do I close an account, empty the rent into a wrapped sol account, and then sync it?
I have an account that stores some data and is owned by my Solana program. I'd like to implement a Close
instruction that "closes" the account and transfers the remaining native-SOL into a wrapped-SOL token account, and then call spl-token's sync_native instruction.
If I try to use the SystemProgram's Transfer
instruction, I hit the error in the processor that says Transfer: from must not carry data
.
So instead, I just do this:
let dest_starting_lamports = dest_account_info.lamports();
**dest_account_info.lamports.borrow_mut() = dest_starting_lamports
.checked_add(source_account_info.lamports())
.unwrap();
**source_account_info.lamports.borrow_mut() = 0;
However, if I later call sync_native
via CPI anywhere in the same instruction, I get an error:
sum of account balances before and after instruction do not match
Is it possible to both modify the lamport values (transfer) of accounts AND call a CPI instruction? Or alternatively, is there a way to close the account with the SystemProgram?
Solution 1:[1]
This may be a bug in the runtime, because otherwise it looks like you're doing everything correctly. The only time this should fail is if dest_account_info
and source_account_info
are the same, but you mentioned that the sync_native
is what caused the problem.
As a workaround, you can have sync_native
done as a separate instruction in the transaction rather than as a CPI.
Solution 2:[2]
Okay So here I want to figure it out that CPI in a single instructions causes conflict with each other as in my case I was using token program and system program in a single instruction and I figured it out that token program CPI should be done above the system program CPI.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jon C |
Solution 2 | Hamza Sajid |