UNPKG

@ledgerhq/coin-tezos

Version:
121 lines (108 loc) 3.69 kB
import { type OperationContents, OpKind } from "@taquito/rpc"; import { DEFAULT_FEE } from "@taquito/taquito"; import coinConfig from "../config"; import { UnsupportedTransactionMode } from "../types/errors"; import { getTezosToolkit } from "./tezosToolkit"; export type TransactionFee = { fees?: string; gasLimit?: string; storageLimit?: string; }; export type TransactionType = "OUT" | "DELEGATE" | "UNDELEGATE"; export async function craftTransaction( account: { address: string; counter?: number; }, transaction: { type: "send" | "delegate" | "undelegate"; recipient: string; amount: bigint; fee: TransactionFee; }, publicKey?: { publicKey: string; publicKeyHash: string; }, ): Promise<{ type: TransactionType; contents: OperationContents[] }> { const { address } = account; const transactionFees = { fee: transaction.fee.fees ?? "0", gas_limit: transaction.fee.gasLimit ?? "0", storage_limit: transaction.fee.storageLimit ?? "0", }; const tezosToolkit = getTezosToolkit(); const sourceData = await tezosToolkit.rpc.getContract(address); const counter = account.counter ?? Number(sourceData.counter); const contents: OperationContents[] = []; if (publicKey !== undefined) { const revealFees = await tezosToolkit.estimate.reveal(); const minRevealGasLimit = coinConfig.getCoinConfig().fees.minRevealGasLimit; const revealGasLimit = Math.max(revealFees?.gasLimit || 0, minRevealGasLimit); contents.push({ kind: OpKind.REVEAL, fee: DEFAULT_FEE.REVEAL.toString(), //TODO: use instead of previous line when this PR will be validated, as the value change (don't forget to update the test too) // fee: getRevealFee(address).toString(), gas_limit: revealGasLimit.toString(), storage_limit: (revealFees?.storageLimit || 0).toString(), source: publicKey.publicKeyHash, counter: (counter + 1 + contents.length).toString(), public_key: publicKey.publicKey, }); } let type: TransactionType; switch (transaction.type) { case "send": { type = "OUT"; contents.push({ kind: OpKind.TRANSACTION, amount: transaction.amount.toString(), destination: transaction.recipient, source: address, counter: (counter + 1 + contents.length).toString(), ...transactionFees, }); break; } case "delegate": { type = "DELEGATE"; contents.push({ kind: OpKind.DELEGATION, source: address, counter: (counter + 1 + contents.length).toString(), delegate: transaction.recipient, ...transactionFees, }); break; } case "undelegate": { // we undelegate as there's no "delegate" field // OpKind is still "DELEGATION" type = "UNDELEGATE"; contents.push({ kind: OpKind.DELEGATION, source: address, counter: (counter + 1).toString(), ...transactionFees, }); break; } default: throw new UnsupportedTransactionMode("unsupported mode", { mode: transaction.type }); } return { type, contents }; } /** * Return transaction in raw encoded format (i.e. hexa) */ export async function rawEncode(contents: OperationContents[]): Promise<string> { const tezosToolkit = getTezosToolkit(); const block = await tezosToolkit.rpc.getBlock(); const forgedBytes = await tezosToolkit.rpc.forgeOperations({ branch: block.hash, contents, }); // 0x03 is a conventional prefix (aka a watermark) for tezos transactions return Buffer.concat([Buffer.from("03", "hex"), Buffer.from(forgedBytes, "hex")]).toString("hex"); }