2

I have a program that is creating a mint account, the associated token account, the meta data account. Right now I'm just testing it out without a frontend, but eventually I want to batch them all together into one transaction. The reason why is because I also want to make function callers pay a fee to a certain address. I have the following functions from the @solana/spl-token library, how can I modify them all to be added to the Web3.js Transaction class?

Here's what I have for the two I couldn't figure out:

    const transactionSignature = await token.mintTo(
        connection,
        payer,
        mint,
        destination,
        authority,
        amount
    )

    const tokenAccount = await token.createAssociatedTokenAccount(connection, payer, mint, owner)

Is it good practice to just have separate transactions? In this case, paying the fee would come first. If not, how can I bundle these two and send them together as transactions? I see that the second transaction depends on the mint variable I've never done them separate before so I'm not sure how unconventional it would really be

1 Answer 1

1

mintTo and createAssociatedTokenAccount are helper functions that automatically sends the transactions to mint tokens / create an associated token account.

A transaction on Solana can be thought of a request to process one or multiple instructions. Note that instructions in a transaction are processed sequentially, in the order they are added to a transaction.

You can build the instructions individually and then add to a single transaction.

Here is a Solana Playground example that creates a new mint account, creates an associated token account, and mints tokens in a single transaction.

import {
  Connection,
  Keypair,
  SystemProgram,
  Transaction,
  clusterApiUrl,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
  MINT_SIZE,
  TOKEN_PROGRAM_ID,
  createInitializeMint2Instruction,
  getMinimumBalanceForRentExemptMint,
  getAssociatedTokenAddressSync,
  createAssociatedTokenAccountInstruction,
  createMintToInstruction,
} from "@solana/spl-token";

// Playground wallet
const payer = pg.wallet.keypair;

// Connection to devnet cluster
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

// Generate keypair to use as address of mint account
const mint = new Keypair();
// Authority that can mint new tokens
const mintAuthority = pg.wallet.publicKey;

// Get associated token account address
const associatedTokenAccountAddress = getAssociatedTokenAddressSync(
  mint.publicKey, // mint address
  payer.publicKey // token account owner
);

// Calculate minimum lamports for space required by mint account
const lamports = await getMinimumBalanceForRentExemptMint(connection);

// Instruction to create new account with space for new mint account
const createAccountInstruction = SystemProgram.createAccount({
  fromPubkey: payer.publicKey,
  newAccountPubkey: mint.publicKey,
  space: MINT_SIZE,
  lamports,
  programId: TOKEN_PROGRAM_ID,
});

// Instruction to initialize mint account
const initializeMintInstruction = createInitializeMint2Instruction(
  mint.publicKey,
  2, // decimals
  mintAuthority, // mint authority
  null // freeze authority
);

// Instruction to create associated token account
const associatedTokenAccountInstruction =
  createAssociatedTokenAccountInstruction(
    payer.publicKey, // payer
    associatedTokenAccountAddress, // token account address
    payer.publicKey, // owner
    mint.publicKey // mint address
  );

// Instruction to mint tokens
const mintToInstruction = createMintToInstruction(
  mint.publicKey, // mint address
  associatedTokenAccountAddress, // destination
  mintAuthority, // mint authority
  100 // amount
);

// Build transaction with instructions to:
// 1. Create and Initialize new Mint Account
// 2. Create Associated Token Account
// 3. Mint tokens to Associated Token Account
const transaction = new Transaction().add(
  createAccountInstruction,
  initializeMintInstruction,
  associatedTokenAccountInstruction,
  mintToInstruction
);

// "mint" keypair has to be included as signer because we are using it's publickey as the address of a new account
const transactionSignature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [payer, mint] // signers
);

console.log(
  "\nTransaction Signature:",
  `https://solana.fm/tx/${transactionSignature}?cluster=devnet-solana`
);
2
  • 1
    This is exactly what I was looking for. Thanks!
    – 0x0x0x0
    Commented Dec 18, 2023 at 0:50
  • Please accept the answer if you believe it's correct. This will help other people find it later
    – Jon C
    Commented Jan 3 at 18:52

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.