0

I am following a tutorial to make a staking app and I want to test the functionality of my instruction. I have tried "getTokenAccountBalance", but it remain unchanged before and after the rpc call.

I wonder how to correctly test the balance change after we do the transfer call.

pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
        Ok(())
    }
    pub fn stake(ctx: Context<Stake>, amount: u64) -> Result<()> {
        // Because we are staking, the stake info should be changed -> mut
        let stake_info = &mut ctx.accounts.stake_info_account;
        // Case:
        //  + user stake, but no token to stake
        //  + try to stake, already stake
        //  + try to destake, but not actually stake anything
        if stake_info.is_staked {
            return Err(ErrorCode::IsStaked.into());
        }
        if amount == 0 {
            return Err(ErrorCode::NoTokens.into());
        }
        let clock = Clock::get()?;
        stake_info.stake_at_slot = clock.slot;
        stake_info.is_staked = true;

        let stake_amount = amount
            .checked_mul(10u64.pow(ctx.accounts.mint.decimals as u32))
            .unwrap();
        // Transfer from user account to the stake account
        transfer(
            CpiContext::new(
                ctx.accounts.token_program.to_account_info(),
                Transfer {
                    from: ctx.accounts.user_token_account.to_account_info(),
                    to: ctx.accounts.stake_account.to_account_info(),
                    authority: ctx.accounts.signer.to_account_info(),
                },
            ),
            stake_amount,
        )?;
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Initialize<'info> {
    #[account(mut)]
    pub signer: Signer<'info>,
    #[account(init_if_needed,
        seeds = [constants::VAULT_SEED],
        bump,
        payer = signer,
        token::mint = mint,
        token::authority= token_vault_account,
    )]
    pub token_vault_account: Account<'info, TokenAccount>,
    pub mint: Account<'info, Mint>,
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Stake<'info> {
    #[account(mut)]
    pub signer: Signer<'info>,
    #[account(
        init_if_needed, 
        seeds = [
            constants::STAKE_INFO_SEED,
            signer.key.as_ref()],
            bump, 
            payer = signer,
            space = 8 + std::mem::size_of::<StakeInfo>()
    )]
    pub stake_info_account: Account<'info, StakeInfo>,
    #[account(
        init_if_needed, 
        seeds = [constants::TOKEN_SEED, signer.key.as_ref()],
        bump, 
        payer = signer,
        token::mint = mint,
        token::authority = stake_account
    )]
    pub stake_account: Account<'info, TokenAccount>,
    #[account(
        mut, 
        associated_token::mint = mint,
        associated_token::authority = signer,
    )]
    pub user_token_account: Account<'info, TokenAccount>,
    pub mint: Account<'info, Mint>,
    pub token_program: Program<'info, Token>,
    pub associated_token_program: Program<'info, AssociatedToken>,
    pub system_program: Program<'info, System>,
}
#[account]
pub struct StakeInfo {
    pub stake_at_slot: u64, //what slot they stake(source of truth of time, not timestamp)
    pub is_staked: bool,
}
#[error_code]
pub enum ErrorCode {
    #[msg("Token are already staked")]
    IsStaked,
    #[msg("Token not staked")]
    NotStaked,
    #[msg("No token to stake")]
    NoTokens,
}

tests:

  it("Is initialized!", async () => {
    await createMintToken();
    let [vaultAccount] = PublicKey.findProgramAddressSync(
      [Buffer.from("vault")],
      program.programId
    );
    const tx = await program.methods
      .initialize()
      .accounts({
        signer: payer.publicKey, // payer,
        tokenVaultAccount: vaultAccount,
        mint: mintKeypair.publicKey,
      })
      .rpc();
    console.log("Your transaction signature", tx);
  });
  it("stake", async () => {
    let userTokenAccount = await getOrCreateAssociatedTokenAccount(
      connection,
      payer.payer,
      mintKeypair.publicKey,
      payer.publicKey
    );
    await mintTo(
      connection,
      payer.payer,
      mintKeypair.publicKey,
      userTokenAccount.address,
      payer.payer,
      1e11
    );
    // Stake info account
    let [stakeInfo] = PublicKey.findProgramAddressSync(
      [Buffer.from("stake_info"), payer.publicKey.toBuffer()],
      program.programId
    );
    // Stake account
    let [stakeAccount] = PublicKey.findProgramAddressSync(
      [Buffer.from("token"), payer.publicKey.toBuffer()],
      program.programId
    );

    await getOrCreateAssociatedTokenAccount(
      connection,
      payer.payer,
      mintKeypair.publicKey,
      payer.publicKey
    );
    // Gold token vault
    // let balanceBefore = await connection.getTokenAccountBalance(stakeAccount);
    // console.log(balanceBefore);
    const tx = await program.methods
      .stake(new anchor.BN(1))
      .signers([payer.payer])
      .accounts({
        stakeInfoAccount: stakeInfo,
        stakeAccount: stakeAccount,
        userTokenAccount: userTokenAccount.address,
        mint: mintKeypair.publicKey,
      })
      .rpc();
    let balanceAfter = await connection.getTokenAccountBalance(
      userTokenAccount.address
    );
    console.log("Your transaction signature", tx);
    console.log(balanceAfter);
  });

1 Answer 1

1

i don't know the .rpc method, but might be related to confirmation status ? try to wait for transaction's confirmation before checking again ?

2
  • or maybe the connection and the provider that the program was created from has got different commitment levels? Like to try to use the program.provider.connection.getTokenAccountBalance instead of the connection.getTokenAccountBalance?
    – chalda
    Commented Sep 19, 2023 at 7:31
  • const provider = anchor.AnchorProvider.env(); anchor.setProvider(provider); const payer = provider.wallet as anchor.Wallet; const connection = new Connection("http://127.0.0.1:8899", "confirmed"); I set the commitment level to "confirmed", not sure if it is relevant or not Commented Sep 19, 2023 at 9:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.