Track 6: RPC and infrastructure provider

Build a protected TRON API service on Shasta and validate routing, failure handling, and transaction confirmation.

This track is a starting point for building a TRON API access layer. It is intended for teams that need a unified, protected data entry point for wallets, DApps, exchanges, indexers, or internal systems.

What you will learn

Starting with service consumers and data semantics, this track covers upstream data sources, API routing, ingress protection, monitoring and failure handling, client acceptance, and an optional event-data extension.

The through-line is a protected TRON API service. It connects to a configurable Shasta endpoint and provides test clients with transaction construction and broadcast, latest-state queries, and solidified-state queries. Across the stages, you will build routing rules, security configuration, health checks, and failure-handling records.

The result is a minimal service for validating interface semantics and operating mechanisms. It does not by itself meet production requirements for capacity, availability, security, compliance, or service levels. ZeroMQ event consumption requires a configurable self-hosted node, so it is an optional Nile extension rather than a prerequisite for the minimal Shasta API service.

You do not need to master every node interface or high-availability pattern before starting. Use the overview to understand each stage, then build the service around one test client. Return to the recommended reading when a broadcast, confirmation, or node failure occurs.

Track overview

StageMain focusAPI service task
1. Define the service and data semanticsDefine consumers, API scope, broadcast semantics, latest and solidified state, and basic service objectivesProduce a service contract and interface-classification table
2. Prepare upstream data sourcesConnect to a configurable Shasta endpoint and understand hosted versus self-hosted boundariesConfigure upstreams and record capabilities, credentials, limits, and standby conditions
3. Establish API routingSeparate transaction construction and broadcast, latest state, and solidified state by request purposeCreate routing rules that preserve data semantics
4. Protect service ingressConfigure TLS, authentication, rate limits, timeouts, access control, and sensitive-method isolationEstablish a protected client entry point
5. Establish monitoring and failure handlingMonitor height, freshness, latency, error rate, and upstream availabilityRun one upstream-failure detection and degradation or failover drill
6. Complete client acceptanceQuery accounts, blocks, and transactions and validate broadcast and later confirmationPreserve acceptance results for successful and invalid requests
7. Extend event dataAdd one ZeroMQ block or contract-event path through a self-hosted Nile nodeBuild an event consumer that detects interruption and data gaps

Before you begin

You should understand HTTP APIs, reverse proxies, TLS, authentication, rate limiting, logging, and basic monitoring, and be familiar with TRON accounts, blocks, and transactions. If the node-interface layers are unclear, begin with API reference — API layers and Confirmation semantics — State semantics quick reference.

The minimal exercise requires a configurable hosted Shasta endpoint, an HTTP test client, and a test account used only on Shasta. The API service may return an unsigned transaction; the client must sign it locally, and the broadcast endpoint accepts and forwards only signed transactions. The service never receives, stores, or logs private keys.

This track organizes the data semantics, access boundaries, and operating mechanisms that an API service must preserve. Follow the linked documentation for node deployment, proxy implementation, method arguments, and event subscription. Because Shasta does not accept external P2P nodes, the minimal service uses a hosted Shasta endpoint. Use Nile only when a self-hosted node or ZeroMQ is required, keeping Nile data strictly separate from the Shasta service.

📘

Network note

The first six stages validate the API service through a hosted Shasta endpoint. Any step that deploys a java-tron node, joins a P2P network, changes node configuration, or enables ZeroMQ uses a non-producing Nile node. Never add that node or its data to the Shasta upstream pool or Shasta acceptance results.

Track stages

1. Define the service and data semantics

An infrastructure service must first state which capabilities it provides and to whom. A wallet may need a latest balance and transaction broadcast, an exchange may require solidified state, and an indexer may require continuous block or event data. Without an explicit scope, one endpoint can inherit incompatible latency, stability, and consistency expectations.

TRON APIs expose different states. A broadcast node accepting a transaction does not mean the transaction is included, executed successfully, or solidified. A FullNode's latest head is not a SolidityNode's solidified state, and a record found by an indexer is not native node state. Reflect these distinctions directly in endpoint names, response fields, and usage guidance.

