Energy Delegation

Delegate generated ENERGY to another TRON account without transferring ownership of the frozen TRX.

Energy Delegation

Delegate generated ENERGY to another TRON account without transferring ownership of the underlying frozen TRX.

What is Energy delegation?

On TRON, every action that touches a smart contract (including TRC-20 transfers, e.g. USDT) consumes ENERGY. ENERGY is generated by freezing TRX via /staking/delegate, the same mechanism used for BANDWIDTH and voting power.

Energy delegation lets the account that froze the TRX (the owner) share the ENERGY it generates with a different account (the receiver), without moving the frozen TRX itself and without giving up ownership of it. The owner keeps the frozen balance, its voting rights, and can reclaim the delegated resource at any time after the lock period expires.

This is the pattern used to cover gas costs for a large number of wallets from a single pool of frozen TRX — for example, an exchange or a custodian freezing TRX once and delegating ENERGY to hundreds of hot wallets so that each of them can pay for TRC-20 transfers without holding TRX of its own.

The full flow

Energy delegation sits between the freeze and unfreeze steps of the regular TRON staking flow:

freeze  →  delegate-resource  →  undelegate-resource  →  unfreeze  →  withdraw
StepEndpointDescription
  1. Freeze
/staking/delegateFreeze TRX and generate ENERGY on the owner account
  1. Delegate resource
/staking/delegate-resourceDelegate generated ENERGY from the owner to a receiver account.
  1. Undelegate resource
/staking/undelegate-resourceReclaim previously delegated ENERGY back to the owner, once the delegation lock period has passed.
  1. Unfreeze
/staking/undelegateUnfreeze the owner's TRX
  1. Withdraw
/staking/withdrawClaim the unfrozen TRX back to the available balance

Steps 1, 4, and 5 are the standard freeze/unfreeze/withdraw operations already described in Getting Started and Withdrawal. This guide focuses on steps 2 and 3, which sit in between.

Note that the owner does not have to unfreeze immediately after undelegating. ENERGY can be delegated and reclaimed many times over the lifetime of a single frozen balance — unfreezing is only required once the owner wants the underlying TRX back.

Signing model

As with any other operation on TRON, /staking/delegate-resource and /staking/undelegate-resource only build and return an unsigned transaction — the API never holds or uses your private key. The client is responsible for signing every transaction in the flow (freeze, delegate-resource, undelegate-resource, unfreeze, withdraw) individually with the P2P Signer SDK and broadcasting it via /transaction/send, following the steps described in Sign and Broadcast Transaction.

The owner address that signs the delegate/undelegate-resource transaction must be the same address that froze the TRX (delegatorAddress) — the receiver never signs anything as part of this flow.

1. Create delegate-resource request

To delegate generated ENERGY to a receiver account, send a POST request to /api/v1/tron/{network}/staking/delegate-resource.

Example request (for testnet-nile network):

curl --request POST \
  --url 'https://api-test.p2p.org/api/v1/tron/testnet-nile/staking/delegate-resource' \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "delegatorAddress": "TVscj8F6wPZ92d1smGYjH9heZR1MaEcE9u",
    "amount": 1000000,
    "resource": "ENERGY"
}'
  • delegatorAddress — owner account address, i.e. the account that froze the TRX and generated the ENERGY.
  • amount — amount of resource to delegate, in SUN (1 TRX = 10⁶ SUN).
  • resource — resource type to delegate. Only ENERGY is supported in the current version, defaults to ENERGY.

Example response:

{
  "error": {},
  "result": {
    "delegatorAddress": "TNDzfERDpxLDS2w1q6yaFC7pzqaSQ3Bg3r",
    "receiverAddress": "TNDzfERDpxLDS2w1q6yaFC7pzqaSQ3Bg3r",
    "amount": 10000000,
    "resource": "ENERGY",
    "lockPeriod": 28800,
    "unsignedTransaction": {},
    "unsignedTransactionSerialized": "eyJ0eElEIjoidHJ4SWQifQ==",
    "createdAt": "2025-06-03T12:00:00.000Z"
  }
}
  • delegatorAddress — owner account address.
  • receiverAddress — account address receiving the delegated resource.
  • amount — amount of resource delegated, in SUN.
  • resource — resource type delegated: ENERGY.
  • unsignedTransaction — original unsigned transaction object returned by tronWeb.
  • unsignedTransactionSerialized — unsigned serialized transaction in Base64 format, ready for signing.
  • createdAt — timestamp of the transaction in the ISO 8601 format.

