cryptnox-pos
1.0.0
Standalone USDC payment terminal firmware (ESP32 + Cryptnox smart card)
Toggle main menu visibility
Loading...
Searching...
No Matches
rpc_error.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
21
22
#ifndef RPC_ERROR_H
23
#define RPC_ERROR_H
24
25
#include <stdbool.h>
26
#include <stddef.h>
27
#include <stdio.h>
28
#include <string.h>
29
30
#ifdef __cplusplus
31
extern
"C"
{
32
#endif
33
35
static
inline
bool
rpc_err_contains
(
const
char
*hay,
const
char
*needle)
36
{
37
if
((hay == NULL) || (needle == NULL) || (needle[0] ==
'\0'
)) {
return
false
; }
38
for
(
size_t
i = 0U; hay[i] !=
'\0'
; i++) {
39
size_t
j = 0U;
40
while
(needle[j] !=
'\0'
) {
41
char
a = hay[i + j];
42
char
b = needle[j];
43
if
((a >=
'A'
) && (a <=
'Z'
)) { a = (char)(a + (
'a'
-
'A'
)); }
44
if
((b >=
'A'
) && (b <=
'Z'
)) { b = (char)(b + (
'a'
-
'A'
)); }
45
if
(a != b) {
break
; }
46
j++;
47
}
48
if
(needle[j] ==
'\0'
) {
return
true
; }
49
}
50
return
false
;
51
}
52
64
static
inline
void
rpc_error_text
(
const
char
*node_msg,
bool
native,
65
bool
polygon,
char
*out,
size_t
n)
66
{
67
/* Substring -> what to say instead. Substrings, not equality: the same
68
* condition is worded differently by geth, erigon and bor, and several of
69
* them append the offending numbers to the sentence. */
70
static
const
struct
{
const
char
*needle;
const
char
*say; } MAP[] = {
71
{
"nonce too low"
,
"Already submitted - check the explorer"
},
72
{
"already known"
,
"Already submitted - check the explorer"
},
73
{
"underpriced"
,
"Fee too low - raise it on Settings > Tx"
},
74
{
"less than block base fee"
,
"Fee too low - raise it on Settings > Tx"
},
75
{
"gas price too low"
,
"Fee too low - raise it on Settings > Tx"
},
76
{
"intrinsic gas too low"
,
"Gas limit too low for this transfer"
},
77
{
"exceeds block gas limit"
,
"Gas limit too high for this network"
},
78
{
"gas limit reached"
,
"Network is full - try again in a moment"
},
79
};
80
81
if
((out == NULL) || (n == 0U)) {
return
; }
82
83
if
((node_msg == NULL) || (node_msg[0] ==
'\0'
)) {
84
/* No JSON-RPC error object: the request never completed, or the body was
85
* not something we could read. Distinct wording from a refusal, because
86
* the operator's next move is different — this one is worth retrying. */
87
(void)snprintf(out, n,
"No answer from the node - try again"
);
88
return
;
89
}
90
91
/* Handled ahead of the table because the right sentence depends on what was
92
* being sent: a token transfer needs gas only, the coin's own transfer needs
93
* the amount too, and saying "not enough ETH" during a USDT sale would send
94
* the operator to top up the wrong thing.
95
*
96
* Three spellings of one condition. geth's is the familiar one; "OutOfFunds"
97
* is what PublicNode's Sepolia endpoint actually returned on 2026-08-31, and
98
* it shares not one word with geth's — which is the argument for matching on
99
* a list of observed strings rather than on what the JSON-RPC spec implies
100
* a node ought to say. */
101
if
(
rpc_err_contains
(node_msg,
"insufficient funds"
) ||
102
rpc_err_contains
(node_msg,
"insufficient balance"
) ||
103
rpc_err_contains
(node_msg,
"outoffunds"
)) {
104
(void)snprintf(out, n,
105
native ?
"Not enough %s for the amount plus gas"
106
:
"Not enough %s on the card for gas"
,
107
polygon ?
"POL"
:
"ETH"
);
108
return
;
109
}
110
111
for
(
size_t
i = 0U; i < (
sizeof
(MAP) /
sizeof
(MAP[0])); i++) {
112
if
(
rpc_err_contains
(node_msg, MAP[i].needle)) {
113
(void)snprintf(out, n,
"%s"
, MAP[i].say);
114
return
;
115
}
116
}
117
118
/* Not one we have words for. Pass the node's own sentence through, clipped
119
* to the panel: an unfamiliar reason in the node's wording is still a lead,
120
* and this is the line somebody will read out over the phone. */
121
(void)snprintf(out, n,
"%s"
, node_msg);
122
}
123
124
#ifdef __cplusplus
125
}
126
#endif
127
128
#endif
/* RPC_ERROR_H */
rpc_err_contains
static bool rpc_err_contains(const char *hay, const char *needle)
Case-insensitive substring search — node wording varies by client.
Definition
rpc_error.h:35
rpc_error_text
static void rpc_error_text(const char *node_msg, bool native, bool polygon, char *out, size_t n)
Render a broadcast refusal for the Declined screen.
Definition
rpc_error.h:64
main
rpc_error.h
Generated by
1.17.0