Set basic service objectives before implementation. In addition to availability, latency, and error rate, define data freshness, acceptable upstream-height difference, client quota, request timeout, and recovery target. A test prototype need not promise a production SLA, but it still needs a measurable acceptance boundary.

Recommended reading

  1. API reference — API layers and FullNode and SolidityNode selection guide

    Distinguish the method scope and data height of FullNode, SolidityNode, JSON-RPC, and indexing services. Method arguments are not required yet.

  2. Confirmation semantics — State semantics quick reference, Latest head is not solidified state, and Indexed data is not native node state

    Distinguish broadcast acceptance, the transaction body, execution receipt, solidified state, and indexed data.

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

    Compare the responsibilities suited to hosted RPC, self-hosted nodes, and indexing services. Providers and prices change, so confirm them separately when selecting a service.

Stage exercise

Create a service contract listing target clients, allowed networks and methods, read/write nature, data source and height, expected response, and explicitly unsupported capabilities. Classify every endpoint as transaction construction/broadcast, latest state, solidified state, or unsupported.

Define minimum targets for success rate, latency, upstream-height difference, data freshness, per-client quota, request timeout, and recovery time. State where and how each metric is measured instead of using untestable labels such as “stable” or “real time.”

Before preparing upstreams: Confirm that every exposed endpoint has a consumer, data semantic, and upstream type and that the service description never presents broadcast acceptance, execution success, and final solidification as one state.

2. Prepare upstream data sources

The upstream determines which data the API service can provide. A FullNode can construct and broadcast transactions and read the latest head; a SolidityNode reads solidified state; and a hosted RPC may add authentication, quotas, and indexing. Record not just its URL but also network, interface type, data height, credentials, rate limits, and supported methods.

The minimal exercise uses one configurable hosted Shasta endpoint. If a second endpoint provides the same network and semantics, configure it as a standby. Inject URLs and credentials through configuration or secret management rather than hard-coding them in a client or repository. Determine whether the standby shares the same operator or failure domain. Without an independent standby, record the single-upstream dependency and verify controlled degradation instead of treating two URLs from one service as disaster recovery.

A self-hosted node increases control over methods and operations but adds synchronization, storage, version, network, and maintenance responsibilities. Shasta does not accept external nodes, so self-hosting exercises use a non-producing Nile node. Never add it to the Shasta pool, and do not qualify it merely because its process is online; first validate height, peers, logs, and resource health.

Recommended reading

  1. Connect to the TRON network — HTTP endpoints from TronGrid and Public nodes vs self-hosted nodes

    Understand Shasta endpoints and hosted, self-hosted, and hybrid access. The main path uses only a hosted Shasta endpoint.

  2. RPC and indexer providers — Comparison dimensions and Indexer and data services

    Compare data capabilities, access limits, index coverage, and failure domains. Do not assume every provider supports Shasta.

  3. Networks — Nile Testnet, Nodes and clients — Fullnode, Deploy a node — Hardware requirements, Pick a configuration file, and Start the node

    Read these only if self-hosting is available. Prepare a non-producing Nile node and skip all block-producing configuration.

Stage exercise

Configure the Shasta upstream and record its endpoint, network, service type, authentication, quota, timeout, supported methods, and operator. Record the same information for an independent standby if available. Query the latest and solidified block separately, saving height and response time, and confirm that each upstream's capabilities match the service contract.

If a safe self-hosted non-producing node already exists, add a separate Nile operations check and record it as an upstream type separate from the Shasta path. If not, keep the hosted Shasta plan; deploying a node solely to complete the minimal track is unnecessary.

Before establishing routing: Confirm that every Shasta upstream supplies its stated data semantics and that its URL, credentials, quota, limitations, and failure domain are recorded. Explicitly record a single-upstream dependency when no independent standby exists. A Nile node never enters the Shasta upstream pool.

3. Establish API routing

Routing must preserve the request's semantics, not just choose whichever upstream is available. Send transaction construction and broadcast to a FullNode service. Latest-state queries may use FullNode, while final confirmation and reconciliation use solidified SolidityNode state. History and event queries generally require an indexer or local index and must not be assumed to exist on an ordinary node.

