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

Ethereum JSON-RPC client over HTTPS (nonce / ecrecover parity / raw-tx broadcast / receipt polling). Network bring-up (Wi-Fi, SNTP) lives in net.h. More...

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

Go to the source code of this file.

Enumerations

enum  eth_rpc_receipt_result_t {
  ETH_RPC_RECEIPT_PENDING , ETH_RPC_RECEIPT_SUCCESS , ETH_RPC_RECEIPT_REVERTED , ETH_RPC_RECEIPT_RPC_ERROR ,
  ETH_RPC_RECEIPT_MISMATCH
}
 Outcome of one eth_getTransactionReceipt poll. More...

Functions

void eth_rpc_init (const char *rpc_url, const char *from_addr)
 Set the RPC URL and the from-address used for nonce queries and ecrecover comparison.
bool eth_rpc_set_from (const char *addr)
 Replace the from-address — the account a sale spends from.
void eth_rpc_set_auth (const char *project_id, const char *api_secret)
 Optional: set Infura-style HTTP Basic Auth credentials.
void eth_rpc_set_ca_cert (const char *ca_pem)
 Optional: pin the RPC endpoint's TLS certificate.
bool eth_rpc_get_nonce (uint64_t *nonce_out)
 Fetch the confirmed transaction count (nonce) for from_addr.
bool eth_rpc_get_balance (uint64_t *wei_out)
 Fetch the native balance of from_addr, in wei.
bool eth_rpc_get_token_balance (const char *token_addr, uint64_t *units_out)
 Fetch from_addr's balance of an ERC-20, via balanceOf over eth_call.
bool eth_rpc_get_token_decimals (const char *token_addr, uint64_t *dec_out)
 Read an ERC-20 contract's decimals().
bool eth_rpc_send_raw_tx (const uint8_t *tx, size_t tx_len, char *tx_hash_out, size_t tx_hash_max, char *err_out, size_t err_max)
 Broadcast a raw signed transaction (type-prefixed RLP bytes).
eth_rpc_receipt_result_t eth_rpc_get_tx_receipt (const eth_receipt_expect_t *want)
 Poll the receipt of a broadcast transaction (one shot).
bool eth_rpc_err_already_known (const char *node_err)
 true if a broadcast error message means the node already HAS this transaction ("already known", "known transaction") — i.e. an earlier attempt whose answer was lost got through.

Detailed Description

Ethereum JSON-RPC client over HTTPS (nonce / ecrecover parity / raw-tx broadcast / receipt polling). Network bring-up (Wi-Fi, SNTP) lives in net.h.

Definition in file eth_rpc.h.

Enumeration Type Documentation

◆ eth_rpc_receipt_result_t

Outcome of one eth_getTransactionReceipt poll.

Enumerator
ETH_RPC_RECEIPT_PENDING 

result is null — not mined yet

ETH_RPC_RECEIPT_SUCCESS 

mined with status 0x1 — payment final

ETH_RPC_RECEIPT_REVERTED 

mined with status 0x0 — execution failed

ETH_RPC_RECEIPT_RPC_ERROR 

transport or parse error (transient)

ETH_RPC_RECEIPT_MISMATCH 

mined, but not the payment asked for

Definition at line 36 of file eth_rpc.h.

Function Documentation

◆ eth_rpc_err_already_known()

bool eth_rpc_err_already_known ( const char * node_err)

true if a broadcast error message means the node already HAS this transaction ("already known", "known transaction") — i.e. an earlier attempt whose answer was lost got through.

Definition at line 377 of file eth_rpc.cpp.

Referenced by sign_and_broadcast().

◆ eth_rpc_get_balance()

bool eth_rpc_get_balance ( uint64_t * wei_out)

Fetch the native balance of from_addr, in wei.

For the pre-flight check that refuses a sale the payer cannot fund before the customer is asked for anything — see evm_balance_ok in main.cpp. Without it the first news of an empty account is the node's refusal after the PIN, the tap and the signature.

Saturating at UINT64_MAX (see eth_json_hex_quantity): 20 ETH does not fit a uint64 of wei, and over-reporting can only fail to refuse.

Parameters
[out]wei_outBalance on success; untouched on failure.
Returns
true on success, false on transport or parse error.

Definition at line 212 of file eth_rpc.cpp.

