2

I'm seeking clarity regarding the signers involved in transactions with the system program. Can transactions accommodate additional signers beyond the required ones mandated by the program?

For instance, suppose I intend to transfer lamports from one account to another using the standard system program, but I also require a third party to co-sign the transaction. If this third party is neither the funding account nor the fee-payer, is there a method to include their signature in the transaction?

2 Answers 2

4
+50

Yes you can do this by adding additional singers in the frontend like this:

let tx = await program.methods
      .mintNft()
      .accounts(
        {
          signer: payer.publicKey,
          systemProgram: anchor.web3.SystemProgram.programId,
          tokenProgram: TOKEN_2022_PROGRAM_ID,
          associatedTokenProgram: ASSOCIATED_PROGRAM_ID,
          tokenAccount: destinationTokenAccount,
          mint: mint.publicKey,
        }    
      ).signers([mint])
      .rpc({skipPreflight: true});

Here you can see that for the NFT mint we also put the mint keypair as an additional signer.

You can then in the program as a signer:

#[account(mut)]
pub mint: Signer<'info>,

and then use the account as normal in the program. And just use the signer for your system program transfer.

If you want to partial sign in the backend and then add the users signature in the fronten you can do this like this:

    const hash = await CONNECTION.getLatestBlockhash();

  const transaction = await mintCompressedNft(
    CONNECTION,
    nftArgs,
    ownerWallet.publicKey,
    TreeAccount,
    CollectionMint,
    collectionMetadataAccount, 
    collectionMasterEditionAccount,
    feepayer
  );
  transaction.recentBlockhash = hash.blockhash;

  transaction.partialSign(ownerWallet);
  console.log("transaction " + transaction.instructions.length);
  
  const serializedTransaction = transaction.serialize({
    verifySignatures: false,
    requireAllSignatures: false,
  });

  const base64Transaction = serializedTransaction.toString('base64');

  res.status(200).json({
    transaction: base64Transaction,
    message: "OK",
  });

Here is a complete example: https://github.com/solana-developers/one-milion-nfts/blob/main/next/pages/api/mint.ts

2

Hey there as you can see:

pub fn transfer<'info>(
    ctx: CpiContext<'_, '_, '_, 'info, Transfer<'info>>,
    amount: u64,
) -> Result<()> {
    #[allow(deprecated)]
    let ix = spl_token_2022::instruction::transfer(
        ctx.program.key,
        ctx.accounts.from.key,
        ctx.accounts.to.key,
        ctx.accounts.authority.key,
        &[],//SIGNER PUBKEYS
        amount,
    )?;
    solana_program::program::invoke_signed(
        &ix,
        &[ctx.accounts.from, ctx.accounts.to, ctx.accounts.authority],
        ctx.signer_seeds,
    )
    .map_err(Into::into)
}

You can have many signer pubkeys.

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.