cryptnox-pos 1.0.0
Standalone USDC payment terminal firmware (ESP32 + Cryptnox smart card)
Loading...
Searching...
No Matches
eth_json.h
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: LGPL-3.0-or-later
3 * Copyright (c) 2026 Cryptnox SA
4 */
5
13
14#ifndef ETH_JSON_H
15#define ETH_JSON_H
16
17#include <stdbool.h>
18#include <stddef.h>
19#include <stdint.h>
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
37
40typedef struct {
41 const char *tx_hash;
43 const uint8_t *to;
45 const uint8_t *payee;
46 uint64_t amount;
48
62bool eth_json_result_string(const char *resp, char *out, size_t out_size);
63
81bool eth_json_error_message(const char *resp, char *out, size_t out_size);
82
96
113 const eth_receipt_expect_t *want);
114
132static inline bool eth_json_hex_u256(const char *hex, uint8_t out[32])
133{
134 if ((hex == NULL) || (out == NULL)) { return false; }
135 if ((hex[0] != '0') || ((hex[1] != 'x') && (hex[1] != 'X'))) { return false; }
136
137 const char *p = &hex[2];
138 if (*p == '\0') { return false; } /* "0x" on its own is not a quantity */
139
140 /* Every digit is checked, leading zeros included: validating only the
141 * significant ones would read "0x00zz" as zero rather than as garbage. */
142 size_t len = 0U;
143 while (p[len] != '\0') {
144 const char c = p[len];
145 const bool is_hex = ((c >= '0') && (c <= '9')) ||
146 ((c >= 'a') && (c <= 'f')) ||
147 ((c >= 'A') && (c <= 'F'));
148 if (!is_hex) { return false; }
149 len++;
150 }
151
152 /* Nodes pad a uint256 out to 64 characters; strip down to the significant
153 * digits so the width test below is about the value, not the encoding.
154 * One digit always survives, so "0x000" stays parseable as zero. */
155 while ((*p == '0') && (p[1] != '\0')) { p++; len--; }
156
157 if (len > 64U) {
158 for (size_t i = 0U; i < 32U; i++) { out[i] = 0xFFU; }
159 return true;
160 }
161
162 /* Right-aligned: the last digit is the low nibble of out[31]. */
163 for (size_t i = 0U; i < 32U; i++) { out[i] = 0U; }
164 for (size_t i = 0U; i < len; i++) {
165 const char c = p[len - 1U - i];
166 uint8_t n;
167 if ((c >= '0') && (c <= '9')) { n = (uint8_t)(c - '0'); }
168 else if ((c >= 'a') && (c <= 'f')) { n = (uint8_t)((c - 'a') + 10); }
169 else { n = (uint8_t)((c - 'A') + 10); }
170 out[31U - (i / 2U)] |= (uint8_t)(((i % 2U) != 0U) ? (n << 4) : n);
171 }
172 return true;
173}
174
183static inline bool eth_json_hex_quantity(const char *hex, uint64_t *out)
184{
185 if (out == NULL) { return false; }
186 uint8_t w[32];
187 if (!eth_json_hex_u256(hex, w)) { return false; }
188 uint64_t v = 0U;
189 for (size_t i = 0U; i < 32U; i++) {
190 if ((i < 24U) && (w[i] != 0U)) { *out = UINT64_MAX; return true; }
191 if (i >= 24U) { v = (v << 8) | (uint64_t)w[i]; }
192 }
193 *out = v;
194 return true;
195}
196
197#ifdef __cplusplus
198}
199#endif
200
201#endif /* ETH_JSON_H */
bool eth_json_error_message(const char *resp, char *out, size_t out_size)
Extract the JSON-RPC error.message from a response body.
Definition eth_json.cpp:39
static bool eth_json_hex_quantity(const char *hex, uint64_t *out)
eth_json_hex_u256, narrowed to a uint64 that saturates at UINT64_MAX instead of wrapping.
Definition eth_json.h:183
eth_json_receipt_t
Verdict for an eth_getTransactionReceipt response body.
Definition eth_json.h:26
@ ETH_JSON_RECEIPT_REVERTED
Definition eth_json.h:32
@ ETH_JSON_RECEIPT_PENDING
Definition eth_json.h:30
@ ETH_JSON_RECEIPT_SUCCESS
Definition eth_json.h:31
@ ETH_JSON_RECEIPT_ERROR
Definition eth_json.h:27
@ ETH_JSON_RECEIPT_MISMATCH
Definition eth_json.h:33
static bool eth_json_hex_u256(const char *hex, uint8_t out[32])
Parse a JSON-RPC QUANTITY ("0x0", "0x1a", 64 hex chars) into a 32-byte big-endian uint256 — the width...
Definition eth_json.h:132
eth_json_receipt_t eth_json_receipt_status(const char *resp)
Classify an eth_getTransactionReceipt response body.
Definition eth_json.cpp:69
bool eth_json_result_string(const char *resp, char *out, size_t out_size)
Extract the top-level "result" string from a JSON-RPC response.
Definition eth_json.cpp:18
eth_json_receipt_t eth_json_receipt_check(const char *resp, const eth_receipt_expect_t *want)
Classify a receipt AND check it is the payment that was asked for.
Definition eth_json.cpp:162
What a receipt must show for the payment to count — see eth_json_receipt_check.
Definition eth_json.h:40
const uint8_t * to
Definition eth_json.h:43
const uint8_t * payee
Definition eth_json.h:45
const char * tx_hash
Definition eth_json.h:41