Skip to content
Logo

Example: delegate

To run this example:

  • Clone the examples repository: git clone https://github.com/throgxyz/examples.git
  • Run: cargo run -p examples-staking --example delegate
//! Delegate energy (or bandwidth) to another account on the Nile testnet.
//!
//! Delegation lets you share your staked resources with another address —
//! useful for paying for a dApp user's transactions without transferring TRX.
//!
//! Required env:
//!   TRON_PRIVATE_KEY — hex private key of the delegating account
//!   TRON_DELEGATE_TO — address to receive the delegation
//!
//! Optional env:
//!   TRON_API_KEY     — TronGrid API key
//!   TRON_FREEZE_SUN  — amount to delegate in sun (default: 10 TRX = 10_000_000)
//!   TRON_LOCK_DAYS   — lock delegation for N days (0–10; default: 0 = no lock)
//!
//! ```bash
//! TRON_PRIVATE_KEY=<key> TRON_DELEGATE_TO=<addr> cargo run -p examples-staking --example delegate
//! ```
 
use tronz::{
    LocalSigner, ProviderBuilder, TRONGRID_NILE, TronProvider, TronSigner, Trx,
    primitives::ResourceCode,
};
 
#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let key_hex = std::env::var("TRON_PRIVATE_KEY").expect("TRON_PRIVATE_KEY env var required");
    let to_str = std::env::var("TRON_DELEGATE_TO").expect("TRON_DELEGATE_TO env var required");
    let api_key = std::env::var("TRON_API_KEY").ok();
    let freeze_sun: i64 =
        std::env::var("TRON_FREEZE_SUN").ok().and_then(|s| s.parse().ok()).unwrap_or(10_000_000);
    let lock_days: i64 =
        std::env::var("TRON_LOCK_DAYS").ok().and_then(|s| s.parse().ok()).unwrap_or(0);
 
    let signer = LocalSigner::from_hex(&key_hex)?;
    let me = signer.address();
    let receiver: tronz::Address = to_str.parse()?;
 
    let provider = ProviderBuilder::new()
        .with_recommended_fillers()
        .with_signer(signer)
        .maybe_api_key(api_key)
        .on_grpc(TRONGRID_NILE)
        .await?;
 
    let amount = Trx::from_sun(freeze_sun)?;
 
    // ── Check how much is delegatable ─────────────────────────────────────────
 
    let max = provider.get_can_delegate_max(me, ResourceCode::Energy).await?;
    println!("=== Delegation ===");
    println!("  from            : {me}");
    println!("  to              : {receiver}");
    println!("  requested       : {amount}");
    println!("  max delegatable : {} TRX (energy)", max);
 
    if amount > max {
        anyhow::bail!(
            "requested {} TRX but max delegatable is {} TRX — stake more energy first",
            amount,
            max
        );
    }
 
    // ── Current delegations to receiver ──────────────────────────────────────
 
    let current = provider.get_delegated_resource(me, receiver).await?;
    if !current.is_empty() {
        println!("\n=== Existing delegations to {receiver} ===");
        for d in &current {
            if d.energy_amount.as_sun() > 0 {
                println!("  energy    : {} TRX", d.energy_amount);
                if d.energy_expire_time_ms > 0 {
                    println!("  locked until: {} ms", d.energy_expire_time_ms);
                }
            }
            if d.bandwidth_amount.as_sun() > 0 {
                println!("  bandwidth : {} TRX", d.bandwidth_amount);
            }
        }
    }
 
    // ── Delegate ──────────────────────────────────────────────────────────────
 
    println!("\n=== Delegating {} energy to {} ===", amount, receiver);
 
    let mut builder =
        provider.delegate_resource().resource(ResourceCode::Energy).amount(amount).to(receiver);
 
    if lock_days > 0 {
        // Lock period is in seconds: 1 day = 86_400 seconds.
        // Max lock is 10 days (864_000 seconds).
        let lock_secs = lock_days.min(10) * 86_400;
        builder = builder.lock_period(lock_secs);
        println!("  lock period : {lock_days} day(s) ({lock_secs}s)");
    }
 
    let pending = builder.send().await?;
    println!("  tx_id  : 0x{}", hex::encode(pending.tx_id()));
    println!("  waiting for confirmation…");
    let info = pending.get_receipt().await?;
    println!("  status : {:?}", info.status);
 
    // ── Verify ───────────────────────────────────────────────────────────────
 
    let after = provider.get_delegated_resource(me, receiver).await?;
    for d in &after {
        if d.energy_amount.as_sun() > 0 {
            println!("\n=== Confirmed ===");
            println!("  energy delegated to {receiver}: {} TRX", d.energy_amount);
        }
    }
 
    Ok(())
}

Find the source code on GitHub here.