4

I'm trying bundle an OrcaSwap tx with another transaction. The thing is, I'm getting a "Signature verification failed" error when trying to serialize the transaction. My code goes something like this:

const existingTransaction = ...;
const swapPayload = await orcaPool.swap(payer, inputToken, amountIn, minAmountOut);

// so that the swap is called first before the existing tx
const transaction = swapPayload.tx.add(existingTransaction);

// finalizeTransaction() just adds blockhash and lastValidBlockHeight
// technically this is unneeded but the call is part of a larger function
// so I just kept it this way
finalizeTransactions(transaction);

// partially sign with orca signers
transaction.partialSign(...swapPayload.signers);

I then attempt to sign the transaction with my payer Keypair, but it fails here:

transaction.sign(user);
// fails here 
const rawTx = transaction.serialize();
const signature = await sendAndConfirmRawTransaction(connection, rawTx, opts);

I have made sure that the transaction is not modified in anyway after partialSign, aside from being finally signed by my keypair. Pretty much stuck at this point, would appreciate any help or hints to a solution.

To add (not sure if this is relevant) but I'm on localnet with the relevant OrcaPool account infos. I assume this isn't related as it fails on serialize() but thought I'd mention it anyway.

1 Answer 1

2

Transaction.sign() resets all existing signatures in the transaction https://github.com/solana-labs/solana-web3.js/blob/ef5a6daf1c404b51bdda186274a955276c8b6e90/src/transaction/legacy.ts#L617. I've run into the same problem since the Transaction.sign() docs didn't seem totally clear about this.

Just use Transaction.partialSign() for all signatures and you should be okay.

2
  • 1
    I concur - when I was trying on localnet (I was signing transactions via test scripts rather than a normal WalletAdapter), the solution was to just sign() with signers set to [...signers, keypair] rather than separating the signing. When using with a WalletAdapter, it works to partialSign, and then do wallet.signTransaction(). While your answer is correct, it doesn't directly answer the question. Would still love to know if it's possible to sign a partially-signed transaction when running unit tests.
    – Kurt
    Commented Aug 28, 2022 at 10:11
  • 2
    @Kurt I mean to use Transaction.partialSign() multiple times on the same tx and never use Transaction.sign(). ie where you are performing the second signing of your transaction as transaction.sign(user), replace that with transaction.partialSign(user). You can just replace all the places you were calling sign() with partialSign(). WalletAdapter's signTransaction() method works more like partialSign() in that it doesn't delete existing signatures, so that's why it was working for you where Transaction.sign() was not.
    – snth
    Commented Aug 29, 2022 at 20:45

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.