cryptnox-pos
1.0.0
Standalone USDC payment terminal firmware (ESP32 + Cryptnox smart card)
Toggle main menu visibility
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
22
extern
"C"
{
23
#endif
24
26
typedef
enum
{
27
ETH_JSON_RECEIPT_ERROR
= 0,
30
ETH_JSON_RECEIPT_PENDING
,
31
ETH_JSON_RECEIPT_SUCCESS
,
32
ETH_JSON_RECEIPT_REVERTED
,
33
ETH_JSON_RECEIPT_MISMATCH
,
36
}
eth_json_receipt_t
;
37
40
typedef
struct
{
41
const
char
*
tx_hash
;
43
const
uint8_t *
to
;
45
const
uint8_t *
payee
;
46
uint64_t
amount
;
47
}
eth_receipt_expect_t
;
48
62
bool
eth_json_result_string
(
const
char
*resp,
char
*out,
size_t
out_size);
63
81
bool
eth_json_error_message
(
const
char
*resp,
char
*out,
size_t
out_size);
82
95
eth_json_receipt_t
eth_json_receipt_status
(
const
char
*resp);
96
112
eth_json_receipt_t
eth_json_receipt_check
(
const
char
*resp,
113
const
eth_receipt_expect_t
*want);
114
132
static
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
183
static
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 */
eth_json_error_message
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
eth_json_hex_quantity
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
eth_json_receipt_t
Verdict for an eth_getTransactionReceipt response body.
Definition
eth_json.h:26
ETH_JSON_RECEIPT_REVERTED
@ ETH_JSON_RECEIPT_REVERTED
Definition
eth_json.h:32
ETH_JSON_RECEIPT_PENDING
@ ETH_JSON_RECEIPT_PENDING
Definition
eth_json.h:30
ETH_JSON_RECEIPT_SUCCESS
@ ETH_JSON_RECEIPT_SUCCESS
Definition
eth_json.h:31
ETH_JSON_RECEIPT_ERROR
@ ETH_JSON_RECEIPT_ERROR
Definition
eth_json.h:27
ETH_JSON_RECEIPT_MISMATCH
@ ETH_JSON_RECEIPT_MISMATCH
Definition
eth_json.h:33
eth_json_hex_u256
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_status
eth_json_receipt_t eth_json_receipt_status(const char *resp)
Classify an eth_getTransactionReceipt response body.
Definition
eth_json.cpp:69
eth_json_result_string
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_check
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
eth_receipt_expect_t
What a receipt must show for the payment to count — see eth_json_receipt_check.
Definition
eth_json.h:40
eth_receipt_expect_t::amount
uint64_t amount
Definition
eth_json.h:46
eth_receipt_expect_t::to
const uint8_t * to
Definition
eth_json.h:43
eth_receipt_expect_t::payee
const uint8_t * payee
Definition
eth_json.h:45
eth_receipt_expect_t::tx_hash
const char * tx_hash
Definition
eth_json.h:41
main
eth_json.h
Generated by
1.17.0