cryptnox-pos 1.0.0
Standalone USDC payment terminal firmware (ESP32 + Cryptnox smart card)
Loading...
Searching...
No Matches
tron_rpc.h File Reference

Tron HTTP API client (Nile testnet): build a TRX transfer, broadcast it signed, poll its receipt. More...

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
Include dependency graph for tron_rpc.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  tron_tx_ctx_t
 A created-and-verified transfer, ready to sign and broadcast. More...

Macros

#define TRON_RAW_HEX_MAX   768U
 Hex capacity for a raw_data protobuf.

Enumerations

enum  tron_receipt_t { TRON_RECEIPT_PENDING , TRON_RECEIPT_SUCCESS , TRON_RECEIPT_FAILED , TRON_RECEIPT_RPC_ERROR }
 Outcome of one gettransactioninfobyid poll. More...

Functions

void tron_rpc_init (const char *base_url)
 Set the Tron HTTP API base URL (no trailing slash).
void tron_rpc_set_ca_cert (const char *ca_pem)
 Optional: pin the Tron endpoint's TLS certificate.
bool tron_rpc_get_balance (const char *owner_hex, uint64_t *sun_out)
 Read an account's TRX balance, in sun.
bool tron_rpc_get_energy (const char *owner_hex, uint64_t *energy_out)
 Read the energy an account still has available.
bool tron_rpc_get_trc20_balance (const char *owner_hex, const char *contract_hex, uint64_t *units_out)
 Read an account's TRC-20 balance via a constant balanceOf call.
bool tron_rpc_get_trc20_decimals (const char *contract_hex, uint64_t *dec_out)
 Read a TRC-20 contract's decimals() — see eth_rpc_get_token_decimals for why it has to be 6.
bool tron_rpc_create_transfer (const char *owner_hex, const char *to_hex, uint64_t amount_sun, tron_tx_ctx_t *out)
 Create a TRX transfer and verify what the node serialised for us.
bool tron_rpc_create_trc20_transfer (const char *owner_hex, const char *contract_hex, const char *to_hex, uint64_t amount, uint64_t fee_limit_sun, tron_tx_ctx_t *out)
 Create a TRC-20 transfer (USDT, USDC, …) and verify what the node serialised for us.
bool tron_rpc_broadcast (const tron_tx_ctx_t *tx, const uint8_t sig[65])
 Broadcast a created transfer with its 65-byte signature.
tron_receipt_t tron_rpc_get_receipt (const char *txid_hex)
 Poll a broadcast transaction's receipt (one shot).

Detailed Description

Tron HTTP API client (Nile testnet): build a TRX transfer, broadcast it signed, poll its receipt.

Tron has no RLP and no local nonce: the full node serialises the transaction (/wallet/createtransaction, which also supplies the reference block and expiry) and we sign its txID. tron_rpc_create_transfer therefore does NOT trust what comes back — it verifies both that the returned txID really is sha256(raw_data) and that raw_data carries exactly the requested TransferContract, so the card never signs a hash of somebody else's payment.

Definition in file tron_rpc.h.

Macro Definition Documentation

◆ TRON_RAW_HEX_MAX

#define TRON_RAW_HEX_MAX   768U

Hex capacity for a raw_data protobuf.

A TRX transfer needs ~280; a TRC-20 TriggerSmartContract carries a longer type_url plus 68 bytes of calldata and lands near ~400.

Definition at line 35 of file tron_rpc.h.

Referenced by tron_rpc_broadcast(), and tx_ctx_from_json().

Enumeration Type Documentation

◆ tron_receipt_t

Outcome of one gettransactioninfobyid poll.

Enumerator
TRON_RECEIPT_PENDING 

Not in a block yet — poll again later.

TRON_RECEIPT_SUCCESS 

In a block, contract executed — final.

TRON_RECEIPT_FAILED 

In a block but failed — funds NOT moved.

TRON_RECEIPT_RPC_ERROR 

Transport or parse error (transient).

Definition at line 47 of file tron_rpc.h.

Function Documentation

◆ tron_rpc_broadcast()

bool tron_rpc_broadcast ( const tron_tx_ctx_t * tx,
const uint8_t sig[65] )

Broadcast a created transfer with its 65-byte signature.

Parameters
[in]txContext returned by tron_rpc_create_transfer.
[in]sigSignature bytes: r(32) || s(32) || recovery id(1).
Returns
true if the node accepted the transaction into its mempool.

