2

I am trying to figure out why createAssociatedAccount does not work. This is the code:

const SendTransaction = ({ children }) => {
const { connection } = useConnection();
const { publicKey, signTransaction } = useWallet();

const onSendSPLTransaction = useCallback(async () => {

try {
  if (!publicKey || !signTransaction) throw new WalletNotConnectedError();

  const toPublicKey = new PublicKey("string pubkey is here");
  
  const tokenPublicKey = new PublicKey("another is here");

  const fromTokenAccount = await getOrCreateAssociatedTokenAccount(
    connection,
    publicKey,
    tokenPublicKey,
    publicKey,
    signTransaction 
  );
  // this console.log confirms that getAccount went well
  console.log(fromTokenAccount.address.toBase58());
  
  // from here the code fails
  const toTokenAccount = await getOrCreateAssociatedTokenAccount(
    connection,
    publicKey,
    tokenPublicKey,
    toPublicKey,
    signTransaction 
  );
  ...
})  

When I run this function, I can observe that the fromTokenAccount part has no problems, and I can confirm that it gets the correct ATA Pubkey (confirmed in explorer). However, for some reason, I receive TokenAccountNotFoundError when the toTokenAccount runs...

Please, help me to understand what is going on --- I believe that I am doing something dumb here.

EDIT: When I change the payer from the one I got from useWallet() hook to the hardcoded Keypair, the whole function works. So, what am I missing here? Have any ideas?

1

2 Answers 2

1

Could be that your callback function is not updating when the wallet changes (e.g. when it connects).

More likely you need a payer and you have a pubkey instead. getOrCreateAssociatedTokenAccount expects a Keypair for the payer arg, you have a pubkey. You can modify the source code of getOrCreate to do the same thing:

let ixes: TransactionInstruction[] = [];
const ata = await getAssociatedTokenAddress(
    mint,
    owner,
    allowOwnerOffCurve,
    programId,
    associatedTokenProgramId
);
let ataAcc = await getAccount(connection, ata);
  if (!ataAcc) {
    ixes.push(
      createAssociatedTokenAccountInstruction(
        wallet.publicKey,
        ata,
        owner,
        tokenMint
      )
    );
  }
// Append this ix before whatever ix you are actually sending to send the create ATA ix as needed...
// e.g. tx.add(...ixes);
0

check if you're using the correct token mint

 // from here the code fails
  const toTokenAccount = await getOrCreateAssociatedTokenAccount(
    connection,
    publicKey,
    tokenPublicKey,// it should token mint
    toPublicKey,
    signTransaction 
  );
  

if tokenPublicKey is not the token mint, there would be a problem

3
  • Thank you for the response! The token mint is correct. As we get the correct ATA in the previous step (given the same tokenPublicKey)
    – Michael
    Commented Sep 26, 2022 at 18:54
  • i think you've answered the question yourself 😀. Actually, the getOrCreateAssociatedTokenAccount function expects user keypair and not a publickey. as it'll be used to pay for transaction and initialization fees. and you cant do that with just a PublicKey
    – iMEF
    Commented Sep 27, 2022 at 2:31
  • I've written a detailed answer here, do check solana.stackexchange.com/questions/2814/… Commented Oct 4, 2022 at 12:02

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.