Fillers
A filler automatically populates fields on a transaction before it is signed
and broadcast — things the caller shouldn't have to compute by hand. tronz
borrows this pattern directly from alloy: you stack fillers on the
ProviderBuilder, and they run on every
.send().
Why fillers exist
A TRON transaction needs more than just "to" and "amount". It must reference a
recent block (TAPOS, for replay protection and expiry), and contract operations
need a fee_limit. The node endpoints that build the currently supported
transactions already fill TAPOS for you, so the recommended set installs an
EnergyFiller that estimates contract energy and derives fee_limit.
with_tapos() remains available for locally referenced transactions.
The recommended set
For almost any read/write provider, start here:
use tronz::{LocalSigner, ProviderBuilder, TRONGRID_NILE};
let provider = ProviderBuilder::new()
.with_signer(signer)
.connect_grpc(TRONGRID_NILE)
.await?;ProviderBuilder::new() already calls with_recommended_fillers(), which adds:
let builder = ProviderBuilder::default()
.with_energy(EnergyFiller::new());It does not add the TAPOS filler: the node endpoints that build the
currently supported transactions already fill TAPOS. Add with_tapos()
explicitly if you build transactions that need tronz to fill those fields.
Available fillers
| Filler | Added by | Fills |
|---|---|---|
| TAPOS | with_tapos() | The reference block hash + expiration (required before broadcast) |
| Energy | new(), with_recommended_fillers(), or with_energy(...) | Estimates energy and derives fee_limit with a safety margin |
| Fee limit | with_fee_limit(Trx) | Sets a fixed default fee_limit |
| Wallet | with_signer(s), wallet(w), or strict_wallet(w) | Selects a credential and signs the transaction id |
The wallet is itself part of the filler chain — that's why a provider's ability
to .send() is encoded in its type. wallet() prefers the owner's key and
falls back to the wallet's default key, which supports active permissions owned
by another account. strict_wallet() rejects a transaction when the wallet has
no key matching its owner.
Choosing a fee limit per call
The fee-limit filler sets a default. The fee limit is the maximum TRX you'll spend if you don't have enough staked energy/bandwidth. Override it when needed via the transaction builders (see Transactions), or set a different default:
use tronz::{ProviderBuilder, Trx, TRONGRID_NILE};
let provider = ProviderBuilder::new()
.with_fee_limit("100".parse()?) // higher cap for heavy contract calls
.connect_grpc(TRONGRID_NILE)
.await?;Estimating energy first
For contract calls you can estimate the energy cost before sending, so you can
pick a sensible fee_limit — analogous to estimate_gas in alloy:
let energy = provider.estimate_energy(params).await?;