Cardano Transaction Signing
To sign and broadcast the transaction to the Cardano network, follow these steps:
-
Prepare unsigned transaction in Base64 encrypted format.
-
Sign the transaction using the following code:
import {
Bip32PrivateKey,
Transaction,
TransactionHash,
TransactionWitnessSet,
Vkey,
Vkeywitness,
Vkeywitnesses,
} from "@emurgo/cardano-serialization-lib-nodejs";
import { mnemonicToEntropy } from "bip39";
import { blake2b } from "blakejs";
const MNEMONIC = "<MNEMONIC>";
const RAW_TX_HEX = "<RAW_TX_HEX>";
function deriveKey(mnemonic: string, role: number, index = 0): Bip32PrivateKey {
const entropy = Buffer.from(mnemonicToEntropy(mnemonic), "hex");
const rootKey = Bip32PrivateKey.from_bip39_entropy(entropy, Buffer.from(""));
return rootKey
.derive(1852 | 0x80000000) // purpose
.derive(1815 | 0x80000000) // coin type
.derive(0 | 0x80000000) // account 0
.derive(role) // role: 0=payment, 2=stake
.derive(index); // index
}
function signTransactionHex(
unsignedHex: string,
paymentKey: Bip32PrivateKey,
stakeKey: Bip32PrivateKey
): string {
const tx = Transaction.from_bytes(Buffer.from(unsignedHex, "hex"));
const txHashBytes = blake2b(tx.body().to_bytes(), undefined, 32);
const txHash = TransactionHash.from_bytes(txHashBytes);
const witnesses = Vkeywitnesses.new();
// Payment key witness
const rawPaymentKey = paymentKey.to_raw_key();
witnesses.add(
Vkeywitness.new(
Vkey.new(rawPaymentKey.to_public()),
rawPaymentKey.sign(txHash.to_bytes())
)
);
// Stake key witness
const rawStakeKey = stakeKey.to_raw_key();
witnesses.add(
Vkeywitness.new(
Vkey.new(rawStakeKey.to_public()),
rawStakeKey.sign(txHash.to_bytes())
)
);
const witnessSet = TransactionWitnessSet.new();
witnessSet.set_vkeys(witnesses);
const signedTx = Transaction.new(tx.body(), witnessSet, tx.auxiliary_data());
return Buffer.from(signedTx.to_bytes()).toString("hex");
}
async function main() {
if (!RAW_TX_HEX || RAW_TX_HEX.length < 10) {
throw new Error("❌ RAW_TX_HEX is missing or invalid.");
}
const paymentKey = deriveKey(MNEMONIC, 0); // m/1852'/1815'/0'/0/0
const stakeKey = deriveKey(MNEMONIC, 2); // m/1852'/1815'/0'/2/0
const signedHex = signTransactionHex(RAW_TX_HEX, paymentKey, stakeKey);
console.log("✅ Signed Cardano Tx (hex):");
console.log(signedHex);
}
main().catch(console.error);
Upon successful execution, the script prints the signed transaction in the hexadecimal format, ready to be broadcasted:
✅ Signed Cardano Tx (hex): ...
- Broadcast the transaction to the Cardano network by sending a POST request to /api/v1/unified/transaction/broadcast.
What's Next?
Updated about 1 month ago