1

I want to load & deserialize a token account which is inputted as AccountInfo<'info> into an anchor program

1
  • The data contained within an AccountInfo is just raw bytes that can be interpreted in many different ways. You may want to narrow the scope of the question to something specific that you're trying to deserialize, e.g. a token account, or a mint account.
    – Jon C
    Jul 25 at 19:59

2 Answers 2

1

Anchor has a try_from method implemented for all anchor accounts and for some special accounts, like the spl token program accounts.

Loading a regular anchor account struct called OpenOrders looks like this

let mut user_open_orders: Account<OpenOrders> =
                    Account::try_from(user_account_info)?;

When trying to load one of the custom structs, you can check the anchor source for SPL tokens. TokenAccount implements the required traits, namely AccountDeserialize so try_from should also work here. Though I haven't run this code.

use anchor_spl::token::TokenAccount;
...
let mut this_token_account: Account<TokenAccount> =
                    Account::try_from(token_account_info)?;
-1

Here's how Account does it:

pub fn try_from(info: &AccountInfo<'a>) -> Result<Account<'a, T>> {
    if info.owner == &system_program::ID && info.lamports() == 0 {
        return Err(ErrorCode::AccountNotInitialized.into());
    }
    if info.owner != &T::owner() {
        return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram)
            .with_pubkeys((*info.owner, T::owner())));
    }
    let mut data: &[u8] = &info.try_borrow_data()?;
    Ok(Account::new(info.clone(), T::try_deserialize(&mut data)?))
}

so your implementation might be something like

pub fn deserialize<T>(info: &AccountInfo<'a>) -> Result<T> {
    if info.owner == &system_program::ID && info.lamports() == 0 {
        return Err(ErrorCode::AccountNotInitialized.into());
    }
    if info.owner != YOUR_PROGRAM {
        return Err(Error::from(ErrorCode::AccountOwnedByWrongProgram)
            .with_pubkeys((*info.owner, YOUR_PROGRAM)));
    }
    let mut data: &[u8] = &info.try_borrow_data()?;
    Ok(T::try_deserialize(&mut data)?)
}
3
  • thanks but how can i do it in anchor. so now I have AccountInfo<'info>. it is TokenAccount Account. how can I check the data? for example: token_vault.owner or token_mint.decimal Jul 25 at 20:15
  • let new_account_info = next_account_info(account_info).unwrap(); let token_a_vault = new_account_info.try_borrow_data()?; what should i do next? Jul 25 at 20:16
  • 1
    It's possible to just call try_from directly rather than reimplementing it. I posted a response showing how
    – Henry E
    Jul 25 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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