Quantcast
Channel: Recent Questions - Solana Stack Exchange
Viewing all articles
Browse latest Browse all 7906

Sign Program Method Transaction with Secret Key

$
0
0

I have a method in my program that can only be fired by the admin address. Now I am trying to fire this method using Next.js server actions using the secret key of the admin address. But I am having issues where the transaction is not being sent. I am facing errors like undefined blockhash and feepayer.What am I missing?

"use server";import { TokenVault } from "@/anchor/types/token_vault";import token_vault_idl from "@/anchor/idl/token_vault.json";import * as anchor from "@coral-xyz/anchor";import { Program, BN, AnchorProvider, Idl } from "@coral-xyz/anchor";import * as web3 from "@solana/web3.js";import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";export async function destake(tokenAccount: string) {  const payer = web3.Keypair.fromSecretKey(    //secret key here  );  const wallet = new NodeWallet(payer);  const url = web3.clusterApiUrl("devnet");  let connection = new web3.Connection(url, "confirmed");  const provider = new AnchorProvider(connection, wallet, {    commitment: "processed",  });  //Create Program Instance  const programId = new web3.PublicKey(process.env.NEXT_PUBLIC_PROGRAM_ID);  const program = new Program(    token_vault_idl as Idl,    process.env.NEXT_PUBLIC_PROGRAM_ID,    provider  );  const DUMMY_TOKEN_ADDRESS = new web3.PublicKey("Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr"  );  //Create required PDAs  const [tokenAccountOwnerPda] = await web3.PublicKey.findProgramAddressSync(    [Buffer.from("token_account_owner_pda")],    programId  );  const [tokenVault] = await web3.PublicKey.findProgramAddressSync(    [Buffer.from("token_vault"), DUMMY_TOKEN_ADDRESS.toBuffer()],    programId  );  const [stakeInfo] = await web3.PublicKey.findProgramAddressSync(    [Buffer.from("stake_info"), new web3.PublicKey(tokenAccount).toBuffer()],    program.programId  );  console.log("Stake Info", stakeInfo.toString());  const destakeInstruction = await program.methods    .destake(new BN(5 * 10 ** 6), payer.publicKey)    .accounts({      tokenAccountOwnerPda,      vaultTokenAccount: tokenVault,      stakeInfo: stakeInfo,      mintOfTokenBeingSent: DUMMY_TOKEN_ADDRESS,      senderTokenAccount: new web3.PublicKey(tokenAccount),    })    .signers([payer])    .transaction();  console.log(destakeInstruction);  const txHash = await web3.sendAndConfirmTransaction(    connection,    destakeInstruction,    [payer]  );  console.log("Transaction Hash", txHash);  const { blockhash, lastValidBlockHeight } =    await program.provider.connection.getLatestBlockhash();  await program.provider.connection.confirmTransaction({    blockhash,    lastValidBlockHeight,    signature: txHash,  });  console.log(    `Solana Explorer: https://explorer.solana.com/tx/${txHash}?cluster=devnet`  );}

Anchor program for reference

