Tron is not "Ethereum with a different chain ID." Wallet and payments builders who paste an EVM provider URL and expect ethers or viem to behave like mainnet Ethereum will hit the wrong API shape, the wrong address encoding, or a public gateway that is rate-limited for production settlement. Before you ship, decide which API you are calling, prove the chain ID, and treat public endpoints as a probe path rather than a payments backplane.
This is not a ranking of providers. Use the TRON Mainnet hub to compare endpoints and paid rows, then run the checks below on the URL you intend to configure.
Two APIs people mix up
Official Tron docs expose more than one way to talk to a node:
- FullNode HTTP API (TronGrid mainnet:
https://api.trongrid.io) — Tron's native HTTP surface. TronWeb and many wallet SDKs expect this shape. - JSON-RPC (TronGrid gateway:
https://api.trongrid.io/jsonrpc) — an Ethereum-compatibleeth_/net_/web3_*surface so Web3.js, ethers, and viem can reuse familiar methods for queries, logs, and contract calls. On a self-hosted java-tron node, JSON-RPC is disabled by default and, when enabled, is usually served at the port root (for examplehttp://127.0.0.1:8545/), not at/jsonrpc./jsonrpcis a TronGrid path. - gRPC — separate FullNode and Solidity ports. Do not treat a gRPC host as a drop-in for either HTTP API or JSON-RPC.
If the product is built around TronWeb, energy, and TRC-20 builders, start from the HTTP API. If the product is an Ethereum-shaped stack that only needs reads and EVM-style calls, use a JSON-RPC URL and confirm eth_chainId on that exact path. Pointing ethers at https://api.trongrid.io without /jsonrpc is a common failure: you are not hitting the JSON-RPC gateway.
buildTransaction exists on the JSON-RPC surface for building Tron transaction objects. Signing and broadcast still follow Tron rules. Do not assume eth_sendRawTransaction is a full substitute for every wallet flow that TronLink or TronWeb already own.
Chain ID for wallet add: 728126428
Mainnet chain ID is 728126428, hex 0x2b6653dc. Shasta and Nile use different IDs. TronLink documents the hex value as what wallet_switchEthereumChain and chainChanged use, and the decimal value as what EIP-712 domain.chainId expects. Those are the same network; they are not interchangeable as strings in every wallet UI.
When you add Tron to a wallet that supports custom EVM networks, use:
- Chain ID:
728126428or0x2b6653dc(match what that wallet's form asks for) - Currency: TRX
- Explorer: tronscan.org
- RPC: a JSON-RPC URL you have already probed, not a guessed host
Call eth_chainId on the JSON-RPC endpoint you will ship. Expect 0x2b6653dc. A gateway that returns a different ID, times out, or answers HTML is not mainnet for that transport. Do this after any load balancer or fallback so you are not checking a different backend than production.
Native Tron wallets (TronLink and similar) already know mainnet. The chain-ID form matters most when the product is an EVM wallet add flow, a multi-chain SDK, or a payments backend that stores one chain ID per network.
Addresses and units are not EVM defaults
Tron addresses show up in more than one encoding. Know which API you are on:
- Base58 — starts with
T(what users paste). Example USDT TRC-20 mainnet contract:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t. - Native hex — starts with
41(on-chain / raw form for the HTTP API and TronWeb). - JSON-RPC / EVM tooling — a 20-byte
0x...address derived by replacing the native41prefix with0x. That is the form ethers, viem, and similar stacks expect on the JSON-RPC path. It is not an Ethereum mainnet address, and it is not a 21-byte41...value with a0xglued on.
tronWeb.address.toHex() / fromHex() convert between Base58 and the native 41... form. On JSON-RPC, use the 20-byte 0x... form. Feeding a raw Ethereum mainnet address into a Tron transfer, or treating a valid Tron JSON-RPC 0x... address as an error, is a payments bug. Always verify token contract addresses on TronScan for the network you are on. Mainnet and testnet addresses differ.
Amounts in many TronWeb builders are in SUN: 1 TRX = 1,000,000 SUN. Wallet UI that shows TRX while the API expects SUN will under- or over-send by six orders of magnitude. Store the unit next to the RPC URL in the same config object.
Public vs dedicated: what wallet and payments traffic actually needs
Public endpoints (including TronGrid public gateways and other shared URLs on the hub) are fine for:
- Local development and wallet QA
- Low-volume read probes (
eth_chainId,eth_blockNumber, balance reads) - Learning and one-off scripts
They are a poor primary path when you:
- Settle user payments or TRC-20 transfers at production volume
- Need predictable latency and a support channel when the gateway 429s
- Depend on historical state, wide log filters, or sustained WebSocket / subscription traffic
- Cannot absorb shared-node brownouts during a mint, airdrop, or market spike
Probe the candidate URL before you call it "dedicated":
- Hit the correct API (HTTP vs
/jsonrpc). Confirm with a method that only that surface supports, or witheth_chainIdon JSON-RPC. eth_chainIdreturns0x2b6653dcon mainnet JSON-RPC.- The latest block or head advances when you poll twice a few seconds apart. Do not use an unchanged account balance as proof the node is live; a healthy endpoint often returns the same balance unless that account moved.
- One TRC-20 balance or allowance read against a known mainnet contract, using the address format your SDK expects (Base58 /
41...on HTTP, 20-byte0x...on JSON-RPC). - If you need push updates, a WebSocket or subscription path that survives a disconnect (many public sockets do not).
Public rows on the hub are shared and rate-limited. Use them for the probe. For production wallet and payments traffic, compare the paid rows on the same hub for method coverage, archive or historical access if you need it, and quota. Dwellir is one of those rows: a flat response-credit model that is easier to budget when the mix of reads and writes is not stable. It is not the only option. A cheaper URL that fails the probe above is not a savings. The public vs paid guide covers when a shared endpoint stops being enough. The pricing calculator is there for the rest.
Practical split for a wallet or payments stack
- User-facing native Tron wallet — Tron HTTP API + TronWeb (or equivalent), Base58 for display, SUN in the builders.
- EVM-shaped multi-chain app adding Tron — JSON-RPC URL with proven
0x2b6653dc, wallet add form filled from that same URL, and a clear note that Tron address encoding is still Tron's. - Payments / settlement backend — dedicated endpoint, chain ID stored with the URL, unit tests that reject Ethereum
0xaddresses and TRX/SUN mismatches, public gateway only as a temporary fallback.
If the probe fails, do not ship the URL because the marketing name said Tron mainnet. Change endpoint, path, or API until the chain ID, address format, and traffic class match the job.