Definition at line 471 of file tron_rpc.cpp.

References bytes_to_hex(), ok(), tron_tx_ctx_t::raw_hex, RESP_BUF_SIZE, RESP_LOG_MAX, TAG, tron_post(), TRON_RAW_HEX_MAX, TRON_SIG_HEX_LEN, and tron_tx_envelope_hex().

Referenced by sign_and_broadcast_tron().

◆ tron_rpc_create_transfer()

bool tron_rpc_create_transfer ( const char * owner_hex,
const char * to_hex,
uint64_t amount_sun,
tron_tx_ctx_t * out )

Create a TRX transfer and verify what the node serialised for us.

Parameters
[in]owner_hexSender address, "41"-prefixed 42-char hex.
[in]to_hexRecipient address, same form.
[in]amount_sunAmount in sun (1 TRX = 1e6 sun); must be non-zero.
[out]outFilled on success; contents undefined on failure.
Returns
true only if the node answered AND the txID matches sha256(raw_data) AND raw_data contains exactly the requested TransferContract.

Definition at line 366 of file tron_rpc.cpp.

References tron_tx_ctx_t::expiration_ms, now_ms(), ok(), tron_tx_ctx_t::raw_hex, RESP_BUF_SIZE, RESP_LOG_MAX, TAG, tron_post(), tron_tx_contract_ok(), tx_ctx_from_json(), and tron_tx_ctx_t::txid_hex.

Referenced by sign_and_broadcast_tron().

◆ tron_rpc_create_trc20_transfer()

bool tron_rpc_create_trc20_transfer ( const char * owner_hex,
const char * contract_hex,
const char * to_hex,
uint64_t amount,
uint64_t fee_limit_sun,
tron_tx_ctx_t * out )

Create a TRC-20 transfer (USDT, USDC, …) and verify what the node serialised for us.

Same trust model as tron_rpc_create_transfer, with one more thing to get wrong: the token contract. A node free to choose it could have the card sign a transfer of a worthless token — or of a different one entirely — so the contract address is pinned by the check just like the recipient is, and so is the fee limit (see tron_tx_trc20_ok).

Parameters
[in]owner_hexSender address, "41"-prefixed 42-char hex.
[in]contract_hexToken contract address, same form.
[in]to_hexRecipient address, same form.
[in]amountAmount in token base units; must be non-zero.
[in]fee_limit_sunMax TRX (in sun) the call may burn; must be non-zero, or a failed call has no cap at all.
[out]outFilled on success; contents undefined on failure.
Returns
true only if the node answered AND txID == sha256(raw_data) AND raw_data carries exactly the requested transfer under the requested fee limit.

Definition at line 411 of file tron_rpc.cpp.

References tron_tx_ctx_t::expiration_ms, now_ms(), ok(), tron_tx_ctx_t::raw_hex, RESP_BUF_SIZE, RESP_LOG_MAX, TAG, tron_post(), tron_trc20_param_hex(), TRON_TRC20_PARAM_HEX_LEN, tron_tx_trc20_ok(), tx_ctx_from_json(), and tron_tx_ctx_t::txid_hex.

Referenced by sign_and_broadcast_tron().

◆ tron_rpc_get_balance()

bool tron_rpc_get_balance ( const char * owner_hex,
uint64_t * sun_out )

Read an account's TRX balance, in sun.

For the pre-flight check that refuses a sale the tapped card cannot fund, before it signs anything — see tron_balance_ok in main.cpp.

An account the chain has never seen answers with an empty object. That is reported as a balance of zero and not as an error, because it is the true answer and it is the case a terminal most needs to catch.

Parameters
[in]owner_hexAccount address, "41"-prefixed 42-char hex.
[out]sun_outBalance in sun on success; untouched on failure.
Returns
true if the node answered with parseable JSON.

Definition at line 218 of file tron_rpc.cpp.

References json_u64(), RESP_BUF_SIZE, RESP_LOG_MAX, TAG, and tron_post().

Referenced by tron_balance_ok().

◆ tron_rpc_get_energy()

bool tron_rpc_get_energy ( const char * owner_hex,
uint64_t * energy_out )

Read the energy an account still has available.