use anchor_lang::prelude::*;use anchor_spl::token::{transfer, Mint, Token, TokenAccount, Transfer};use solana_program::clock::Clock;use solana_program::{pubkey, pubkey::Pubkey};pub mod error;pub mod states;use crate::{error::*, states::*};declare_id!("3kgj71kWEa5wFsKkNTjjyBX188zKT1X8ohY6KEst5Eg1");pub const ADMIN: Pubkey = pubkey!("E6q6HeKopLXp447tcqScBFeiFDScHakK26TrTxqHbncE");#[program]mod token_vault {    use super::*;    pub fn initialize(_ctx: Context<Initialize>) -> Result<()> {        Ok(())    }    pub fn stake(ctx: Context<Stake>, amount: u64, stake_price: f32) -> Result<()> {        msg!("Stake amount: {}!", amount);        let clock = Clock::get()?;        let stake_info = &mut ctx.accounts.stake_info;        stake_info.amount = amount;        stake_info.staker = ctx.accounts.signer.key();        stake_info.initial_stake_amount = amount;        stake_info.stake_price = stake_price;        stake_info.staking_time = clock.unix_timestamp;        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,        );        transfer(cpi_ctx, amount)?;        Ok(())    }    pub fn destake(ctx: Context<DeStake>, amount: u64, staker_address: Pubkey) -> Result<()> {        msg!("Destake amount: {}!", staker_address);        let stake_info = &mut ctx.accounts.stake_info;        if amount == 0 {            return Err(error!(Errors::AmountZero));        }        if amount > stake_info.amount {            return Err(error!(Errors::WithdrawAmountGreater));        }        if stake_info.amount == 0 {            return Err(error!(Errors::StakeAmountZero));        }        let updated_amount = stake_info.amount.checked_sub(amount).unwrap();        ctx.accounts.stake_info.amount = updated_amount;        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 bump = ctx.bumps.token_account_owner_pda;        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,        );        transfer(cpi_ctx, amount)?;        Ok(())    }    pub fn delete_stake_acc(_ctx: Context<DeleteStakeAcc>, _staker_address: Pubkey) -> Result<()> {        Ok(())    }}#[derive(Accounts)]pub struct Initialize<'info> {    // Derived PDAs    #[account(        init,        payer = signer,        seeds=[b"token_account_owner_pda".as_ref()],        bump,        space = 8    )]    token_account_owner_pda: Account<'info, TokenOwnerAccount>,    #[account(        init,        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>,    mint_of_token_being_sent: Account<'info, Mint>,    #[account(mut)]    signer: Signer<'info>,    system_program: Program<'info, System>,    token_program: Program<'info, Token>,    rent: Sysvar<'info, Rent>,}#[derive(Accounts)]pub struct Stake<'info> {    // Derived PDAs    #[account(        init,        payer = signer,        seeds=[b"stake_info", sender_token_account.key().as_ref()],        bump,        space = 8 + StakeInfo::INIT_SPACE    )]    pub stake_info: Account<'info, StakeInfo>,    #[account(        mut,        seeds=[b"token_account_owner_pda"],        bump    )]    token_account_owner_pda: Account<'info, TokenOwnerAccount>,    #[account(mut,        seeds=[b"token_vault", 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)]    sender_token_account: Account<'info, TokenAccount>,    mint_of_token_being_sent: Account<'info, Mint>,    #[account(mut)]    signer: Signer<'info>,    system_program: Program<'info, System>,    token_program: Program<'info, Token>,    rent: Sysvar<'info, Rent>,}#[derive(Accounts)]#[instruction(staker_address: Pubkey)]pub struct DeStake<'info> {    // Derived PDAs    #[account(        mut,        seeds=[b"stake_info", sender_token_account.key().as_ref()],        bump,    )]    pub stake_info: Account<'info, StakeInfo>,    #[account(mut,        seeds=[b"token_account_owner_pda"],        bump    )]    token_account_owner_pda: Account<'info, TokenOwnerAccount>,    #[account(mut,        seeds=[b"token_vault", 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)]    sender_token_account: Account<'info, TokenAccount>,    mint_of_token_being_sent: Account<'info, Mint>,    #[account(mut, address = ADMIN @ Errors::NotAdmin)]    signer: Signer<'info>,    system_program: Program<'info, System>,    token_program: Program<'info, Token>,    rent: Sysvar<'info, Rent>,}#[derive(Accounts)]#[instruction(staker_address: Pubkey)]pub struct DeleteStakeAcc<'info> {    #[account(        mut,        seeds=[b"stake_info", staker_address.as_ref()],        bump,        close = signer    )]    pub stake_info: Account<'info, StakeInfo>,    #[account(mut, address = ADMIN @ Errors::NotAdmin)]    signer: Signer<'info>,}

Viewing all articles
Browse latest Browse all 7906

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>