References do_post(), eth_json_hex_quantity(), eth_json_result_string(), RESP_BUF_SIZE, RESP_LOG_MAX, RESULT_STR_MAX, s_from_addr, and TAG.

Referenced by evm_balance_ok().

◆ eth_rpc_get_nonce()

bool eth_rpc_get_nonce ( uint64_t * nonce_out)

Fetch the confirmed transaction count (nonce) for from_addr.

"latest", not "pending": a sale whose broadcast answer was lost may still be in the mempool, and a retry must REPLACE it (same nonce, only one can land) rather than queue behind it as a second payment.

Responses with an HTTP status other than 200, malformed JSON, or a nonce above 2^32-1 are rejected.

Parameters
[out]nonce_outNonce on success; untouched on failure.
Returns
true on success, false on transport, parse or range error.

Definition at line 157 of file eth_rpc.cpp.

References do_post(), eth_json_result_string(), NONCE_MAX, RESP_BUF_SIZE, RESP_LOG_MAX, RESULT_STR_MAX, s_from_addr, and TAG.

Referenced by pos_boot(), and sign_and_broadcast().

◆ eth_rpc_get_token_balance()

bool eth_rpc_get_token_balance ( const char * token_addr,
uint64_t * units_out )

Fetch from_addr's balance of an ERC-20, via balanceOf over eth_call.

The token half of the same check, and the one that saves more: a transfer of more tokens than the account holds is not refused by the node at all. It is broadcast, mined, reverted, and charged for — so the customer waits through the whole confirmation only to be declined, and pays the gas for the privilege.

Saturating, like eth_rpc_get_balance.

Parameters
[in]token_addr"0x..."-prefixed contract address to call.
[out]units_outBalance in the token's base units on success; untouched on failure.
Returns
true on success, false on transport or parse error, or if the configured from_addr is not a 20-byte hex address.

Definition at line 239 of file eth_rpc.cpp.

References do_post(), eth_json_hex_quantity(), eth_json_result_string(), from_no_prefix(), RESP_BUF_SIZE, RESP_LOG_MAX, RESULT_STR_MAX, s_from_addr, and TAG.

Referenced by evm_balance_ok().

◆ eth_rpc_get_token_decimals()

bool eth_rpc_get_token_decimals ( const char * token_addr,
uint64_t * dec_out )

Read an ERC-20 contract's decimals().

Every amount this terminal signs is in 6-decimal base units, so a contract with any other precision would be charged the wrong sum — 10^12 too little for an 18-decimal token. Checked before such a contract can be accepted.

Parameters
[in]token_addr"0x"-prefixed contract address.
[out]dec_outdecimals() on success; untouched on failure.
Returns
false on transport error, no contract code, or a malformed answer.

Definition at line 354 of file eth_rpc.cpp.

References do_post(), eth_json_hex_quantity(), eth_json_result_string(), RESP_BUF_SIZE, RESP_LOG_MAX, RESULT_STR_MAX, and TAG.

Referenced by token_decimals_ok().

◆ eth_rpc_get_tx_receipt()

eth_rpc_receipt_result_t eth_rpc_get_tx_receipt ( const eth_receipt_expect_t * want)

Poll the receipt of a broadcast transaction (one shot).

Calls eth_getTransactionReceipt. A broadcast acceptance only means the tx entered the mempool — a POS must wait for the mined receipt (status 0x1) before declaring the payment approved.

Parameters
[in]wantWhat the receipt must show (see eth_json.h); its tx_hash is the hash computed on the device, not the node's answer to the broadcast.
Return values
ETH_RPC_RECEIPT_PENDINGNot mined yet — poll again later.
ETH_RPC_RECEIPT_SUCCESSMined, execution succeeded, and it is our transfer.
ETH_RPC_RECEIPT_REVERTEDMined but reverted — funds NOT moved.
ETH_RPC_RECEIPT_RPC_ERRORTransport/parse error (may be transient).
ETH_RPC_RECEIPT_MISMATCHA receipt that is not our payment.

Definition at line 385 of file eth_rpc.cpp.

