4

I would like to add multiple instructions into a single transaction, using Anchor TS (@project-serum/anchor). Here is an example how this works with Solana Web3.js (@solana/web3.js): What is the best practice to sign and send multiple transaction at once in solana with one popup of phantom wallet?.

Is there a way to do this using Anchor TS (@project-serum/anchor) as well?

2 Answers 2

6

Yep! Assuming you have something like this:

await program.methods
  .createPixel(x, y, 0, 0, 255)
  .accounts({
    pixel: pixelKeypair.publicKey,
    user: anchorProvider.wallet.publicKey,
    systemProgram: web3.SystemProgram.programId,
  })
  .signers([pixelKeypair])
  .rpc()

You can use either .preInstructions([]) or .postInstructions([]) to add instructions before or after the Anchor instruction.

Here's an example:

await program.methods
  .createPixel(x, y, 0, 0, 255)
  .accounts({
    pixel: pixelKeypair.publicKey,
    user: anchorProvider.wallet.publicKey,
    systemProgram: web3.SystemProgram.programId,
  })
  .signers([pixelKeypair])
  .postInstructions([
    // add an instruction to the transaction to send 1 lamport 
    web3.SystemProgram.transfer({
      fromPubkey: anchorProvider.wallet.publicKey,
      toPubkey: anchorProvider.wallet.publicKey,
      lamports: 1,
    })
  ])
  .rpc()
1
  • 1
    This is a nice answer, but if you want to arrange your instructions in the same way as each other using tx.add(instruction), rather than arrange your other instructions around Anchor instruction, the other answer is better. Jan 30 at 20:11
4

You may prefer to turn your Anchor instruction into a regular web3.js instruction, using Anchor's .instruction() to get the instruction as a normal Instruction you can use with web3.js

You can then use web3.js tranaction.add() to add the Anchor instruction to your transaction, then use the normal web3.js connection.sendTransaction() to process your transaction.

For example:

let tx = new Transaction();

// Add a compute unit limit instruction (a normal instruction)
const setComputeUnitLimitInstruction = ComputeBudgetProgram.setComputeUnitLimit(
  { units: 200_000 }
);
tx.add(setComputeUnitLimitInstruction);

// Add the 'reveal' instruction from my Anchor program
const revealInstruction = await program.methods
  .reveal(id, encodedData)
  .instruction();
tx.add(revealInstruction);

const transactionSignature = await connection.sendTransaction(tx, [sender], {
  skipPreflight: true,
});

3
  • 2
    Good point! You can also do .transaction() and then add instructions if that's easier. It's a really nicely thought out API :)
    – Callum M
    Sep 13, 2022 at 14:49
  • 1
    Oh sweet, didn't know that. Great API.
    – Sushi
    Sep 13, 2022 at 14:51
  • I really liked this answer - being able to add my transactions using normal web3.js methods was very convenient - so I added to the example a little. I hope that's OK. Jan 30 at 20:05

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.