> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tron

> Derive Tron addresses and sign transactions using Dynamic embedded wallets in React Native

## Overview

Tron uses the secp256k1 elliptic curve with keccak256 hashing — the same cryptographic scheme as Ethereum. Tron addresses are derived directly from the EVM address without key recovery: swap the `0x` prefix for `41` and base58check-encode.

| Property       | Value                  |
| -------------- | ---------------------- |
| Curve          | secp256k1              |
| Root Wallet    | EVM                    |
| Address Format | base58check (`T...`)   |
| Hashing        | Keccak-256             |
| Serialization  | TronWeb SDK            |
| Smallest Unit  | Sun (1 TRX = 10^6 sun) |

## Dependencies

<CodeGroup>
  ```bash npm theme={"system"}
  npm install tronweb
  ```

  ```bash yarn theme={"system"}
  yarn add tronweb
  ```

  ```bash pnpm theme={"system"}
  pnpm add tronweb
  ```

  ```bash bun theme={"system"}
  bun add tronweb
  ```
</CodeGroup>

## Derive Address

Swap the EVM address prefix from `0x` to `41` and base58check-encode:

```typescript theme={"system"}
import { TronWeb } from "tronweb";

function deriveTronAddress(evmAddress: string): string {
  const hex = "41" + evmAddress.slice(2).toLowerCase();
  return TronWeb.address.fromHex(hex);
}
```

<Tip>
  This is the simplest derivation of all secp256k1 chains — no key recovery needed. The last 20 bytes of keccak256(uncompressed\_pubkey) are identical for both EVM and Tron.
</Tip>

## Sign a Message

```typescript theme={"system"}
import { keccak256, toUtf8Bytes, concat } from "tronweb/utils";

async function signTronMessage(message: string): Promise<string> {
  const wallet = dynamicClient.wallets.userWallets.find(w => w.chain === "EVM")!;

  const messageBytes = toUtf8Bytes(message);
  const prefix = toUtf8Bytes("\x19TRON Signed Message:\n");
  const lengthStr = toUtf8Bytes(String(messageBytes.length));
  const messageDigest = keccak256(concat([prefix, lengthStr, messageBytes]));

  const signature = await dynamicClient.wallets.waas.signRawMessage(wallet.id, {
    accountAddress: wallet.address,
    message: messageDigest.replace(/^0x/, ""),
  });

  return signature;
}
```

## Sign a Transaction

Build the unsigned transaction with TronWeb, then sign the transaction ID and broadcast:

```typescript theme={"system"}
import { TronWeb } from "tronweb";

const tw = new TronWeb({ fullHost: "https://nile.trongrid.io" });

async function sendTrxTransfer(
  to: string,
  amount: number,
  tronAddress: string,
): Promise<string> {
  const wallet = dynamicClient.wallets.userWallets.find(w => w.chain === "EVM")!;
  const amountSun = BigInt(Math.round(amount * 1_000_000));

  const unsignedTx = await tw.transactionBuilder.sendTrx(
    to,
    Number(amountSun),
    tronAddress,
  );

  // The transaction ID is the hash to sign
  const txId = unsignedTx.txID.replace(/^0x/, "");
  const signature = await dynamicClient.wallets.waas.signRawMessage(wallet.id, {
    accountAddress: wallet.address,
    message: txId,
  });

  // Normalize the v-byte to Tron's expected range (27 or 28)
  const sigBytes = hexToBytes(signature.replace(/^0x/, ""));
  const sig65 = new Uint8Array(65);
  sig65.set(sigBytes.slice(0, 64));
  let v = sigBytes[64];
  if (v < 27) v += 27;
  sig65[64] = v;

  const signedTx = { ...unsignedTx, signature: [bytesToHex(sig65)] };
  const result = await tw.trx.broadcast(signedTx);

  if (!result.result) throw new Error(`Broadcast failed: ${result.message}`);
  return result.txid;
}
```

<Note>
  Tron signing is simpler than other chains because TronWeb handles transaction construction and serialization. You only need to sign the transaction ID (a SHA-256 hash) using the EVM wallet's raw signing capability.
</Note>

## Verify a Signature

```typescript theme={"system"}
import { TronWeb } from "tronweb";

async function verifyTronSignature(message: string, signature: string): Promise<string> {
  const tw = new TronWeb({ fullHost: "https://nile.trongrid.io" });
  return tw.trx.verifyMessageV2(message, signature);
}
```

## Check Balance

```typescript theme={"system"}
async function getTronBalance(tronAddress: string): Promise<string> {
  const tw = new TronWeb({ fullHost: "https://nile.trongrid.io" });
  const sunBalance = await tw.trx.getBalance(tronAddress);
  return (Number(sunBalance) / 1_000_000).toString();
}
```

For full implementation details including TRC20 transfers see the [JavaScript Tron guide](/javascript/reference/tier-2-chains/tron). The only difference in React Native is the signing call.
