App now has all the network icons and can use them when needed

This commit is contained in:
Alexandre Paillier
2023-09-11 10:00:46 +02:00
parent 015842d4e5
commit 31f0d7f034
7 changed files with 171 additions and 7 deletions

View File

@@ -300,6 +300,16 @@ test: install_tests run_tests
unit-test:
make -C tests/unit
ifeq ($(TARGET_NAME),TARGET_STAX)
NETWORK_ICONS_FILE = $(GEN_SRC_DIR)/net_icons.gen.c
NETWORK_ICONS_DIR = $(shell dirname "$(NETWORK_ICONS_FILE)")
$(NETWORK_ICONS_FILE):
$(shell python3 tools/gen_networks.py "$(NETWORK_ICONS_DIR)")
APP_SOURCE_FILES += $(NETWORK_ICONS_FILE)
endif
# import generic rules from the sdk
include $(BOLOS_SDK)/Makefile.rules

20
src_nbgl/network_icons.c Normal file
View File

@@ -0,0 +1,20 @@
#include "os_utils.h"
#include "os_pic.h"
#include "net_icons.gen.h"
/**
* Get the network icon from a given chain ID
*
* Loops onto the generated \ref g_network_icons array until a chain ID matches.
*
* @param[in] chain_id network's chain ID
* @return the network icon if found, \ref NULL otherwise
*/
const nbgl_icon_details_t *get_network_icon_from_chain_id(const uint64_t *chain_id) {
for (size_t i = 0; i < ARRAYLEN(g_network_icons); ++i) {
if ((uint64_t) PIC(g_network_icons[i].chain_id) == *chain_id) {
return PIC(g_network_icons[i].icon);
}
}
return NULL;
}

9
src_nbgl/network_icons.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef NETWORK_ICONS_H_
#define NETWORK_ICONS_H_
#include <stdbool.h>
#include "nbgl_types.h"
const nbgl_icon_details_t *get_network_icon_from_chain_id(const uint64_t *chain_id);
#endif // NETWORK_ICONS_H_

View File

@@ -7,6 +7,7 @@
#include "ui_signing.h"
#include "plugins.h"
#include "domain_name.h"
#include "network_icons.h"
#define TEXT_TX "transaction"
// 1 more than actually displayed on screen, because of calculations in StaticReview
@@ -190,7 +191,12 @@ static const nbgl_icon_details_t *get_tx_icon(void) {
}
}
} else {
icon = get_app_icon(false);
uint64_t chain_id = get_tx_chain_id();
if (chain_id == chainConfig->chainId) {
icon = get_app_icon(false);
} else {
icon = get_network_icon_from_chain_id(&chain_id);
}
}
return icon;
}

View File

@@ -3,6 +3,7 @@
#include "ui_callbacks.h"
#include "ui_nbgl.h"
#include "network.h"
#include "network_icons.h"
static void cancel_send(void) {
io_seproxyhal_touch_address_cancel(NULL);
@@ -34,6 +35,8 @@ static void display_addr(void) {
}
void ui_display_public_key(const uint64_t *chain_id) {
const nbgl_icon_details_t *icon;
// - if a chain_id is given and it's - known, we specify its network name
// - unknown, we don't specify anything
// - if no chain_id is given we specify the APPNAME (legacy behaviour)
@@ -45,14 +48,11 @@ void ui_display_public_key(const uint64_t *chain_id) {
sizeof(g_stax_shared_buffer));
strlcat(g_stax_shared_buffer, "\n", sizeof(g_stax_shared_buffer));
}
icon = get_network_icon_from_chain_id(chain_id);
} else {
strlcat(g_stax_shared_buffer, APPNAME "\n", sizeof(g_stax_shared_buffer));
icon = get_app_icon(false);
}
strlcat(g_stax_shared_buffer, "address", sizeof(g_stax_shared_buffer));
nbgl_useCaseReviewStart(get_app_icon(false),
g_stax_shared_buffer,
NULL,
"Cancel",
display_addr,
reject_addr);
nbgl_useCaseReviewStart(icon, g_stax_shared_buffer, NULL, "Cancel", display_addr, reject_addr);
}

View File

@@ -24,10 +24,12 @@ GAS_PRICE = 13
GAS_LIMIT = 21000
AMOUNT = 1.22
@pytest.fixture(params=[False, True])
def verbose(request) -> bool:
return request.param
def common(app_client: EthAppClient) -> int:
if app_client._client.firmware.device == "nanos":
pytest.skip("Not supported on LNS")

117
tools/gen_networks.py Executable file
View File

@@ -0,0 +1,117 @@
#!/usr/bin/env python3
import os
import sys
import re
import argparse
class Network:
chain_id: int
name: str
ticker: str
def __init__(self, chain_id: int, name: str, ticker: str):
self.chain_id = chain_id
self.name = name
self.ticker = ticker
def get_network_glyph_name(net: Network) -> str:
return "stax_chain_%u_64px" % (net.chain_id)
def get_header() -> str:
return """\
/*
* Generated by %s
*/
""" % (sys.argv[0])
def gen_icons_array_inc(networks: list[Network], path: str) -> bool:
with open(path + ".h", "w") as out:
print(get_header() + """\
#ifndef NETWORK_ICONS_GENERATED_H_
#define NETWORK_ICONS_GENERATED_H_
#include <stdint.h>
#include "nbgl_types.h"
typedef struct {
uint64_t chain_id;
const nbgl_icon_details_t *icon;
} network_icon_t;
extern const network_icon_t g_network_icons[%u];
#endif // NETWORK_ICONS_GENERATED_H_ \
""" % (len(networks)), file=out)
return True
def gen_icons_array_src(networks: list[Network], path: str) -> bool:
with open(path + ".c", "w") as out:
print(get_header() + """\
#include "glyphs.h"
#include "%s.h"
const network_icon_t g_network_icons[%u] = {\
""" % (os.path.basename(path), len(networks)), file=out)
for net in networks:
glyph_name = get_network_glyph_name(net)
if os.path.isfile("glyphs/%s.gif" % (glyph_name)):
print(" "*4, end="", file=out)
print("{.chain_id = %u, .icon = &C_%s}, // %s" % (net.chain_id,
glyph_name,
net.name),
file=out)
print("};", file=out)
return True
def gen_icons_array(networks: list[Network], path: str) -> bool:
path += "/net_icons.gen"
if not gen_icons_array_inc(networks, path) or \
not gen_icons_array_src(networks, path):
return False
return True
def network_icon_exists(net: Network) -> bool:
return os.path.isfile("glyphs/%s.gif" % (get_network_glyph_name(net)))
def main(output_dir: str) -> bool:
networks: list[Network] = list()
# get chain IDs and network names
expr = r"{\.chain_id = ([0-9]*), \.name = \"(.*)\", \.ticker = \"(.*)\"},"
with open("src_common/network.c") as f:
for line in f.readlines():
line = line.strip()
if line.startswith("{") and line.endswith("},"):
m = re.search(expr,
line)
assert(m.lastindex == 3)
networks.append(Network(int(m.group(1)),
m.group(2),
m.group(3)))
networks.sort(key=lambda x: x.chain_id)
if not gen_icons_array(list(filter(network_icon_exists, networks)),
output_dir):
return False
return True
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("OUTPUT_DIR")
args = parser.parse_args()
assert os.path.isdir(args.OUTPUT_DIR)
quit(0 if main(args.OUTPUT_DIR) else 1)