Separate latest and solidified queries through distinct paths, explicit parameters, or client methods. If the solidified upstream fails, never silently return latest-head data under the same response contract. If degradation is permitted, return the data source, height, and degradation state explicitly so the caller can decide whether to accept it.

The broadcast path must preserve transaction identity. After local signing, forward the same transaction without changing raw_data, its signature, or its txID. If the upstream times out or reports a duplicate, query the original txID before constructing another transaction that could duplicate a payment.

Recommended reading

  1. API reference — Build and broadcast transactions, Query solidified data, and Query account history and events

    Map construction, broadcast, latest queries, solidified queries, and indexing queries to the correct interface layer.

  2. Confirmation semantics — State semantics quick reference and Latest head is not solidified state

    Design result status, data source, and the later confirmation path. Never silently substitute the latest head for solidified data.

  3. Transaction signature and broadcast — The three-step workflow and Confirm the transaction result

    Understand the relationship among transaction construction, local signing, broadcast, execution, and final confirmation.

Stage exercise

Create three explicit route groups: transaction construction and signed-transaction broadcast, latest-state queries, and solidified-state queries. For each group configure allowed methods, target network, upstream type, timeout, and possible errors, and record the selected upstream and data height in the response or logs.

Use one account and block height to call the latest and solidified routes and confirm that each reaches the intended upstream. Simulate an unavailable solidified upstream and verify the service does not disguise latest-head data as solidified. Leave actual broadcast until client acceptance; for now, verify only that the request body passes through unchanged and that the service has no signing capability.

Before protecting ingress: Confirm that construction/broadcast, latest, and solidified queries have separate, reviewable routing rules and that no degradation changes semantics or hides the data source.

4. Protect service ingress

A unified API service concentrates node capabilities at one entry point, so it must protect transport, identity, and resources together. Use TLS for external connections. Identify clients with an API key, short-lived token, or mutual TLS appropriate to the internal environment, and limit each identity to allowed networks and methods.

Do not use one global rate-limit number. Queries and broadcasts have different costs, risks, and retry behavior, so configure rate, concurrency, body size, and timeouts by client, path, and method. When an upstream reports rate limiting or overload, preserve the error meaning and follow an explicit backoff, failover, or rejection policy. Unbounded retries amplify failures.

Remove node-management, debugging, signing, and out-of-contract methods from public ingress. The service neither stores private keys nor offers custodial signing. Access logs must support auditing while redacting authentication data, upstream credentials, private keys, complete signature material, and other sensitive fields.

Recommended reading

  1. API reference — Node HTTP API, Node gRPC API, and Node JSON-RPC API

    Read only the protocol the service exposes. Use it to build a method allowlist.

  2. TronGrid — API key and Rate limit

    Handle upstream credentials and quotas. A TronGrid API key is a service-access credential, not an on-chain signing key or a client credential issued by your own API service.

  3. Broadcast and RPC errors — Broadcast response codes, SERVER_BUSY, and TronGrid 503

    Distinguish transaction validation failure, node overload, and hosted-service throttling, then assign reject, backoff, or retry behavior.

  4. Build a protected node API entry point

    Run an HTTPS test entry point that exposes only explicit methods and verify latest versus solidified routes, API-key authentication, body limits, timeouts, and single-process rate and concurrency limits. Multi-instance deployment still needs shared limiting, credential rotation, circuit breakers, and same-semantics failover.

Stage exercise

Enable TLS and one client-authentication method for the test entry point. Configure method allowlists, rates, concurrency, request-body limits, and timeouts per client and route. Verify that missing or invalid credentials, unauthorized methods, over-quota traffic, and timed-out requests are rejected, and preserve the status codes and service logs.

Inspect configuration, errors, and logs to confirm that upstream API keys, client credentials, and sensitive transaction fields are never returned or logged in plaintext. Attempt one method absent from the service contract through public ingress and confirm it is rejected before reaching an upstream.

Before monitoring and failure handling: Confirm that ingress has encryption, client identity, method-level authorization, and traffic controls and that logs and errors do not disclose credentials or signature material.

5. Establish monitoring and failure handling

An HTTP response does not prove healthy upstream data. Monitor latest height, solidified height, last update time, height difference from an independent reference, request latency, errors, timeouts, and throttling together. For self-hosted nodes, also monitor process state, peers, logs, JVM, CPU, memory, disk, and I/O.

