I've created a dApp on React which uses the Solana blockchain to create, mint, and send utility tokens. I'm using @metaplex-foundation/umi and @mpl-toolbox to create the token, mint it to the creator's account, and then send the created tokens to any wallet address. Now, the token creation ( using createFungibleAsset instruction ) and the token minting (using mintV1) are working perfectly fine. When I use the transferToken instruction, the instruction fails with this error:
Program returned error: "invalid account data for instruction"
Also, the instruction works perfectly for the account to which the tokens were minted ( also being the creator account ) but fails for the accounts with no ATA. I've even tried creating an ATA for these accounts but still, the transaction fails.
Here's the relevant part of the code:
const [mint, setMint] = useState(generateSigner(umi));
// function triggered when the 'Create Token' button is clicked
const submitHandler = async () => {
const tokenName = tokenNameRef.current?.value || "";
const tokenSymbol = tokenSymbolRef.current?.value || "";
const tokenDescription = tokenDescriptionRef.current?.value || "";
console.log(tokenName, tokenSymbol, tokenDescription);
const mint = generateSigner(umi);
setMint(mint);
const tokenMetadata = {
tokenName,
tokenSymbol,
tokenDescription,
};
// upload the tokenMetadata to irys ( previously bundlr)
const uri = await umi.uploader.uploadJson([tokenMetadata]);
console.log("TokenMetadata uploaded successfully", uri);
toast.success("Token metadata uploaded successfully");
// create the fungible token
createFungibleAsset(umi, {
mint,
name: tokenMetadata.tokenName,
symbol: tokenMetadata.tokenSymbol,
uri: uri,
sellerFeeBasisPoints: percentAmount(0),
isMutable: true,
isCollection: false,
authority: umi.identity, // the address which is allowed to mint the tokens
decimals: 3, // the divisibility of the fungible token
})
.sendAndConfirm(umi)
.then(() => {
console.log(
tokenMetadata.tokenName + "created successfully: ",
mint.publicKey
);
toast.success("🦄 Token created successfully!");
setCanMintTokens(true);
});
};
// Minting the fungible token using the mpl-token-metadata library's mintV1 function
const mintHandler = () => {
const tokensToMint = mintAmountRef.current?.value || 0;
mintV1(umi, {
mint: mint.publicKey,
authority: umi.identity,
amount: +tokensToMint * 1000,
tokenOwner: umi.identity.publicKey,
tokenStandard: TokenStandard.Fungible,
})
.sendAndConfirm(umi, { send: { skipPreflight: true } }) // preflight is Solana's simulation of the txn, if simulation fails, txn is failed and not even sent to the chains
.then(() => {
console.log("minted successfully!");
toast.success("🦄 Token minted successfully!");
});
};
// Send SPL tokens
const sendSplTokensHandler = async () => {
const tokenAmount = Number(numOfTokensToSendRef.current?.value) || 0;
if (!destinationWalletAddressRef.current?.value) {
throw new Error("Please provide a destination wallet address.");
}
if (!wallet || !wallet.publicKey) {
throw new Error("Wallet not loaded");
}
if (tokenAmount <= 0) {
throw new Error("Token amount must be greater than 0.");
}
const destinationWalletAddress = publicKey(
destinationWalletAddressRef.current?.value
);
const senderTokenAccount = findAssociatedTokenPda(umi, {
// Gets the ATA of the sender account
mint: mint.publicKey,
owner: umi.payer.publicKey,
});
const receiverTokenAccount = findAssociatedTokenPda(umi, {
// Predicts the ATA of the recepient acc which doesn't exist yet
mint: mint.publicKey,
owner: destinationWalletAddress,
});
let txnBuilder = transactionBuilder();
txnBuilder = txnBuilder.add(
createTokenIfMissing(umi, {
// creates the recipient ATA
mint: mint.publicKey,
// token: receiverTokenAccount,
// ata: receiverTokenAccount,
owner: receiverTokenAccount,
})
);
txnBuilder = txnBuilder.append(
transferTokens(umi, {
source: senderTokenAccount,
destination: receiverTokenAccount,
amount: tokenAmount,
})
);
txnBuilder
.sendAndConfirm(umi, { send: { skipPreflight: true } })
.then(() => {
console.log("Token sent");
toast.success("Token sent");
});
};
Now, I'll attach the transaction failure screenshot:
I'll also attach the Solana Explorer link: