1

My anchor program "A", expect to use data from a anchor program name "B".

Let's say program_b (which I don't have code, just know it's address) has declare PDA account data struct:

#[account]
#[derive(InitSpace)] 
pub struct FeeData {
    pub fee: u64,
}

and I got this account address that pass into program_a.

And in program_a, related code is:

        ...
#[account]
#[derive(InitSpace)] 
pub struct FeeData {     // mock after the struct on program_b
    pub fee: u64,
}

#[derive(Accounts)]
pub struct Initialize<'info> {
        ...
/// CHECK: no check purposely
pub fee_from_prog_b: Account<'info, FeeData>,
        ...
}

But, once invode instruction on program_a, I got error: Error Code: AccountDiscriminatorMismatch. Error Number: 3002. Error Message: 8 byte discriminator did not match what was expected.'

I know there is account discriminator and why this error raise. After search in the forumn, I got this one: How to Deserialize Anchor Accounts from Other Programs in Accounts Struct but I don't like this way to make it work.

Edit: I would like an #account attribute way, or hand coding to read that out(but I don't know how to).

So, I'm looking for a better solution to this requirement.

Thanks in advance.

2 Answers 2

2

Import from program B namespace the typed account.

use program_b::{  
    state::FeeData,
};

If you need to use any ix from program B you can make use of CPI namespace that's can be included as a feature in your Cargo.tomk When importing program B

program-b = { path = "../program-b", features = ["cpi"] }
1
  • Thanks, I know this approach. But I don't have the program mod of program_b, and dislike to create a stub program_b mod. Commented Sep 10 at 23:36
0

Finally, I figure it out. This is my solution



#[derive(Clone, AnchorSerialize, AnchorDeserialize)]
pub struct FeeData {
    pub fee: u64,
}

#[program]
pub mod test_program {
    use super::*;
 
    pub fn initialize(ctx: Context<Initialize>) -> Result<()> {

        let fee_account = ctx.accounts.fee_ata.to_account_info();
        let fee_data = FeeData::try_from_slice(&fee_account.data.borrow()[..][8..]).expect("Should success");

        msg!("initialize: {:?}", fee_data.fee);
        msg!("initialize:  owner {:?}", fee_account.owner);

        Ok(())
    }

}

#[derive(Accounts)]
pub struct Initialize<'info> {

    /// CHECK:
    pub fee_ata: UncheckedAccount<'info>,
}

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.