Health checks must detect a node that is reachable but stale. Latest and solidified upstreams have different heights, so set their thresholds separately rather than requiring equality. A standby must preserve network, capability, and semantics: never route Mainnet or Nile into a Shasta service or latest state into a solidified route. Without a same-semantics standby, return an explicit degraded or unavailable state.

Failover also needs anti-flapping and retry controls. Consecutive-failure thresholds, circuit breaking, recovery observation, and gradual failback can reduce oscillation. A broadcast timeout produces an unknown outcome. If retrying through a standby, resend only the same signed transaction and continue querying its original txID; do not apply stateless query retry behavior to a funds operation.

Recommended reading

  1. Confirmation semantics — Latest head is not solidified state and Indexed data is not native node state

    Monitor the freshness of the latest head, solidified state, and indexed data separately.

  2. Broadcast and RPC errors — SERVER_BUSY, TronGrid 503, and Broadcast succeeded but the transaction never appears on chain

    Define handling for overload, throttling, insufficient connections, synchronization lag, and an unknown broadcast outcome.

  3. Node operations troubleshooting — Slow or stopped block sync and Network stability and resource usage control

    Use these only if stage 2 added a self-hosted Nile node; a hosted Shasta endpoint does not allow node-side inspection.

  4. Check node synchronization and data freshness

    Turn latest height, solidified height, reference height, and block time into a repeatable health check. Adjust thresholds for the upstream role and normal solidification delay.

Stage exercise

Build a dashboard and alerts that record each upstream's latest or solidified height, data freshness, difference from a reference, request volume, latency, error rate, timeouts, and throttling. For every alert, define a threshold, duration, owner, and response entry point.

In a test environment, make the Shasta upstream temporarily unavailable or return a controlled error and verify that the service detects it and stops unbounded retries. With a same-semantics standby, verify failover, recovery, observation, and controlled failback. Without one, verify an explicit degraded or unavailable result. Preserve the failure start, alert, degradation or switch, recovery time, and client results during the event.

Before client acceptance: Confirm that the service detects connection failure and stale data; a standby never changes the network or query semantics; and no-standby failures are explicit. Continue tracking the original txID after an unknown broadcast outcome.

6. Complete client acceptance

Client acceptance validates both data and service boundaries. HTTP 200 alone does not prove correct routing. Confirm that account, block, and transaction data comes from the intended network and height and that invalid credentials, quota exhaustion, and upstream failure produce stable, explainable responses.

For transaction acceptance, the client requests an unsigned transaction and signs it locally. The API service accepts only the signed transaction and returns the upstream broadcast result. result: true means only that the broadcast node accepted it. The client must query the transaction body, execution receipt, and solidified receipt under the original txID to determine discovery, execution success, and final state separately.

An acceptance run should correlate the client request, internal route, and upstream call. A correlation ID helps trace latency and failure, but logs must not contain private keys, credentials, or unnecessary complete transaction contents. Fix routing, security, and monitoring findings before rerunning the same cases.

Recommended reading

  1. API signature and broadcast flow and Confirm the transaction result

    Set the recipe's FULLNODE to the protected Shasta API address and complete local signing and broadcast. The recipe ends at broadcast; continue with the documentation to query execution and solidified state.

  2. API task map — Accounts, balances, and resources and Blocks, transactions, and indexing

    Select the correct account, latest/solidified block, transaction-body, and receipt methods. For a read-only account check, reuse Query TRX balance and resources with fullHost set to the protected entry point.

  3. Broadcast and RPC errors — Broadcast response codes, TronGrid 503, and Broadcast succeeded but the transaction never appears on chain

    Validate duplicate, expired, throttled, busy-node, and accepted-but-not-included paths.

Stage exercise

Through the protected entry point, query one Shasta account, the latest block, a solidified block, and an existing transaction. Record the request ID, route type, upstream, returned height, latency, and result, then cross-check against an independent Shasta source.

Next, have the client request a small unsigned Shasta transaction from the API service, sign it locally, and broadcast it through the same service while preserving the original txID. Query the transaction body, FullNode execution receipt, and SolidityNode solidified receipt in order, recording acceptance, inclusion, execution, and solidification. Finally replay missing credentials, invalid credentials, quota exhaustion, request timeout, and primary-upstream failure and confirm that access control, error responses, monitoring, and failure handling match the service contract.

