@ledgerhq/coin-canton
Version:
45 lines • 1.91 kB
JavaScript
import { splitTransaction } from "@ledgerhq/hw-app-canton";
/**
* Sign a Canton transaction - handles both prepared transactions and untyped versioned messages
*/
export async function signTransaction(signer, derivationPath, transactionData) {
let signPayload;
// OnboardingPrepareResponse — sign topology transactions as untyped versioned messages
if ("transactions" in transactionData && transactionData.transactions) {
const challenge = getTransactionChallenge(transactionData);
const { transactions } = transactionData;
signPayload = {
transactions: [
transactions.namespace_transaction.serialized,
transactions.party_to_key_transaction.serialized,
transactions.party_to_participant_transaction.serialized,
],
...(challenge && { challenge }),
};
}
else {
// PrepareTransferResponse / PrepareTransactionResponse (.json) or raw JSON from craftTransaction
const rawTransactionData = "json" in transactionData ? transactionData.json : transactionData;
signPayload = splitTransaction(rawTransactionData);
}
const signature = await signer.signTransaction(derivationPath, signPayload);
if (!signature?.signature) {
throw new Error("Device returned empty signature");
}
return signature;
}
const getTransactionChallenge = ({ challenge_nonce, challenge_deadline, }) => {
if (!challenge_nonce || !challenge_deadline) {
return undefined;
}
try {
const deadlineHex = Buffer.alloc(8);
deadlineHex.writeBigInt64BE(BigInt(challenge_deadline), 0);
// Format: [length (1B) = 0x18][challenge (16 bytes)][deadline (8 bytes)]
return "18" + challenge_nonce.toLowerCase() + deadlineHex.toString("hex");
}
catch {
return undefined;
}
};
//# sourceMappingURL=sign.js.map