References do_post(), eth_json_receipt_check(), ETH_JSON_RECEIPT_ERROR, ETH_JSON_RECEIPT_MISMATCH, ETH_JSON_RECEIPT_PENDING, ETH_JSON_RECEIPT_REVERTED, ETH_JSON_RECEIPT_SUCCESS, ETH_RPC_RECEIPT_MISMATCH, ETH_RPC_RECEIPT_PENDING, ETH_RPC_RECEIPT_REVERTED, ETH_RPC_RECEIPT_RPC_ERROR, ETH_RPC_RECEIPT_SUCCESS, RESP_LOG_MAX, TAG, and eth_receipt_expect_t::tx_hash.

Referenced by settle_inflight().

◆ eth_rpc_init()

void eth_rpc_init ( const char * rpc_url,
const char * from_addr )

Set the RPC URL and the from-address used for nonce queries and ecrecover comparison.

Must be called before any other eth_rpc_* function.

Lifetime: the module stores the pointers as-is (no copy). Both strings must outlive every eth_rpc_* call — pass string literals or static storage, never stack buffers.

Parameters
[in]rpc_urlHTTPS JSON-RPC endpoint URL.
[in]from_addr"0x..."-prefixed 40-hex-char sender address.

Definition at line 122 of file eth_rpc.cpp.

References s_from_addr, and s_rpc_url.

Referenced by eth_rpc_select_for().

◆ eth_rpc_send_raw_tx()

bool eth_rpc_send_raw_tx ( const uint8_t * tx,
size_t tx_len,
char * tx_hash_out,
size_t tx_hash_max,
char * err_out,
size_t err_max )

Broadcast a raw signed transaction (type-prefixed RLP bytes).

Parameters
[in]txSigned transaction bytes.
[in]tx_lenLength of tx in bytes.
[out]tx_hash_out"0x..."-prefixed tx hash on success; must be at least 68 bytes (2 + 64 + NUL).
[in]tx_hash_maxCapacity of tx_hash_out.
[out]err_outOn failure, the node's own error.message when it sent one ("insufficient funds for gas * price + value", "nonce too low", …), truncated to fit; set to "" when the failure was a transport or parse error with no message to report. May be NULL.
[in]err_maxCapacity of err_out.
Returns
true on success, false on transport error, JSON-RPC error response, or undersized tx_hash_out.

Definition at line 286 of file eth_rpc.cpp.

References bytes_to_hex(), do_post(), eth_json_error_message(), eth_json_result_string(), HEX_PER_BYTE, ok(), RESP_BUF_SIZE, RESP_LOG_MAX, RESULT_STR_MAX, and TAG.

Referenced by sign_and_broadcast().

◆ eth_rpc_set_auth()

void eth_rpc_set_auth ( const char * project_id,
const char * api_secret )

Optional: set Infura-style HTTP Basic Auth credentials.

Same lifetime contract as eth_rpc_init: pointers are stored, not copied.

Parameters
[in]project_idUsername (Infura project ID); NULL/empty disables auth.
[in]api_secretPassword (Infura API secret); NULL/empty disables auth.

Definition at line 146 of file eth_rpc.cpp.

References s_api_secret, and s_project_id.

Referenced by eth_rpc_select_for().

◆ eth_rpc_set_ca_cert()

void eth_rpc_set_ca_cert ( const char * ca_pem)

Optional: pin the RPC endpoint's TLS certificate.

When set, the HTTPS connection is validated only against this PEM (leaf or its issuing CA) instead of the full Mozilla CA bundle, so no unrelated CA can MITM the RPC traffic. Pointer stored as-is (must outlive every call — pass a static/embedded literal). NULL keeps the CA bundle.

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

Definition at line 152 of file eth_rpc.cpp.

References s_ca_cert.

Referenced by eth_rpc_select_for().

◆ eth_rpc_set_from()

bool eth_rpc_set_from ( const char * addr)

Replace the from-address — the account a sale spends from.

The payer is the card on the reader, so it is not known until somebody taps. eth_rpc_init's from_addr is only the boot-time default (the config.h literal, used for the startup reachability probe); this is the per-tap override, and everything that reads the sender — the nonce, the balance, the ecrecover comparison — follows it.

Unlike every other setter in this header the string is copied, because its caller derives it into a stack buffer inside one sale.

Parameters
[in]addr"0x"-prefixed, 40 hex characters. A malformed one is refused rather than silently leaving the previous payer in force — the next nonce would otherwise be somebody else's.
Returns
true if the address was accepted and is now in force.

Definition at line 133 of file eth_rpc.cpp.

References s_from_addr, and s_from_buf.

Referenced by sign_and_broadcast().