Validate the minimal API service: Confirm that account, block, and transaction queries use the correct routes, broadcasts always retain the original txID, final state comes from a solidified query, and every error case has correlated client and service records.

7. Extend event data

Polling is appropriate for on-demand queries, but continuously discovering blocks or contract events usually requires an event path. java-tron can publish block and contract triggers through its built-in ZeroMQ message queue. This requires a self-hosted node whose startup arguments and event configuration you control; it cannot be added to an ordinary hosted Shasta endpoint. Use a non-producing Nile node and record this path separately from the first six stages' Shasta API service.

A minimal extension can enable only one event type, such as new blocks or events from one contract, and expose the ZeroMQ port only to the internal network. Enabling only required triggers reduces load on both node and consumer. Persist block height, block hash, or a processing identifier composed of txID and event position for deduplication and later state queries.

ZeroMQ is a real-time message stream, not persistent history or replay. A disconnected consumer may miss messages, so monitor the connection, last processed height, and height gaps, then backfill gaps from solidified blocks or indexed data. If the service needs stronger persistence, replay, and multi-consumer guarantees, evaluate Kafka, the MongoDB plugin, or a dedicated indexer.

Recommended reading

  1. Event subscription — How to access events and Event types

    Choose triggers and understand the boundaries among ZeroMQ, Kafka, MongoDB, and hosted event queries. External plugin deployment and V2 historical backfill are not required.

  2. ZeroMQ event plugin — Configure the node and Subscribe with Node.js

    Configure the Nile publisher, choose triggers, and build the consumer. If you only need hosted Shasta contract-event queries, use Listen for contract events instead; that recipe is not a ZeroMQ consumer and does not replace this self-hosted extension.

  3. Confirmation semantics — Latest head is not solidified state and Indexed data is not native node state

    Separate real-time discovery from solidified state and design the final confirmation path.

Stage exercise

Only if a configurable non-producing Nile node is available, enable one block or contract-event trigger and restrict the ZeroMQ publisher to the internal network. Build a minimal consumer that records network, event type, block height, block hash, txID, event position, and receipt time and verify that duplicates do not cause duplicate processing.

Disconnect the consumer briefly, reconnect it, and check that monitoring detects the outage and processing-height gap. Backfill the missing range through node or index queries and record the relationship between real-time messages and solidified state. If no self-hosted node is available, mark this optional extension as not enabled; the first six stages still qualify the minimal service.

Validate the event extension: Confirm that the path is explicitly labeled Nile, exposes only required triggers and an internal port, and supports deduplication, interruption detection, and gap recovery. Never treat a real-time event as a solidified result or mix it into Shasta acceptance data.

Next steps and extensions

After the first six stages, you should have a Shasta API endpoint for test clients, upstream-routing rules, security and traffic controls, health checks, a failure-handling record, and client-acceptance results. If you have self-hosting capability and complete stage 7, you will also have a separate Nile ZeroMQ block or contract-event consumer.

Before production, add capacity and load tests, multiple failure domains or regions, certificate and credential rotation, log and data retention, change management, on-call and incident response, and confirm that upstream quota and cost cover expected traffic. For funds-related clients, review broadcast retry, final confirmation, and duplicate processing separately.

As the service scope grows, maintain method inventories and compatibility tests for HTTP, JSON-RPC, and gRPC separately. For a gRPC client example, see Call TRON with gRPC. Add an indexing or event-data layer for account history or event search, with independent monitoring for processed height, backfill, and query lag. Cache only queries with an explicit freshness contract; caching must not change latest versus solidified semantics.

If an event consumer enters a critical path, add persistence, replay, checkpoint recovery, data validation, and backfill. The ZeroMQ extension teaches the real-time event path; it must not become the only data source without gap detection and compensation.

If you are still blocked at any stage, share track feedback and include “Track 6,” the current stage, target network, API protocol, upstream type, completed steps, and redacted error information. Do not submit private keys, API keys, access tokens, complete signed transactions, or internal network addresses.