How to Buy TRON Energy Programmatically, Without Manual Confirmation

Energy on TRON is acquired the same way as any other operation: your backend builds an unsigned transaction via the API (FreezeBalanceV2 for staking, DelegateResource to hand the resource over to a hot address), signs it with a local private key, and submits it to broadcasttransaction. Manual confirmation is only required when the key lives in the user's wallet; if your code holds the key, there is nothing to confirm. An alternative to staking is renting energy on JustLend DAO's Energy Rental Market without freezing any TRX.
Short answer: TRON energy is purchased programmatically using the same build → sign → broadcast flow as an ordinary transfer. Your service builds an unsigned transaction with an HTTP method (wallet/freezebalancev2 — staking for energy, DelegateResource — assigning the resource to a specific address), signs it locally with the pool's private key, and submits it to wallet/broadcasttransaction. Manual confirmation only appears where the key sits in the user's wallet (TronLink, ecosystem MCP servers). If your code holds the key, there is nothing to confirm, and automated procurement becomes just another step in the payout pipeline.
Where energy comes from
Unlike Bandwidth, Energy has no free daily quota (Bandwidth does — 600 units per day for an external account). To execute a TRC-20 transfer, an account must either have staked or delegated energy, or top it up by burning TRX at the current getEnergyFee price — the documentation lists 100 sun (0.0001 TRX) per unit. This is a chain parameter changed by SR voting, so in production it should be read from the network rather than hardcoded.
There are two standard ways to obtain energy:
- staking TRX (Stake 2.0) — you freeze TRX and receive a share of the total network limit according to the formula
staked TRX / total network TRX staked for Energy × 180,000,000,000; - renting on JustLend DAO's Energy Rental Market — access to energy without freezing your own assets.
The primitive that pools and rental services are built on is DelegateResourceContract: the stake holder delegates energy to another account, and the recipient spends it directly, without staking anything themselves. This is exactly how exchanges and DApp operators cover user costs out of a single staking pool.
The "pool + delegation" architecture
- A dedicated pool account with TRX staked for ENERGY (the minimum for a single FreezeBalanceV2 operation is 1 TRX, i.e. 1,000,000 sun; anything less is rejected with
ContractValidateException). - Before every payout — query
wallet/getaccountresourcefor the hot address: how much energy is available right now. - If there isn't enough —
DelegateResourcefrom the pool for the required amount, sign, broadcast. - After a batch of payouts —
UnDelegateResource, returning the resource to the pool.
The resource field accepts the strings ENERGY or BANDWIDTH. Delegation is reversible, but it supports an optional lock: until the lock expires, the resource cannot be reclaimed — in the backend this must be treated as "the pool is temporarily smaller," otherwise the scheduler will keep bumping into balances it cannot withdraw.
If your resource allocation logic is already on-chain, the same thing can be done without a server: Stake 2.0 is available from Solidity — freezebalancev2(1000000, 1), receiver.delegateResource(1000000, 0), receiver.unDelegateResource(...), plus the view method target.delegatableResource(1) for monitoring the amount available for delegation. Details are in the Bandwidth and Energy section.
If you plan to handle procurement through an AI agent, keep one limitation in mind: TronScan's MCP tools are currently read-only, TronGrid can build unsigned transactions and broadcast already-signed ones, but it does not sign or store private keys, and the other ecosystem servers require explicit user authorization. A fully "hands-off" scenario via MCP is not supported out of the box — signing has to stay inside your own code.
How much to buy: calculating at runtime
Don't hardcode the amount of energy per transfer.
| Step | Method | What it gives you |
|---|---|---|
| Estimation | /wallet/triggerconstantcontract | local execution with no transaction and no resource spend |
| Refinement | estimateenergy | energy_used; more accurate for specific contracts, requires vm.estimateEnergy and vm.supportConstant enabled on the node |
| Price | getEnergyFee (parameter #11) | sun per unit of Energy |
| Ceiling | getMaxFeeLimit (parameter #47) | currently 15,000 TRX |
The math is simple: fee_limit (sun) = energy_required × getEnergyFee. The estimate reflects the node's state at the moment of the request and does not guarantee that the subsequent on-chain transaction will succeed.
The main cost risk is the dynamic energy model (DEM). Parameter #75 getDynamicEnergyMaxFactor returns 34,000 on mainnet, i.e. max_factor = 3.4, while the combined energy multiplier can reach 4.4. The factor changes after the maintenance cycle rolls over, so any cache of estimates that outlives the cycle has to be invalidated. The "always calculate at max_factor" strategy is safe for getting transactions through, but it over-budgets. A breakdown is in FeeLimit & Energy.
Budget separately for activation: calling a smart contract on an "empty" address costs an extra 25,000 Energy on top of the usual spend.
What breaks under load
- Transaction TTL is 60 seconds after building. It happens that a broadcast is "successful" but the transaction never reaches an SR node; retrying only makes sense after the validity period expires.
- OUT_OF_TIME: the global execution limit for a contract transaction is 80 ms (changeable by SR voting). If exceeded, the entire fee_limit is charged.
- Energy is not refunded — neither from stake nor from burning — even if the transaction reverts or fails on another check.
- Recovery takes 24 hours, linearly. If you spend again or revoke a delegation during that period, the system proportionally merges the recovery progress with the new cycle: "revoked" does not mean "immediately available."
- Unstaking takes 14 days:
UnfreezeBalanceV2Contract, wait, thenWithdrawExpireUnfreezeContract. This is not a fast rebalancing tool. - Stake 1.0 in copy-pasted code: older examples contain
frozen_duration: 3andFreezeBalanceContract— copy them and you'll build a transaction for the old mechanism. - API key: the
TRON-PRO-API-KEYheader is only needed for mainnet; Shasta and Nile work without it, and Stake 2.0 behaves there just as it does on mainnet — which makes them the right place to debug automated procurement.
The takeaway: manual confirmation disappears not because of some special "rental API," but because signing stays on your side. Everything else is discipline: estimate energy at runtime, read chain parameters from the network (wallet/getchainparameters), and remember that staking, delegation, and resource recovery each run on their own timers.
This material is for informational purposes only and is not investment advice.