Last active
April 8, 2024 22:02
-
-
Save belivenn/45aca827e19e40b5cbf1d6c1c05a81a5 to your computer and use it in GitHub Desktop.
Solana Stack Exchange Answer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use anchor_lang::prelude::*; | |
| use anchor_spl::{ | |
| token_interface::{TokenAccount, Mint, TokenInterface, TransferChecked, transfer_checked}, | |
| associated_token::AssociatedToken} | |
| }; | |
| declare_id!("exampleid00121312312312312312312"); | |
| #[program] | |
| pub mod SolanStackExchange { | |
| use super::*; | |
| //send tokens from ata to pda | |
| pub fn send_tokens(ctx: Context<SendTokens>, amount: u64) -> Result<()> { | |
| // send spls to pda | |
| ctx.accounts.send_spl_tokens_to_pda(amount) | |
| } | |
| // withdraw tokens from pda to ata | |
| pub fn withdraw_tokens_from_pda(ctx: Context<SendTokens>, amount: u64) -> Result<()> { | |
| // Withdraw tokens | |
| ctx.accounts.withdraw_tokens_from_pda(amount) | |
| } | |
| pub fn close_pda(ctx: Context<ClosePda>) -> Result<()> { | |
| // Close a pda account | |
| ctx.accounts.close_pda(&ctx.bumps) | |
| } | |
| } | |
| #[derive(Accounts)] | |
| pub struct SendTokens<'info> { | |
| #[account(mut)] | |
| //Signer | |
| owner: Signer<'info>, | |
| #[account( | |
| mut, | |
| associated_token::mint = mint, | |
| associated_token::authority = owner | |
| )] | |
| //Signer ATA | |
| owner_ata: InterfaceAccount<'info, TokenAccount>, | |
| #[account( | |
| mut, | |
| //Example seeds | |
| seeds = [b"vault", owner.key().as_ref(), mint.key().as_ref()], | |
| bump = pda.bump, | |
| token::mint = mint, | |
| token::authority = pda | |
| )] | |
| //PDA - VAULT | |
| pda: InterfaceAccount<'info, TokenAccount>, | |
| //SPL_TOKEN/TOKEN2022 | |
| mint: InterfaceAccount<'info, Mint>, | |
| token_program: Interface<'info, TokenInterface>, | |
| associated_token_program: Program<'info, AssociatedToken>, | |
| system_program: Program<'info, System> | |
| } | |
| impl<'info> SendTokens<'info> { | |
| pub fn send_spl_tokens_to_pda( | |
| &mut self, | |
| amount: u64 | |
| ) -> Result<()> { | |
| //Transfer Checked CPI, This works for SPLS AND TOKEN2022 | |
| let accounts = TransferChecked { | |
| from: self.owner_ata.to_account_info(), | |
| to: self.pda.to_account_info(), | |
| authority: self.owner.to_account_info(), | |
| mint: self.mint.to_account_info() | |
| }; | |
| let ctx = CpiContext::new( | |
| self.token_program.to_account_info(), | |
| accounts, | |
| ); | |
| transfer_checked(ctx, amount, self.mint.decimals) | |
| } | |
| pub fn withdraw_tokens_from_pda( | |
| &mut self, | |
| amount: u64 | |
| ) -> Result<()> { | |
| let accounts = TransferChecked { | |
| from: self.pda.to_account_info(), | |
| to: self.owner_ata.to_account_info(), | |
| authority: self.pda.to_account_info(), | |
| mint: self.mint.to_account_info() | |
| }; | |
| let seeds = &[ | |
| &b"pda"[..], | |
| &self.owner.key().to_bytes()[..], | |
| &self.mint.key().to_bytes()[..], | |
| &[self.pda.bump], | |
| ]; | |
| let signer_seeds = &[&seeds[..]]; | |
| let ctx = CpiContext::new_with_signer( | |
| self.token_program.to_account_info(), | |
| accounts, | |
| signer_seeds | |
| ); | |
| transfer_checked(ctx, amount, self.mint.decimals) | |
| } | |
| } | |
| #[derive(Accounts)] | |
| pub struct ClosePda<'info> { | |
| #[account(mut)] | |
| owner: Signer<'info>, | |
| #[account( | |
| mut, | |
| seeds = [b"pda"owner.key().as_ref(), mint.key().as_ref()], | |
| bump = pda.bump | |
| token::mint = mint, | |
| token::authority = pda | |
| )] | |
| pda: InterfaceAccount<'info, TokenAccount>, | |
| mint: InterfaceAccount<'info, Mint>, | |
| token_program: Interface<'info, TokenInterface>, | |
| associated_token_program: Program<'info, AssociatedToken>, | |
| system_program: Program<'info, System> | |
| } | |
| impl<'info> ClosePda<'info> { | |
| pub fn close_pda( | |
| &self | |
| ) -> Result<()> { | |
| let accounts = CloseAccount { | |
| account: self.pda.to_account_info(), | |
| destination: self.owner.to_account_info(), | |
| authority: self.owner.to_account_info() | |
| }; | |
| let seeds = &[ | |
| &b"pda"[..], | |
| &self.owner.key().to_bytes()[..], | |
| &self.mint.key().to_bytes()[..], | |
| &[self.pda.bump], | |
| ]; | |
| let signer_seeds = &[&seeds[..]]; | |
| let ctx = CpiContext::new_with_signer( | |
| self.token_program.to_account_info(), | |
| accounts, | |
| signer_seeds | |
| ); | |
| close_account(ctx) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment