Merge pull request #584 from LedgerHQ/cev/B2CA-1558_eip191-streaming

NBGL porting: improve EIP191
This commit is contained in:
apaillier-ledger
2024-07-22 17:56:33 +02:00
committed by GitHub
67 changed files with 224 additions and 356 deletions

View File

@@ -10,6 +10,7 @@ import struct
from client import keychain
from client.client import EthAppClient, EIP712FieldType
from ragger.firmware import Firmware
# global variables
app_client: EthAppClient = None
@@ -391,7 +392,7 @@ def next_timeout(_signum: int, _frame):
def enable_autonext():
if app_client._client.firmware.device in ("stax", "flex"):
if app_client._client.firmware in (Firmware.STAX, Firmware.FLEX):
delay = 1/3
else:
delay = 1/4

View File

@@ -11,31 +11,29 @@ class SettingID(Enum):
DEBUG_DATA = auto()
def get_device_settings(device: str) -> list[SettingID]:
if device == "nanos":
def get_device_settings(firmware: Firmware) -> list[SettingID]:
if firmware == Firmware.NANOS:
return [
SettingID.NONCE,
SettingID.DEBUG_DATA,
]
if device in ("nanox", "nanosp", "stax", "flex"):
return [
SettingID.VERBOSE_ENS,
SettingID.VERBOSE_EIP712,
SettingID.NONCE,
SettingID.DEBUG_DATA,
]
return []
return [
SettingID.VERBOSE_ENS,
SettingID.VERBOSE_EIP712,
SettingID.NONCE,
SettingID.DEBUG_DATA,
]
def get_setting_per_page(device: str) -> int:
if device == "stax":
def get_setting_per_page(firmware: Firmware) -> int:
if firmware == Firmware.STAX:
return 3
return 2
def get_setting_position(device: str, setting: Union[NavInsID, SettingID]) -> tuple[int, int]:
settings_per_page = get_setting_per_page(device)
if device == "stax":
def get_setting_position(firmware: Firmware, setting: Union[NavInsID, SettingID]) -> tuple[int, int]:
settings_per_page = get_setting_per_page(firmware)
if firmware == Firmware.STAX:
screen_height = 672 # px
header_height = 88 # px
footer_height = 92 # px
@@ -47,15 +45,15 @@ def get_setting_position(device: str, setting: Union[NavInsID, SettingID]) -> tu
option_offset = 420 # px
usable_height = screen_height - (header_height + footer_height)
setting_height = usable_height // settings_per_page
index_in_page = get_device_settings(device).index(SettingID(setting)) % settings_per_page
index_in_page = get_device_settings(firmware).index(SettingID(setting)) % settings_per_page
return option_offset, header_height + (setting_height * index_in_page) + (setting_height // 2)
def settings_toggle(fw: Firmware, nav: Navigator, to_toggle: list[SettingID]):
def settings_toggle(firmware: Firmware, nav: Navigator, to_toggle: list[SettingID]):
moves: list[Union[NavIns, NavInsID]] = list()
settings = get_device_settings(fw.device)
settings = get_device_settings(firmware)
# Assume the app is on the home page
if fw.device.startswith("nano"):
if firmware.is_nano:
moves += [NavInsID.RIGHT_CLICK] * 2
moves += [NavInsID.BOTH_CLICK]
for setting in settings:
@@ -65,12 +63,12 @@ def settings_toggle(fw: Firmware, nav: Navigator, to_toggle: list[SettingID]):
moves += [NavInsID.BOTH_CLICK] # Back
else:
moves += [NavInsID.USE_CASE_HOME_SETTINGS]
settings_per_page = get_setting_per_page(fw.device)
settings_per_page = get_setting_per_page(firmware)
for setting in settings:
setting_idx = settings.index(setting)
if (setting_idx > 0) and (setting_idx % settings_per_page) == 0:
moves += [NavInsID.USE_CASE_SETTINGS_NEXT]
if setting in to_toggle:
moves += [NavIns(NavInsID.TOUCH, get_setting_position(fw.device, setting))]
moves += [NavIns(NavInsID.TOUCH, get_setting_position(firmware, setting))]
moves += [NavInsID.USE_CASE_SETTINGS_MULTI_PAGE_EXIT]
nav.navigate(moves, screen_change_before_first_instruction=False)

View File

@@ -4,9 +4,10 @@ sdk = "C"
devices = ["nanos", "nanox", "nanos+", "stax", "flex"]
[use_cases] # Coherent build options that make sense for your application
debug = "DEBUG=1"
use_test_keys = "DEBUG=1 CAL_TEST_KEY=1 DOMAIN_NAME_TEST_KEY=1 SET_PLUGIN_TEST_KEY=1 NFT_TEST_KEY=1"
cal_bypass = "DEBUG=1 BYPASS_SIGNATURES=1"
test_keys = "CAL_TEST_KEY=1 DOMAIN_NAME_TEST_KEY=1 SET_PLUGIN_TEST_KEY=1 NFT_TEST_KEY=1"
dbg_test_keys = "DEBUG=1 CAL_TEST_KEY=1 DOMAIN_NAME_TEST_KEY=1 SET_PLUGIN_TEST_KEY=1 NFT_TEST_KEY=1"
cal_bypass = "BYPASS_SIGNATURES=1"
dbg_cal_bypass = "DEBUG=1 BYPASS_SIGNATURES=1"
[tests]
unit_directory = "./tests/unit"

View File

@@ -51,7 +51,7 @@ static void reviewChoice(bool confirm) {
}
}
static const nbgl_icon_details_t *get_tx_icon(void) {
const nbgl_icon_details_t *get_tx_icon(void) {
const nbgl_icon_details_t *icon = NULL;
if (tx_approval_context.fromPlugin && (pluginType == EXTERNAL)) {

View File

@@ -4,30 +4,25 @@
#include "network.h"
typedef enum { PARAMETER_CONFIRMATION, SELECTOR_CONFIRMATION } e_confirmation_type;
static nbgl_contentTagValue_t pair;
static nbgl_contentTagValueList_t pairsList;
enum {
TOKEN_APPROVE = FIRST_USER_TOKEN,
};
static void reviewReject(void) {
io_seproxyhal_touch_data_cancel(NULL);
}
static void long_press_cb(int token, uint8_t index, int page) {
UNUSED(index);
UNUSED(page);
if (token == TOKEN_APPROVE) {
static void reviewChoice(bool confirm) {
if (confirm) {
io_seproxyhal_touch_data_ok(NULL);
} else {
io_seproxyhal_touch_data_cancel(NULL);
}
}
static void buildScreen(e_confirmation_type confirm_type) {
static nbgl_genericContents_t contents = {0};
static nbgl_content_t contentsList[3] = {0};
static nbgl_contentTagValue_t pair = {0};
uint8_t nbContents = 0;
uint32_t buf_size = SHARED_BUFFER_SIZE / 2;
nbgl_operationType_t op = TYPE_TRANSACTION;
pair.item = (confirm_type == PARAMETER_CONFIRMATION) ? "Parameter" : "Selector";
pair.value = strings.tmp.tmp;
pairsList.nbPairs = 1;
pairsList.pairs = &pair;
snprintf(g_stax_shared_buffer,
buf_size,
"Verify %s",
@@ -38,37 +33,16 @@ static void buildScreen(e_confirmation_type confirm_type) {
"Confirm %s",
(confirm_type == PARAMETER_CONFIRMATION) ? "parameter" : "selector");
pair.item = (confirm_type == PARAMETER_CONFIRMATION) ? "Parameter" : "Selector";
pair.value = strings.tmp.tmp;
// Title page
contentsList[nbContents].type = CENTERED_INFO;
contentsList[nbContents].content.centeredInfo.text1 = g_stax_shared_buffer;
contentsList[nbContents].content.centeredInfo.icon = get_app_icon(true);
contentsList[nbContents].content.centeredInfo.style = LARGE_CASE_INFO;
nbContents++;
// Values to be reviewed
contentsList[nbContents].type = TAG_VALUE_LIST;
contentsList[nbContents].content.tagValueList.pairs = &pair;
contentsList[nbContents].content.tagValueList.nbPairs = 1;
nbContents++;
// Approval screen
contentsList[nbContents].type = INFO_LONG_PRESS;
contentsList[nbContents].content.infoLongPress.text = g_stax_shared_buffer + buf_size;
contentsList[nbContents].content.infoLongPress.icon = get_app_icon(true);
contentsList[nbContents].content.infoLongPress.longPressText = "Hold to confirm";
contentsList[nbContents].content.infoLongPress.longPressToken = TOKEN_APPROVE;
contentsList[nbContents].content.infoLongPress.tuneId = NB_TUNES;
contentsList[nbContents].contentActionCallback = long_press_cb;
nbContents++;
contents.callbackCallNeeded = false;
contents.contentsList = contentsList;
contents.nbContents = nbContents;
nbgl_useCaseGenericReview(&contents, REJECT_BUTTON, reviewReject);
if (tmpContent.txContent.dataPresent) {
op |= BLIND_OPERATION;
}
nbgl_useCaseReview(op,
&pairsList,
get_tx_icon(),
g_stax_shared_buffer,
NULL,
g_stax_shared_buffer + buf_size,
reviewChoice);
}
void ui_confirm_parameter(void) {

View File

@@ -4,64 +4,32 @@
#include "nbgl_use_case.h"
#include "nbgl_content.h"
enum {
TOKEN_APPROVE = FIRST_USER_TOKEN,
};
static void reviewReject(void) {
io_seproxyhal_touch_privacy_cancel(NULL);
}
static void long_press_cb(int token, uint8_t index, int page) {
UNUSED(index);
UNUSED(page);
if (token == TOKEN_APPROVE) {
static void reviewChoice(bool confirm) {
if (confirm) {
io_seproxyhal_touch_privacy_ok(NULL);
} else {
io_seproxyhal_touch_privacy_cancel(NULL);
}
}
static void buildFirstPage(const char *review_string) {
static nbgl_genericContents_t contents = {0};
static nbgl_content_t contentsList[3] = {0};
static nbgl_contentTagValue_t pairs[2] = {0};
uint8_t nbContents = 0;
uint8_t nbPairs = 0;
static nbgl_contentTagValueList_t pairsList = {0};
pairs[nbPairs].item = "Address";
pairs[nbPairs].value = strings.common.toAddress;
nbPairs++;
pairs[nbPairs].item = "Key";
pairs[nbPairs].value = strings.common.fullAmount;
nbPairs++;
pairs[0].item = "Address";
pairs[0].value = strings.common.toAddress;
pairs[1].item = "Key";
pairs[1].value = strings.common.fullAmount;
pairsList.nbPairs = 2;
pairsList.pairs = pairs;
// Title page
contentsList[nbContents].type = CENTERED_INFO;
contentsList[nbContents].content.centeredInfo.text1 = review_string;
contentsList[nbContents].content.centeredInfo.icon = get_app_icon(true);
contentsList[nbContents].content.centeredInfo.style = LARGE_CASE_INFO;
nbContents++;
// Values to be reviewed
contentsList[nbContents].type = TAG_VALUE_LIST;
contentsList[nbContents].content.tagValueList.pairs = pairs;
contentsList[nbContents].content.tagValueList.nbPairs = nbPairs;
nbContents++;
// Approval screen
contentsList[nbContents].type = INFO_LONG_PRESS;
contentsList[nbContents].content.infoLongPress.text = review_string;
contentsList[nbContents].content.infoLongPress.icon = get_app_icon(true);
contentsList[nbContents].content.infoLongPress.longPressText = "Hold to approve";
contentsList[nbContents].content.infoLongPress.longPressToken = TOKEN_APPROVE;
contentsList[nbContents].content.infoLongPress.tuneId = NB_TUNES;
contentsList[nbContents].contentActionCallback = long_press_cb;
nbContents++;
contents.callbackCallNeeded = false;
contents.contentsList = contentsList;
contents.nbContents = nbContents;
nbgl_useCaseGenericReview(&contents, REJECT_BUTTON, reviewReject);
nbgl_useCaseReview(TYPE_OPERATION,
&pairsList,
get_tx_icon(),
review_string,
NULL,
review_string,
reviewChoice);
}
void ui_display_privacy_public_key(void) {

View File

@@ -1,45 +1,5 @@
#include "ui_nbgl.h"
#include "ui_signing.h"
#include "ui_logic.h"
#include "ui_message_signing.h"
#include "glyphs.h"
static void (*g_approved_func)(void) = NULL;
static void (*g_rejected_func)(void) = NULL;
static void ui_message_rejection_handler() {
nbgl_useCaseStatus("Message signing\ncancelled", false, g_rejected_func);
}
static void ui_message_confirm_rejection(void) {
nbgl_useCaseConfirm(REJECT_QUESTION(TEXT_MESSAGE),
NULL,
REJECT_CONFIRM_BUTTON,
RESUME(TEXT_MESSAGE),
ui_message_rejection_handler);
}
void ui_message_review_choice(bool confirm) {
if (confirm) {
nbgl_useCaseStatus("MESSAGE\nSIGNED", true, g_approved_func);
} else {
ui_message_confirm_rejection();
}
}
void ui_message_start(const char *title,
void (*start_func)(void),
void (*approved_func)(void),
void (*rejected_func)(void)) {
g_approved_func = approved_func;
g_rejected_func = rejected_func;
nbgl_useCaseReviewStart(&C_Review_64px,
title,
NULL,
REJECT_BUTTON,
start_func,
ui_message_confirm_rejection);
}
static void ui_message_712_approved(void) {
ui_712_approve();

View File

@@ -9,11 +9,6 @@
#define TEXT_REVIEW_EIP712 REVIEW(TEXT_TYPED_MESSAGE)
#define TEXT_SIGN_EIP712 SIGN(TEXT_TYPED_MESSAGE)
void ui_message_review_choice(bool confirm);
void ui_message_start(const char *title,
void (*start_func)(void),
void (*approved_func)(void),
void (*rejected_func)(void));
void ui_typed_message_review_choice(bool confirm);
#endif // UI_MESSAGE_SIGNING_H_

View File

@@ -11,6 +11,7 @@ extern char g_stax_shared_buffer[SHARED_BUFFER_SIZE];
extern nbgl_page_t* pageContext;
const nbgl_icon_details_t* get_app_icon(bool caller_icon);
const nbgl_icon_details_t* get_tx_icon(void);
void ui_idle(void);

View File

@@ -1,4 +1,4 @@
#include <nbgl_page.h>
#include "nbgl_page.h"
#include "shared_context.h"
#include "ui_callbacks.h"
#include "ui_nbgl.h"
@@ -20,12 +20,14 @@ typedef enum {
static e_ui_191_action g_action;
static bool skip_message;
static nbgl_contentTagValue_t pair;
static nbgl_contentTagValueList_t pairs_list;
static uint32_t eip191MessageIdx = 0;
static uint32_t stringsTmpTmpIdx = 0;
static uint32_t g_display_buffer_idx;
static uint32_t g_rcv_buffer_idx;
static bool g_skipped;
static void ui_191_process_state(void);
static void reject_message(void) {
io_seproxyhal_touch_signMessage_cancel();
@@ -35,125 +37,111 @@ static void sign_message(void) {
io_seproxyhal_touch_signMessage_ok();
}
static bool display_message(nbgl_pageContent_t *content) {
static void ui_191_finish_cb(bool confirm) {
if (confirm) {
nbgl_useCaseReviewStatus(STATUS_TYPE_MESSAGE_SIGNED, sign_message);
} else {
nbgl_useCaseReviewStatus(STATUS_TYPE_MESSAGE_REJECTED, reject_message);
}
}
static void ui_191_skip_cb(void) {
g_skipped = true;
skip_rest_of_message();
}
static bool ui_191_update_display_buffer(void) {
uint16_t len = 0;
bool reached;
if (g_action == UI_191_ACTION_ADVANCE_IN_MESSAGE) {
strncpy(g_stax_shared_buffer + eip191MessageIdx,
strings.tmp.tmp + stringsTmpTmpIdx,
SHARED_BUFFER_SIZE - eip191MessageIdx);
reached = nbgl_getTextMaxLenInNbLines(LARGE_MEDIUM_FONT,
(char *) g_stax_shared_buffer,
SCREEN_WIDTH - (2 * BORDER_MARGIN),
NB_MAX_LINES_IN_REVIEW,
#if (API_LEVEL == 0 || API_LEVEL >= 14)
&len,
false);
#else
&len);
#endif
g_stax_shared_buffer[g_display_buffer_idx] = '\0';
strlcat(g_stax_shared_buffer + g_display_buffer_idx,
strings.tmp.tmp + g_rcv_buffer_idx,
sizeof(g_stax_shared_buffer) - g_display_buffer_idx);
reached = nbgl_getTextMaxLenInNbLines(LARGE_MEDIUM_FONT,
(char *) g_stax_shared_buffer,
SCREEN_WIDTH - (2 * BORDER_MARGIN),
NB_MAX_LINES_IN_REVIEW,
&len,
false);
stringsTmpTmpIdx = len - eip191MessageIdx;
eip191MessageIdx = len;
g_stax_shared_buffer[eip191MessageIdx] = '\0';
g_rcv_buffer_idx += (len - g_display_buffer_idx);
g_display_buffer_idx = len;
g_stax_shared_buffer[g_display_buffer_idx] = '\0';
if (!reached && eip191MessageIdx < SHARED_BUFFER_SIZE) {
stringsTmpTmpIdx = 0;
question_switcher();
if (g_action != UI_191_ACTION_GO_TO_SIGN) {
return false;
}
} else if (reached || eip191MessageIdx == SHARED_BUFFER_SIZE) {
eip191MessageIdx = 0;
}
}
pair.value = g_stax_shared_buffer;
pair.item = "Message";
content->type = TAG_VALUE_LIST;
content->tagValueList.nbPairs = 1;
content->tagValueList.pairs = &pair;
content->tagValueList.smallCaseForValue = false;
content->tagValueList.nbMaxLinesForValue = NB_MAX_LINES_IN_REVIEW;
content->tagValueList.wrapping = false;
if ((g_action != UI_191_ACTION_IDLE) && (stringsTmpTmpIdx >= strlen(strings.tmp.tmp))) {
// Fetch the next content to display into strings.tmp.tmp buffer.
stringsTmpTmpIdx = 0;
if (!reached) {
g_rcv_buffer_idx = 0;
question_switcher();
return false;
}
g_display_buffer_idx = 0;
return true;
}
static bool display_sign(nbgl_pageContent_t *content) {
bool ret = false;
if (g_position != UI_SIGNING_POSITION_SIGN) {
content->type = INFO_LONG_PRESS, content->infoLongPress.icon = &C_Review_64px;
content->infoLongPress.text = TEXT_SIGN_EIP191;
content->infoLongPress.longPressText = SIGN_BUTTON;
g_position = UI_SIGNING_POSITION_SIGN;
ret = true;
}
return ret;
}
static bool nav_callback(uint8_t page, nbgl_pageContent_t *content) {
bool ret = true;
if (page == LAST_PAGE_FOR_REVIEW) { // was skipped
skip_message = true;
skip_rest_of_message();
}
if ((g_action != UI_191_ACTION_GO_TO_SIGN) && (g_position != UI_SIGNING_POSITION_SIGN)) {
if (skip_message) {
// do not refresh when this callback triggers after user validation
ret = false;
} else {
ret = display_message(content);
}
static void ui_191_data_cb(bool more) {
if (more) {
ui_191_process_state();
} else {
// the last page must contain a long press button
ret = display_sign(content);
ui_191_finish_cb(false);
}
return ret;
}
static void continue_review(void) {
nbgl_useCaseForwardOnlyReview(REJECT_BUTTON, NULL, nav_callback, ui_message_review_choice);
static void ui_191_show_message(void) {
pair.value = g_stax_shared_buffer;
pair.item = "Message";
pairs_list.nbPairs = 1;
pairs_list.pairs = &pair;
pairs_list.smallCaseForValue = false;
pairs_list.nbMaxLinesForValue = NB_MAX_LINES_IN_REVIEW;
pairs_list.wrapping = false;
nbgl_useCaseReviewStreamingContinueExt(&pairs_list, ui_191_data_cb, ui_191_skip_cb);
}
static void ui_191_process_state(void) {
switch (g_action) {
case UI_191_ACTION_IDLE:
g_action = UI_191_ACTION_ADVANCE_IN_MESSAGE;
__attribute__((fallthrough));
case UI_191_ACTION_ADVANCE_IN_MESSAGE:
if (ui_191_update_display_buffer()) {
ui_191_show_message();
}
break;
case UI_191_ACTION_GO_TO_SIGN:
nbgl_useCaseReviewStreamingFinish(TEXT_SIGN_EIP191, ui_191_finish_cb);
break;
}
}
void ui_191_start(void) {
g_position = UI_SIGNING_POSITION_START;
g_action = UI_191_ACTION_IDLE;
g_display_buffer_idx = 0;
g_rcv_buffer_idx = 0;
g_skipped = false;
skip_message = false;
eip191MessageIdx = 0;
stringsTmpTmpIdx = 0;
ui_message_start(TEXT_REVIEW_EIP191, &ui_191_switch_to_message, &sign_message, &reject_message);
nbgl_useCaseReviewStreamingStart(TYPE_MESSAGE | SKIPPABLE_OPERATION,
&C_Review_64px,
TEXT_REVIEW_EIP191,
NULL,
ui_191_data_cb);
}
void ui_191_switch_to_message(void) {
g_position = UI_SIGNING_POSITION_REVIEW;
g_action = UI_191_ACTION_ADVANCE_IN_MESSAGE;
// No question mechanism on Stax:
// Message is already displayed
continue_review();
// Get following part of the message
ui_191_process_state();
}
void ui_191_switch_to_sign(void) {
g_action = UI_191_ACTION_GO_TO_SIGN;
// Next nav_callback callback must display
// the hold to approve screen
if (skip_message) {
continue_review(); // to force screen refresh
if (g_skipped) {
nbgl_useCaseReviewStreamingFinish(TEXT_SIGN_EIP191, ui_191_finish_cb);
} else if (g_display_buffer_idx > 0) {
// still on an incomplete display buffer, show it before the last page
ui_191_show_message();
}
}
void ui_191_switch_to_question(void) {
// No question mechanism on Stax:
// Always display the next message chunk.
// No question mechanism on Stax: Always display the next message chunk.
continue_displaying_message();
}

View File

@@ -1,5 +1,6 @@
import sys
from pathlib import Path
from os import path
import warnings
import glob
@@ -17,8 +18,8 @@ def pytest_addoption(parser):
parser.addoption("--with_lib_mode", action="store_true", help="Run the test with Library Mode")
parent: Path = Path(__file__).parent
testFiles = glob.glob("test_*.py", root_dir=f"{parent}")
pattern = f"{Path(__file__).parent}/test_*.py"
testFiles = [path.basename(x) for x in glob.glob(pattern)]
collect_ignore = []
if "--with_lib_mode" in sys.argv:

View File

@@ -8,6 +8,9 @@ disable = C0114, # missing-module-docstring
C0103, # invalid-name
R0801, # duplicate-code
R0903, # too-few-public-methods
R0904, # too-many-public-methods
R0911, # too-many-statements
R0912, # too-many-branches
R0913, # too-many-arguments
R0914, # too-many-locals
W0603, # global-statement

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -7,7 +7,6 @@ from web3 import Web3
from ragger.backend import BackendInterface
from ragger.firmware import Firmware
from ragger.navigator import Navigator, NavInsID
from ragger.navigator.navigation_scenario import NavigateWithScenario
from ragger.error import ExceptionRAPDU
from constants import ABIS_FOLDER
@@ -77,8 +76,8 @@ def test_blind_sign(firmware: Firmware,
test_name += "_rejected"
moves = []
if firmware.device.startswith("nano"):
if firmware.device == "nanos":
if firmware.is_nano:
if firmware == Firmware.NANOS:
moves += [NavInsID.RIGHT_CLICK] * 2
else:
moves += [NavInsID.RIGHT_CLICK] * 4
@@ -89,13 +88,13 @@ def test_blind_sign(firmware: Firmware,
moves += [NavInsID.BOTH_CLICK]
if sign:
if firmware.device == "nanos":
if firmware == Firmware.NANOS:
moves += [NavInsID.RIGHT_CLICK] * 10
else:
moves += [NavInsID.RIGHT_CLICK] * 6
moves += [NavInsID.BOTH_CLICK]
else:
if firmware.device == "stax":
if firmware == Firmware.STAX:
tap_number = 2
else:
tap_number = 3
@@ -126,7 +125,7 @@ def test_blind_sign_reject_in_risk_review(firmware: Firmware,
test_name: str):
app_client = EthAppClient(backend)
if firmware.device not in ["stax", "flex"]:
if firmware.is_nano:
pytest.skip("Not supported on non-NBGL apps")
try:
@@ -146,7 +145,6 @@ def test_blind_sign_reject_in_risk_review(firmware: Firmware,
def test_sign_parameter_selector(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
global DEVICE_ADDR
@@ -168,8 +166,8 @@ def test_sign_parameter_selector(firmware: Firmware,
flows += data_len // 32
with app_client.sign(BIP32_PATH, tx_params):
moves = []
if firmware.device.startswith("nano"):
if firmware.device == "nanos":
if firmware.is_nano:
if firmware == Firmware.NANOS:
moves += [NavInsID.RIGHT_CLICK] * 2 + [NavInsID.BOTH_CLICK]
# Parameters on Nano S are split on multiple pages, hardcoded because the two parameters don't use the
# same amount of pages because of non-monospace fonts
@@ -178,19 +176,19 @@ def test_sign_parameter_selector(firmware: Firmware,
else:
moves += ([NavInsID.RIGHT_CLICK] * 2 + [NavInsID.BOTH_CLICK]) * flows
if firmware.device == "nanos":
if firmware == Firmware.NANOS:
moves += [NavInsID.RIGHT_CLICK] * 2
else:
moves += [NavInsID.RIGHT_CLICK] * 4
moves += [NavInsID.BOTH_CLICK]
if firmware.device == "nanos":
if firmware == Firmware.NANOS:
moves += [NavInsID.RIGHT_CLICK] * 9
else:
moves += [NavInsID.RIGHT_CLICK] * 5
moves += [NavInsID.BOTH_CLICK]
else:
if firmware.device == "stax":
if firmware == Firmware.STAX:
tap_number = 2
else:
tap_number = 3

View File

@@ -1,4 +1,3 @@
from pathlib import Path
import pytest
from web3 import Web3
@@ -33,7 +32,7 @@ def verbose_fixture(request) -> bool:
def common(firmware: Firmware, app_client: EthAppClient) -> int:
if firmware.device == "nanos":
if firmware == Firmware.NANOS:
pytest.skip("Not supported on LNS")
challenge = app_client.get_challenge()
return ResponseParser.challenge(challenge.data)
@@ -43,7 +42,6 @@ def test_send_fund(firmware: Firmware,
backend: BackendInterface,
navigator: Navigator,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path,
verbose: bool):
app_client = EthAppClient(backend)
challenge = common(firmware, app_client)
@@ -62,12 +60,12 @@ def test_send_fund(firmware: Firmware,
"value": Web3.to_wei(AMOUNT, "ether"),
"chainId": CHAIN_ID
}):
if firmware.device.startswith("nano"):
if firmware.is_nano:
end_text = "Accept"
else:
end_text = "Sign"
scenario_navigator.review_approve(default_screenshot_path, f"domain_name_verbose_{str(verbose)}", end_text)
scenario_navigator.review_approve(test_name=f"domain_name_verbose_{str(verbose)}", custom_screen_text=end_text)
def test_send_fund_wrong_challenge(firmware: Firmware, backend: BackendInterface):
@@ -81,8 +79,7 @@ def test_send_fund_wrong_challenge(firmware: Firmware, backend: BackendInterface
def test_send_fund_wrong_addr(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path):
scenario_navigator: NavigateWithScenario):
app_client = EthAppClient(backend)
challenge = common(firmware, app_client)
@@ -100,18 +97,17 @@ def test_send_fund_wrong_addr(firmware: Firmware,
"value": Web3.to_wei(AMOUNT, "ether"),
"chainId": CHAIN_ID
}):
if firmware.device.startswith("nano"):
if firmware.is_nano:
end_text = "Accept"
else:
end_text = "Sign"
scenario_navigator.review_approve(default_screenshot_path, "domain_name_wrong_addr", end_text)
scenario_navigator.review_approve(test_name="domain_name_wrong_addr", custom_screen_text=end_text)
def test_send_fund_non_mainnet(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path):
scenario_navigator: NavigateWithScenario):
app_client = EthAppClient(backend)
challenge = common(firmware, app_client)
@@ -126,18 +122,17 @@ def test_send_fund_non_mainnet(firmware: Firmware,
"value": Web3.to_wei(AMOUNT, "ether"),
"chainId": 5
}):
if firmware.device.startswith("nano"):
if firmware.is_nano:
end_text = "Accept"
else:
end_text = "Sign"
scenario_navigator.review_approve(default_screenshot_path, "domain_name_non_mainnet", end_text)
scenario_navigator.review_approve(test_name="domain_name_non_mainnet", custom_screen_text=end_text)
def test_send_fund_unknown_chain(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path):
scenario_navigator: NavigateWithScenario):
app_client = EthAppClient(backend)
challenge = common(firmware, app_client)
@@ -152,12 +147,12 @@ def test_send_fund_unknown_chain(firmware: Firmware,
"value": Web3.to_wei(AMOUNT, "ether"),
"chainId": 9
}):
if firmware.device.startswith("nano"):
if firmware.is_nano:
end_text = "Accept"
else:
end_text = "Sign"
scenario_navigator.review_approve(default_screenshot_path, "domain_name_unknown_chain", end_text)
scenario_navigator.review_approve(test_name="domain_name_unknown_chain", custom_screen_text=end_text)
def test_send_fund_domain_too_long(firmware: Firmware, backend: BackendInterface):

View File

@@ -1,4 +1,3 @@
from pathlib import Path
import pytest
from ragger.error import ExceptionRAPDU
@@ -17,7 +16,6 @@ BIP32_PATH = "m/44'/60'/0'/0/0"
def common(backend: BackendInterface,
scenario: NavigateWithScenario,
test_name: str,
screenshot_path: Path,
msg: str):
app_client = EthAppClient(backend)
@@ -27,7 +25,7 @@ def common(backend: BackendInterface,
_, DEVICE_ADDR, _ = ResponseParser.pk_addr(app_client.response().data)
with app_client.personal_sign(BIP32_PATH, msg.encode('utf-8')):
scenario.review_approve(screenshot_path, test_name, "Sign")
scenario.review_approve(test_name=test_name, custom_screen_text="Sign")
# verify signature
vrs = ResponseParser.signature(app_client.response().data)
@@ -37,29 +35,26 @@ def common(backend: BackendInterface,
def test_personal_sign_metamask(backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
test_name: str):
msg = "Example `personal_sign` message"
common(backend, scenario_navigator, test_name, default_screenshot_path, msg)
common(backend, scenario_navigator, test_name, msg)
def test_personal_sign_non_ascii(backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
test_name: str):
msg = "0x9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658"
common(backend, scenario_navigator, test_name, default_screenshot_path, msg)
common(backend, scenario_navigator, test_name, msg)
def test_personal_sign_opensea(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
test_name: str):
if firmware.device == "nanos":
if firmware == Firmware.NANOS:
pytest.skip("Not supported on LNS")
msg = "Welcome to OpenSea!\n\n"
@@ -67,14 +62,12 @@ def test_personal_sign_opensea(firmware: Firmware,
msg += "This request will not trigger a blockchain transaction or cost any gas fees.\n\n"
msg += "Your authentication status will reset after 24 hours.\n\n"
msg += "Wallet address:\n0x9858effd232b4033e47d90003d41ec34ecaeda94\n\nNonce:\n2b02c8a0-f74f-4554-9821-a28054dc9121"
common(backend, scenario_navigator, test_name, default_screenshot_path, msg)
common(backend, scenario_navigator, test_name, msg)
def test_personal_sign_reject(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
scenario_navigator: NavigateWithScenario):
msg = "This is an reject sign"
@@ -82,11 +75,11 @@ def test_personal_sign_reject(firmware: Firmware,
try:
with app_client.personal_sign(BIP32_PATH, msg.encode('utf-8')):
if firmware.device.startswith("nano"):
if firmware.is_nano:
end_text = "Cancel"
else:
end_text = "Sign"
scenario_navigator.review_reject(default_screenshot_path, test_name, end_text)
scenario_navigator.review_reject(custom_screen_text=end_text)
except ExceptionRAPDU as e:
assert e.status == StatusWord.CONDITION_NOT_SATISFIED

View File

@@ -90,7 +90,7 @@ def test_eip712_legacy(backend: BackendInterface, scenario_navigator: NavigateWi
def autonext(firmware: Firmware, navigator: Navigator, default_screenshot_path: Path):
moves = []
if firmware.device.startswith("nano"):
if firmware.is_nano:
moves = [NavInsID.RIGHT_CLICK]
else:
moves = [NavInsID.SWIPE_CENTER_TO_LEFT]
@@ -123,10 +123,10 @@ def eip712_new_common(firmware: Firmware,
golden_run)
with app_client.eip712_sign_new(BIP32_PATH):
moves = []
if firmware.device.startswith("nano"):
if firmware.is_nano:
# need to skip the message hash
if not verbose and filters is None:
moves = [NavInsID.RIGHT_CLICK] * 2
moves += [NavInsID.RIGHT_CLICK] * 2
moves += [NavInsID.BOTH_CLICK]
else:
# this move is necessary most of the times, but can't be 100% sure with the fields grouping
@@ -159,7 +159,7 @@ def test_eip712_new(firmware: Firmware,
verbose: bool,
filtering: bool):
app_client = EthAppClient(backend)
if firmware.device == "nanos":
if firmware == Firmware.NANOS:
pytest.skip("Not supported on LNS")
test_path = f"{input_file.parent}/{'-'.join(input_file.stem.split('-')[:-1])}"
@@ -420,7 +420,7 @@ def test_eip712_advanced_filtering(firmware: Firmware,
global SNAPS_CONFIG
app_client = EthAppClient(backend)
if firmware.device == "nanos":
if firmware == Firmware.NANOS:
pytest.skip("Not supported on LNS")
SNAPS_CONFIG = SnapshotsConfig(test_name + data_set.suffix)

View File

@@ -1,4 +1,3 @@
from pathlib import Path
from typing import Optional
import pytest
@@ -36,27 +35,25 @@ def chain_fixture(request) -> Optional[int]:
)
def test_get_pk_rejected(backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path,
path,
suffix):
app_client = EthAppClient(backend)
with pytest.raises(ExceptionRAPDU) as e:
with app_client.get_public_addr(bip32_path=path):
scenario_navigator.address_review_reject(default_screenshot_path, f"get_pk_rejected_{suffix}")
scenario_navigator.address_review_reject(test_name=f"get_pk_rejected_{suffix}")
assert e.value.status == StatusWord.CONDITION_NOT_SATISFIED
def test_get_pk(backend: BackendInterface,
default_screenshot_path: Path,
scenario_navigator: NavigateWithScenario,
with_chaincode: bool,
chain: Optional[int]):
app_client = EthAppClient(backend)
with app_client.get_public_addr(chaincode=with_chaincode, chain_id=chain):
scenario_navigator.address_review_approve(default_screenshot_path, f"get_pk_{chain}")
scenario_navigator.address_review_approve(test_name=f"get_pk_{chain}")
pk, _, chaincode = ResponseParser.pk_addr(app_client.response().data, with_chaincode)
ref_pk, ref_chaincode = calculate_public_key_and_chaincode(curve=CurveChoice.Secp256k1,
@@ -69,18 +66,17 @@ def test_get_pk(backend: BackendInterface,
def test_get_eth2_pk(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
test_name: str):
app_client = EthAppClient(backend)
path="m/12381/3600/0/0"
with app_client.get_eth2_public_addr(bip32_path=path):
scenario_navigator.address_review_approve(default_screenshot_path, test_name)
scenario_navigator.address_review_approve(test_name=test_name)
pk = app_client.response().data
ref_pk = bls.SkToPk(mnemonic_and_path_to_key(SPECULOS_MNEMONIC, path))
if firmware.name in ("stax", "flex"):
if firmware in (Firmware.STAX, Firmware.FLEX):
pk = pk[1:49]
assert pk == ref_pk

View File

@@ -1,4 +1,3 @@
from pathlib import Path
from typing import Callable, Optional, Any
import json
import pytest
@@ -51,7 +50,6 @@ class Action:
def common_test_nft(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path,
collec: NFTCollection,
action: Action,
reject: bool,
@@ -59,7 +57,7 @@ def common_test_nft(firmware: Firmware,
global DEVICE_ADDR
app_client = EthAppClient(backend)
if firmware.device == "nanos":
if firmware == Firmware.NANOS:
pytest.skip("Not supported on LNS")
if DEVICE_ADDR is None: # to only have to request it once
@@ -86,13 +84,13 @@ def common_test_nft(firmware: Firmware,
test_name = f"{plugin_name.lower()}_{action.fn_name}_{str(collec.chain_id)}"
if reject:
test_name += "-rejected"
scenario_navigator.review_reject(default_screenshot_path, test_name)
scenario_navigator.review_reject(test_name=test_name)
else:
if firmware.device.startswith("nano"):
if firmware.is_nano:
end_text = "Accept"
else:
end_text = "Sign"
scenario_navigator.review_approve(default_screenshot_path, test_name, end_text)
scenario_navigator.review_approve(test_name=test_name, custom_screen_text=end_text)
# verify signature
vrs = ResponseParser.signature(app_client.response().data)
@@ -104,11 +102,10 @@ def common_test_nft_reject(test_fn: Callable,
firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path,
collec: NFTCollection,
action: Action):
with pytest.raises(ExceptionRAPDU) as e:
test_fn(firmware, backend, scenario_navigator, default_screenshot_path, collec, action, True)
test_fn(firmware, backend, scenario_navigator, collec, action, True)
assert e.value.status == StatusWord.CONDITION_NOT_SATISFIED
# ERC-721
@@ -158,14 +155,12 @@ def action_721_fixture(request) -> Action:
def test_erc721(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path,
collec_721: NFTCollection,
action_721: Action,
reject: bool = False):
common_test_nft(firmware,
backend,
scenario_navigator,
default_screenshot_path,
collec_721,
action_721,
reject,
@@ -174,13 +169,11 @@ def test_erc721(firmware: Firmware,
def test_erc721_reject(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path):
scenario_navigator: NavigateWithScenario):
common_test_nft_reject(test_erc721,
firmware,
backend,
scenario_navigator,
default_screenshot_path,
collecs_721[0],
actions_721[0])
@@ -237,14 +230,12 @@ def action_1155_fixture(request) -> Action:
def test_erc1155(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path,
collec_1155: NFTCollection,
action_1155: Action,
reject: bool = False):
common_test_nft(firmware,
backend,
scenario_navigator,
default_screenshot_path,
collec_1155,
action_1155,
reject,
@@ -253,12 +244,10 @@ def test_erc1155(firmware: Firmware,
def test_erc1155_reject(firmware: Firmware,
backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path):
scenario_navigator: NavigateWithScenario):
common_test_nft_reject(test_erc1155,
firmware,
backend,
scenario_navigator,
default_screenshot_path,
collecs_1155[0],
actions_1155[0])

View File

@@ -46,18 +46,18 @@ def common(firmware: Firmware,
_, DEVICE_ADDR, _ = ResponseParser.pk_addr(app_client.response().data)
with app_client.sign(path, tx_params):
if not firmware.device.startswith("nano") and confirm:
if not firmware.is_nano and confirm:
navigator.navigate_and_compare(default_screenshot_path,
f"{test_name}/confirm",
[NavInsID.USE_CASE_CHOICE_CONFIRM],
screen_change_after_last_instruction=False)
if firmware.device.startswith("nano"):
if firmware.is_nano:
end_text = "Accept"
else:
end_text = "Sign"
scenario_navigator.review_approve(default_screenshot_path, test_name, end_text, (test_name != ""))
scenario_navigator.review_approve(custom_screen_text=end_text, do_comparison=test_name!="")
# verify signature
vrs = ResponseParser.signature(app_client.response().data)
@@ -67,15 +67,13 @@ def common(firmware: Firmware,
def common_reject(backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
default_screenshot_path: Path,
tx_params: dict,
test_name: str,
path: str = BIP32_PATH):
app_client = EthAppClient(backend)
try:
with app_client.sign(path, tx_params):
scenario_navigator.review_reject(default_screenshot_path, test_name)
scenario_navigator.review_reject()
except ExceptionRAPDU as e:
assert e.status == StatusWord.CONDITION_NOT_SATISFIED
@@ -235,10 +233,7 @@ def test_sign_nonce_display(firmware: Firmware,
common(firmware, backend, navigator, scenario_navigator, default_screenshot_path, tx_params, test_name, "m/44'/60'/1'/0/0")
def test_sign_reject(backend: BackendInterface,
scenario_navigator: NavigateWithScenario,
test_name: str,
default_screenshot_path: Path):
def test_sign_reject(backend: BackendInterface, scenario_navigator: NavigateWithScenario):
tx_params: dict = {
"nonce": NONCE2,
"gasPrice": Web3.to_wei(GAS_PRICE, 'gwei'),
@@ -247,7 +242,7 @@ def test_sign_reject(backend: BackendInterface,
"value": Web3.to_wei(AMOUNT2, "ether"),
"chainId": CHAIN_ID
}
common_reject(backend, scenario_navigator, default_screenshot_path, tx_params, test_name, "m/44'/60'/1'/0/0")
common_reject(backend, scenario_navigator, tx_params, "m/44'/60'/1'/0/0")
def test_sign_error_transaction_type(backend: BackendInterface):

12
tools/copy_clones.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
DEVICES=(nanos nanos2 nanox stax flex)
for dev in "${DEVICES[@]}"; do
elf_file="build/${dev}/bin/app.elf"
if [[ -f ${elf_file} ]]; then
cp "${elf_file}" "tests/ragger/.test_dependencies/clone/build/${dev}/bin/"
else
echo "Ignoring unknown file/dev: ${elf_file}"
fi
done