17 0x80U, 0x00U, 0x00U, 0x2CU,
18 0x80U, 0x00U, 0x00U, 0x3CU,
19 0x80U, 0x00U, 0x00U, 0x00U,
20 0x00U, 0x00U, 0x00U, 0x00U,
21 0x00U, 0x00U, 0x00U, 0x00U,
63 uint8_t c21[CW_TRON_ADDRESS_BYTES];
64 uint8_t c21_echo[CW_TRON_ADDRESS_BYTES];
65 t->
ok = CW_Tron::decodeAddress(t->
str, crypto, c21) &&
66 CW_Tron::decodeAddress(t->
str, crypto, c21_echo);
90 ESP_LOGW(
TAG,
"stored %s contract not usable - trying config.h",
93 (void)snprintf(t->
str,
sizeof(t->
str),
"%s%s", tron ?
"" :
"0x",
98 ESP_LOGW(
TAG,
"%s not usable - %s on %s disabled", cfg->
name, a->
ticker,
118 if ((t == NULL) || t->
checked) {
return true; }
123 uint8_t c21[CW_TRON_ADDRESS_BYTES];
124 c21[0] = CW_TRON_ADDRESS_PREFIX;
125 (void)CW_Utils::safe_memcpy(&c21[1],
sizeof(c21) - 1U, t->
addr.
addr,
135 if (asked && (dec == 6U)) {
140 (void)snprintf(err, err_max,
"Token contract has %u decimals - set it again",
141 static_cast<unsigned>((dec > 99U) ? 99U : dec));
143 (void)snprintf(err, err_max,
"Could not check the token contract");
145 ESP_LOGW(
TAG,
"contract %s refused: %s", t->
str, err);
165 :
"Native ETH (no contract)",
216 (void)snprintf(out, n,
"Fee up to %s", amt);
240 if ((gettimeofday(&tv, NULL) != 0) || (tv.tv_sec < 1600000000)) {
return 0U; }
241 return (
static_cast<uint64_t
>(tv.tv_sec) * 1000U) +
242 (
static_cast<uint64_t
>(tv.tv_usec) / 1000U);
263 :
"Checking it was sent");
269 const int64_t deadline = esp_timer_get_time() + 120LL * 1000000LL;
275 snprintf(left,
sizeof(left),
"%d s remaining",
276 static_cast<int>((deadline - esp_timer_get_time() + 999999LL)
289 const uint64_t now =
wall_ms();
295 if (esp_timer_get_time() >= deadline) {
break; }
296 vTaskDelay(pdMS_TO_TICKS(4000));
308 ESP_LOGI(
TAG,
"Tx confirmed on-chain");
314 ESP_LOGE(
TAG,
"Integrity gate failed post-receipt: %s", fl->
hash);
326 ESP_LOGE(
TAG,
"Tx reverted on-chain: %s", fl->
hash);
328 "Reverted - check the card's balance");
332 ESP_LOGW(
TAG,
"Tron tx %s expired unseen - not sent", fl->
hash);
340 ESP_LOGW(
TAG,
"Tx %s unconfirmed after 120 s", fl->
hash);
349 const char *pin,
size_t pin_chars,
inflight_t *fl,
350 char *err_out,
size_t err_max)
362 fl, err_out, err_max);
static const pos_asset_t * pos_asset_of(pos_chain_t chain)
The row describing chain.
static bool pos_chain_is_tron(pos_chain_t c)
true for the Tron selections; every other one is EVM.
static bool pos_chain_is_polygon(pos_chain_t c)
true for the Polygon selections. EVM like Ethereum, but its own endpoint, chain id and contracts.
static const pos_net_info_t * pos_net_info(pos_net_t net)
Names for net, or Ethereum's for a value out of range.
#define TRON_ADDR_USDC_MAIN
#define TRON_TRC20_FEE_LIMIT_SUN
#define POLY_ADDR_USDC_MAIN
#define POLY_ADDR_USDT_MAIN
#define TRON_ADDR_USDT_MAIN
bool eth_addr_parse(const char *hex, uint8_t out[ETH_ADDR_LEN])
Parse a 20-byte Ethereum address from a hex string.
#define ETH_ADDR_LEN
Length of a raw (binary) Ethereum address, in 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).
static const char *const TAG
bool eth_rpc_get_token_decimals(const char *token_addr, uint64_t *dec_out)
Read an ERC-20 contract's decimals().
eth_rpc_receipt_result_t
Outcome of one eth_getTransactionReceipt poll.
@ ETH_RPC_RECEIPT_MISMATCH
@ ETH_RPC_RECEIPT_REVERTED
@ ETH_RPC_RECEIPT_PENDING
@ ETH_RPC_RECEIPT_SUCCESS
void pos_handle_anomaly(const char *where)
Report an anomaly: bump a self-checked persisted counter, log it, and keep a local ring buffer for on...
static bool32 run_payment_decision(const pos_amount_t *amount, const pos_addr_t *to, pos_verdict_t verdict)
§4 decision gate: return TRUE32 only if amount and recipient are self-consistent AND the verdict is t...
#define POS_VERDICT_APPROVED
#define POS_VERDICT_DECLINED
static void fmt_coin(char *out, size_t n, uint64_t v, unsigned dec, const char *coin)
"0.0013 ETH": v base units of a dec-decimal coin, to six places, rounded UP — it is a ceiling,...
const token_cfg_t TOKEN_CFG[]
static bool token_parse(token_t *t, bool tron, CW_CryptoProvider &crypto)
Parse t->str into its dual store, twice and independently.
token_t * active_token(pos_chain_t chain)
The selection's token, or NULL for a native coin.
void token_load(const token_cfg_t *cfg, CW_CryptoProvider &crypto)
Load one token at boot: the operator's contract if one is set and parses, config.h otherwise.
char s_payout_tron[SETTINGS_PAYOUT_MAX]
const size_t TOKEN_CFG_COUNT
uint64_t wall_ms(void)
Unix time in ms, 0 while the clock is unset.
bool token_decimals_ok(pos_chain_t chain, char *err, size_t err_max)
Before the first sale in an operator-set token, read its decimals() and refuse anything but 6.
const uint8_t ETH_DERIVE_PATH[20]
bcast_t pay_sign_and_broadcast(CryptnoxWallet &wallet, Pn532NfcTransport &transport, CW_CryptoProvider &crypto, const pos_amount_t *amount, const char *pin, size_t pin_chars, inflight_t *fl, char *err_out, size_t err_max)
Sign and broadcast the reconciled sale on whichever family is selected. The family is read once,...
void sale_fee_text(char *out, size_t n)
The most network fee the customer's card can be charged on top of the sale, for the confirm screen....
void ui_refresh_addresses_for(uint8_t c)
Point the UI's address rows at the selected chain.
void ui_refresh_addresses(void)
Implemented by main: repoint those two rows at the selected chain.
void settle_inflight(void)
Poll the in-flight sale for up to 120 s and show what the chain says.
void inflight_persist(const inflight_t *fl)
Write the sale to NVS just before it leaves the terminal.
const pos_addr_t * active_dest(void)
The reconciled recipient for the chain currently selected.
char s_payout_eth[SETTINGS_PAYOUT_MAX]
token_t s_token[POS_CHAIN__COUNT]
void eth_rpc_select_for(bool polygon)
Point eth_rpc at the endpoint for the selected EVM network.
void eth_rpc_select(void)
bcast_t sign_and_broadcast(CryptnoxWallet &wallet, Pn532NfcTransport &transport, const pos_amount_t *amount, const pos_addr_t *to, const char *pin, size_t pin_chars, inflight_t *fl, char *err_out, size_t err_max)
Sign an EVM token or coin transfer on the card and broadcast it.
eth_rpc_receipt_result_t tron_receipt_as_eth(tron_receipt_t r)
Map a Tron receipt onto the Ethereum verdicts the UI flow uses.
bcast_t sign_and_broadcast_tron(CryptnoxWallet &wallet, Pn532NfcTransport &transport, CW_CryptoProvider &crypto, const pos_amount_t *amount, const pos_addr_t *to, const token_t *token, const char *pin, size_t pin_chars, inflight_t *fl, char *err_out, size_t err_max)
Sign a Tron transfer on the card and broadcast it — TRX or TRC-20.
void tron_addr_to_hex(const uint8_t *addr21, char *out, size_t n)
Format a raw 21-byte Tron address as the "41..." hex the API wants.
Private to the application files (main, boot, card_io, pay, pay_evm, pay_tron): the state they share ...
static bool chain_is_tron(void)
true when the operator has switched the terminal to Tron.
static bool chain_is_polygon(void)
true when the terminal is charging on Polygon rather than Ethereum.
static bool chain_is_native_evm(void)
true when charging in the network's own coin (ETH / POL), not a token.
static bool expired(void)
True once the portal's own window has closed.
const char * settings_net_str(const char *testnet, const char *mainnet)
Pick the string belonging to the network the terminal is on.
pos_chain_t settings_get_chain(void)
Selected chain, or POS_CHAIN_ETH_USDC if never set.
bool settings_get_contract(pos_chain_t chain, char *out, size_t n)
Read the token-contract address for a network.
void settings_inflight_clear(void)
Drop the persisted sale. Writes nothing when there is none.
bool settings_inflight_save(const void *rec, size_t n)
Persist the sale between broadcast and verdict (opaque record).
pos_chain_t
Which chain (and therefore which asset) the terminal charges in.
#define SETTINGS_PAYOUT_MAX
Longest payout address plus NUL — "0x" + 40 hex, or 34 base58 Tron.
What a receipt must show for the payment to count — see eth_json_receipt_check.
uint8_t payee[ETH_ADDR_LEN]
uint8_t addr_echo[ETH_ADDR_LEN]
uint8_t addr[ETH_ADDR_LEN]
A token's contract, dual-stored.
char str[SETTINGS_PAYOUT_MAX]
tron_receipt_t tron_rpc_get_receipt(const char *txid_hex)
Poll a broadcast transaction's receipt (one shot).
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.
#define TRON_ADDR_HEX_LEN
Hex length of a Tron address (21 bytes: 0x41 || 20-byte key hash).
void ui_set_addresses(const char *token_contract, const char *dest_addr)
Provide the token contract and destination addresses for the confirm screen and the settings "Tx" tab...
void ui_show_tx_status(ui_tx_state_t state, const char *info)
Switch to the transaction-status screen.
void ui_set_tx_info(const char *info)
Replace the transaction screen's info line without rebuilding it.
@ UI_TX_STATE_UNCONFIRMED
static void wdt_feed(void)
Feed the task watchdog if, and only if, the calling task is subscribed.