EnergyLimit minus EnergyUsed from /wallet/getaccountresource. Only the distinction between none and some is used: a TRC-20 transfer burns energy paid for out of a stake or out of TRX, so an account with zero TRX can still pay if it has frozen some — and refusing that sale would be worse than the late failure the check exists to avoid.

Parameters
[in]owner_hexAccount address, "41"-prefixed 42-char hex.
[out]energy_outEnergy available on success; untouched on failure.
Returns
true if the node answered with parseable JSON.

Definition at line 241 of file tron_rpc.cpp.

References json_u64(), RESP_BUF_SIZE, RESP_LOG_MAX, TAG, and tron_post().

Referenced by tron_balance_ok().

◆ tron_rpc_get_receipt()

tron_receipt_t tron_rpc_get_receipt ( const char * txid_hex)

Poll a broadcast transaction's receipt (one shot).

Parameters
[in]txid_hex64-char transaction id hex.
Returns
One of tron_receipt_t.

Definition at line 511 of file tron_rpc.cpp.

References RESP_BUF_SIZE, TAG, tron_post(), TRON_RECEIPT_FAILED, TRON_RECEIPT_PENDING, TRON_RECEIPT_RPC_ERROR, and TRON_RECEIPT_SUCCESS.

Referenced by settle_inflight().

◆ tron_rpc_get_trc20_balance()

bool tron_rpc_get_trc20_balance ( const char * owner_hex,
const char * contract_hex,
uint64_t * units_out )

Read an account's TRC-20 balance via a constant balanceOf call.

The check that tron_rpc_create_trc20_transfer cannot make: creating a TriggerSmartContract is only serialisation, and a node will serialise a transfer of tokens the account does not hold just as readily as one it does. Without this the card signs it, it broadcasts, it reverts on-chain, and the customer is declined after the full wait — having paid the energy for it.

Parameters
[in]owner_hexAccount address, "41"-prefixed 42-char hex.
[in]contract_hexToken contract address, same form.
[out]units_outBalance in the token's base units on success; untouched on failure. Saturating, as for the EVM side (see eth_json_hex_quantity).
Returns
true if the node answered with a well-formed constant result.

Definition at line 269 of file tron_rpc.cpp.

References eth_json_hex_quantity(), ok(), RESP_BUF_SIZE, RESP_LOG_MAX, TAG, TRON_ADDR_HEX_LEN, and tron_post().

Referenced by tron_balance_ok().

◆ tron_rpc_get_trc20_decimals()

bool tron_rpc_get_trc20_decimals ( const char * contract_hex,
uint64_t * dec_out )

Read a TRC-20 contract's decimals() — see eth_rpc_get_token_decimals for why it has to be 6.

Parameters
[in]contract_hexContract, TRON_ADDR_HEX_LEN hex chars, "41"-prefixed.
[out]dec_outdecimals() on success; untouched on failure.
Returns
false on transport error or a malformed answer.

Definition at line 330 of file tron_rpc.cpp.

References eth_json_hex_quantity(), ok(), RESP_BUF_SIZE, RESP_LOG_MAX, TAG, TRON_ADDR_HEX_LEN, and tron_post().

Referenced by token_decimals_ok().

◆ tron_rpc_init()

void tron_rpc_init ( const char * base_url)

Set the Tron HTTP API base URL (no trailing slash).

Lifetime: the pointer is stored as-is — pass a literal or static storage.

Parameters
[in]base_urle.g. "https://nile.trongrid.io".

Definition at line 190 of file tron_rpc.cpp.

References s_base_url.

Referenced by pos_boot().

◆ tron_rpc_set_ca_cert()

void tron_rpc_set_ca_cert ( const char * ca_pem)

Optional: pin the Tron endpoint's TLS certificate.

The sibling of eth_rpc_set_ca_cert, and for the same reason: unset, the connection is validated against the whole Mozilla CA bundle, so any one of ~150 CAs can stand in for the node. That is survivable here — tron_tx_contract_ok re-derives the bytes a transfer must contain, so a node (or anything impersonating one) cannot redirect a payment — but it is the difference between one check standing between an attacker and the funds and two. Pin it in production.

Pointer stored as-is (must outlive every call). NULL keeps the CA bundle.

Parameters
[in]ca_pemNUL-terminated PEM certificate, or NULL for the bundle.

Definition at line 195 of file tron_rpc.cpp.

References s_ca_cert.

Referenced by pos_boot().