Search code examples
solanaanchor-solana

Which seeds does the `getAssociatedTokenAddress` function use to determine the associated token account public key?


The @solana/spl-token package contains the getAssociatedTokenAddress function which can be used to obtain the address (public key) of an associated token account. Here's an example:

const programATAPublicKey = await getAssociatedTokenAddress(
  mintPublicKey,
  programPDAPublicKey,
  true,
  program.programId
);

I am trying to achieve the same result using the findProgramAddress function from the @project-serum/anchor package. My problem is that I can't figure out which seeds are used inside getAssociatedTokenAddress. For example, I expected the following code to return the associated token account public key:

const [programATAPublicKey] =
      await anchor.web3.PublicKey.findProgramAddress(
        [mintPublicKey.toBuffer(), programPDAPublicKey.toBuffer()],
        program.programId
      );

The result is, however, different. Which seed combination would yield an identical result to whatever is returned from getAssociatedTokenAddress?


Solution

  • The best is to use the source! Here's the exact code that generates the associated token account address:

    export async function getAssociatedTokenAddress(
        mint: PublicKey,
        owner: PublicKey,
        allowOwnerOffCurve = false,
        programId = TOKEN_PROGRAM_ID,
        associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
    ): Promise<PublicKey> {
        if (!allowOwnerOffCurve && !PublicKey.isOnCurve(owner.toBuffer())) throw new TokenOwnerOffCurveError();
    
        const [address] = await PublicKey.findProgramAddress(
            [owner.toBuffer(), programId.toBuffer(), mint.toBuffer()],
            associatedTokenProgramId
        );
    
        return address;
    }
    

    where ASSOCIATED_TOKEN_PROGRAM_ID is "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL".

    Taken from https://github.com/solana-labs/solana-program-library/blob/ad97543192e05e6ecba88fff3b1da08ca523a5b6/token/js/src/state/mint.ts#L156