Keeping in mind the potential applications for this feature, I followed the very clever and optimized approach from Metaplex.
With this instruction, we prioritize checks on the delegate rather than solely focusing on the NFT Account owner. This choice aims to craft an instruction that prevents users from unstaking their NFTs without the delegate's intervention. The delegate should be a Program Derived Address (PDA) of the Staking program where it will be used.
We start with a first assertion to check that the freeze_authorithy is the manager PDA:
Then we leverage the way that the Token Account & FreezeAccount instruction work since:
Token Accounts can have only one Delegate at a time.
Token Accounts cannot change the delegate account while they are frozen.
This will give us all the checks that we need to make sure that the only account that can unfreeze this Token Account is the current Delegate without having to save it on an external PDA.
So for this assertion, we just check that the signer passed in is the delegate_authority of the Token Account
To finish off this instruction we then use the Freeze instruction to freeze the NFT in place:
let cpi_accounts = FreezeAccount {
account: self.mint_token_account.to_account_info(),
mint: self.mint.to_account_info(),
authority: self.manager.to_account_info(),
};
let cpi_ctx = CpiContext::new_with_signer(self.token_program.to_account_info(), cpi_accounts, signer_seeds);
freeze_account(cpi_ctx)?;
The only way this NFT can be unfrozen will be if the current delegate of the Token Account uses the Thaw instruction.
Burn
We decided to add a burn instruction because the authority of the CloseMintAccount Extension is the Manager PDA. So to close it forever we need to CPI inside the WNS program.
This instruction:
Burn the Token
Close the Token Account where the mint was contained
Close the Mint Account forever
In the future, once we add a collection_auth as the group extension authority we should be able to decrease the amount of NFT in a group.
Thaw & Freeze Instruction
Keeping in mind the potential applications for this feature, I followed the very clever and optimized approach from Metaplex.
With this instruction, we prioritize checks on the delegate rather than solely focusing on the NFT Account owner. This choice aims to craft an instruction that prevents users from unstaking their NFTs without the delegate's intervention. The delegate should be a Program Derived Address (PDA) of the Staking program where it will be used.
We start with a first assertion to check that the freeze_authorithy is the manager PDA:
Then we leverage the way that the Token Account & FreezeAccount instruction work since:
Token Accounts cannot change the delegate account while they are frozen. This will give us all the checks that we need to make sure that the only account that can unfreeze this Token Account is the current Delegate without having to save it on an external PDA.
So for this assertion, we just check that the signer passed in is the delegate_authority of the Token Account
To finish off this instruction we then use the Freeze instruction to freeze the NFT in place:
The only way this NFT can be unfrozen will be if the current delegate of the Token Account uses the Thaw instruction.
Burn
We decided to add a burn instruction because the authority of the CloseMintAccount Extension is the Manager PDA. So to close it forever we need to CPI inside the WNS program.
This instruction:
In the future, once we add a collection_auth as the group extension authority we should be able to decrease the amount of NFT in a group.