Do they have to deserialize that to tx object again and then sign ? Any way to sign without deserializing the tx ?
2 Answers
It depends on your use case. It's possible to arbitrarily sign any message (serialized transaction).
e.g. with the tweet NaCl library:
// imports
import * as nacl from "tweetnacl";
const tx = new Transaction().add(//some instruction);
const serializedTx = tx.serializeMessage();
// Sign Transaction
const signature = nacl.sign.detached(
serializedTx,
some.secretKey // The private key you want to sign the transaction with
);
You can use this signature to verify later that the transaction hasn't been modified/changed.
Though it's equally trivial to deserialize the transaction and signing it (via partialSign()
or sign()
).
// serializedTx = some serialized transaction
const deserializedTx = Transaction.from(
Buffer.from(serializedTx, "base64")
);
You will have to call sign
or partialSign
if an instruction that's part of the transaction requires the authority on that account to sign.
No, you cannot sign a serialized transaction without deserializing it first.
Actually the funny thing, all signers need to sign a serialized message.
But, the serialized message is not the only thing what is in the transaction. A transaction also contains other metadata and information about the signers which does not need to be signed. Therefore you always first need to deserialize the tx, extract the message (containing the instructions, feepayer and such data you need to sign), serialize that message, and sign it.
Deserializing a transaction can be done with the static from() method.
-
you've rightly pointed out a flaw that exists specifically in the data structures design of
@solana/web3.js
. none of the signing operations should ever have been implemented onTransaction
, rather they should all be onKeypair
(orSigner
? I forget) and takeMessage
as an argument Commented Jul 21, 2022 at 18:07