diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 0b240304..c9fd3208 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -13,7 +13,7 @@ jobs: name: Analyse strategy: matrix: - sdk: ["$NANOS_SDK", "$NANOX_SDK", "$NANOSP_SDK"] + sdk: ["$NANOS_SDK", "$NANOX_SDK", "$NANOSP_SDK", "$STAX_SDK"] runs-on: ubuntu-latest container: image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-legacy:latest diff --git a/.github/workflows/guidelines_enforcer.yml b/.github/workflows/guidelines_enforcer.yml index b39250cb..0b958e52 100644 --- a/.github/workflows/guidelines_enforcer.yml +++ b/.github/workflows/guidelines_enforcer.yml @@ -22,5 +22,4 @@ jobs: name: Call Ledger guidelines_enforcer uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_guidelines_enforcer.yml@v1 with: - relative_app_directory: app - run_for_devices: '["nanos", "nanosp", "nanox"]' + relative_app_directory: 'app' diff --git a/.gitmodules b/.gitmodules index 721a3223..5024ec55 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,10 +3,13 @@ url = https://github.com/LedgerHQ/nanos-secure-sdk.git [submodule "deps/nanox-secure-sdk"] path = deps/nanox-secure-sdk - url = https://github.com/LedgerHQ/nanox-secure-sdk.git + url = https://github.com/LedgerHQ/ledger-secure-sdk.git [submodule "deps/nanosplus-secure-sdk"] path = deps/nanosplus-secure-sdk - url = https://github.com/LedgerHQ/nanosplus-secure-sdk + url = https://github.com/LedgerHQ/ledger-secure-sdk.git [submodule "deps/ledger-zxlib"] path = deps/ledger-zxlib url = https://github.com/Zondax/ledger-zxlib.git +[submodule "deps/stax-secure-sdk"] + path = deps/stax-secure-sdk + url = https://github.com/LedgerHQ/ledger-secure-sdk diff --git a/Makefile b/Makefile index 4246ff0d..74ff1e13 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ #******************************************************************************* -#* (c) 2019 Zondax GmbH +#* (c) 2019 - 2023 Zondax AG #* #* Licensed under the Apache License, Version 2.0 (the "License"); #* you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ # BOLOS_SDK NOT DEFINED We use a containerized build approach ifeq ($(BOLOS_SDK),) +ZXLIB_COMPILE_STAX ?= 1 include $(CURDIR)/deps/ledger-zxlib/dockerized_build.mk else default: @@ -30,5 +31,5 @@ endif test_all: make zemu_install - make clean_build && make + make make zemu_test diff --git a/app/Makefile b/app/Makefile index ed8aa532..e60abb9c 100755 --- a/app/Makefile +++ b/app/Makefile @@ -1,6 +1,6 @@ #******************************************************************************* # Ledger App -# (c) 2018 - 2022 Zondax GmbH +# (c) 2018 - 2023 Zondax AG # (c) 2017 Ledger # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,7 +44,6 @@ APPPATH = "44'/118'" --path "44'/60'" else define error_message - COIN value not supported: [$(COIN)] endef diff --git a/app/Makefile.version b/app/Makefile.version index 163597f4..ca6bd018 100644 --- a/app/Makefile.version +++ b/app/Makefile.version @@ -3,4 +3,4 @@ APPVERSION_M=2 # This is the `spec_version` field of `Runtime` APPVERSION_N=35 # This is the patch version of this release -APPVERSION_P=10 +APPVERSION_P=11 diff --git a/app/glyphs/digit_dot.gif b/app/glyphs/digit_dot.gif deleted file mode 100644 index f8f79606..00000000 Binary files a/app/glyphs/digit_dot.gif and /dev/null differ diff --git a/app/glyphs/icon_back.gif b/app/glyphs/icon_back.gif deleted file mode 100644 index a2a7e6d4..00000000 Binary files a/app/glyphs/icon_back.gif and /dev/null differ diff --git a/app/glyphs/icon_close.gif b/app/glyphs/icon_close.gif deleted file mode 100644 index 12d24a12..00000000 Binary files a/app/glyphs/icon_close.gif and /dev/null differ diff --git a/app/glyphs/icon_crossmark.gif b/app/glyphs/icon_crossmark.gif deleted file mode 100644 index 2dcf9d9e..00000000 Binary files a/app/glyphs/icon_crossmark.gif and /dev/null differ diff --git a/app/glyphs/icon_dashboard.gif b/app/glyphs/icon_dashboard.gif deleted file mode 100644 index 33d9b0a7..00000000 Binary files a/app/glyphs/icon_dashboard.gif and /dev/null differ diff --git a/app/glyphs/icon_eye.gif b/app/glyphs/icon_eye.gif deleted file mode 100644 index df4bb829..00000000 Binary files a/app/glyphs/icon_eye.gif and /dev/null differ diff --git a/app/glyphs/icon_stax_32.gif b/app/glyphs/icon_stax_32.gif new file mode 100644 index 00000000..c33ae718 Binary files /dev/null and b/app/glyphs/icon_stax_32.gif differ diff --git a/app/glyphs/icon_stax_64.gif b/app/glyphs/icon_stax_64.gif new file mode 100644 index 00000000..72cef217 Binary files /dev/null and b/app/glyphs/icon_stax_64.gif differ diff --git a/app/glyphs/icon_validate.gif b/app/glyphs/icon_validate.gif deleted file mode 100644 index 5d1bc5ac..00000000 Binary files a/app/glyphs/icon_validate.gif and /dev/null differ diff --git a/app/glyphs/icon_validate_14.gif b/app/glyphs/icon_validate_14.gif deleted file mode 100644 index ccb5cabe..00000000 Binary files a/app/glyphs/icon_validate_14.gif and /dev/null differ diff --git a/app/src/apdu_handler.c b/app/src/apdu_handler.c index 150abcfb..3222c96f 100644 --- a/app/src/apdu_handler.c +++ b/app/src/apdu_handler.c @@ -1,5 +1,5 @@ /******************************************************************************* -* (c) 2018, 2019 Zondax GmbH +* (c) 2018 - 2023 Zondax AG * (c) 2016 Ledger * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,7 +49,9 @@ __Z_INLINE void handle_getversion(__Z_UNUSED volatile uint32_t *flags, volatile G_io_apdu_buffer[1] = LEDGER_MAJOR_VERSION; G_io_apdu_buffer[2] = LEDGER_MINOR_VERSION; G_io_apdu_buffer[3] = LEDGER_PATCH_VERSION; - G_io_apdu_buffer[4] = !IS_UX_ALLOWED; + // SDK won't let the app reply an apdu message if screensaver is active + // device_locked field --> Always false + G_io_apdu_buffer[4] = 0; G_io_apdu_buffer[5] = (TARGET_ID >> 24) & 0xFF; G_io_apdu_buffer[6] = (TARGET_ID >> 16) & 0xFF; @@ -60,7 +62,25 @@ __Z_INLINE void handle_getversion(__Z_UNUSED volatile uint32_t *flags, volatile THROW(APDU_CODE_OK); } -static void extractHDPath(uint32_t rx, uint32_t offset) { +__Z_INLINE uint8_t extractHRP(uint32_t rx, uint32_t offset) { + if (rx < offset + 1) { + THROW(APDU_CODE_DATA_INVALID); + } + MEMZERO(bech32_hrp, MAX_BECH32_HRP_LEN); + + bech32_hrp_len = G_io_apdu_buffer[offset]; + + if (bech32_hrp_len == 0 || bech32_hrp_len > MAX_BECH32_HRP_LEN) { + THROW(APDU_CODE_DATA_INVALID); + } + + memcpy(bech32_hrp, G_io_apdu_buffer + offset + 1, bech32_hrp_len); + bech32_hrp[bech32_hrp_len] = 0; // zero terminate + + return bech32_hrp_len; +} + +__Z_INLINE void extractHDPath(uint32_t rx, uint32_t offset) { if ((rx - offset) < sizeof(uint32_t) * HDPATH_LEN_DEFAULT) { THROW(APDU_CODE_WRONG_LENGTH); } @@ -74,12 +94,6 @@ static void extractHDPath(uint32_t rx, uint32_t offset) { THROW(APDU_CODE_DATA_INVALID); } - encoding = checkChainConfig(hdPath[1], bech32_hrp, bech32_hrp_len); - if (encoding == UNSUPPORTED) { - ZEMU_LOGF(50, "Chain config not supported for: %s\n", bech32_hrp) - THROW(APDU_CODE_COMMAND_NOT_ALLOWED); - } - // Limit values unless the app is running in expert mode if (!app_mode_expert()) { for(int i=2; i < HDPATH_LEN_DEFAULT; i++) { @@ -89,6 +103,24 @@ static void extractHDPath(uint32_t rx, uint32_t offset) { } } +static void extractHDPath_HRP(uint32_t rx, uint32_t offset) { + extractHDPath(rx, offset); + // Set BECH32_COSMOS as default for backward compatibility + encoding = BECH32_COSMOS; + + // Check if HRP was sent + if ((rx - offset) > sizeof(uint32_t) * HDPATH_LEN_DEFAULT) { + extractHRP(rx, offset + sizeof(uint32_t) * HDPATH_LEN_DEFAULT); + encoding = checkChainConfig(hdPath[1], bech32_hrp, bech32_hrp_len); + if (encoding == UNSUPPORTED) { + ZEMU_LOGF(50, "Chain config not supported for: %s\n", bech32_hrp) + THROW(APDU_CODE_COMMAND_NOT_ALLOWED); + } + } else if (hdPath[1] == HDPATH_ETH_1_DEFAULT) { + THROW(APDU_CODE_COMMAND_NOT_ALLOWED); + } +} + static bool process_chunk(volatile uint32_t *tx, uint32_t rx) { UNUSED(tx); @@ -103,7 +135,7 @@ static bool process_chunk(volatile uint32_t *tx, uint32_t rx) { case P1_INIT: tx_initialize(); tx_reset(); - extractHDPath(rx, OFFSET_DATA); + extractHDPath_HRP(rx, OFFSET_DATA); return false; case P1_ADD: added = tx_append(&(G_io_apdu_buffer[OFFSET_DATA]), rx - OFFSET_DATA); @@ -126,6 +158,13 @@ __Z_INLINE void handleGetAddrSecp256K1(volatile uint32_t *flags, volatile uint32 uint8_t len = extractHRP(rx, OFFSET_DATA); extractHDPath(rx, OFFSET_DATA + 1 + len); + // Verify encoding + encoding = checkChainConfig(hdPath[1], bech32_hrp, bech32_hrp_len); + if (encoding == UNSUPPORTED) { + ZEMU_LOGF(50, "Chain config not supported for: %s\n", bech32_hrp) + THROW(APDU_CODE_COMMAND_NOT_ALLOWED); + } + uint8_t requireConfirmation = G_io_apdu_buffer[OFFSET_P1]; zxerr_t zxerr = app_fill_address(); if (zxerr != zxerr_ok) { @@ -152,19 +191,20 @@ __Z_INLINE void handleSign(volatile uint32_t *flags, volatile uint32_t *tx, uint // Let grab P2 value and if it's not valid, the parser should reject it const tx_type_e sign_type = (tx_type_e) G_io_apdu_buffer[OFFSET_P2]; + if ((hdPath[1] == HDPATH_ETH_1_DEFAULT) && !app_mode_expert()) { + *flags |= IO_ASYNCH_REPLY; + view_custom_error_show(PIC(msg_error1),PIC(msg_error2)); + THROW(APDU_CODE_DATA_INVALID); + } + // Put address in output buffer, we will use it to confirm source address zxerr_t zxerr = app_fill_address(); if (zxerr != zxerr_ok) { *tx = 0; THROW(APDU_CODE_DATA_INVALID); } - parser_tx_obj.tx_json.own_addr = (const char *) (G_io_apdu_buffer + VIEW_ADDRESS_OFFSET_SECP256K1); - if ((encoding != BECH32_COSMOS) && !app_mode_expert()) { - *flags |= IO_ASYNCH_REPLY; - view_custom_error_show(PIC(msg_error1),PIC(msg_error2)); - THROW(APDU_CODE_DATA_INVALID); - } + parser_tx_obj.tx_json.own_addr = (const char *) (G_io_apdu_buffer + VIEW_ADDRESS_OFFSET_SECP256K1); const char *error_msg = tx_parse(sign_type); if (error_msg != NULL) { diff --git a/app/src/coin.h b/app/src/coin.h index ece4d77f..2c5a7fae 100644 --- a/app/src/coin.h +++ b/app/src/coin.h @@ -14,12 +14,12 @@ * limitations under the License. ********************************************************************************/ #pragma once -#include "stdbool.h" + #ifdef __cplusplus extern "C" { #endif -#define CLA 0x55 +#define CLA 0x55u #define HDPATH_LEN_DEFAULT 5 @@ -60,8 +60,8 @@ typedef enum { // In non-expert mode, the app will convert from uatom to ATOM #define COIN_DEFAULT_DENOM_BASE "uatom" #define COIN_DEFAULT_DENOM_REPR "ATOM" -#define COIN_DEFAULT_DENOM_FACTOR 6 -#define COIN_DEFAULT_DENOM_TRIMMING 6 +#define COIN_DEFAULT_DENOM_FACTOR 6u +#define COIN_DEFAULT_DENOM_TRIMMING 6u // Coin denoms may be up to 128 characters long // https://github.com/cosmos/cosmos-sdk/blob/master/types/coin.go#L780 @@ -69,18 +69,18 @@ typedef enum { #define COIN_DENOM_MAXSIZE 129 #define COIN_AMOUNT_MAXSIZE 50 -#define COIN_MAX_CHAINID_LEN 20 -#define INDEXING_TMP_KEYSIZE 70 -#define INDEXING_TMP_VALUESIZE 70 -#define INDEXING_GROUPING_REF_TYPE_SIZE 70 -#define INDEXING_GROUPING_REF_FROM_SIZE 70 +#define COIN_MAX_CHAINID_LEN 20u +#define INDEXING_TMP_KEYSIZE 70u +#define INDEXING_TMP_VALUESIZE 70u +#define INDEXING_GROUPING_REF_TYPE_SIZE 70u +#define INDEXING_GROUPING_REF_FROM_SIZE 70u #define MENU_MAIN_APP_LINE2_SECRET "?" #define COIN_SECRET_REQUIRED_CLICKS 0 #define INS_GET_VERSION 0x00 -#define INS_SIGN_SECP256K1 0x02 -#define INS_GET_ADDR_SECP256K1 0x04 +#define INS_SIGN_SECP256K1 0x02u +#define INS_GET_ADDR_SECP256K1 0x04u #ifdef __cplusplus } diff --git a/app/src/common/actions.h b/app/src/common/actions.h index fd955e87..79032a64 100644 --- a/app/src/common/actions.h +++ b/app/src/common/actions.h @@ -25,15 +25,11 @@ extern uint16_t action_addrResponseLen; -__Z_INLINE void app_set_hrp(char *p) { - crypto_set_hrp(p); -} - __Z_INLINE void app_sign() { uint16_t replyLen = 0; MEMZERO(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE); - zxerr_t err = crypto_sign(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, &replyLen); + const zxerr_t err = crypto_sign(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 3, &replyLen); if (err != zxerr_ok || replyLen == 0) { set_code(G_io_apdu_buffer, 0, APDU_CODE_SIGN_VERIFY_ERROR); @@ -49,7 +45,7 @@ __Z_INLINE zxerr_t app_fill_address() { MEMZERO(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE); action_addrResponseLen = 0; - zxerr_t err = crypto_fillAddress(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 2, &action_addrResponseLen); + const zxerr_t err = crypto_fillAddress(G_io_apdu_buffer, IO_APDU_BUFFER_SIZE - 2, &action_addrResponseLen); if (err != zxerr_ok || action_addrResponseLen == 0) { THROW(APDU_CODE_EXECUTION_ERROR); diff --git a/app/src/common/tx.c b/app/src/common/tx.c index d7280a1a..9a7c8a4e 100644 --- a/app/src/common/tx.c +++ b/app/src/common/tx.c @@ -21,7 +21,7 @@ #include #include "zxmacros.h" -#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) +#if defined(TARGET_NANOX) || defined(TARGET_NANOS2) || defined(TARGET_STAX) #define RAM_BUFFER_SIZE 8192 #define FLASH_BUFFER_SIZE 16384 #elif defined(TARGET_NANOS) @@ -38,7 +38,7 @@ typedef struct uint8_t buffer[FLASH_BUFFER_SIZE]; } storage_t; -#if defined(TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) +#if defined(TARGET_NANOS) || defined(TARGET_NANOX) || defined(TARGET_NANOS2) || defined(TARGET_STAX) storage_t NV_CONST N_appdata_impl __attribute__((aligned(64))); #define N_appdata (*(NV_VOLATILE storage_t *)PIC(&N_appdata_impl)) #endif diff --git a/app/src/crypto.c b/app/src/crypto.c index d6de7652..f2972e4e 100644 --- a/app/src/crypto.c +++ b/app/src/crypto.c @@ -1,5 +1,5 @@ /******************************************************************************* -* (c) 2019 Zondax GmbH +* (c) 2023 Zondax AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,8 @@ #include #include "chain_config.h" +#define MAX_DER_SIGNATURE_LEN 73u + uint32_t hdPath[HDPATH_LEN_DEFAULT]; uint8_t bech32_hrp_len; @@ -31,41 +33,41 @@ address_encoding_e encoding; #include "cx.h" -zxerr_t crypto_extractUncompressedPublicKey(const uint32_t path[HDPATH_LEN_DEFAULT], uint8_t *pubKey, uint16_t pubKeyLen) { +static zxerr_t crypto_extractUncompressedPublicKey(uint8_t *pubKey, uint16_t pubKeyLen) { + if (pubKey == NULL || pubKeyLen < PK_LEN_SECP256K1_UNCOMPRESSED) { + return zxerr_invalid_crypto_settings; + } + cx_ecfp_public_key_t cx_publicKey = {0}; cx_ecfp_private_key_t cx_privateKey = {0}; - uint8_t privateKeyData[32] = {0}; + uint8_t privateKeyData[64] = {0}; + + zxerr_t error = zxerr_unknown; + // Generate keys + CATCH_CXERROR(os_derive_bip32_with_seed_no_throw(HDW_NORMAL, + CX_CURVE_256K1, + hdPath, + HDPATH_LEN_DEFAULT, + privateKeyData, + NULL, + NULL, + 0)) + + CATCH_CXERROR(cx_ecfp_init_private_key_no_throw(CX_CURVE_256K1, privateKeyData, 32, &cx_privateKey)) + CATCH_CXERROR(cx_ecfp_init_public_key_no_throw(CX_CURVE_256K1, NULL, 0, &cx_publicKey)) + CATCH_CXERROR(cx_ecfp_generate_pair_no_throw(CX_CURVE_256K1, &cx_publicKey, &cx_privateKey, 1)) + memcpy(pubKey, cx_publicKey.W, PK_LEN_SECP256K1_UNCOMPRESSED); + error = zxerr_ok; - if (pubKeyLen < PK_LEN_SECP256K1_UNCOMPRESSED) { - return zxerr_invalid_crypto_settings; - } +catch_cx_error: + MEMZERO(&cx_privateKey, sizeof(cx_privateKey)); + MEMZERO(privateKeyData, sizeof(privateKeyData)); - volatile zxerr_t err = zxerr_unknown; - BEGIN_TRY - { - TRY { - os_perso_derive_node_bip32(CX_CURVE_256K1, - path, - HDPATH_LEN_DEFAULT, - privateKeyData, NULL); - - cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &cx_privateKey); - cx_ecfp_init_public_key(CX_CURVE_256K1, NULL, 0, &cx_publicKey); - cx_ecfp_generate_pair(CX_CURVE_256K1, &cx_publicKey, &cx_privateKey, 1); - err = zxerr_ok; - } - CATCH_OTHER(e) { - err = zxerr_ledger_api_error; - } - FINALLY { - MEMZERO(&cx_privateKey, sizeof(cx_privateKey)); - MEMZERO(privateKeyData, 32); - } + if (error != zxerr_ok) { + MEMZERO(pubKey, pubKeyLen); } - END_TRY; - memcpy(pubKey, cx_publicKey.W, PK_LEN_SECP256K1_UNCOMPRESSED); - return err; + return error; } __Z_INLINE zxerr_t compressPubkey(const uint8_t *pubkey, uint16_t pubkeyLen, uint8_t *output, uint16_t outputLen) { @@ -87,18 +89,12 @@ __Z_INLINE zxerr_t compressPubkey(const uint8_t *pubkey, uint16_t pubkeyLen, uin return zxerr_ok; } -zxerr_t crypto_sign(uint8_t *signature, - uint16_t signatureMaxlen, - uint16_t *sigSize) { - uint8_t messageDigest[CX_SHA256_SIZE] = {0}; - - // Hash it - const uint8_t *message = tx_get_buffer(); - const uint16_t messageLen = tx_get_buffer_length(); +static zxerr_t crypto_hashBuffer(const uint8_t *input, const uint16_t inputLen, + uint8_t *output, uint16_t outputLen) { switch (encoding) { case BECH32_COSMOS: { - cx_hash_sha256(message, messageLen, messageDigest, CX_SHA256_SIZE); + cx_hash_sha256(input, inputLen, output, outputLen); break; } @@ -108,7 +104,7 @@ zxerr_t crypto_sign(uint8_t *signature, if (status != CX_OK) { return zxerr_ledger_api_error; } - status = cx_hash_no_throw((cx_hash_t*) &sha3, CX_LAST, message, messageLen, messageDigest, CX_SHA256_SIZE); + status = cx_hash_no_throw((cx_hash_t*) &sha3, CX_LAST, input, inputLen, output, outputLen); if (status != CX_OK) { return zxerr_ledger_api_error; } @@ -118,79 +114,67 @@ zxerr_t crypto_sign(uint8_t *signature, default: return zxerr_unknown; } + return zxerr_ok; +} - cx_ecfp_private_key_t cx_privateKey = {0}; - uint8_t privateKeyData[32] = {0}; - unsigned int info = 0; - volatile int signatureLength = 0; - - volatile zxerr_t err = zxerr_unknown; - BEGIN_TRY - { - TRY - { - // Generate keys - os_perso_derive_node_bip32(CX_CURVE_SECP256K1, - hdPath, - HDPATH_LEN_DEFAULT, - privateKeyData, NULL); - - cx_ecfp_init_private_key(CX_CURVE_SECP256K1, privateKeyData, 32, &cx_privateKey); - - // Sign - signatureLength = cx_ecdsa_sign(&cx_privateKey, - CX_RND_RFC6979 | CX_LAST, - CX_SHA256, - messageDigest, - CX_SHA256_SIZE, - signature, - signatureMaxlen, - &info); - err = zxerr_ok; - } - CATCH_OTHER(e) { - err = zxerr_ledger_api_error; - } - FINALLY { - MEMZERO(&cx_privateKey, sizeof(cx_privateKey)); - MEMZERO(privateKeyData, 32); - } +zxerr_t crypto_sign(uint8_t *output, + uint16_t outputLen, + uint16_t *sigSize) { + if (output == NULL || sigSize == NULL || outputLen < MAX_DER_SIGNATURE_LEN) { + return zxerr_invalid_crypto_settings; } - END_TRY; - *sigSize = signatureLength; - return err; -} + uint8_t messageDigest[CX_SHA256_SIZE] = {0}; -uint8_t extractHRP(uint32_t rx, uint32_t offset) { - if (rx < offset + 1) { - THROW(APDU_CODE_DATA_INVALID); - } - MEMZERO(bech32_hrp, MAX_BECH32_HRP_LEN); + // Hash it + const uint8_t *message = tx_get_buffer(); + const uint16_t messageLen = tx_get_buffer_length(); - bech32_hrp_len = G_io_apdu_buffer[offset]; + CHECK_ZXERR(crypto_hashBuffer(message, messageLen, messageDigest, CX_SHA256_SIZE)) + CHECK_APP_CANARY() + + cx_ecfp_private_key_t cx_privateKey; + uint8_t privateKeyData[64] = {0}; + size_t signatureLength = MAX_DER_SIGNATURE_LEN; + uint32_t tmpInfo = 0; + *sigSize = 0; + + zxerr_t error = zxerr_unknown; + + CATCH_CXERROR(os_derive_bip32_with_seed_no_throw(HDW_NORMAL, + CX_CURVE_256K1, + hdPath, + HDPATH_LEN_DEFAULT, + privateKeyData, + NULL, + NULL, + 0)) + CATCH_CXERROR(cx_ecfp_init_private_key_no_throw(CX_CURVE_256K1, privateKeyData, 32, &cx_privateKey)) + CATCH_CXERROR(cx_ecdsa_sign_no_throw(&cx_privateKey, + CX_RND_RFC6979 | CX_LAST, + CX_SHA256, + messageDigest, + CX_SHA256_SIZE, + output, + &signatureLength, &tmpInfo)) + *sigSize = signatureLength; + error = zxerr_ok; - if (bech32_hrp_len == 0 || bech32_hrp_len > MAX_BECH32_HRP_LEN) { - THROW(APDU_CODE_DATA_INVALID); - } +catch_cx_error: + MEMZERO(&cx_privateKey, sizeof(cx_privateKey)); + MEMZERO(privateKeyData, sizeof(privateKeyData)); - memcpy(bech32_hrp, G_io_apdu_buffer + offset + 1, bech32_hrp_len); - bech32_hrp[bech32_hrp_len] = 0; // zero terminate + if (error != zxerr_ok) { + MEMZERO(output, outputLen); + } - return bech32_hrp_len; + return error; } void ripemd160_32(uint8_t *out, uint8_t *in) { cx_ripemd160_t rip160; cx_ripemd160_init(&rip160); - cx_hash(&rip160.header, CX_LAST, in, CX_SHA256_SIZE, out, CX_RIPEMD160_SIZE); -} - -void crypto_set_hrp(char *p) { - bech32_hrp_len = strlen(p); - if (bech32_hrp_len < MAX_BECH32_HRP_LEN) { - snprintf(bech32_hrp, sizeof(bech32_hrp), "%s", p); - } + cx_hash_no_throw(&rip160.header, CX_LAST, in, CX_SHA256_SIZE, out, CX_RIPEMD160_SIZE); } zxerr_t crypto_fillAddress(uint8_t *buffer, uint16_t buffer_len, uint16_t *addrResponseLen) { @@ -200,7 +184,7 @@ zxerr_t crypto_fillAddress(uint8_t *buffer, uint16_t buffer_len, uint16_t *addrR // extract pubkey uint8_t uncompressedPubkey [PK_LEN_SECP256K1_UNCOMPRESSED] = {0}; - CHECK_ZXERR(crypto_extractUncompressedPublicKey(hdPath, uncompressedPubkey, sizeof(uncompressedPubkey))) + CHECK_ZXERR(crypto_extractUncompressedPublicKey(uncompressedPubkey, sizeof(uncompressedPubkey))) CHECK_ZXERR(compressPubkey(uncompressedPubkey, sizeof(uncompressedPubkey), buffer, buffer_len)) char *addr = (char *) (buffer + PK_LEN_SECP256K1); @@ -221,7 +205,7 @@ zxerr_t crypto_fillAddress(uint8_t *buffer, uint16_t buffer_len, uint16_t *addrR if (cx_keccak_init_no_throw(&ctx, 256) != CX_OK) { return zxerr_unknown; } - cx_hash((cx_hash_t *)&ctx, CX_LAST, uncompressedPubkey+1, sizeof(uncompressedPubkey)-1, hashed1_pk, sizeof(hashed1_pk)); + cx_hash_no_throw((cx_hash_t *)&ctx, CX_LAST, uncompressedPubkey+1, sizeof(uncompressedPubkey)-1, hashed1_pk, sizeof(hashed1_pk)); CHECK_ZXERR(bech32EncodeFromBytes(addr, buffer_len - PK_LEN_SECP256K1, bech32_hrp, hashed1_pk + 12, sizeof(hashed1_pk) - 12, 1, BECH32_ENCODING_BECH32)) break; } diff --git a/app/src/crypto.h b/app/src/crypto.h index 6a7d319f..12a0ea6e 100644 --- a/app/src/crypto.h +++ b/app/src/crypto.h @@ -33,8 +33,6 @@ extern char bech32_hrp[MAX_BECH32_HRP_LEN + 1]; extern uint8_t bech32_hrp_len; extern address_encoding_e encoding; -uint8_t extractHRP(uint32_t rx, uint32_t offset); - void crypto_set_hrp(char *p); zxerr_t crypto_fillAddress(uint8_t *buffer, uint16_t bufferLen, uint16_t *addrResponseLen); diff --git a/app/src/json/json_parser.h b/app/src/json/json_parser.h index bce15840..e62677cd 100644 --- a/app/src/json/json_parser.h +++ b/app/src/json/json_parser.h @@ -1,5 +1,5 @@ /******************************************************************************* -* (c) 2018, 2019 Zondax GmbH +* (c) 2018 - 2023 Zondax AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,6 +39,11 @@ extern "C" { #define MAX_NUMBER_OF_TOKENS 70 #endif +#if defined(TARGET_STAX) +#undef MAX_NUMBER_OF_TOKENS +#define MAX_NUMBER_OF_TOKENS 600 +#endif + #define ROOT_TOKEN_INDEX 0 //--------------------------------------------- diff --git a/app/src/tx_display.c b/app/src/tx_display.c index f5c23a06..787e745e 100644 --- a/app/src/tx_display.c +++ b/app/src/tx_display.c @@ -1,5 +1,5 @@ /******************************************************************************* -* (c) 2018, 2019 Zondax GmbH +* (c) 2018 - 2023 Zondax AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -599,6 +599,7 @@ parser_error_t tx_display_translation(char *dst, uint16_t dstLen, char *src, uin *dst = 0; return parser_ok; } + #ifdef __cplusplus #pragma clang diagnostic pop #endif diff --git a/app/src/tx_parser.c b/app/src/tx_parser.c index 415eabba..f8ded002 100644 --- a/app/src/tx_parser.c +++ b/app/src/tx_parser.c @@ -1,5 +1,5 @@ /******************************************************************************* -* (c) 2018, 2019 Zondax GmbH +* (c) 2018 - 2023 Zondax AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ #pragma clang diagnostic push #pragma ide diagnostic ignored "misc-no-recursion" #endif + #include #include "tx_parser.h" #include "zxmacros.h" diff --git a/app/src/tx_parser.h b/app/src/tx_parser.h index f69a62e7..2bebc3ad 100644 --- a/app/src/tx_parser.h +++ b/app/src/tx_parser.h @@ -1,5 +1,5 @@ /******************************************************************************* -* (c) 2018, 2019 Zondax GmbH +* (c) 2018 - 2023 Zondax AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/app/stax_icon.gif b/app/stax_icon.gif new file mode 100644 index 00000000..361019ee Binary files /dev/null and b/app/stax_icon.gif differ diff --git a/deps/ledger-zxlib b/deps/ledger-zxlib index 2f509248..3ffe6488 160000 --- a/deps/ledger-zxlib +++ b/deps/ledger-zxlib @@ -1 +1 @@ -Subproject commit 2f509248f5e4e273b9793c8cc609a79dfdeadef9 +Subproject commit 3ffe64882bece4e6a17895ce306c0129862681c6 diff --git a/deps/nanos-secure-sdk b/deps/nanos-secure-sdk index 760b313a..40a60bc8 160000 --- a/deps/nanos-secure-sdk +++ b/deps/nanos-secure-sdk @@ -1 +1 @@ -Subproject commit 760b313a61692869556f210a4320306d8012679c +Subproject commit 40a60bc83c6b1422e047c36beb4018891bc34b12 diff --git a/deps/nanosplus-secure-sdk b/deps/nanosplus-secure-sdk index 6a028440..a80708f9 160000 --- a/deps/nanosplus-secure-sdk +++ b/deps/nanosplus-secure-sdk @@ -1 +1 @@ -Subproject commit 6a0284400066b5d0575847e4546ecb0c01691350 +Subproject commit a80708f93fdbbc447bc7506aee314fe41a093068 diff --git a/deps/nanox-secure-sdk b/deps/nanox-secure-sdk index 05465c19..a80708f9 160000 --- a/deps/nanox-secure-sdk +++ b/deps/nanox-secure-sdk @@ -1 +1 @@ -Subproject commit 05465c19add6fc688afaebbef92e5f26649c484b +Subproject commit a80708f93fdbbc447bc7506aee314fe41a093068 diff --git a/docs/APDUSPEC.md b/docs/APDUSPEC.md index 2e4e8f33..b125614e 100644 --- a/docs/APDUSPEC.md +++ b/docs/APDUSPEC.md @@ -64,7 +64,7 @@ The general structure of commands and responses is as follows: -------------- -### INS_GET_ADDR_SECP256K1 +### INS_GET_ADDR #### Command @@ -79,7 +79,7 @@ The general structure of commands and responses is as follows: | HRP_LEN | byte(1) | Bech32 HRP Length | 1<=HRP_LEN<=83 | | HRP | byte (HRP_LEN) | Bech32 HRP | | | Path[0] | byte (4) | Derivation Path Data | 44 | -| Path[1] | byte (4) | Derivation Path Data | 118 | +| Path[1] | byte (4) | Derivation Path Data | 118 / 60 | | Path[2] | byte (4) | Derivation Path Data | ? | | Path[3] | byte (4) | Derivation Path Data | ? | | Path[4] | byte (4) | Derivation Path Data | ? | @@ -94,7 +94,7 @@ First three items in the derivation path will be hardened automatically hardened | ADDR | byte (65) | Bech 32 addr | | | SW1-SW2 | byte (2) | Return code | see list of return codes | -### SIGN_SECP256K1 +### INS_SIGN #### Command @@ -109,7 +109,8 @@ First three items in the derivation path will be hardened automatically hardened | | | | 1 = textual | | L | byte (1) | Bytes in payload | (depends) | -The first packet/chunk includes only the derivation path +The first packet/chunk includes only the derivation path and HRP. +At the moment, seding HRP is optional but it will be mandatory in a future version. All other packets/chunks should contain message to sign @@ -117,11 +118,13 @@ All other packets/chunks should contain message to sign | Field | Type | Content | Expected | | ---------- | -------- | ---------------------- | --------- | -| Path[0] | byte (4) | Derivation Path Data | 44 | -| Path[1] | byte (4) | Derivation Path Data | 118 | -| Path[2] | byte (4) | Derivation Path Data | ? | -| Path[3] | byte (4) | Derivation Path Data | ? | -| Path[4] | byte (4) | Derivation Path Data | ? | +| Path[0] | byte (4) | Derivation Path Data | 44 | +| Path[1] | byte (4) | Derivation Path Data | 118 / 60 | +| Path[2] | byte (4) | Derivation Path Data | ? | +| Path[3] | byte (4) | Derivation Path Data | ? | +| Path[4] | byte (4) | Derivation Path Data | ? | +| HRP_LEN | byte(1) | Bech32 HRP Length | 1<=HRP_LEN<=83 | +| HRP | byte (HRP_LEN) | Bech32 HRP | | *Other Chunks/Packets* diff --git a/tests/common.cpp b/tests/common.cpp index 738a8331..276d9c19 100644 --- a/tests/common.cpp +++ b/tests/common.cpp @@ -23,6 +23,7 @@ #include "bech32.h" #include "hexutils.h" #include "gmock/gmock.h" +#include "coin.h" std::vector dumpUI(parser_context_t *ctx, uint16_t maxKeyLen, diff --git a/tests_zemu/package.json b/tests_zemu/package.json index 88d928c9..f91257ce 100644 --- a/tests_zemu/package.json +++ b/tests_zemu/package.json @@ -14,34 +14,35 @@ "Ledger" ], "scripts": { - "test": "ts-node tests/pullImageKillOld.ts && jest --maxConcurrency 2" + "clean": "ts-node tests/pullImageKillOld.ts", + "test": "yarn clean && jest --maxConcurrency 2" }, "dependencies": { - "@zondax/ledger-cosmos-js": "^3.0.2", - "@zondax/zemu": "^0.42.1" + "@zondax/ledger-cosmos-js": "^3.0.3", + "@zondax/zemu": "^0.44.0" }, "devDependencies": { - "@types/jest": "^29.2.3", + "@types/jest": "^29.5.3", "@types/ledgerhq__hw-transport": "^4.21.4", - "@typescript-eslint/eslint-plugin": "^5.59.6", - "@typescript-eslint/parser": "^5.59.6", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", + "bech32": "^2.0.0", "blakejs": "^1.1.1", "crypto-js": "4.1.1", - "eslint": "^8.40.0", - "eslint-config-prettier": "^8.8.0", - "eslint-plugin-import": "^2.27.5", - "eslint-plugin-jest": "^27.1.5", - "eslint-plugin-prettier": "^4.0.0", - "jest": "29.5.0", + "eslint": "^8.44.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-jest": "^27.2.1", + "eslint-plugin-prettier": "^5.0.0", + "jest": "29.6.2", "jest-serial-runner": "^1.1.0", "js-sha3": "0.8.0", "jssha": "^3.2.0", - "prettier": "^2.8.8", - "secp256k1": "^4.0.3", - "ts-jest": "^29.0.3", - "ts-node": "^10.9.1", "keccak256": "^1.0.6", - "bech32": "^2.0.0", + "prettier": "^3.0.0", + "secp256k1": "^5.0.0", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.1", "typescript": "^5.0.4" } } diff --git a/tests_zemu/snapshots/s-mainmenu/00004.png b/tests_zemu/snapshots/s-mainmenu/00004.png index 98030e9a..8b61000f 100644 Binary files a/tests_zemu/snapshots/s-mainmenu/00004.png and b/tests_zemu/snapshots/s-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/s-mainmenu/00007.png b/tests_zemu/snapshots/s-mainmenu/00007.png index a4fbbac9..3ad12346 100644 Binary files a/tests_zemu/snapshots/s-mainmenu/00007.png and b/tests_zemu/snapshots/s-mainmenu/00007.png differ diff --git a/tests_zemu/snapshots/s-mainmenu/00010.png b/tests_zemu/snapshots/s-mainmenu/00010.png index 98030e9a..8b61000f 100644 Binary files a/tests_zemu/snapshots/s-mainmenu/00010.png and b/tests_zemu/snapshots/s-mainmenu/00010.png differ diff --git a/tests_zemu/snapshots/sp-mainmenu/00004.png b/tests_zemu/snapshots/sp-mainmenu/00004.png index d8d85a04..b639e800 100644 Binary files a/tests_zemu/snapshots/sp-mainmenu/00004.png and b/tests_zemu/snapshots/sp-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/sp-mainmenu/00007.png b/tests_zemu/snapshots/sp-mainmenu/00007.png index 3922fb6c..c7703726 100644 Binary files a/tests_zemu/snapshots/sp-mainmenu/00007.png and b/tests_zemu/snapshots/sp-mainmenu/00007.png differ diff --git a/tests_zemu/snapshots/sp-mainmenu/00010.png b/tests_zemu/snapshots/sp-mainmenu/00010.png index d8d85a04..b639e800 100644 Binary files a/tests_zemu/snapshots/sp-mainmenu/00010.png and b/tests_zemu/snapshots/sp-mainmenu/00010.png differ diff --git a/tests_zemu/snapshots/st-govDeposit/00000.png b/tests_zemu/snapshots/st-govDeposit/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-govDeposit/00000.png differ diff --git a/tests_zemu/snapshots/st-govDeposit/00001.png b/tests_zemu/snapshots/st-govDeposit/00001.png new file mode 100644 index 00000000..2a5ad8a8 Binary files /dev/null and b/tests_zemu/snapshots/st-govDeposit/00001.png differ diff --git a/tests_zemu/snapshots/st-govDeposit/00002.png b/tests_zemu/snapshots/st-govDeposit/00002.png new file mode 100644 index 00000000..524b0425 Binary files /dev/null and b/tests_zemu/snapshots/st-govDeposit/00002.png differ diff --git a/tests_zemu/snapshots/st-govDeposit/00003.png b/tests_zemu/snapshots/st-govDeposit/00003.png new file mode 100644 index 00000000..9bfecf27 Binary files /dev/null and b/tests_zemu/snapshots/st-govDeposit/00003.png differ diff --git a/tests_zemu/snapshots/st-govDeposit/00004.png b/tests_zemu/snapshots/st-govDeposit/00004.png new file mode 100644 index 00000000..411107f8 Binary files /dev/null and b/tests_zemu/snapshots/st-govDeposit/00004.png differ diff --git a/tests_zemu/snapshots/st-govDeposit/00005.png b/tests_zemu/snapshots/st-govDeposit/00005.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-govDeposit/00005.png differ diff --git a/tests_zemu/snapshots/st-ibc_denoms/00000.png b/tests_zemu/snapshots/st-ibc_denoms/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-ibc_denoms/00000.png differ diff --git a/tests_zemu/snapshots/st-ibc_denoms/00001.png b/tests_zemu/snapshots/st-ibc_denoms/00001.png new file mode 100644 index 00000000..ff5a113d Binary files /dev/null and b/tests_zemu/snapshots/st-ibc_denoms/00001.png differ diff --git a/tests_zemu/snapshots/st-ibc_denoms/00002.png b/tests_zemu/snapshots/st-ibc_denoms/00002.png new file mode 100644 index 00000000..493649b3 Binary files /dev/null and b/tests_zemu/snapshots/st-ibc_denoms/00002.png differ diff --git a/tests_zemu/snapshots/st-ibc_denoms/00003.png b/tests_zemu/snapshots/st-ibc_denoms/00003.png new file mode 100644 index 00000000..49d196c0 Binary files /dev/null and b/tests_zemu/snapshots/st-ibc_denoms/00003.png differ diff --git a/tests_zemu/snapshots/st-ibc_denoms/00004.png b/tests_zemu/snapshots/st-ibc_denoms/00004.png new file mode 100644 index 00000000..411107f8 Binary files /dev/null and b/tests_zemu/snapshots/st-ibc_denoms/00004.png differ diff --git a/tests_zemu/snapshots/st-ibc_denoms/00005.png b/tests_zemu/snapshots/st-ibc_denoms/00005.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-ibc_denoms/00005.png differ diff --git a/tests_zemu/snapshots/st-mainmenu/00000.png b/tests_zemu/snapshots/st-mainmenu/00000.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-mainmenu/00000.png differ diff --git a/tests_zemu/snapshots/st-mainmenu/00001.png b/tests_zemu/snapshots/st-mainmenu/00001.png new file mode 100644 index 00000000..e971ae89 Binary files /dev/null and b/tests_zemu/snapshots/st-mainmenu/00001.png differ diff --git a/tests_zemu/snapshots/st-mainmenu/00002.png b/tests_zemu/snapshots/st-mainmenu/00002.png new file mode 100644 index 00000000..8dd2cdc2 Binary files /dev/null and b/tests_zemu/snapshots/st-mainmenu/00002.png differ diff --git a/tests_zemu/snapshots/st-mainmenu/00003.png b/tests_zemu/snapshots/st-mainmenu/00003.png new file mode 100644 index 00000000..f1012e76 Binary files /dev/null and b/tests_zemu/snapshots/st-mainmenu/00003.png differ diff --git a/tests_zemu/snapshots/st-mainmenu/00004.png b/tests_zemu/snapshots/st-mainmenu/00004.png new file mode 100644 index 00000000..8dd2cdc2 Binary files /dev/null and b/tests_zemu/snapshots/st-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/st-mainmenu/00005.png b/tests_zemu/snapshots/st-mainmenu/00005.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-mainmenu/00005.png differ diff --git a/tests_zemu/snapshots/st-msgMultiSend/00000.png b/tests_zemu/snapshots/st-msgMultiSend/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-msgMultiSend/00000.png differ diff --git a/tests_zemu/snapshots/st-msgMultiSend/00001.png b/tests_zemu/snapshots/st-msgMultiSend/00001.png new file mode 100644 index 00000000..ea564414 Binary files /dev/null and b/tests_zemu/snapshots/st-msgMultiSend/00001.png differ diff --git a/tests_zemu/snapshots/st-msgMultiSend/00002.png b/tests_zemu/snapshots/st-msgMultiSend/00002.png new file mode 100644 index 00000000..5f7e2fdd Binary files /dev/null and b/tests_zemu/snapshots/st-msgMultiSend/00002.png differ diff --git a/tests_zemu/snapshots/st-msgMultiSend/00003.png b/tests_zemu/snapshots/st-msgMultiSend/00003.png new file mode 100644 index 00000000..4e7f82c1 Binary files /dev/null and b/tests_zemu/snapshots/st-msgMultiSend/00003.png differ diff --git a/tests_zemu/snapshots/st-msgMultiSend/00004.png b/tests_zemu/snapshots/st-msgMultiSend/00004.png new file mode 100644 index 00000000..5b392f6e Binary files /dev/null and b/tests_zemu/snapshots/st-msgMultiSend/00004.png differ diff --git a/tests_zemu/snapshots/st-msgMultiSend/00005.png b/tests_zemu/snapshots/st-msgMultiSend/00005.png new file mode 100644 index 00000000..ec8695b4 Binary files /dev/null and b/tests_zemu/snapshots/st-msgMultiSend/00005.png differ diff --git a/tests_zemu/snapshots/st-msgMultiSend/00006.png b/tests_zemu/snapshots/st-msgMultiSend/00006.png new file mode 100644 index 00000000..5cc4bafc Binary files /dev/null and b/tests_zemu/snapshots/st-msgMultiSend/00006.png differ diff --git a/tests_zemu/snapshots/st-msgMultiSend/00007.png b/tests_zemu/snapshots/st-msgMultiSend/00007.png new file mode 100644 index 00000000..254d887f Binary files /dev/null and b/tests_zemu/snapshots/st-msgMultiSend/00007.png differ diff --git a/tests_zemu/snapshots/st-msgMultiSend/00008.png b/tests_zemu/snapshots/st-msgMultiSend/00008.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-msgMultiSend/00008.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress-eth/00000.png b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00000.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress-eth/00001.png b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00001.png new file mode 100644 index 00000000..66ffedaf Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00001.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress-eth/00002.png b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00002.png new file mode 100644 index 00000000..3d7f5c46 Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00002.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress-eth/00003.png b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00003.png new file mode 100644 index 00000000..265f2286 Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00003.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress-eth/00004.png b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00004.png new file mode 100644 index 00000000..80170bf5 Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00004.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress-eth/00005.png b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00005.png new file mode 100644 index 00000000..f5a56e6d Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00005.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress-eth/00006.png b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00006.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress-eth/00006.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress/00000.png b/tests_zemu/snapshots/st-setWithdrawAddress/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress/00000.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress/00001.png b/tests_zemu/snapshots/st-setWithdrawAddress/00001.png new file mode 100644 index 00000000..66ffedaf Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress/00001.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress/00002.png b/tests_zemu/snapshots/st-setWithdrawAddress/00002.png new file mode 100644 index 00000000..3d7f5c46 Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress/00002.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress/00003.png b/tests_zemu/snapshots/st-setWithdrawAddress/00003.png new file mode 100644 index 00000000..265f2286 Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress/00003.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress/00004.png b/tests_zemu/snapshots/st-setWithdrawAddress/00004.png new file mode 100644 index 00000000..80170bf5 Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress/00004.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress/00005.png b/tests_zemu/snapshots/st-setWithdrawAddress/00005.png new file mode 100644 index 00000000..f5a56e6d Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress/00005.png differ diff --git a/tests_zemu/snapshots/st-setWithdrawAddress/00006.png b/tests_zemu/snapshots/st-setWithdrawAddress/00006.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-setWithdrawAddress/00006.png differ diff --git a/tests_zemu/snapshots/st-show_address/00000.png b/tests_zemu/snapshots/st-show_address/00000.png new file mode 100644 index 00000000..6779246a Binary files /dev/null and b/tests_zemu/snapshots/st-show_address/00000.png differ diff --git a/tests_zemu/snapshots/st-show_address/00001.png b/tests_zemu/snapshots/st-show_address/00001.png new file mode 100644 index 00000000..8b119985 Binary files /dev/null and b/tests_zemu/snapshots/st-show_address/00001.png differ diff --git a/tests_zemu/snapshots/st-show_address/00002.png b/tests_zemu/snapshots/st-show_address/00002.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-show_address/00002.png differ diff --git a/tests_zemu/snapshots/st-show_address_huge/00000.png b/tests_zemu/snapshots/st-show_address_huge/00000.png new file mode 100644 index 00000000..6779246a Binary files /dev/null and b/tests_zemu/snapshots/st-show_address_huge/00000.png differ diff --git a/tests_zemu/snapshots/st-show_address_huge/00001.png b/tests_zemu/snapshots/st-show_address_huge/00001.png new file mode 100644 index 00000000..02dfca11 Binary files /dev/null and b/tests_zemu/snapshots/st-show_address_huge/00001.png differ diff --git a/tests_zemu/snapshots/st-show_address_huge/00002.png b/tests_zemu/snapshots/st-show_address_huge/00002.png new file mode 100644 index 00000000..38861a7f Binary files /dev/null and b/tests_zemu/snapshots/st-show_address_huge/00002.png differ diff --git a/tests_zemu/snapshots/st-show_address_huge/00003.png b/tests_zemu/snapshots/st-show_address_huge/00003.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-show_address_huge/00003.png differ diff --git a/tests_zemu/snapshots/st-show_eth_address/00000.png b/tests_zemu/snapshots/st-show_eth_address/00000.png new file mode 100644 index 00000000..6779246a Binary files /dev/null and b/tests_zemu/snapshots/st-show_eth_address/00000.png differ diff --git a/tests_zemu/snapshots/st-show_eth_address/00001.png b/tests_zemu/snapshots/st-show_eth_address/00001.png new file mode 100644 index 00000000..e0c21f9c Binary files /dev/null and b/tests_zemu/snapshots/st-show_eth_address/00001.png differ diff --git a/tests_zemu/snapshots/st-show_eth_address/00002.png b/tests_zemu/snapshots/st-show_eth_address/00002.png new file mode 100644 index 00000000..b134010b Binary files /dev/null and b/tests_zemu/snapshots/st-show_eth_address/00002.png differ diff --git a/tests_zemu/snapshots/st-show_eth_address/00003.png b/tests_zemu/snapshots/st-show_eth_address/00003.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-show_eth_address/00003.png differ diff --git a/tests_zemu/snapshots/st-sign_basic/00000.png b/tests_zemu/snapshots/st-sign_basic/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic/00000.png differ diff --git a/tests_zemu/snapshots/st-sign_basic/00001.png b/tests_zemu/snapshots/st-sign_basic/00001.png new file mode 100644 index 00000000..d9c11af8 Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic/00001.png differ diff --git a/tests_zemu/snapshots/st-sign_basic/00002.png b/tests_zemu/snapshots/st-sign_basic/00002.png new file mode 100644 index 00000000..08c557da Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic/00002.png differ diff --git a/tests_zemu/snapshots/st-sign_basic/00003.png b/tests_zemu/snapshots/st-sign_basic/00003.png new file mode 100644 index 00000000..1ca1ef4e Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic/00003.png differ diff --git a/tests_zemu/snapshots/st-sign_basic/00004.png b/tests_zemu/snapshots/st-sign_basic/00004.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic/00004.png differ diff --git a/tests_zemu/snapshots/st-sign_basic2/00000.png b/tests_zemu/snapshots/st-sign_basic2/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic2/00000.png differ diff --git a/tests_zemu/snapshots/st-sign_basic2/00001.png b/tests_zemu/snapshots/st-sign_basic2/00001.png new file mode 100644 index 00000000..2abb6f8d Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic2/00001.png differ diff --git a/tests_zemu/snapshots/st-sign_basic2/00002.png b/tests_zemu/snapshots/st-sign_basic2/00002.png new file mode 100644 index 00000000..c229b26d Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic2/00002.png differ diff --git a/tests_zemu/snapshots/st-sign_basic2/00003.png b/tests_zemu/snapshots/st-sign_basic2/00003.png new file mode 100644 index 00000000..1ca1ef4e Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic2/00003.png differ diff --git a/tests_zemu/snapshots/st-sign_basic2/00004.png b/tests_zemu/snapshots/st-sign_basic2/00004.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic2/00004.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_eth/00000.png b/tests_zemu/snapshots/st-sign_basic_eth/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_eth/00000.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_eth/00001.png b/tests_zemu/snapshots/st-sign_basic_eth/00001.png new file mode 100644 index 00000000..fc500d3a Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_eth/00001.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_eth/00002.png b/tests_zemu/snapshots/st-sign_basic_eth/00002.png new file mode 100644 index 00000000..24fbff89 Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_eth/00002.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_eth/00003.png b/tests_zemu/snapshots/st-sign_basic_eth/00003.png new file mode 100644 index 00000000..b57125f1 Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_eth/00003.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_eth/00004.png b/tests_zemu/snapshots/st-sign_basic_eth/00004.png new file mode 100644 index 00000000..a1bda4ee Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_eth/00004.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_eth/00005.png b/tests_zemu/snapshots/st-sign_basic_eth/00005.png new file mode 100644 index 00000000..f5a56e6d Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_eth/00005.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_eth/00006.png b/tests_zemu/snapshots/st-sign_basic_eth/00006.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_eth/00006.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_eth_warning/00000.png b/tests_zemu/snapshots/st-sign_basic_eth_warning/00000.png new file mode 100644 index 00000000..ec85a9bb Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_eth_warning/00000.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_eth_warning/00001.png b/tests_zemu/snapshots/st-sign_basic_eth_warning/00001.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_eth_warning/00001.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_extra_fields/00000.png b/tests_zemu/snapshots/st-sign_basic_extra_fields/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_extra_fields/00000.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_extra_fields/00001.png b/tests_zemu/snapshots/st-sign_basic_extra_fields/00001.png new file mode 100644 index 00000000..d9c11af8 Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_extra_fields/00001.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_extra_fields/00002.png b/tests_zemu/snapshots/st-sign_basic_extra_fields/00002.png new file mode 100644 index 00000000..08c557da Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_extra_fields/00002.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_extra_fields/00003.png b/tests_zemu/snapshots/st-sign_basic_extra_fields/00003.png new file mode 100644 index 00000000..1ca1ef4e Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_extra_fields/00003.png differ diff --git a/tests_zemu/snapshots/st-sign_basic_extra_fields/00004.png b/tests_zemu/snapshots/st-sign_basic_extra_fields/00004.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-sign_basic_extra_fields/00004.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic/00000.png b/tests_zemu/snapshots/st-textual-sign_basic/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic/00000.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic/00001.png b/tests_zemu/snapshots/st-textual-sign_basic/00001.png new file mode 100644 index 00000000..60bd1e9b Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic/00001.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic/00002.png b/tests_zemu/snapshots/st-textual-sign_basic/00002.png new file mode 100644 index 00000000..7a6a5ac3 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic/00002.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic/00003.png b/tests_zemu/snapshots/st-textual-sign_basic/00003.png new file mode 100644 index 00000000..a9c25d2b Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic/00003.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic/00004.png b/tests_zemu/snapshots/st-textual-sign_basic/00004.png new file mode 100644 index 00000000..e54582a5 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic/00004.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic/00005.png b/tests_zemu/snapshots/st-textual-sign_basic/00005.png new file mode 100644 index 00000000..f5a56e6d Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic/00005.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic/00006.png b/tests_zemu/snapshots/st-textual-sign_basic/00006.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic/00006.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00000.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00000.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00001.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00001.png new file mode 100644 index 00000000..a68d599f Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00001.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00002.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00002.png new file mode 100644 index 00000000..9aaa234b Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00002.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00003.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00003.png new file mode 100644 index 00000000..276bf01b Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00003.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00004.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00004.png new file mode 100644 index 00000000..62d2fbd5 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00004.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00005.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00005.png new file mode 100644 index 00000000..c62a1df2 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00005.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00006.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00006.png new file mode 100644 index 00000000..6d397962 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00006.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00007.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00007.png new file mode 100644 index 00000000..0733415b Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00007.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00008.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00008.png new file mode 100644 index 00000000..d5d1f8e3 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00008.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth/00009.png b/tests_zemu/snapshots/st-textual-sign_basic_eth/00009.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth/00009.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth_warning/00000.png b/tests_zemu/snapshots/st-textual-sign_basic_eth_warning/00000.png new file mode 100644 index 00000000..ec85a9bb Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth_warning/00000.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_eth_warning/00001.png b/tests_zemu/snapshots/st-textual-sign_basic_eth_warning/00001.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_eth_warning/00001.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00000.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00000.png new file mode 100644 index 00000000..a99b458a Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00000.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00001.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00001.png new file mode 100644 index 00000000..a68d599f Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00001.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00002.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00002.png new file mode 100644 index 00000000..9aaa234b Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00002.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00003.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00003.png new file mode 100644 index 00000000..276bf01b Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00003.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00004.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00004.png new file mode 100644 index 00000000..62d2fbd5 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00004.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00005.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00005.png new file mode 100644 index 00000000..c62a1df2 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00005.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00006.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00006.png new file mode 100644 index 00000000..6d397962 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00006.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00007.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00007.png new file mode 100644 index 00000000..0733415b Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00007.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00008.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00008.png new file mode 100644 index 00000000..d5d1f8e3 Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00008.png differ diff --git a/tests_zemu/snapshots/st-textual-sign_basic_expert/00009.png b/tests_zemu/snapshots/st-textual-sign_basic_expert/00009.png new file mode 100644 index 00000000..364600bb Binary files /dev/null and b/tests_zemu/snapshots/st-textual-sign_basic_expert/00009.png differ diff --git a/tests_zemu/snapshots/x-govDeposit/00003.png b/tests_zemu/snapshots/x-govDeposit/00003.png index 84bc70f9..2ced4d49 100644 Binary files a/tests_zemu/snapshots/x-govDeposit/00003.png and b/tests_zemu/snapshots/x-govDeposit/00003.png differ diff --git a/tests_zemu/snapshots/x-govDeposit/00006.png b/tests_zemu/snapshots/x-govDeposit/00006.png index b3a92e31..70d09100 100644 Binary files a/tests_zemu/snapshots/x-govDeposit/00006.png and b/tests_zemu/snapshots/x-govDeposit/00006.png differ diff --git a/tests_zemu/snapshots/x-govDeposit/00008.png b/tests_zemu/snapshots/x-govDeposit/00008.png index 9d32864f..d8fcf1cc 100644 Binary files a/tests_zemu/snapshots/x-govDeposit/00008.png and b/tests_zemu/snapshots/x-govDeposit/00008.png differ diff --git a/tests_zemu/snapshots/x-ibc_denoms/00001.png b/tests_zemu/snapshots/x-ibc_denoms/00001.png index 70772708..b8f6cdc1 100644 Binary files a/tests_zemu/snapshots/x-ibc_denoms/00001.png and b/tests_zemu/snapshots/x-ibc_denoms/00001.png differ diff --git a/tests_zemu/snapshots/x-ibc_denoms/00002.png b/tests_zemu/snapshots/x-ibc_denoms/00002.png index 46ba8198..1009a3c2 100644 Binary files a/tests_zemu/snapshots/x-ibc_denoms/00002.png and b/tests_zemu/snapshots/x-ibc_denoms/00002.png differ diff --git a/tests_zemu/snapshots/x-ibc_denoms/00003.png b/tests_zemu/snapshots/x-ibc_denoms/00003.png index e42e6ee7..da1b3f2b 100644 Binary files a/tests_zemu/snapshots/x-ibc_denoms/00003.png and b/tests_zemu/snapshots/x-ibc_denoms/00003.png differ diff --git a/tests_zemu/snapshots/x-ibc_denoms/00004.png b/tests_zemu/snapshots/x-ibc_denoms/00004.png index 19374588..58eed79e 100644 Binary files a/tests_zemu/snapshots/x-ibc_denoms/00004.png and b/tests_zemu/snapshots/x-ibc_denoms/00004.png differ diff --git a/tests_zemu/snapshots/x-ibc_denoms/00005.png b/tests_zemu/snapshots/x-ibc_denoms/00005.png index e234dbb0..b5ec39f8 100644 Binary files a/tests_zemu/snapshots/x-ibc_denoms/00005.png and b/tests_zemu/snapshots/x-ibc_denoms/00005.png differ diff --git a/tests_zemu/snapshots/x-ibc_denoms/00006.png b/tests_zemu/snapshots/x-ibc_denoms/00006.png index a1980245..5d38a7e5 100644 Binary files a/tests_zemu/snapshots/x-ibc_denoms/00006.png and b/tests_zemu/snapshots/x-ibc_denoms/00006.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00001.png b/tests_zemu/snapshots/x-mainmenu/00001.png index e10e0049..8472e5d9 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00001.png and b/tests_zemu/snapshots/x-mainmenu/00001.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00002.png b/tests_zemu/snapshots/x-mainmenu/00002.png index 7e236da6..f7921677 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00002.png and b/tests_zemu/snapshots/x-mainmenu/00002.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00003.png b/tests_zemu/snapshots/x-mainmenu/00003.png index e10e0049..8472e5d9 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00003.png and b/tests_zemu/snapshots/x-mainmenu/00003.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00004.png b/tests_zemu/snapshots/x-mainmenu/00004.png index d8d85a04..b639e800 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00004.png and b/tests_zemu/snapshots/x-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00007.png b/tests_zemu/snapshots/x-mainmenu/00007.png index 3922fb6c..c7703726 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00007.png and b/tests_zemu/snapshots/x-mainmenu/00007.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00010.png b/tests_zemu/snapshots/x-mainmenu/00010.png index d8d85a04..b639e800 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00010.png and b/tests_zemu/snapshots/x-mainmenu/00010.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00011.png b/tests_zemu/snapshots/x-mainmenu/00011.png index e10e0049..8472e5d9 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00011.png and b/tests_zemu/snapshots/x-mainmenu/00011.png differ diff --git a/tests_zemu/snapshots/x-msgMultiSend/00003.png b/tests_zemu/snapshots/x-msgMultiSend/00003.png index c572861c..f43853dd 100644 Binary files a/tests_zemu/snapshots/x-msgMultiSend/00003.png and b/tests_zemu/snapshots/x-msgMultiSend/00003.png differ diff --git a/tests_zemu/snapshots/x-msgMultiSend/00005.png b/tests_zemu/snapshots/x-msgMultiSend/00005.png index b84ba3b4..0ab9cc3d 100644 Binary files a/tests_zemu/snapshots/x-msgMultiSend/00005.png and b/tests_zemu/snapshots/x-msgMultiSend/00005.png differ diff --git a/tests_zemu/snapshots/x-msgMultiSend/00006.png b/tests_zemu/snapshots/x-msgMultiSend/00006.png index c498f6b2..74e5092c 100644 Binary files a/tests_zemu/snapshots/x-msgMultiSend/00006.png and b/tests_zemu/snapshots/x-msgMultiSend/00006.png differ diff --git a/tests_zemu/snapshots/x-msgMultiSend/00007.png b/tests_zemu/snapshots/x-msgMultiSend/00007.png index f1418b66..50456f70 100644 Binary files a/tests_zemu/snapshots/x-msgMultiSend/00007.png and b/tests_zemu/snapshots/x-msgMultiSend/00007.png differ diff --git a/tests_zemu/snapshots/x-msgMultiSend/00008.png b/tests_zemu/snapshots/x-msgMultiSend/00008.png index e4149aaf..d4deb7e0 100644 Binary files a/tests_zemu/snapshots/x-msgMultiSend/00008.png and b/tests_zemu/snapshots/x-msgMultiSend/00008.png differ diff --git a/tests_zemu/snapshots/x-msgMultiSend/00009.png b/tests_zemu/snapshots/x-msgMultiSend/00009.png index 6425843f..1271607c 100644 Binary files a/tests_zemu/snapshots/x-msgMultiSend/00009.png and b/tests_zemu/snapshots/x-msgMultiSend/00009.png differ diff --git a/tests_zemu/snapshots/x-msgMultiSend/00010.png b/tests_zemu/snapshots/x-msgMultiSend/00010.png index e4149aaf..d4deb7e0 100644 Binary files a/tests_zemu/snapshots/x-msgMultiSend/00010.png and b/tests_zemu/snapshots/x-msgMultiSend/00010.png differ diff --git a/tests_zemu/snapshots/x-msgMultiSend/00011.png b/tests_zemu/snapshots/x-msgMultiSend/00011.png index 7279040d..328b356c 100644 Binary files a/tests_zemu/snapshots/x-msgMultiSend/00011.png and b/tests_zemu/snapshots/x-msgMultiSend/00011.png differ diff --git a/tests_zemu/snapshots/x-msgMultiSend/00012.png b/tests_zemu/snapshots/x-msgMultiSend/00012.png index e4149aaf..d4deb7e0 100644 Binary files a/tests_zemu/snapshots/x-msgMultiSend/00012.png and b/tests_zemu/snapshots/x-msgMultiSend/00012.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00003.png b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00003.png index 350ef295..eb470379 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00003.png and b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00003.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00004.png b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00004.png index 65b749f5..9ae6d13c 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00004.png and b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00004.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00005.png b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00005.png index 8c729777..ddde590b 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00005.png and b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00005.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00006.png b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00006.png index 4dc44ae4..db3ad2c1 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00006.png and b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00006.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00008.png b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00008.png index 8c729777..ddde590b 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00008.png and b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00008.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00009.png b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00009.png index 21583d12..7a814c79 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress-eth/00009.png and b/tests_zemu/snapshots/x-setWithdrawAddress-eth/00009.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress/00003.png b/tests_zemu/snapshots/x-setWithdrawAddress/00003.png index 350ef295..eb470379 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress/00003.png and b/tests_zemu/snapshots/x-setWithdrawAddress/00003.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress/00004.png b/tests_zemu/snapshots/x-setWithdrawAddress/00004.png index 65b749f5..9ae6d13c 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress/00004.png and b/tests_zemu/snapshots/x-setWithdrawAddress/00004.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress/00005.png b/tests_zemu/snapshots/x-setWithdrawAddress/00005.png index 8c729777..ddde590b 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress/00005.png and b/tests_zemu/snapshots/x-setWithdrawAddress/00005.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress/00006.png b/tests_zemu/snapshots/x-setWithdrawAddress/00006.png index 4dc44ae4..db3ad2c1 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress/00006.png and b/tests_zemu/snapshots/x-setWithdrawAddress/00006.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress/00008.png b/tests_zemu/snapshots/x-setWithdrawAddress/00008.png index 8c729777..ddde590b 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress/00008.png and b/tests_zemu/snapshots/x-setWithdrawAddress/00008.png differ diff --git a/tests_zemu/snapshots/x-setWithdrawAddress/00009.png b/tests_zemu/snapshots/x-setWithdrawAddress/00009.png index 21583d12..7a814c79 100644 Binary files a/tests_zemu/snapshots/x-setWithdrawAddress/00009.png and b/tests_zemu/snapshots/x-setWithdrawAddress/00009.png differ diff --git a/tests_zemu/snapshots/x-show_address/00001.png b/tests_zemu/snapshots/x-show_address/00001.png index 4a1aa7e1..79a82065 100644 Binary files a/tests_zemu/snapshots/x-show_address/00001.png and b/tests_zemu/snapshots/x-show_address/00001.png differ diff --git a/tests_zemu/snapshots/x-show_eth_address/00001.png b/tests_zemu/snapshots/x-show_eth_address/00001.png index 84ed31e4..35024425 100644 Binary files a/tests_zemu/snapshots/x-show_eth_address/00001.png and b/tests_zemu/snapshots/x-show_eth_address/00001.png differ diff --git a/tests_zemu/snapshots/x-sign_basic/00002.png b/tests_zemu/snapshots/x-sign_basic/00002.png index b47dabb4..5a83f183 100644 Binary files a/tests_zemu/snapshots/x-sign_basic/00002.png and b/tests_zemu/snapshots/x-sign_basic/00002.png differ diff --git a/tests_zemu/snapshots/x-sign_basic/00003.png b/tests_zemu/snapshots/x-sign_basic/00003.png index 4e0f2906..88e82f3d 100644 Binary files a/tests_zemu/snapshots/x-sign_basic/00003.png and b/tests_zemu/snapshots/x-sign_basic/00003.png differ diff --git a/tests_zemu/snapshots/x-sign_basic2/00003.png b/tests_zemu/snapshots/x-sign_basic2/00003.png index 17f84d47..c9e22f2d 100644 Binary files a/tests_zemu/snapshots/x-sign_basic2/00003.png and b/tests_zemu/snapshots/x-sign_basic2/00003.png differ diff --git a/tests_zemu/snapshots/x-sign_basic2/00004.png b/tests_zemu/snapshots/x-sign_basic2/00004.png index 0e82ee25..262628b3 100644 Binary files a/tests_zemu/snapshots/x-sign_basic2/00004.png and b/tests_zemu/snapshots/x-sign_basic2/00004.png differ diff --git a/tests_zemu/snapshots/x-sign_basic_eth/00003.png b/tests_zemu/snapshots/x-sign_basic_eth/00003.png index 7da06771..8f46e011 100644 Binary files a/tests_zemu/snapshots/x-sign_basic_eth/00003.png and b/tests_zemu/snapshots/x-sign_basic_eth/00003.png differ diff --git a/tests_zemu/snapshots/x-sign_basic_eth/00005.png b/tests_zemu/snapshots/x-sign_basic_eth/00005.png index d5c15863..88e2d4c9 100644 Binary files a/tests_zemu/snapshots/x-sign_basic_eth/00005.png and b/tests_zemu/snapshots/x-sign_basic_eth/00005.png differ diff --git a/tests_zemu/snapshots/x-sign_basic_eth/00006.png b/tests_zemu/snapshots/x-sign_basic_eth/00006.png index b47dabb4..5a83f183 100644 Binary files a/tests_zemu/snapshots/x-sign_basic_eth/00006.png and b/tests_zemu/snapshots/x-sign_basic_eth/00006.png differ diff --git a/tests_zemu/snapshots/x-sign_basic_eth/00007.png b/tests_zemu/snapshots/x-sign_basic_eth/00007.png index d5c15863..88e2d4c9 100644 Binary files a/tests_zemu/snapshots/x-sign_basic_eth/00007.png and b/tests_zemu/snapshots/x-sign_basic_eth/00007.png differ diff --git a/tests_zemu/snapshots/x-sign_basic_eth/00008.png b/tests_zemu/snapshots/x-sign_basic_eth/00008.png index 4e0f2906..88e82f3d 100644 Binary files a/tests_zemu/snapshots/x-sign_basic_eth/00008.png and b/tests_zemu/snapshots/x-sign_basic_eth/00008.png differ diff --git a/tests_zemu/snapshots/x-sign_basic_eth_warning/00000.png b/tests_zemu/snapshots/x-sign_basic_eth_warning/00000.png index 53e74dc2..50d75f83 100644 Binary files a/tests_zemu/snapshots/x-sign_basic_eth_warning/00000.png and b/tests_zemu/snapshots/x-sign_basic_eth_warning/00000.png differ diff --git a/tests_zemu/snapshots/x-sign_basic_extra_fields/00002.png b/tests_zemu/snapshots/x-sign_basic_extra_fields/00002.png index b47dabb4..5a83f183 100644 Binary files a/tests_zemu/snapshots/x-sign_basic_extra_fields/00002.png and b/tests_zemu/snapshots/x-sign_basic_extra_fields/00002.png differ diff --git a/tests_zemu/snapshots/x-sign_basic_extra_fields/00003.png b/tests_zemu/snapshots/x-sign_basic_extra_fields/00003.png index 4e0f2906..88e82f3d 100644 Binary files a/tests_zemu/snapshots/x-sign_basic_extra_fields/00003.png and b/tests_zemu/snapshots/x-sign_basic_extra_fields/00003.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic/00002.png b/tests_zemu/snapshots/x-textual-sign_basic/00002.png index 4b37d348..3d76db2e 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic/00002.png and b/tests_zemu/snapshots/x-textual-sign_basic/00002.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic/00003.png b/tests_zemu/snapshots/x-textual-sign_basic/00003.png index 84bc70f9..2ced4d49 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic/00003.png and b/tests_zemu/snapshots/x-textual-sign_basic/00003.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic/00004.png b/tests_zemu/snapshots/x-textual-sign_basic/00004.png index 966622a8..fcf0fafa 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic/00004.png and b/tests_zemu/snapshots/x-textual-sign_basic/00004.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic/00006.png b/tests_zemu/snapshots/x-textual-sign_basic/00006.png index 9236c111..3da6cc6b 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic/00006.png and b/tests_zemu/snapshots/x-textual-sign_basic/00006.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic/00008.png b/tests_zemu/snapshots/x-textual-sign_basic/00008.png index b7dffacb..057e364b 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic/00008.png and b/tests_zemu/snapshots/x-textual-sign_basic/00008.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00002.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00002.png index 4b37d348..3d76db2e 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00002.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00002.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00003.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00003.png index 84bc70f9..2ced4d49 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00003.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00003.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00005.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00005.png index bdfcf1a0..b384c6dc 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00005.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00005.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00006.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00006.png index 41277be7..115b7ce4 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00006.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00006.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00007.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00007.png index 58e46d54..ec1db5ad 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00007.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00007.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00008.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00008.png index 2e818453..8de335a2 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00008.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00008.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00009.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00009.png index 966622a8..fcf0fafa 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00009.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00009.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00011.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00011.png index 9236c111..3da6cc6b 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00011.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00011.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00013.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00013.png index b7dffacb..057e364b 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00013.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00013.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00018.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00018.png index 46f31cef..a73d7695 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00018.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00018.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00019.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00019.png index dacd2afc..dd0bbb34 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00019.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00019.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth/00020.png b/tests_zemu/snapshots/x-textual-sign_basic_eth/00020.png index a8292f84..9da0fe80 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth/00020.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth/00020.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_eth_warning/00000.png b/tests_zemu/snapshots/x-textual-sign_basic_eth_warning/00000.png index 53e74dc2..50d75f83 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_eth_warning/00000.png and b/tests_zemu/snapshots/x-textual-sign_basic_eth_warning/00000.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00002.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00002.png index 4b37d348..3d76db2e 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00002.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00002.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00003.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00003.png index 84bc70f9..2ced4d49 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00003.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00003.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00005.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00005.png index bdfcf1a0..b384c6dc 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00005.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00005.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00006.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00006.png index 41277be7..115b7ce4 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00006.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00006.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00007.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00007.png index 58e46d54..ec1db5ad 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00007.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00007.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00008.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00008.png index 2e818453..8de335a2 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00008.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00008.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00009.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00009.png index 966622a8..fcf0fafa 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00009.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00009.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00011.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00011.png index 9236c111..3da6cc6b 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00011.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00011.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00013.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00013.png index b7dffacb..057e364b 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00013.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00013.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00018.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00018.png index 46f31cef..a73d7695 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00018.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00018.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00019.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00019.png index dacd2afc..dd0bbb34 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00019.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00019.png differ diff --git a/tests_zemu/snapshots/x-textual-sign_basic_expert/00020.png b/tests_zemu/snapshots/x-textual-sign_basic_expert/00020.png index a8292f84..9da0fe80 100644 Binary files a/tests_zemu/snapshots/x-textual-sign_basic_expert/00020.png and b/tests_zemu/snapshots/x-textual-sign_basic_expert/00020.png differ diff --git a/tests_zemu/tests/json.test.ts b/tests_zemu/tests/amino.test.ts similarity index 70% rename from tests_zemu/tests/json.test.ts rename to tests_zemu/tests/amino.test.ts index 5d2e9d45..9bc28d0f 100644 --- a/tests_zemu/tests/json.test.ts +++ b/tests_zemu/tests/amino.test.ts @@ -14,11 +14,11 @@ * limitations under the License. ******************************************************************************* */ -import Zemu from '@zondax/zemu' +import Zemu, { ClickNavigation, TouchNavigation } from '@zondax/zemu' // @ts-ignore import { CosmosApp } from '@zondax/ledger-cosmos-js' import { - DEFAULT_OPTIONS, + defaultOptions, DEVICE_MODELS, example_tx_str_basic, example_tx_str_basic2, @@ -33,15 +33,16 @@ import { import secp256k1 from 'secp256k1/elliptic' // @ts-ignore import crypto from 'crypto' +import { ButtonKind, IButton } from '@zondax/zemu/dist/types' jest.setTimeout(120000) -describe('Json', function () { +describe('Amino', function () { // eslint-disable-next-line jest/expect-expect test.concurrent.each(DEVICE_MODELS)('can start and stop container', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) } finally { await sim.close() } @@ -50,20 +51,21 @@ describe('Json', function () { test.concurrent.each(DEVICE_MODELS)('sign basic normal', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) const path = [44, 118, 0, 0, 0] - const tx = Buffer.from(JSON.stringify(example_tx_str_basic)) + const tx = Buffer.from(JSON.stringify(example_tx_str_basic), "utf-8") + const hrp = 'cosmos' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, AMINO_JSON_TX) + const signatureRequest = app.sign(path, tx, hrp, AMINO_JSON_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -95,20 +97,21 @@ describe('Json', function () { test.concurrent.each(DEVICE_MODELS)('sign basic normal2', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) const path = [44, 118, 0, 0, 0] const tx = Buffer.from(JSON.stringify(example_tx_str_basic2)) + const hrp = 'cosmos' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, AMINO_JSON_TX) + const signatureRequest = app.sign(path, tx, hrp, AMINO_JSON_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -139,20 +142,21 @@ describe('Json', function () { test.concurrent.each(DEVICE_MODELS)('sign basic with extra fields', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) const path = [44, 118, 0, 0, 0] const tx = Buffer.from(JSON.stringify(example_tx_str_basic)) + const hrp = 'cosmos' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, 0x0) + const signatureRequest = app.sign(path, tx, hrp, AMINO_JSON_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -184,20 +188,21 @@ describe('Json', function () { test.concurrent.each(DEVICE_MODELS)('ibc denoms', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) const path = [44, 118, 0, 0, 0] const tx = Buffer.from(JSON.stringify(ibc_denoms)) + const hrp = 'cosmos' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, 0x0) + const signatureRequest = app.sign(path, tx, hrp, AMINO_JSON_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -229,20 +234,21 @@ describe('Json', function () { test.concurrent.each(DEVICE_MODELS)('SetWithdrawAddress', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) const path = [44, 118, 0, 0, 0] const tx = Buffer.from(JSON.stringify(setWithdrawAddress)) + const hrp = 'cosmos' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, 0x0) + const signatureRequest = app.sign(path, tx, hrp, AMINO_JSON_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -274,20 +280,21 @@ describe('Json', function () { test.concurrent.each(DEVICE_MODELS)('CLIGovDeposit', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) const path = [44, 118, 0, 0, 0] const tx = Buffer.from(JSON.stringify(cliGovDeposit)) + const hrp = 'cosmos' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, 0x0) + const signatureRequest = app.sign(path, tx, hrp, AMINO_JSON_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -319,7 +326,7 @@ describe('Json', function () { test.concurrent.each(DEVICE_MODELS)('MsgMultisend', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) // Activate expert mode @@ -327,15 +334,16 @@ describe('Json', function () { const path = [44, 118, 0, 0, 0] const tx = Buffer.from(JSON.stringify(example_tx_str_msgMultiSend)) + const hrp = 'cosmos' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, 0x0) + const signatureRequest = app.sign(path, tx, hrp, AMINO_JSON_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -367,7 +375,7 @@ describe('Json', function () { test.concurrent.each(DEVICE_MODELS)('SetWithdrawAddress-eth', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) // Change to expert mode so we can skip fields @@ -375,15 +383,16 @@ describe('Json', function () { const path = [44, 60, 0, 0, 0] const tx = Buffer.from(JSON.stringify(setWithdrawAddress)) + const hrp = 'inj' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'inj') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, 0x0) + const signatureRequest = app.sign(path, tx, hrp, AMINO_JSON_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -411,4 +420,103 @@ describe('Json', function () { await sim.close() } }) + + test.concurrent.each(DEVICE_MODELS)('sign basic normal Eth', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new CosmosApp(sim.getTransport()) + + // Enable expert to allow sign with eth path + await sim.toggleExpertMode(); + + const path = [44, 60, 0, 0, 0] + const tx = Buffer.from(JSON.stringify(example_tx_str_basic), "utf-8") + const hrp = 'inj' + + // check with invalid HRP + const errorRespPk = await app.getAddressAndPubKey(path, 'forbiddenHRP') + expect(errorRespPk.return_code).toEqual(0x6986) + expect(errorRespPk.error_message).toEqual('Transaction rejected') + + // do not wait here.. + const signatureRequest = app.sign(path, tx, hrp) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-sign_basic_eth`) + + const resp = await signatureRequest + console.log(resp) + + expect(resp.return_code).toEqual(0x9000) + expect(resp.error_message).toEqual('No errors') + expect(resp).toHaveProperty('signature') + + // get address / publickey + const respPk = await app.getAddressAndPubKey(path, hrp) + expect(respPk.return_code).toEqual(0x9000) + expect(respPk.error_message).toEqual('No errors') + console.log(respPk) + + // Now verify the signature + const sha3 = require('js-sha3') + const msgHash = Buffer.from(sha3.keccak256(tx), 'hex') + + const signatureDER = resp.signature + const signature = secp256k1.signatureImport(Uint8Array.from(signatureDER)) + + const pk = Uint8Array.from(respPk.compressed_pk) + + const signatureOk = secp256k1.ecdsaVerify(signature, msgHash, pk) + expect(signatureOk).toEqual(true) + } finally { + await sim.close() + } + }) + + test.concurrent.each(DEVICE_MODELS)('sign basic normal Eth no expert', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new CosmosApp(sim.getTransport()) + + const path = [44, 60, 0, 0, 0] + const tx = Buffer.from(JSON.stringify(example_tx_str_basic), "utf-8") + + // get address / publickey + const respPk = await app.getAddressAndPubKey(path, 'inj') + expect(respPk.return_code).toEqual(0x9000) + expect(respPk.error_message).toEqual('No errors') + console.log(respPk) + + // do not wait here.. + const signatureRequest = app.sign(path, tx) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + let nav = undefined; + if (m.name === 'stax') { + const okButton: IButton = { + x: 200, + y: 540, + delay: 0.25, + }; + nav = new TouchNavigation([ + ButtonKind.ConfirmYesButton, + ]); + nav.schedule[0].button = okButton; + } else { + nav = new ClickNavigation([1, 0]); + } + await sim.navigate('.', `${m.prefix.toLowerCase()}-sign_basic_eth_warning`, nav.schedule); + + const resp = await signatureRequest + console.log(resp) + + expect(resp.return_code).toEqual(0x6984) + } finally { + await sim.close() + } + }) }) diff --git a/tests_zemu/tests/common.ts b/tests_zemu/tests/common.ts index 59b934fe..722cae2a 100644 --- a/tests_zemu/tests/common.ts +++ b/tests_zemu/tests/common.ts @@ -1,5 +1,5 @@ /** ****************************************************************************** - * (c) 2021-2022 Zondax GmbH + * (c) 2021-2023 Zondax AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,8 +24,9 @@ export const APP_SEED = 'equip will roof matter pink blind book anxiety banner e const APP_PATH_S = Resolve('../app/output/app_s.elf') const APP_PATH_X = Resolve('../app/output/app_x.elf') const APP_PATH_SP = Resolve('../app/output/app_s2.elf') +const APP_PATH_ST = Resolve('../app/output/app_stax.elf') -export const DEFAULT_OPTIONS = { +export const defaultOptions = { ...DEFAULT_START_OPTIONS, logging: true, custom: `-s "${APP_SEED}"`, @@ -36,6 +37,7 @@ export const DEVICE_MODELS: IDeviceModel[] = [ { name: 'nanos', prefix: 'S', path: APP_PATH_S }, { name: 'nanox', prefix: 'X', path: APP_PATH_X }, { name: 'nanosp', prefix: 'SP', path: APP_PATH_SP }, + { name: 'stax', prefix: 'ST', path: APP_PATH_ST }, ] export const tx_sign_textual = 'a10192a20168436861696e20696402686d792d636861696ea2016e4163636f756e74206e756d626572026131a2016853657175656e6365026132a301674164647265737302782d636f736d6f7331756c6176336873656e7570737771666b77327933737570356b677471776e767161386579687304f5a3016a5075626c6963206b657902781f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657904f5a3026d5075624b6579206f626a656374030104f5a401634b657902785230324542204444374620453446442045423736204443384120323035452046363544203739304320443330452038413337203541354320323532382045423341203932334120463146422034443739203444030204f5a102781e54686973207472616e73616374696f6e206861732031204d657373616765a3016d4d6573736167652028312f312902781c2f636f736d6f732e62616e6b2e763162657461312e4d736753656e640301a2026e4d736753656e64206f626a6563740302a3016c46726f6d206164647265737302782d636f736d6f7331756c6176336873656e7570737771666b77327933737570356b677471776e76716138657968730303a3016a546f206164647265737302782d636f736d6f7331656a726634637572327779366b667572673966326a707070326833616665356836706b6835740303a30166416d6f756e74026731302041544f4d0303a1026e456e64206f66204d657373616765a201644d656d6f0278193e20e29a9befb88f5c7532363942e29a9befb88f2020202020a2016446656573026a302e3030322041544f4da30169476173206c696d697402673130302730303004f5a3017148617368206f66207261772062797465730278403963303433323930313039633237306232666661396633633066613535613039306330313235656265663838316637646135333937386462663933663733383504f5' diff --git a/tests_zemu/tests/standard.test.ts b/tests_zemu/tests/standard.test.ts index 03e629a1..65e15f46 100644 --- a/tests_zemu/tests/standard.test.ts +++ b/tests_zemu/tests/standard.test.ts @@ -1,5 +1,5 @@ /** ****************************************************************************** - * (c) 2018-2022 Zondax GmbH + * (c) 2018 - 2023 Zondax AG * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,24 +14,23 @@ * limitations under the License. ******************************************************************************* */ -import Zemu from '@zondax/zemu' -// @ts-ignore +import Zemu, { zondaxMainmenuNavigation, ButtonKind, ClickNavigation, TouchNavigation } from '@zondax/zemu' import { CosmosApp } from '@zondax/ledger-cosmos-js' -import { DEFAULT_OPTIONS, DEVICE_MODELS, example_tx_str_basic, example_tx_str_basic2, ibc_denoms } from './common' +import { defaultOptions, DEVICE_MODELS, example_tx_str_basic, example_tx_str_basic2, ibc_denoms } from './common' // @ts-ignore import secp256k1 from 'secp256k1/elliptic' // @ts-ignore import crypto from 'crypto' +import { ActionKind, IButton, INavElement } from '@zondax/zemu/dist/types' jest.setTimeout(90000) describe('Standard', function () { - // eslint-disable-next-line jest/expect-expect test.concurrent.each(DEVICE_MODELS)('can start and stop container', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) } finally { await sim.close() } @@ -40,8 +39,9 @@ describe('Standard', function () { test.concurrent.each(DEVICE_MODELS)('main menu', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) - expect(await sim.navigateAndCompareSnapshots('.', `${m.prefix.toLowerCase()}-mainmenu`, [1, 0, 0, 4, -5])).toEqual(true) + await sim.start({ ...defaultOptions, model: m.name }) + const nav = zondaxMainmenuNavigation(m.name, [1, 0, 0, 4, -5]) + await sim.navigateAndCompareSnapshots('.', `${m.prefix.toLowerCase()}-mainmenu`, nav.schedule) } finally { await sim.close() } @@ -50,7 +50,7 @@ describe('Standard', function () { test.concurrent.each(DEVICE_MODELS)('get app version', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) const resp = await app.getVersion() @@ -70,7 +70,7 @@ describe('Standard', function () { test.concurrent.each(DEVICE_MODELS)('get address', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) // Derivation path. First 3 items are automatically hardened! @@ -95,7 +95,12 @@ describe('Standard', function () { test.concurrent.each(DEVICE_MODELS)('show address', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ + ...defaultOptions, + model: m.name, + approveKeyword: m.name === 'stax' ? 'QR' : '', + approveAction: ButtonKind.ApproveTapButton, + }) const app = new CosmosApp(sim.getTransport()) // Derivation path. First 3 items are automatically hardened! @@ -124,7 +129,12 @@ describe('Standard', function () { test.concurrent.each(DEVICE_MODELS)('show Eth address', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ + ...defaultOptions, + model: m.name, + approveKeyword: m.name === 'stax' ? 'Path' : '', + approveAction: ButtonKind.ApproveTapButton, + }) const app = new CosmosApp(sim.getTransport()) // Derivation path. First 3 items are automatically hardened! @@ -172,7 +182,12 @@ describe('Standard', function () { test.concurrent.each(DEVICE_MODELS)('show address HUGE', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ + ...defaultOptions, + model: m.name, + approveKeyword: m.name === 'stax' ? 'QR' : '', + approveAction: ButtonKind.ApproveTapButton, + }) const app = new CosmosApp(sim.getTransport()) // Derivation path. First 3 items are automatically hardened! @@ -190,7 +205,12 @@ describe('Standard', function () { test.concurrent.each(DEVICE_MODELS)('show address HUGE Expert', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ + ...defaultOptions, + model: m.name, + approveKeyword: m.name === 'stax' ? 'Path' : '', + approveAction: ButtonKind.ApproveTapButton, + }) const app = new CosmosApp(sim.getTransport()) // Activate expert mode @@ -219,267 +239,4 @@ describe('Standard', function () { await sim.close() } }) - - test.concurrent.each(DEVICE_MODELS)('sign basic normal', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) - const app = new CosmosApp(sim.getTransport()) - - const path = [44, 118, 0, 0, 0] - const tx = Buffer.from(JSON.stringify(example_tx_str_basic), "utf-8") - - // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') - expect(respPk.return_code).toEqual(0x9000) - expect(respPk.error_message).toEqual('No errors') - console.log(respPk) - - // do not wait here.. - const signatureRequest = app.sign(path, tx) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-sign_basic`) - - const resp = await signatureRequest - console.log(resp) - - expect(resp.return_code).toEqual(0x9000) - expect(resp.error_message).toEqual('No errors') - expect(resp).toHaveProperty('signature') - - // Now verify the signature - const hash = crypto.createHash('sha256') - const msgHash = Uint8Array.from(hash.update(tx).digest()) - - const signatureDER = resp.signature - const signature = secp256k1.signatureImport(Uint8Array.from(signatureDER)) - - const pk = Uint8Array.from(respPk.compressed_pk) - - const signatureOk = secp256k1.ecdsaVerify(signature, msgHash, pk) - expect(signatureOk).toEqual(true) - } finally { - await sim.close() - } - }) - - test.concurrent.each(DEVICE_MODELS)('sign basic normal2', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) - const app = new CosmosApp(sim.getTransport()) - - const path = [44, 118, 0, 0, 0] - const tx = Buffer.from(JSON.stringify(example_tx_str_basic2), "utf-8") - - // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') - expect(respPk.return_code).toEqual(0x9000) - expect(respPk.error_message).toEqual('No errors') - console.log(respPk) - - // do not wait here.. - const signatureRequest = app.sign(path, tx) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-sign_basic2`) - - const resp = await signatureRequest - console.log(resp) - - expect(resp.return_code).toEqual(0x9000) - expect(resp.error_message).toEqual('No errors') - - // Now verify the signature - const hash = crypto.createHash('sha256') - const msgHash = Uint8Array.from(hash.update(tx).digest()) - - const signatureDER = resp.signature - const signature = secp256k1.signatureImport(Uint8Array.from(signatureDER)) - - const pk = Uint8Array.from(respPk.compressed_pk) - - const signatureOk = secp256k1.ecdsaVerify(signature, msgHash, pk) - expect(signatureOk).toEqual(true) - } finally { - await sim.close() - } - }) - - test.concurrent.each(DEVICE_MODELS)('sign basic with extra fields', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) - const app = new CosmosApp(sim.getTransport()) - - const path = [44, 118, 0, 0, 0] - const tx = Buffer.from(JSON.stringify(example_tx_str_basic), "utf-8") - - // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') - expect(respPk.return_code).toEqual(0x9000) - expect(respPk.error_message).toEqual('No errors') - console.log(respPk) - - // do not wait here.. - const signatureRequest = app.sign(path, tx) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-sign_basic_extra_fields`) - - const resp = await signatureRequest - console.log(resp) - - expect(resp.return_code).toEqual(0x9000) - expect(resp.error_message).toEqual('No errors') - expect(resp).toHaveProperty('signature') - - // Now verify the signature - const hash = crypto.createHash('sha256') - const msgHash = Uint8Array.from(hash.update(tx).digest()) - - const signatureDER = resp.signature - const signature = secp256k1.signatureImport(Uint8Array.from(signatureDER)) - - const pk = Uint8Array.from(respPk.compressed_pk) - - const signatureOk = secp256k1.ecdsaVerify(signature, msgHash, pk) - expect(signatureOk).toEqual(true) - } finally { - await sim.close() - } - }) - - test.concurrent.each(DEVICE_MODELS)('ibc denoms', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) - const app = new CosmosApp(sim.getTransport()) - - const path = [44, 118, 0, 0, 0] - const tx = Buffer.from(JSON.stringify(ibc_denoms), "utf-8") - - - // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') - expect(respPk.return_code).toEqual(0x9000) - expect(respPk.error_message).toEqual('No errors') - console.log(respPk) - - // do not wait here.. - const signatureRequest = app.sign(path, tx) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-ibc_denoms`) - - const resp = await signatureRequest - console.log(resp) - - expect(resp.return_code).toEqual(0x9000) - expect(resp.error_message).toEqual('No errors') - expect(resp).toHaveProperty('signature') - - // Now verify the signature - const hash = crypto.createHash('sha256') - const msgHash = Uint8Array.from(hash.update(tx).digest()) - - const signatureDER = resp.signature - const signature = secp256k1.signatureImport(Uint8Array.from(signatureDER)) - - const pk = Uint8Array.from(respPk.compressed_pk) - - const signatureOk = secp256k1.ecdsaVerify(signature, msgHash, pk) - expect(signatureOk).toEqual(true) - } finally { - await sim.close() - } - }) - - test.concurrent.each(DEVICE_MODELS)('sign basic normal Eth', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) - const app = new CosmosApp(sim.getTransport()) - - // Enable expert to allow sign with eth path - await sim.toggleExpertMode(); - - const path = [44, 60, 0, 0, 0] - const tx = Buffer.from(JSON.stringify(example_tx_str_basic), "utf-8") - - // check with invalid HRP - const errorRespPk = await app.getAddressAndPubKey(path, 'forbiddenHRP') - expect(errorRespPk.return_code).toEqual(0x6986) - expect(errorRespPk.error_message).toEqual('Transaction rejected') - - // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'inj') - expect(respPk.return_code).toEqual(0x9000) - expect(respPk.error_message).toEqual('No errors') - console.log(respPk) - - // do not wait here.. - const signatureRequest = app.sign(path, tx) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - await sim.compareSnapshotsAndApprove('.', `${m.prefix.toLowerCase()}-sign_basic_eth`) - - const resp = await signatureRequest - console.log(resp) - - expect(resp.return_code).toEqual(0x9000) - expect(resp.error_message).toEqual('No errors') - - // Now verify the signature - const sha3 = require('js-sha3') - const msgHash = Buffer.from(sha3.keccak256(tx), 'hex') - - const signatureDER = resp.signature - const signature = secp256k1.signatureImport(Uint8Array.from(signatureDER)) - - const pk = Uint8Array.from(respPk.compressed_pk) - - const signatureOk = secp256k1.ecdsaVerify(signature, msgHash, pk) - expect(signatureOk).toEqual(true) - } finally { - await sim.close() - } - }) - - test.concurrent.each(DEVICE_MODELS)('sign basic normal Eth no expert', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) - const app = new CosmosApp(sim.getTransport()) - - const path = [44, 60, 0, 0, 0] - const tx = Buffer.from(JSON.stringify(example_tx_str_basic), "utf-8") - - // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'inj') - expect(respPk.return_code).toEqual(0x9000) - expect(respPk.error_message).toEqual('No errors') - console.log(respPk) - - // do not wait here.. - const signatureRequest = app.sign(path, tx) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - await sim.navigateAndCompareSnapshots('.', `${m.prefix.toLowerCase()}-sign_basic_eth_warning`, [1,0], false) - - const resp = await signatureRequest - console.log(resp) - - expect(resp.return_code).toEqual(0x6984) - } finally { - await sim.close() - } - }) }) diff --git a/tests_zemu/tests/textual.test.ts b/tests_zemu/tests/textual.test.ts index 2118e157..a62ee084 100644 --- a/tests_zemu/tests/textual.test.ts +++ b/tests_zemu/tests/textual.test.ts @@ -14,14 +14,15 @@ * limitations under the License. ******************************************************************************* */ -import Zemu from '@zondax/zemu' +import Zemu, { ClickNavigation, TouchNavigation } from '@zondax/zemu' // @ts-ignore import { CosmosApp } from '@zondax/ledger-cosmos-js' -import { DEFAULT_OPTIONS, DEVICE_MODELS, tx_sign_textual, TEXTUAL_TX } from './common' +import { defaultOptions, DEVICE_MODELS, tx_sign_textual, TEXTUAL_TX } from './common' // @ts-ignore import secp256k1 from 'secp256k1/elliptic' // @ts-ignore import crypto from 'crypto' +import { ButtonKind, IButton } from '@zondax/zemu/dist/types' jest.setTimeout(90000) @@ -30,7 +31,7 @@ describe('Textual', function () { test.concurrent.each(DEVICE_MODELS)('can start and stop container', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) } finally { await sim.close() } @@ -39,20 +40,21 @@ describe('Textual', function () { test.concurrent.each(DEVICE_MODELS)('sign basic textual', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) const path = [44, 118, 0, 0, 0] const tx = Buffer.from(tx_sign_textual, 'hex') + const hrp = 'cosmos' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, TEXTUAL_TX) + const signatureRequest = app.sign(path, tx, hrp, TEXTUAL_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -84,7 +86,7 @@ describe('Textual', function () { test.concurrent.each(DEVICE_MODELS)('sign basic textual expert', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) // Change to expert mode so we can skip fields @@ -92,15 +94,16 @@ describe('Textual', function () { const path = [44, 118, 0, 0, 0] const tx = Buffer.from(tx_sign_textual, 'hex') + const hrp = 'cosmos' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'cosmos') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, TEXTUAL_TX) + const signatureRequest = app.sign(path, tx, hrp, TEXTUAL_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -132,7 +135,7 @@ describe('Textual', function () { test.concurrent.each(DEVICE_MODELS)('sign basic textual eth ', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) // Enable expert to allow sign with eth path @@ -140,15 +143,16 @@ describe('Textual', function () { const path = [44, 60, 0, 0, 0] const tx = Buffer.from(tx_sign_textual, 'hex') + const hrp = 'inj' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'inj') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, TEXTUAL_TX) + const signatureRequest = app.sign(path, tx, hrp, TEXTUAL_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) @@ -180,24 +184,39 @@ describe('Textual', function () { test.concurrent.each(DEVICE_MODELS)('sign basic textual eth warning ', async function (m) { const sim = new Zemu(m.path) try { - await sim.start({ ...DEFAULT_OPTIONS, model: m.name }) + await sim.start({ ...defaultOptions, model: m.name }) const app = new CosmosApp(sim.getTransport()) const path = [44, 60, 0, 0, 0] const tx = Buffer.from(tx_sign_textual, 'hex') + const hrp = 'inj' // get address / publickey - const respPk = await app.getAddressAndPubKey(path, 'inj') + const respPk = await app.getAddressAndPubKey(path, hrp) expect(respPk.return_code).toEqual(0x9000) expect(respPk.error_message).toEqual('No errors') console.log(respPk) // do not wait here.. - const signatureRequest = app.sign(path, tx, TEXTUAL_TX) + const signatureRequest = app.sign(path, tx, hrp, TEXTUAL_TX) // Wait until we are not in the main menu await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - await sim.navigateAndCompareSnapshots('.', `${m.prefix.toLowerCase()}-textual-sign_basic_eth_warning`, [1,0], false) + let nav = undefined; + if (m.name === 'stax') { + const okButton: IButton = { + x: 200, + y: 540, + delay: 0.25, + }; + nav = new TouchNavigation([ + ButtonKind.ConfirmYesButton, + ]); + nav.schedule[0].button = okButton; + } else { + nav = new ClickNavigation([1, 0]); + } + await sim.navigate('.', `${m.prefix.toLowerCase()}-textual-sign_basic_eth_warning`, nav.schedule); const resp = await signatureRequest console.log(resp)