So I had this account as a PDA and used this account Program as Signers, and it was working fine you can see the transaction history and then suddenly I'm getting Signature verification failed error whenever I try to run my program and after some debugging I've found the my PDA does not exists.
3 Answers
can you please update your question to be more specific in what you want to do. Your explorer link just points to a normal account so its not a PDA and its not intialized. From your comments it looks like you want to transfer a token from a token account where the owner is a PDA. Here is a complete example on how to transfer a token into a vault and out using a PDA as vault authority:
use anchor_lang::prelude::*;
use anchor_spl::token::{Mint, Token, TokenAccount, Transfer};
// This is your program's public key and it will update
// automatically when you build the project.
declare_id!("HCLBrPG3A9agLsVE3j1BCBRUfv9jc1juk5Wt888ZDDsV");
#[program]
mod token_vault {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
Ok(())
}
pub fn transfer_in(ctx: Context<TransferIn>, data: u64) -> Result<()> {
msg!("Tokens to transfer: {}!", data);
// Below is the actual instruction that we are going to send to the Token program.
let transfer_instruction = Transfer {
from: ctx.accounts.sender_token_account.to_account_info(),
to: ctx.accounts.vault_token_account.to_account_info(),
authority: ctx.accounts.signer.to_account_info(),
};
let cpi_ctx = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
transfer_instruction,
);
// The `?` at the end will cause the function to return early in case of an error.
// This pattern is common in Rust.
anchor_spl::token::transfer(cpi_ctx, data)?;
Ok(())
}
pub fn transfer_out(ctx: Context<TransferOut>, bump: u8, data: u64) -> Result<()> {
msg!("Changed data to: {}!", data);
// Below is the actual instruction that we are going to send to the Token program.
let transfer_instruction = Transfer {
from: ctx.accounts.vault_token_account.to_account_info(),
to: ctx.accounts.sender_token_account.to_account_info(),
authority: ctx.accounts.token_account_owner_pda.to_account_info(),
};
let seeds = &[b"token_account_owner_pda".as_ref(), &[bump]];
let signer = &[&seeds[..]];
let cpi_ctx = CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
transfer_instruction,
signer,
);
anchor_spl::token::transfer(cpi_ctx, data)?;
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
// Derived PDAs
#[account(
init_if_needed,
payer = signer,
seeds=[b"token_account_owner_pda".as_ref()],
bump,
space = 8
)]
token_account_owner_pda: AccountInfo<'info>,
#[account(
init_if_needed,
payer = signer,
seeds=[b"token_vault".as_ref(), mint_of_token_being_sent.key().as_ref()],
token::mint=mint_of_token_being_sent,
token::authority=token_account_owner_pda,
bump
)]
vault_token_account: Account<'info, TokenAccount>,
#[account(mut)]
pub sender_token_account: Account<'info, TokenAccount>,
pub mint_of_token_being_sent: Account<'info, Mint>,
#[account(mut)]
pub signer: Signer<'info>,
pub system_program: Program<'info, System>,
token_program: Program<'info, Token>,
rent: Sysvar<'info, Rent>,
}
#[derive(Accounts)]
pub struct TransferIn<'info> {
// Derived PDAs
#[account(mut,
seeds=[b"token_account_owner_pda".as_ref()],
bump
)]
token_account_owner_pda: AccountInfo<'info>,
#[account(mut,
seeds=[b"token_vault".as_ref(), mint_of_token_being_sent.key().as_ref()],
bump,
token::mint=mint_of_token_being_sent,
token::authority=token_account_owner_pda,
)]
vault_token_account: Account<'info, TokenAccount>,
#[account(mut)]
pub sender_token_account: Account<'info, TokenAccount>,
pub mint_of_token_being_sent: Account<'info, Mint>,
#[account(mut)]
pub signer: Signer<'info>,
pub system_program: Program<'info, System>,
token_program: Program<'info, Token>,
rent: Sysvar<'info, Rent>,
}
#[derive(Accounts)]
pub struct TransferOut<'info> {
// Derived PDAs
#[account(mut,
seeds=[b"token_account_owner_pda".as_ref()],
bump
)]
token_account_owner_pda: AccountInfo<'info>,
#[account(mut,
seeds=[b"token_vault".as_ref(), mint_of_token_being_sent.key().as_ref()],
bump
)]
vault_token_account: Account<'info, TokenAccount>,
#[account(mut)]
pub sender_token_account: Account<'info, TokenAccount>,
pub mint_of_token_being_sent: Account<'info, Mint>,
#[account(mut)]
pub signer: Signer<'info>,
pub system_program: Program<'info, System>,
token_program: Program<'info, Token>,
rent: Sysvar<'info, Rent>,
}
-
1H, So I had this account as a PDA and used this account Program as Signers, and it was working fine you can see the transaction history and then suddenly I'm getting
Signature verification failed
error whenever I try to run my program and after some debugging I've found the my PDA does not exists.– BunnyCommented May 18, 2023 at 12:09
You have to initialize PDA first to use it.
here is the following rust code example.
#[account(
init, //this is main point
payer = signer,
space = 8 + 8,
seeds = [mun_sol_mint.key().as_ref(),constants::MUN_SOL_VAULT_SEED.as_ref()],
bump
)]
pub mun_sol_vault: AccountInfo<'info>,
here seeds are also used to get PDA address in frontend.
-
do we have to use init with PDA, accoirding to my knowledge we have to use it with just normal account?– BunnyCommented May 18, 2023 at 7:51
-
we have to initialize PDA at first, then we can use it as normal account by getting from seeds. Commented May 18, 2023 at 8:46
-
-
so you need to withdraw some tokens from PDA account to user wallet? transfer tokens from user wallet to PDA, then user wallet is signer, but from PDA to user wallet, what is signer. this is your point, right? Commented May 18, 2023 at 9:15
-
Yeah, I have a token account whose owner is this PDA. I want to transfer that token to my token account but I'm getting
Signature verification failed
. Token Account– BunnyCommented May 18, 2023 at 9:46
let nonce = *(ctx.bumps.get("stablecoin_vault").unwrap());
let seeds = &[ctx.accounts.stablecoin_mint.to_account_info().key.as_ref(), constants::NFT_COLLATERIZED_LOANS_ST_VAULT_SEED.as_ref(), &[nonce]];
let signer = &[&seeds[..]];
let cpi_ctx = CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
token::Transfer {
from: ctx.accounts.stablecoin_vault.to_account_info(),
to: ctx.accounts.user_stablecoin_vault.to_account_info(),
authority: ctx.accounts.stablecoin_vault.to_account_info(),
},
signer
);
token::transfer(cpi_ctx, order.additional_collateral)?;
please reference this. here stablecoin_vault is PDA account. I get signer from nonce and seeds of that. If you still got issue, please don't hesitate to ask me. I will give you full support.
-
-
please reference this project. you will get clear idea of how to use PDA account as vault. github.com/seiji0411/nft-collaterized-loan Commented May 18, 2023 at 10:16