5

Doing this in Typescript is pretty straightforward by making an RPC call or getOrCreateAssociatedAccount, but I am wondering if there is a way to do this program side as well without using Anchor.

For example, say I want my program to mint some tokens to a user - but I'll also want the program to create the token account if it does not already exist before minting. Does this check have to be handled on the client side or can I implement the program side as well?

3
  • in anchor add init_if_needed constraint Exact same functionality as the init constraint but only runs if the account does not exist yet. If the account does exist, it still checks whether the given init constraints are correct, e.g. that the account has the expected amount of space and, if it's a PDA, the correct seeds etc. ``` #[account(init_if_needed, payer = payer)] pub data_account: Account<'info, MyData>, ``` --- note This feature should be used with care and is therefore behind a feature flag. You can enable it by importing anchor-lang with the init-if-needed cargo feature.
    – vicyyn
    Commented Aug 20, 2022 at 16:29
  • Thank you for the answer, I should have clarified though I was looking for a way to do this in Native Rust (i.e. without Anchor)
    – ixmorrow
    Commented Aug 22, 2022 at 0:11
  • Although I really advise you that you use Anchor since it saves you a lot of time, you can either check init_if_needed in the anchor lang repo and try to do the same, or you can check the data if allocated then only initialize if it's empty (just throwing ideas)
    – vicyyn
    Commented Aug 22, 2022 at 7:55

1 Answer 1

2

Assuming you need the target associated token account for something in your program already - like to transfer to it - you can just conditionally create it if it doesn't exist.

The logic looks like this, but note you'd want to coordinate who signs/pays for this account creation, and it's not usually advisable to have unpredictable rent-paying in a program's instruction.

if to_associated_token_account.lamports() == 0 {
    msg!("Creating associated token account for recipient...");
    invoke(
        &associated_token_account_instruction::create_associated_token_account(
            payer.key,
            recipient.key,
            mint_account.key,
            token_program.key,
        ),
        &[
            mint_account.clone(),
            to_associated_token_account.clone(),
            recipient.clone(),
            payer.clone(),
            system_program.clone(),
            token_program.clone(),
            associated_token_program.clone(),
        ],
    )?;
} else {
    msg!("Associated token account exists.");
}
1
  • You might want to check the attributes of the associated token account in this case - i.e. make sure that it's own by associated_token_program. If for some reason the ATA had lamports in it without having been initialised, you would get a false positive with the above logic only!
    – neft
    Commented Jun 18 at 20:34

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.