3

I'm following this tutorial (https://solanacookbook.com/guides/account-maps.html#single-map-account) to create an account that store a mapping. But when I run anchor test, the compiler returns

"IdlError: Type not found: {"name":"map","type":{"defined":"BTreeMap<u128,MarketItem>"}}"

This is my code:

pub mod nft {
use super::*;
pub fn init_state(ctx: Context<InitState>) -> Result<()> {
        let authority_account = &ctx.accounts.authority_account;
        let system_program = &ctx.accounts.system_program;
        let state_account = &ctx.accounts.state_account;

        let (state_pda, state_bump) =
            Pubkey::find_program_address(&[b"state".as_ref()], system_program.key);

        if state_pda != *state_account.key
            || !state_account.is_writable
            || !state_account.data_is_empty()
        {
            return Err(error::Error::InvalidStateAccount.into());
        }

        let rent = Rent::get()?;
        let rent_lamports = rent.minimum_balance(State::LEN);

        let create_state_ix = &solana_program::system_instruction::create_account(
            authority_account.key,
            state_account.key,
            rent_lamports,
            State::LEN.try_into().unwrap(),
            system_program.key,
        );

        // msg!("Creating stateAccount account");
        solana_program::program::invoke_signed(
            create_state_ix,
            &[
                authority_account.clone(),
                state_account.clone(),
                system_program.to_account_info(),
            ],
            &[&[b"state".as_ref(), &[state_bump]]],
        )?;

        // msg!("Deserializing MapAccount account");
        let mut program_state =
            solana_program::borsh::try_from_slice_unchecked::<State>(&state_account.data.borrow())
                .unwrap();
        let empty_map: BTreeMap<u128, MarketItem> = BTreeMap::new();

        program_state.map = empty_map;

        // msg!("Serializing MapAccount account");
        program_state.serialize(&mut &mut state_account.data.borrow_mut()[..])?;

        Ok(())
    }
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct MarketItem {
    item_id: u128,
    nft_contract: Pubkey, // program id,
    token_id: Pubkey,     // ATA
    seller: Pubkey,
    owner: Option<Pubkey>,
    price: u128,
    file_name: String,
    description: String,
    cash_back: u8,
    sold: bool,
    gacha: bool,
    bump: u8,
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct State {
    pub map: BTreeMap<u128, MarketItem>,
    pub item_ids: u128,
    pub item_sold: u128,
    pub owner: Pubkey,
    pub seed: u64,
}

impl State {
    const LEN: usize = 1 + (4 + (10 * 64));
}

How can I fix this? Thanks

0

1 Answer 1

1

Unfortunately, Anchor/Solana does not support IDL type for BtreeMap.

You can find all available types here: https://www.anchor-lang.com/docs/javascript-anchor-types

The tutorial link given in your question does not saying that it used BTreeMap like what you did, but it's explaining how to achieve Map-like logic in Solana using PDAs.

In your example, you can create a PDA for a MarketItem seeded with item_id and the address of State ensuring it's market from your state account.

However, it would be nicer to have state address stored in MarketItem struct as well so that you can filter markets by state in your offchain logic.

2
  • Clearly Solana does support BtreeMap as seen in the tutorial, are you saying this type is not supported by anchor, or just by anchor clients? What is a workaround to use this type with anchor, when memory-efficient insertion and deletion in a sorted list is desired? Commented Dec 25, 2023 at 8:29
  • Hey Mike how are you? So i'm pretty sure i know what's happening. What's happening is that when you are anchor building this type is not going into the idl.(Unfortunaly i know this because recently happened the same to me) If you could check/share the idl just to be 100% sure. (You will see that this type is not there). Commented Jan 21 at 4:23

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.