Delegation lock

TRON enforces a protocol-level lock on delegated resources: once ENERGY has been delegated to a receiver, it cannot be undelegated for approximately 24 hours from the moment the delegation transaction is confirmed. This is a network rule, and it applies per delegation — each new /staking/delegate-resource call starts its own 24-hour lock for the amount it delegates.

Calling /staking/undelegate-resource before the lock period has elapsed will cause the transaction to fail on-chain. Plan any automated re-delegation or rebalancing logic around this window, and track the delegation's confirmation time so you know when it becomes eligible for undelegation.

2. Create undelegate-resource request

Once the lock period has passed, reclaim the delegated ENERGY back to the owner account by sending a POST request to /api/v1/tron/{network}/staking/undelegate-resource.

Example request (for testnet-nile network):

curl --request POST \
  --url 'https://api-test.p2p.org/api/v1/tron/testnet-nile/staking/undelegate-resource' \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "delegatorAddress": "TVscj8F6wPZ92d1smGYjH9heZR1MaEcE9u",
    "amount": 1000000,
    "resource": "ENERGY"
}'
  • delegatorAddress — owner account address that originally delegated the resource.
  • amount — amount of resource to reclaim, in SUN.
  • resource — resource type to reclaim. Only ENERGY is supported, defaults to ENERGY.

Example response:

{
  "error": {},
  "result": {
    "delegatorAddress": "TNDzfERDpxLDS2w1q6yaFC7pzqaSQ3Bg3r",
    "receiverAddress": "TNDzfERDpxLDS2w1q6yaFC7pzqaSQ3Bg3r",
    "amount": 10000000,
    "resource": "ENERGY",
    "unsignedTransaction": {},
    "unsignedTransactionSerialized": "eyJ0eElEIjoidHJ4SWQifQ==",
    "createdAt": "2025-06-03T12:00:00.000Z"
  }
}

Field descriptions mirror the delegate-resource response above; the only difference is the underlying UnDelegateResourceContract type.

Error codes

/staking/delegate-resource and /staking/undelegate-resource can return the following 400 Bad request errors in addition to the standard 401 and 429 responses:

CodeDescription
ExceedsDelegatableMaxExeptionThe requested amount exceeds the amount of ENERGY
InvalidReceiverExeptionreceiverAddress is malformed or is not a valid
ReceiverEqualsOwnerExeptionreceiverAddress is the same as delegatorAddress
ResourceNotSupportedExeptionresource is set to a value other than ENERGY
InvalidDelegatorAddressExeptiondelegatorAddress is malformed or does not match the address used to freeze the TRX
FreezeAmountTooLowExeptionThe requested amount is below the minimum amount that can be delegated.

Testing on the Nile testnet

Before delegating on mainnet, validate the full flow on TRON's Nile testnet using the testnet-nile network identifier.

  1. Fund a Nile testnet account. Use the Nile faucet to receive test TRX on your account.

  2. Freeze TRX for ENERGY. Send a POST request to /api/v1/tron/testnet-nile/staking/delegate with resource: "ENERGY", sign, and broadcast the transaction, as described in Getting Started.

  3. Delegate the resource. Send a POST request to:

    https://api-test.p2p.org/api/v1/tron/testnet-nile/staking/delegate-resource

    with your delegatorAddress, a receiverAddress you control (a second Nile testnet account), and the amount to delegate. Sign and broadcast the returned transaction.

  4. Broadcast via POST /tron/testnet-nile/transaction/send

  5. Verify the delegation. The transaction confirms as DelegateResourceContract; getDelegatedResourceV2(owner, pool) shows the delegation with an expire_time.

  6. Undelegate the resource. Before the lock has expired, send a POST request to:

    https://api-test.p2p.org/api/v1/tron/testnet-nile/staking/undelegate-resource

    with the same delegatorAddress/receiverAddress pair and amount, then sign and broadcast.

Testnet transactions use the same request/response shapes as mainnet. Only the network path parameter and the api-test.p2p.org host differ, so code validated on Nile carries over to production without changes.

What's next?


Did this page help you?