Turbin3 / poseidon

A Transpiler to convert your Solana programs from Typescript to Anchor
https://turbin3.github.io/poseidon/
47 stars 16 forks source link

Incorrect Usage of new_with_signer Instead of new in CpiContext Transpilation #33

Closed ritikbhatt20 closed 3 days ago

ritikbhatt20 commented 3 days ago

For example, Poseidon code:

import { AssociatedTokenAccount, Mint, Pubkey, Result, Signer, SystemAccount, SystemProgram, TokenProgram, u8, u64 } from '@solanaturbine/poseidon';

export default class SplTokenMinter {
  static PROGRAM_ID = new Pubkey('DmrXSUGWYaqtWg8sbi9JQN48yVZ1y2m7HvWXbND52Mcw');

  createTokenMint(mintAuthority: Signer, mintAccount: Mint, decimals: u8, freezeAuthority?: Pubkey): Result {
    // Initialize the mint account with specified decimals
    TokenProgram.initializeMint(
      mintAccount,
      decimals,
      mintAuthority, // authority
      freezeAuthority, // freeze authority
    );
  }

  mint(mintAuthority: Signer, mintAccount: Mint, recipient: SystemAccount, associatedTokenAccount: AssociatedTokenAccount, amount: u64): Result {
    associatedTokenAccount.derive(mintAccount, recipient.key).initIfNeeded();
    TokenProgram.mintTo(mintAccount, associatedTokenAccount, mintAuthority, amount);
  }
}

Transpiled Anchor code:

use anchor_lang::prelude::*;
use anchor_spl::{
    associated_token::AssociatedToken,
    token::Mint,
};
declare_id!("DmrXSUGWYaqtWg8sbi9JQN48yVZ1y2m7HvWXbND52Mcw");
#[program]
pub mod spl_token_minter {
    use super::*;
    pub fn create_token_mint(
        ctx: Context<CreateTokenMintContext>,
        decimals: u8,
        freeze_authority: Pubkey,
    ) -> Result<()> {
        Ok(())
    }
    pub fn mint(ctx: Context<MintContext>, amount: u64) -> Result<()> {
        let cpi_ctx = CpiContext::new_with_signer(
            ctx.accounts.token_program.to_account_info(),
            MintTo {
                mint: ctx.accounts.mint_account.to_account_info(),
                to: ctx.accounts.associated_token_account.to_account_info(),
                authority: ctx.accounts.mint_authority.to_account_info(),
            },
            signer,
        );
        mint_to(cpi_ctx, amount)?;
        Ok(())
    }
}
#[derive(Accounts)]
pub struct CreateTokenMintContext<'info> {
    #[account(mut)]
    pub mint_authority: Signer<'info>,
    #[account()]
    pub mint_account: Account<'info, Mint>,
}
#[derive(Accounts)]
pub struct MintContext<'info> {
    #[account(
        init_if_needed,
        payer = mintAuthority,
        associated_token::mint = mint_account,
        associated_token::authority = recipient,
    )]
    pub associated_token_account: Account<'info, TokenAccount>,
    #[account(mut)]
    pub recipient: SystemAccount<'info>,
    #[account(mut)]
    pub mint_authority: Signer<'info>,
    #[account()]
    pub mint_account: Account<'info, Mint>,
    pub associated_token_program: Program<'info, AssociatedToken>,
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
}

Expected code should have been:

let cpi_ctx = CpiContext::new(
    ctx.accounts.token_program.to_account_info(),
    MintTo {
        mint: ctx.accounts.mint_account.to_account_info(),
        to: ctx.accounts.associated_token_account.to_account_info(),
        authority: ctx.accounts.mint_authority.to_account_info(),
    },
);
mint_to(cpi_ctx, amount)?;

Proposed Solution: Modify the transpiler logic to select new for CpiContext creation unless a signer is explicitly required.

ShrinathNR commented 3 days ago

In the latest master branch commit, new_with_signer will be used only when the authority is a PDA and you should have passed signer seeds array