2

I am trying to send usdc dev token using code to a wallet address but it kept on showing "Unable to simulate. Make sure you trust this website since approving can lead to loss of funds."

And even if I approve, tx would get rejected.

After hours of debugging, I tried first sending a little of the usdc token to that wallet address and then tried to resend again using my code and it worked fine.

So I was wondering, must the wallet have a bit of that token before being able to send to it using code? If yes, is there a way to do it successfully using code? Because that's my main goal

code below:

import {
  createAssociatedTokenAccountInstruction,
  createTransferInstruction,
  getAssociatedTokenAddress,
  TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import { useConnection, useWallet } from "@solana/wallet-adapter-react";
import { PublicKey, Transaction } from "@solana/web3.js";

//to convert the wallet address to usdc dev
async function convertToUsdcDev(address) {
  const mint = new PublicKey("Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr");
  const owner = new PublicKey(address);

  const tokenAddress = await getAssociatedTokenAddress(mint, owner);
  console.log(console.log("tokenAddress.toBase58()", tokenAddress.toBase58()));
  return tokenAddress.toBase58();
}
function usePayUSDC() {
  const { connection } = useConnection();
  const { publicKey, sendTransaction } = useWallet();

  // Token
  const valueTokenAddress = "Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr";
  const mint = new PublicKey(valueTokenAddress);

  const NUM_DROPS_PER_TX = 4;
  const TX_INTERVAL = 1000;

  // populate this with the amount to be sent, from req.body.amount
  const valueAmount = 10;

  async function generateTransactions(batchSize, dropList) {
    let result = [];

    const payerPublicKey = publicKey;

    const payerTokenAccount = await getAssociatedTokenAddress(
      mint,
      payerPublicKey
    );

    const payerAccountInfo = await connection.getAccountInfo(payerTokenAccount);

    // Token
    let txInstructions = dropList.map((drop) => {
      const takerTokenAccount = new PublicKey(drop.walletAddress);

      if (!payerAccountInfo || !payerAccountInfo.data) {
        createAssociatedTokenAccountInstruction(
          payerPublicKey,
          payerTokenAccount,
          payerPublicKey,
          mint // mint
        );
      }
      return createTransferInstruction(
        payerTokenAccount,
        takerTokenAccount,
        payerPublicKey,
        Number(drop.amount) * 10 ** 6,
        [],
        TOKEN_PROGRAM_ID // programId
      );
    });
   //some more code here
    return result;
  }

//execute tx function here ----

  async function transfer(data) {
    const { amount, wallet } = data;
    const usdcWallet = await convertToUsdcDev(wallet);

    const dropList = [
      {
        walletAddress: "vjm7kKuECdbR7Ste2c3DPDS6u9Pzccy2vsuXH9BSHs3",
        amount: (amount * 0.08163).toFixed(6),
      },
      {
        walletAddress: usdcWallet,
        amount: (amount * 0.91837).toFixed(6),
      },
    ];

    const transactionList = await generateTransactions(
      NUM_DROPS_PER_TX,
      dropList
    );

    const txResults = await executeTransactions(transactionList);

    return txResults.value || txResults.status;
  }

  return { transfer };
}

1 Answer 1

2

You're likely getting an error because the recipient's token account for that specific mint hasn't been created.

Below is an example for how to build a transaction and add an instruction to create a token account if it doesn't exist.

Note that:

  • the example assumes sender has an existing token account with a balance for the MINT
  • the amount transferred hasn't been adjusted for decimals of the MINT
  • await initializeKeypair(connection) is a helper function that isn't shown, but is just another keypair

Other than that you can use it as a reference

async function main() {
  const connection = new Connection(clusterApiUrl("devnet"))

  // Generate a new keypair to represent the sender
  const sender = await initializeKeypair(connection)

  // Generate a new keypair to represent the sender
  const receiver = Keypair.generate()

  // The MINT address of token to transfer
  const MINT = new PublicKey("Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr")

  // Get the sender's associated token account address
  const senderTokenAccountAddress = await getAssociatedTokenAddress(
    MINT,
    sender.publicKey
  )

  // Get the receiver's associated token account address
  const receiverTokenAccountAddress = await getAssociatedTokenAddress(
    MINT,
    receiver.publicKey
  )

  // Create a new transaction
  const transaction = new Transaction()

  // Create an instruction to create the receiver's token account if it does not exist
  const createAccountInstruction = createAssociatedTokenAccountInstruction(
    sender.publicKey,
    receiverTokenAccountAddress,
    receiver.publicKey,
    MINT,
    TOKEN_PROGRAM_ID,
    ASSOCIATED_TOKEN_PROGRAM_ID
  )

  // Check if the receiver's token account exists
  let receiverTokenAccount: Account
  try {
    receiverTokenAccount = await getAccount(
      connection,
      receiverTokenAccountAddress,
      "confirmed",
      TOKEN_PROGRAM_ID
    )
  } catch (e) {
    // If the account does not exist, add the create account instruction to the transaction
    transaction.add(createAccountInstruction)
  }

  // Create an instruction to transfer amount from the sender's token account to the receiver's token account
  const transferInstruction = await createTransferInstruction(
    senderTokenAccountAddress,
    receiverTokenAccountAddress,
    sender.publicKey,
    1
  )

  // Add the transfer instruction to the transaction
  transaction.add(transferInstruction)

  // Send the transaction signed by the sender
  const transactionSignature = await connection.sendTransaction(transaction, [
    sender,
  ])

  console.log(transactionSignature)
}
4

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.