import type * as anchor from "@coral-xyz/anchor"; import { ASSOCIATED_TOKEN_PROGRAM_ID, createAssociatedTokenAccountIdempotentInstruction, getAssociatedTokenAddressSync, TOKEN_PROGRAM_ID, } from "@solana/spl-token"; import type { PublicKey } from "@solana/web3.js"; import { sendAndConfirmTransaction } from "./sendAndConfirmTransaction.js"; /** * Creates an ATA idempotently for the given mint and owner. * @param provider * @param mint * @param owner * @param allowOwnerOffCurve * @returns */ export async function createATA( provider: anchor.AnchorProvider, mint: PublicKey, owner: PublicKey, allowOwnerOffCurve = false, ): Promise { const associatedToken = getAssociatedTokenAddressSync( mint, owner, allowOwnerOffCurve, TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, ); // Skip if the ATA already exists const existing = await provider.connection.getAccountInfo(associatedToken, { commitment: "processed", }); if (existing) { return associatedToken; } await sendAndConfirmTransaction(provider, { instructions: [ createAssociatedTokenAccountIdempotentInstruction( provider.wallet.publicKey, associatedToken, owner, mint, TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, ), ], }); return associatedToken; }