How to Estimate Transaction Fees with GenLayer-JS Fee Presets
GenLayer-JS provides a built-in fee preset system that maps preset levels (low, standard, high) to deterministic fee options, performs raw estimation, optionally simulates the contract call for higher accuracy, and converts the result into a transaction-ready fee payload.
Estimating transaction fees accurately is critical when writing to smart contracts on GenLayer. The genlayer-project-boilerplate repository demonstrates how to leverage fee presets to simplify this process, offering three severity levels that automatically configure appeal rounds and rotation counts. This guide explains how to use the estimateWriteFeePreset helper and related utilities in frontend/lib/genlayer/fees.ts to calculate and apply transaction fees efficiently.
Understanding Fee Presets in GenLayer-JS
GenLayer-JS abstracts complex fee calculations behind intuitive preset levels. Instead of manually configuring appeal rounds and validator rotations, developers select a fee preset level that matches their desired confirmation speed and cost tolerance.
The system recognizes three distinct levels defined by the FeePresetLevel type in frontend/lib/genlayer/fees.ts:
"low"– Minimal fees, suitable for non-urgent transactions with fewer appeal rounds."standard"– Balanced configuration for typical contract interactions."high"– Maximum fee allocation for rapid execution with extensive validation.
These levels map to deterministic configurations via the PRESET_OPTIONS constant (lines 24–30 of fees.ts), which stores the specific appeal round counts and rotation parameters for each tier.
The Fee Estimation Workflow
The estimation process follows a multi-step pipeline that combines static preset options with dynamic simulation data. According to the implementation in frontend/lib/genlayer/fees.ts, the workflow proceeds as follows:
Selecting a Preset Level
Begin by choosing a FeePresetLevel that reflects your transaction priority. This value determines which static options the estimator retrieves from PRESET_OPTIONS before calculating base fees.
Generating Initial Estimates
Call estimateWriteFeePreset (lines 55–94 of fees.ts) with your GenLayer client, contract details, and selected preset level. This function invokes client.estimateTransactionFees using the preset's static configuration to produce an initial fee estimate.
Simulation-Based Refinement
If the client instance implements simulateWriteContract and estimateTransactionFeesFromSimulation, the library performs an additional accuracy step. It simulates the actual contract call—including any custom fee structures—and re-estimates fees based on that simulation result, ensuring the final estimate reflects real execution conditions.
Converting to Transaction Fees
Transform the FeePresetEstimate object into a usable payload using feePresetToTransactionFees (lines 51–53 of fees.ts). This extractor pulls the distribution data, optional message allocations, and final fee value required by the transaction sender.
Implementing Fee Estimation in Practice
To integrate fee estimation into your application, import the helper functions from the boilerplate's fee module and invoke them before writing to the contract.
The following example demonstrates estimating fees for a custom contract method:
import { createClient } from "genlayer-js";
import { studionet } from "genlayer-js/chains";
import {
estimateWriteFeePreset,
feePresetToTransactionFees,
type FeePresetLevel,
type FeePresetEstimate,
} from "./genlayer/fees";
const client = createClient({ chain: studionet, account: "0xYourAddress" });
async function estimateMyMethodFees(
level: FeePresetLevel = "standard"
): Promise<FeePresetEstimate | undefined> {
return estimateWriteFeePreset(
client,
{
address: "0xContractAddress",
functionName: "my_method",
args: [/* method args */],
},
level
);
}
async function sendMyMethod(level?: FeePresetLevel) {
const preset = await estimateMyMethodFees(level);
const fees = feePresetToTransactionFees(preset);
const txHash = await client.writeContract({
address: "0xContractAddress",
functionName: "my_method",
args: [/* method args */],
value: 0n,
...(fees ? { fees } : {}),
});
const receipt = await client.waitForTransactionReceipt({
hash: txHash,
status: "ACCEPTED",
retries: 24,
interval: 5_000,
});
return receipt;
}
Using the FootballBets Wrapper
The FootballBets contract wrapper in frontend/lib/contracts/FootballBets.ts provides a concrete implementation of this pattern. It exposes estimateCreateBetFees and estimateResolveBetFees methods (lines 58–74 and 76–88) that forward preset levels to estimateWriteFeePreset, then apply the results in createBet and resolveBet (lines 101–108 and 131–138).
import FootballBets from "./contracts/FootballBets";
const fb = new FootballBets("0xBetContract", "0xYourAddress");
// Estimate fees for creating a bet with the "high" preset
const feeEstimate = await fb.estimateCreateBetFees(
"2024-11-01",
"TeamA",
"TeamB",
"TeamA",
"high"
);
// Convert to the payload and send the transaction
const receipt = await fb.createBet(
"2024-11-01",
"TeamA",
"TeamB",
"TeamA",
feeEstimate
);
Summary
- GenLayer-JS uses fee presets (
low,standard,high) to abstract complex fee configurations into simple severity levels. - The
estimateWriteFeePresetfunction infrontend/lib/genlayer/fees.tshandles two-step estimation: raw calculation followed by optional simulation refinement. - Convert estimates to transaction payloads using
feePresetToTransactionFeesbefore passing them toclient.writeContract. - The
FootballBetswrapper demonstrates production-ready implementation of this workflow for contract-specific methods.
Frequently Asked Questions
What is the difference between the three fee preset levels?
The low, standard, and high levels map to different configurations of appeal rounds and validator rotations defined in PRESET_OPTIONS. Higher presets allocate more resources for validation and appeals, resulting in faster confirmation but higher costs, while lower presets reduce fees at the expense of potentially slower finality.
Can I use fee presets without simulating the contract call?
Yes. If the client does not implement simulateWriteContract and estimateTransactionFeesFromSimulation, estimateWriteFeePreset returns the initial raw estimate without simulation refinement. However, simulation provides higher accuracy for contracts with complex fee logic.
How do I apply the estimated fees to a transaction?
Pass the result of feePresetToTransactionFees to the fees parameter in client.writeContract. The FootballBets.createBet method demonstrates this pattern by spreading ...(fees ? { fees } : {}) into the write contract options (lines 101–108 of FootballBets.ts).
Where are the fee preset types and constants defined?
All type definitions, preset configurations, and helper functions reside in frontend/lib/genlayer/fees.ts within the genlayer-project-boilerplate repository. The FeePresetLevel type and PRESET_OPTIONS constant appear at the top of this file, while estimateWriteFeePreset occupies lines 55–94.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →