Track 2: Non-custodial wallet developer

Build account recovery, read-only asset display, and locally signed TRX and TRC-20 transfer workflows on Shasta.

This track is a starting point for understanding the core TRON integration flow in a non-custodial wallet. It is intended for developers building a wallet prototype or evaluating the account, asset-query, and transfer capabilities needed by an existing multi-chain wallet.

What you will learn

The track begins with account recovery and key boundaries, then covers asset and resource queries, TRX transfers, TRC-20 transfers, and transaction-state handling. The focus is completing these operations without giving private keys to a node or backend service.

The throughline is a minimal wallet prototype that restores TRON accounts from fixed test vectors, displays TRX, TRC-20, Bandwidth, and Energy, signs and broadcasts transfers locally, and updates transaction state from the original txID.

Use fixed public test vectors only for offline derivation verification; never fund them or use them in onchain transactions. Use a separately generated Shasta account that holds only test assets for balance queries and transfers.

Build the capabilities progressively inside an existing wallet project. The prototype establishes the core TRON wallet flow. Production key protection, security review, node failover, risk controls, and release readiness depend on the product and remain separate work.

You do not need to learn every protocol detail in advance. Review the stages, follow the hands-on tasks in order, and return to the recommended reading when account, transaction, or contract encoding details become relevant.

Track overview

StageMain topicTask in the minimal wallet prototype
1. Establish account recovery and key scopeUnderstand mnemonics, derivation paths, address formats, and private-key boundariesVerify recovery, derivation, and secret visibility with fixed test vectors
2. Build a read-only walletUnderstand the chain adapter, asset precision, and resource queriesQuery and display TRX, TRC-20, Bandwidth, and Energy
3. Support TRX transfersUnderstand construction, review, local signing, and broadcastDerive review data from the actual unsigned transaction and complete one Shasta TRX transfer
4. Support TRC-20 transfersUnderstand standard transfer, parameter parsing, and fee informationDisplay token, amount, recipient, target contract, and cost, then complete one test transfer
5. Build a unified transaction state modelUnderstand broadcast, execution, solidification, and recoveryUpdate state from the original txID and handle rejection, tampering, expiration, and node failure

Before you begin

You should understand basic TRON accounts, transactions, resources, and testnets. If these are unfamiliar, begin with Track 0: Complete beginner. The hands-on work also requires proficiency in one wallet-development language, familiarity with HD wallet derivation and basic ECDSA verification, and a Shasta account holding only test assets plus a test TRC-20 token.

Obtain test assets from a Shasta faucet. If you need a custom test token, use Deploy a TRC-20 token with TronWeb; that recipe requires an ABI and bytecode produced by an actual compiler. Keep every query, construction, broadcast, and confirmation on a Shasta endpoint.

This track explains the core workflow and points to the relevant documentation. For address algorithms, Protobuf fields, API requests, and SDK code, use Wallet developer guide — What a TRON wallet needs to do and the links in each stage.

WalletConnect, multisig, account permissions, Stake 2.0, and hardware-device signing are not required for the minimal prototype. Add them after the core workflow is stable and only when product scope requires them.

Track stages

1. Establish account recovery and key scope

A non-custodial wallet must derive the same accounts consistently from the same recovery material. TRON wallets commonly use a BIP-39 mnemonic to create a seed and BIP-44 coin type 195 to derive accounts. Once selected, the derivation path, account index, and address format must remain consistent across versions and implementations.

TRON accounts use secp256k1. One address can be represented as 41-prefixed hex or T-prefixed Base58Check. Define which representation storage, SDK calls, and the user interface use; conversion must not change the underlying account. The address itself does not identify Mainnet or Shasta, so the wallet must store and display the selected network separately.

Successful recovery is only the first boundary. Mnemonics and private keys belong only in controlled key storage and the local signer. They must never enter node requests, backend APIs, logs, analytics, crash reports, or clipboard history. Keep networked chain-data access separate from modules that hold secret material.

Recommended reading

  1. Wallet developer guide — Key derivation specifics

    Read this section only to verify BIP-39, BIP-44, coin type 195, derivation paths, secp256k1, and address-generation order. SDK, Stake 2.0, and multisig content can wait.

  2. Accounts and keys — Key pairs and Address and data encoding — Address formats

    Verify the relationship from public key to address, then continue through the visible flag and conversion methods in the encoding page. Leave transaction payload and ABI encoding for later stages.

  3. Network security — Wallet and key hygiene

    Review mnemonic backup, trusted installation sources, and response to compromise. This user-facing guidance does not replace platform-specific key-storage implementation or a security review.

  4. Validate TRON account derivation

    Use a public test mnemonic to verify derivation paths, public keys, and both address formats across several indexes. Never place real recovery material in a test script.

Stage task

Choose a public, test-only fixed mnemonic that holds no assets. Record the derivation path, public key, hex address, and Base58Check address for several account indexes. Clear local wallet state, restore again, and verify the results with another TRON SDK or independent implementation.

Record where the wallet exposes secret material. Account recovery and the signer may access it; asset queries, broadcast, logs, and backend services may not. Check error and debug output during testing to ensure that no secret appears.

Generate a separate Shasta-only account for the later onchain stages. Use the public fixed-vector addresses only for derivation checks, never for funding, signing, or broadcast.

Before building the read-only wallet: Confirm that the fixed vector repeatedly restores the same accounts in the same order and that no mnemonic or private key enters a log or network request. The next stage uses only the separately generated Shasta address to query chain data.

2. Build a read-only wallet

Once recovery is stable, separate key management from chain-data access. A read-only wallet queries assets and resources by address; it needs neither a private key nor a user signature. A node or RPC provider returns onchain data and must not participate in recovery or signing.

The minimal wallet displays TRX balance, supported TRC-20 balances, Bandwidth, and Energy. These values come from different queries. Hide those differences behind a dedicated TRON chain adapter so the business UI does not depend directly on one SDK, provider, or raw response shape.

TRC-20 display amounts require the contract's decimals. Retain both the raw integer and the display amount; avoid floating-point arithmetic. Identify a token by current network and contract address, not by a possibly duplicated name or symbol. Represent unknown tokens, missing metadata, query timeouts, and partial failure explicitly rather than converting them silently to a zero balance.

When account state is absent, first determine whether the address is inactive instead of presenting it as an ordinary zero-balance account. Before a user sends the first TRX transfer to an inactive address, explain that account creation adds cost and read the current values from chain parameters.

Recommended reading

  1. Query TRX balance and resources and Bandwidth and Energy — Quick comparison

    Run the Shasta example at the top of the recipe and verify TRX balance, Bandwidth, and Energy. In the resource page, distinguish the two resource types; staking and delegation can wait.

  2. TRC-20 — Key facts and TRC-20 contract interaction — decimals, balanceOf

    Confirm how contract address and precision identify the token. Read only the decimals and balanceOf examples for your selected SDK or HTTP API. Leave allowances and transfers until Stage 4.

  3. RPC and indexer providers — Self-hosted or hosted?

    Use this to understand the boundary between a node and hosted RPC. Provider selection, history indexing, and node operation are not prerequisites for this stage.

Stage task

Create a dedicated TRON chain adapter with stable interfaces for account information, TRX balance, TRC-20 metadata and balance, Bandwidth, and Energy. Initialize a read-only client with the network and endpoint only—never a private key.

Query the separately generated Shasta account from Stage 1 and compare the UI with an independent node or Shasta block explorer. Test an unknown token, missing metadata, one failed subquery, and a node timeout. The UI should retain available data and mark the unverified parts explicitly.

Before supporting TRX transfers: Confirm that the business layer displays TRX, TRC-20, Bandwidth, and Energy without access to a private key, and that changing the node or mock implementation does not change the UI data model. The next stage authorizes a transaction in a separate signer.

3. Support TRX transfers

A TRX transfer moves through construction, review, signing, and broadcast. First construct the real unsigned transaction containing the sender, recipient, amount, TAPOS reference, and expiration. Derive the confirmation screen from that transaction's final raw_data. Do not merely repeat form input, because form state and the actual bytes to be signed may have diverged.

After user approval, the local signer signs the txID computed from the final raw_data. Recover the signer address from the signature and verify that it matches the sender. Do not reconstruct or modify the transaction after signing; broadcast the exact transaction the user reviewed and authorized.

The txID exists once the unsigned transaction has been constructed; broadcast does not create it. Node acceptance only proves preliminary validation, not block inclusion or solidification. Save the original txID and continue querying the transaction body, execution result, and solidified state.

Recommended reading

  1. Transactions — Transaction structure and TAPOS

    Read transaction structure, expiration, and TAPOS to understand the payload reviewed before signing. Consult other transaction and system-contract types only as needed.

  2. Signature validation — The signed message

    Continue through “ECDSA verification” and “Single-signature verification” to understand txID, signature format, and signer recovery. Multisig and permission weights are outside the minimal prototype.

  3. Transaction signing and broadcast — The three-step workflow

    Read Steps 1 through 4 to distinguish construction, signing, broadcast, receipt, and solidification. When running the confirmation code, use an explicit Shasta endpoint rather than any Mainnet default shown on the page.

  4. Send your first transaction and Offline transaction signing

    The first gives a minimal Shasta transfer. The second demonstrates the boundary between online construction, offline review and signing, and online broadcast. Neither replaces validation of every field the wallet supports.

Stage task

Use the Shasta test account from Stage 1 and the chain adapter from Stage 2 to construct a Shasta TRX transfer. Parse the final raw_data into a confirmation view that shows the network, sender, recipient, amount, expiration, and expected resource information, then authorize it through the local signer.

Recover the signer and recheck raw_data after signing, then broadcast that exact transaction. Save the original txID, query execution and solidification, and compare the displayed confirmation with the onchain transaction.

Before supporting TRC-20 transfers: Confirm that Shasta contains one locally signed and solidified TRX transfer from the wallet. The retained record must show that the confirmation view, signed bytes, and broadcast transaction agree and that no private key entered a node or backend service.

4. Support TRC-20 transfers

A TRC-20 transfer is not a standard TRX transfer. It calls transfer(address,uint256) on a token contract. The transaction target is the TRC-20 contract; the actual token recipient and amount are encoded in call parameters. Display both addresses so users do not confuse the recipient with the target contract.

Parse the amount with the contract's decimals while retaining the raw uint256. The confirmation view should also show token name and symbol, sender, network, function, fee information, and fee_limit. Derive these fields from the actual unsigned call and verified token metadata rather than trusting a name or amount supplied by an external request.

Distinguish the Energy estimate, expected TRX burn, and the fee_limit cap. fee_limit is not a fixed charge, and a failed estimate must not be displayed as zero.

A standard transfer consumes both Bandwidth and Energy. After broadcast, inspect the receipt to determine success or failure. Node acceptance does not prove that tokens moved.

Recommended reading

  1. TRC-20 contract interaction — decimals, balanceOf, and transfer

    Read the matching examples for your selected SDK or HTTP API. approve, transferFrom, and allowance are outside this stage.

  2. Parameter encoding and decoding — Function selector

    Continue through static address and uint256 rules and the transaction-parameter decoding example for your language. Do not run any Nile private-key example on that page; this track's transactions remain on Shasta.

  3. FeeLimit and Energy cost — What fee_limit actually does and Estimating Energy before broadcasting

    Distinguish caller budget, Energy estimate, and actual cost. Deployer resource sharing and contract-deployment configuration are not wallet-transfer prerequisites.

  4. Send and confirm a TRC-20 transfer

    Verify base-unit amounts, local signing, fee_limit, and the solidified execution result. The example reads a test key from the environment; a real wallet must use its local key module or connected device instead.

Stage task

Add one supported Shasta test TRC-20 token to the TRX workflow. Read and verify its contract address, name, symbol, and decimals, then construct a standard transfer(address,uint256) call.

Parse the target contract, function, recipient, and raw amount from the final unsigned transaction. Combine those fields with verified token metadata to display the user amount and fee information. After approval, sign with the same local signer, broadcast, save the original txID, and query the final result from a solidified receipt.

Before building the unified transaction state model: Confirm that Shasta contains one locally signed and solidified TRC-20 transfer. The confirmation view must distinguish token recipient from target contract and keep the raw amount, display amount, and call parameters consistent.

5. Build a unified transaction state model

TRX and TRC-20 can share one transaction-state model, but every state needs precise semantics. Signed means that a local signature exists. Broadcast means that a node accepted the transaction. Execution success or failure comes from chain execution. Solidified means the transaction entered an irreversible block. Unknown means that current data is insufficient to determine the outcome.

Do not display business success when the user confirms, signing completes, or broadcast succeeds. A TRC-20 call can enter a block and still fail, so continue querying the receipt. A node timeout or indexing delay also does not prove failure; retain the original txID and keep querying.

Error handling must follow the same state model. Stop before broadcast on the wrong network, an invalid address, modified unsigned data, or a signer mismatch. User rejection must not create a success state. Expired transactions or invalid TAPOS references require reconstruction, a new review, and a new signature. For node failures, first query the original transaction, then decide whether to wait, rebroadcast the same valid transaction, or reconstruct it. Reconstruction produces a new txID and always requires fresh user authorization.

Recommended reading

  1. Confirmation semantics — State semantics quick reference

    Continue through “Broadcast acceptance is not execution success,” “Transaction body is not execution receipt,” and “Latest head is not solidified state.” Read the indexed-data section only if the wallet displays history.

  2. Broadcast and RPC errors — Broadcast response codes

    Focus on duplicate transactions, TAPOS, expiration, signature errors, and node-busy responses, then consult Broadcast succeeded but the transaction never appears on chain as needed. P2P configuration applies to self-hosted nodes, not a wallet client.

  3. Signature validation — Cancelling a transaction

    Confirm why a broadcast transaction cannot be cancelled or replaced by raising its fee and why reconstructing an expired transaction requires new user authorization.

Stage task

Build one state machine for TRX and TRC-20 and record the evidence source for every transition. Cover signed, broadcast, execution success, execution failure, solidified, and unknown with fixed tests. The UI must not skip execution state or show final success early.

Add cases for wrong network, invalid address, modified unsigned data, user rejection, expiration, invalid TAPOS, broadcast timeout, unavailable node, and duplicate broadcast. For each case, record where processing stopped, whether a txID exists, whether querying can continue, whether rebroadcast is safe, and when reconstruction and new user authorization are mandatory.

Verify state handling: Repeat the successful TRX and TRC-20 flows and confirm that every failure case stops in a state matching reality. When a node times out or the result remains unknown, continue tracking the original txID to avoid duplicate payment or false success.

Next steps

After this track, the minimal wallet should restore test accounts consistently, display TRX, TRC-20, Bandwidth, and Energy, sign and broadcast TRX and TRC-20 transfers locally, and update transaction state accurately from the original txID.

After the core flow is stable, add WalletConnect, multisig, or staking on TRON as product scope requires. For the corresponding operations, see Multisignature transaction and Stake and delegate resources. Moving signing into a hardware device introduces a separate boundary for device display, device signing, and host verification.

If only part of the workflow is complete, retain the fixed test vectors, chain-adapter interfaces, unsigned transaction samples, txID values, and negative-test results, then resume at the relevant stage. Never include a mnemonic or private key in these records.

If you are still blocked, share documentation feedback. Include “Track 2,” the current stage, wallet platform and SDK, Shasta endpoint, completed steps, and the actual error. Never include a mnemonic, passphrase, private key, API key, or production account information.