40#define AMOUNT_CENTS_MAX 999999ULL
42#define AMOUNT_CENTS_MAX_NATIVE (POS_AMOUNT_UNITS_MAX_NATIVE / 10000ULL)
60 const uint64_t n = (cents * 10ULL) +
static_cast<uint64_t
>(digit);
61 return (n <= cap) ? n : cents;
67 const uint64_t n = cents * 100ULL;
68 return (n > cap) ? cap : n;
80 return cents * 10000ULL;
86 uint64_t whole = units / 1000000ULL;
87 uint64_t cents = (units % 1000000ULL) / 10000ULL;
88 snprintf(out, n,
"%" PRIu64
".%02" PRIu64, whole, cents);
106 *wei = units * 1000000000000ULL;
122 bool polygon, uint32_t floor_gwei,
123 uint64_t *max_fee, uint64_t *prio_fee)
127 uint64_t max_fee_wei = (uint64_t)max_gwei * 1000000000ULL;
128 uint64_t prio_fee_wei = (uint64_t)prio_gwei * 1000000000ULL;
129 if (prio_fee_wei > max_fee_wei) { prio_fee_wei = max_fee_wei; }
135 const uint64_t floor_wei = (uint64_t)floor_gwei * 1000000000ULL;
136 if (prio_fee_wei < floor_wei) { prio_fee_wei = floor_wei; }
137 if (max_fee_wei < prio_fee_wei) { max_fee_wei = prio_fee_wei; }
139 *max_fee = max_fee_wei;
140 *prio_fee = prio_fee_wei;
160 uint64_t gas_cost, uint64_t units)
164 uint64_t value_wei = 0U;
177static inline void fmt_coin(
char *out,
size_t n, uint64_t v,
unsigned dec,
181 for (
unsigned i = 6U; i < dec; i++) { div *= 10U; }
182 const uint64_t micro = (v / div) + (((v % div) != 0U) ? 1U : 0U);
184 (void)snprintf(frac,
sizeof(frac),
"%06" PRIu64, micro % 1000000U);
185 size_t f = strlen(frac);
186 while ((f > 0U) && (frac[f - 1U] ==
'0')) { frac[--f] =
'\0'; }
187 (void)snprintf(out, n,
"%" PRIu64
"%s%s %s", micro / 1000000U,
188 (f > 0U) ?
"." :
"", frac, coin);
197#define ABI_SELECTOR_LEN 4U
198#define ABI_WORD_LEN 32U
199#define USDC_CALLDATA_LEN (ABI_SELECTOR_LEN + (2U * ABI_WORD_LEN))
200#define ABI_TO_OFFSET (ABI_SELECTOR_LEN + (ABI_WORD_LEN - ETH_ADDR_LEN))
228 for (j = 0U; j <
sizeof(amount); j++) {
230 static_cast<uint8_t
>((amount >> (8U * j)) & 0xFFU);
Hex Ethereum-address parsing — a pure, dependency-free unit so it can be unit-tested and fuzzed on th...
#define ETH_ADDR_LEN
Length of a raw (binary) Ethereum address, in bytes.
#define AMOUNT_CENTS_MAX_NATIVE
static const uint8_t TRANSFER_SELECTOR[4]
static void evm_fees_from_gwei(uint32_t max_gwei, uint32_t prio_gwei, bool polygon, uint32_t floor_gwei, uint64_t *max_fee, uint64_t *prio_fee)
The EIP-1559 fees one EVM sale will offer, in wei per gas, from the operator's Gwei settings.
static uint64_t amount_cents_cap(bool native)
Ceiling on what the keypad will accept, in cents.
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,...
evm_funds_t
What the pre-flight balance check concluded.
static uint64_t amount_key_00(uint64_t cents, uint64_t cap)
The "00" key: two zeroes shifted in, clamped to cap.
static evm_funds_t evm_funds_check(bool native, uint64_t have_wei, uint64_t gas_cost, uint64_t units)
Can have_wei pay for this sale?
static void build_usdc_calldata(uint8_t out[USDC_CALLDATA_LEN], const uint8_t to[ETH_ADDR_LEN], uint64_t amount)
Build the 68-byte ABI-encoded calldata for a USDC transfer call.
static uint64_t amount_key_back(uint64_t cents)
The backspace key: the last digit dropped.
static void amount_format(uint64_t units, char *out, size_t n)
"12.50": 6-decimal base units to two places, truncated.
static uint64_t amount_key_digit(uint64_t cents, unsigned digit, uint64_t cap)
A digit shifted in from the right; refused whole if it passes cap.
static uint64_t amount_cents_to_units(uint64_t cents)
Keypad cents to 6-decimal base units.
#define USDC_CALLDATA_LEN
static bool evm_units_to_wei(uint64_t units, uint64_t *wei)
6-decimal keypad units -> wei, for the 18-decimal coins only.
Persistent device settings stored in NVS (backlight, Wi-Fi creds).
#define POS_AMOUNT_UNITS_MAX_NATIVE
Ceiling on a native-coin sale, in the keypad's 6-decimal base units.