Skip to content

Commit a2dbcaa

Browse files
author
Paulo Oliveira
committed
feat: format token amount due to token info
1 parent e813dd0 commit a2dbcaa

2 files changed

Lines changed: 119 additions & 1 deletion

File tree

app/src/parser/operation_parser.c

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,44 @@ static tz_parser_result push_frame(tz_parser_state *state,
2828
tz_operation_parser_step_kind step);
2929
static tz_parser_result pop_frame(tz_parser_state *state);
3030

31+
typedef struct {
32+
const char name[32];
33+
const char symbol[12];
34+
uint8_t decimals;
35+
const uint8_t contract_hash[20];
36+
} fa2_token_metadata_t;
37+
38+
static const fa2_token_metadata_t FA2_TOKEN_REGISTRY[] = {
39+
/* KT18amZmM5W7qDWVt2pH6uj7sCEd3kbzLrHT */
40+
{"FA2 Token",
41+
"FA2",
42+
6,
43+
{0x00, 0x00, 0x00, 0x00, 0x00,
44+
0x00, 0x00, 0x00, 0x00, 0x00,
45+
0x00, 0x00, 0x00, 0x00, 0x00,
46+
0x00, 0x00, 0x00, 0x00, 0x00}},
47+
};
48+
49+
#define FA2_TOKEN_REGISTRY_SIZE \
50+
(sizeof(FA2_TOKEN_REGISTRY) / sizeof(FA2_TOKEN_REGISTRY[0]))
51+
52+
static const fa2_token_metadata_t *
53+
fa2_find_token(const uint8_t *destination_22bytes)
54+
{
55+
if (destination_22bytes[0] != 1) {
56+
return NULL;
57+
}
58+
for (size_t i = 0; i < FA2_TOKEN_REGISTRY_SIZE; i++) {
59+
if (memcmp(destination_22bytes + 1,
60+
FA2_TOKEN_REGISTRY[i].contract_hash,
61+
20)
62+
== 0) {
63+
return &FA2_TOKEN_REGISTRY[i];
64+
}
65+
}
66+
return NULL;
67+
}
68+
3169
#ifdef TEZOS_DEBUG
3270
const char *const tz_operation_parser_step_name[] = {"OPTION",
3371
"TUPLE",
@@ -605,6 +643,69 @@ tz_step_tag(tz_parser_state *state)
605643
#define FA2_TO_ADDR_OFS (TZ_CAPTURE_BUFFER_SIZE / 2)
606644
#define FA2_ADDR_MAX_LEN (TZ_CAPTURE_BUFFER_SIZE / 2 - 1)
607645

646+
static void
647+
tz_format_token_amount(char *str, uint8_t decimals, const char *symbol)
648+
{
649+
int len = 0;
650+
651+
while (str[len]) {
652+
len++;
653+
}
654+
if (len == 0) {
655+
str[0] = '0';
656+
str[1] = 0;
657+
len = 1;
658+
}
659+
660+
if (decimals > 0) {
661+
if (len <= decimals) {
662+
int pad = (int)decimals + 1 - len;
663+
for (int j = len; j >= 0; j--) {
664+
str[j + pad] = str[j];
665+
}
666+
for (int j = 0; j < pad; j++) {
667+
str[j] = '0';
668+
}
669+
len += pad;
670+
}
671+
672+
int no_decimals = 1;
673+
for (int i = 0; i < decimals; i++) {
674+
no_decimals &= (str[len - 1 - i] == '0');
675+
}
676+
if (no_decimals) {
677+
str[len - decimals] = 0;
678+
len -= decimals;
679+
} else {
680+
for (int i = 0; i < decimals; i++) {
681+
str[len - i] = str[len - i - 1];
682+
}
683+
str[len - decimals] = '.';
684+
len++;
685+
str[len] = 0;
686+
while ((len > 0) && (str[len - 1] == '0')) {
687+
len--;
688+
str[len] = 0;
689+
}
690+
if ((len > 0) && (str[len - 1] == '.')) {
691+
len--;
692+
str[len] = 0;
693+
}
694+
}
695+
}
696+
697+
if ((symbol != NULL) && symbol[0]) {
698+
str[len] = ' ';
699+
len++;
700+
while (*symbol) {
701+
str[len] = *symbol;
702+
len++;
703+
symbol++;
704+
}
705+
str[len] = 0;
706+
}
707+
}
708+
608709
/**
609710
* @brief Switch FA2 parser to binary fallback for remaining bytes
610711
*
@@ -952,7 +1053,16 @@ tz_step_read_fa2_transfer(tz_parser_state *state)
9521053
if (regs->oofs > 0) {
9531054
tz_stop(IM_FULL);
9541055
}
955-
STRLCPY(state->field_info.field_name, "Token Amount");
1056+
if (op->frame->step_read_fa2.token_idx >= 0) {
1057+
const fa2_token_metadata_t *token
1058+
= &FA2_TOKEN_REGISTRY[op->frame->step_read_fa2.token_idx];
1059+
tz_format_token_amount((char *)state->buffers.num.decimal,
1060+
token->decimals,
1061+
token->symbol);
1062+
STRLCPY(state->field_info.field_name, token->name);
1063+
} else {
1064+
STRLCPY(state->field_info.field_name, "Token Amount");
1065+
}
9561066
state->field_info.is_field_complex = false;
9571067
state->field_info.field_index++;
9581068
/* Pop the FA2 frame first, then push PRINT so PRINT pops to parent */
@@ -1544,12 +1654,19 @@ tz_step_field(tz_parser_state *state)
15441654
}
15451655
case TZ_OPERATION_FIELD_EXPR: {
15461656
if (op->is_fa2_candidate && !field->skip) {
1657+
const fa2_token_metadata_t *token;
15471658
op->frame->step = TZ_OPERATION_STEP_READ_FA2_TRANSFER;
15481659
op->frame->step_read_fa2.sub_step = FA2_STEP_OUTER_SEQ_TAG;
15491660
op->frame->step_read_fa2.addr_ofs = 0;
15501661
op->frame->step_read_fa2.size_ofs = 0;
15511662
op->frame->step_read_fa2.size_val = 0;
15521663
op->frame->step_read_fa2.addr_len = 0;
1664+
op->frame->step_read_fa2.token_idx = -1;
1665+
token = fa2_find_token(op->destination);
1666+
if (token != NULL) {
1667+
op->frame->step_read_fa2.token_idx
1668+
= (int8_t)(token - FA2_TOKEN_REGISTRY);
1669+
}
15531670
} else {
15541671
op->frame->step = TZ_OPERATION_STEP_READ_MICHELINE;
15551672
op->frame->step_read_micheline.inited = 0;

app/src/parser/operation_state.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ typedef struct {
233233
uint32_t size_val; /// accumulator for 4-byte size
234234
uint16_t addr_len; /// remaining bytes for address
235235
tz_num_parser_regs num_state; /// num parser state for amount
236+
int8_t token_idx; /// matched token index, -1 if unknown
236237
} step_read_fa2; /// TZ_OPERATION_STEP_READ_FA2_TRANSFER
237238
};
238239
} tz_operation_parser_frame;

0 commit comments

Comments
 (0)