Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
fbeutin-ledger committed Jun 30, 2023
1 parent 680eb89 commit 84ef759
Show file tree
Hide file tree
Showing 20 changed files with 169 additions and 40 deletions.
3 changes: 2 additions & 1 deletion src/currency_lib_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ int create_payin_transaction(create_transaction_parameters_t *lib_in_out_params)
libcall_params[3] = 0;
libcall_params[4] = (unsigned int) lib_in_out_params;

PRINTF("Exchange will call '%s' as library for SIGN_TRANSACTION\n", G_swap_ctx.payin_binary_name);
PRINTF("Exchange will call '%s' as library for SIGN_TRANSACTION\n",
G_swap_ctx.payin_binary_name);
USB_power(0);

#ifdef HAVE_NBGL
Expand Down
14 changes: 7 additions & 7 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,16 @@ __attribute__((section(".boot"))) int main(__attribute__((unused)) int arg0) {
os_boot();

for (;;) {

// Before cleaning our BSS, remember if we tried signing and if it worked
if (G_swap_ctx.state == SIGN_FINISHED_SUCCESS
|| G_swap_ctx.state == SIGN_FINISHED_FAIL) {
if (G_swap_ctx.state == SIGN_FINISHED_SUCCESS || G_swap_ctx.state == SIGN_FINISHED_FAIL) {
// We save everythin in the stack to avoid erasing it with the BSS reset
previous_cycle_data.had_previous_cycle = true;
previous_cycle_data.was_successful = (G_swap_ctx.state == SIGN_FINISHED_SUCCESS);
memcpy(previous_cycle_data.appname_last_cycle, G_swap_ctx.payin_binary_name, sizeof(previous_cycle_data.appname_last_cycle));
memcpy(previous_cycle_data.appname_last_cycle,
G_swap_ctx.payin_binary_name,
sizeof(previous_cycle_data.appname_last_cycle));

// Fully reset the global space, as it is was corrupted by the signing app
// Fully reset the global space, as it is was corrupted by the signing app
PRINTF("Exchange new cycle, reset BSS\n");
os_explicit_zero_BSS_segment();
}
Expand Down Expand Up @@ -154,8 +154,8 @@ __attribute__((section(".boot"))) int main(__attribute__((unused)) int arg0) {
} else {
ui_idle();
}
#else // HAVE_BAGL
// No "Ledger Moment" modal, sad
#else // HAVE_BAGL
// No "Ledger Moment" modal, sad
ui_idle();
#endif

Expand Down
167 changes: 144 additions & 23 deletions src/ui/validate_transaction_nbgl.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,85 @@
#include "io.h"
#include "ux.h"

#define SPINNER_TEXT_PART_1 "Starting the "
#define SPINNER_TEXT_PART_2 " app to sign the transaction"
static char spinner_text[(sizeof(SPINNER_TEXT_PART_1) - 1)
+ BOLOS_APPNAME_MAX_SIZE_B
+ (sizeof(SPINNER_TEXT_PART_2) - 1)
+ 1];

// #define SPINNER_TEXT_PART_1 "Starting the "
// #define SPINNER_TEXT_PART_2 "\napp to sign the transaction"
// #define SPINNER_TEXT_MAX_SIZE \
// ((sizeof(SPINNER_TEXT_PART_1) - 1) + (sizeof(G_swap_ctx.payin_binary_name) - 1) + \
// (sizeof(SPINNER_TEXT_PART_2) - 1) + 1)
// static char spinner_text[SPINNER_TEXT_MAX_SIZE];

#define REFUSAL_TEXT_PART_1 "Incorrect transaction\nrejected by the\n"
#define REFUSAL_TEXT_PART_2 " app"
static char refusal_text[(sizeof(REFUSAL_TEXT_PART_1) - 1)
+ BOLOS_APPNAME_MAX_SIZE_B
+ (sizeof(REFUSAL_TEXT_PART_2) - 1)
+ 1];
#define REFUSAL_TEXT_MAX_SIZE \
((sizeof(REFUSAL_TEXT_PART_1) - 1) + (sizeof(G_swap_ctx.payin_binary_name) - 1) + \
(sizeof(REFUSAL_TEXT_PART_2) - 1) + 1)
static char refusal_text[REFUSAL_TEXT_MAX_SIZE];

// One of:
#define REVIEW_P1_TITLE "Review transaction"
#define REVIEW_P1_CONFIRM "Sign transaction"

// Delimitor ' ' or '\n'

#define REVIEW_P2 "to"

// Delimitor ' ' or '\n'

// One of:
#define REVIEW_P3_SWAP "swap "
#define REVIEW_P3_SELL "sell "
#define REVIEW_P3_FUND "fund account"

// Delimitor ' ' or '\n'

// One of:
#define REVIEW_P4_SWAP "to "
#define REVIEW_P4_SELL "for "
#define REVIEW_P4_FUND "with "

// Maybe:
#define REVIEW_P5_CONFIRM "?"

// Calculate REVIEW_TITLE_MAX_SIZE with the SELL operation as it is the longest
#define REVIEW_TITLE_MAX_SIZE \
(sizeof(REVIEW_P1_TITLE) /* Review transaction */ \
+ 1 /* ' ' */ \
+ sizeof(REVIEW_P2) /* to */ \
+ 1 /* ' ' */ \
+ sizeof(REVIEW_P3_SELL) /* sell */ \
+ (sizeof(G_swap_ctx.sell_transaction.in_currency) - 1) /* TOKEN */ \
+ 1 /* ' ' */ \
+ sizeof(REVIEW_P4_SELL) /* for */ \
+ (sizeof(G_swap_ctx.sell_transaction.out_currency) - 1) /* CURRENCY */ \
+ 1) /* '\0' */

// Calculate REVIEW_CONFIRM_MAX_SIZE with the SELL operation as it is the longest
#define REVIEW_CONFIRM_MAX_SIZE \
(sizeof(REVIEW_P1_CONFIRM) /* Sign transaction */ \
+ 1 /* ' ' */ \
+ sizeof(REVIEW_P2) /* to */ \
+ 1 /* ' ' */ \
+ sizeof(REVIEW_P3_SELL) /* sell */ \
+ (sizeof(G_swap_ctx.sell_transaction.in_currency) - 1) /* TOKEN */ \
+ 1 /* ' ' */ \
+ sizeof(REVIEW_P4_SELL) /* for */ \
+ (sizeof(G_swap_ctx.sell_transaction.out_currency) - 1) /* CURRENCY */ \
+ 1 /* ? */ \
+ 1) /* '\0' */

// Dynamic texts, dimensionned for worst case scenario
static char review_title[REVIEW_TITLE_MAX_SIZE];
static char review_confirm[REVIEW_CONFIRM_MAX_SIZE];

static void accept_tx(void) {
snprintf(spinner_text,
sizeof(spinner_text),
"%s%s%s",
SPINNER_TEXT_PART_1,
G_swap_ctx.payin_binary_name,
SPINNER_TEXT_PART_2);
nbgl_useCaseSpinner(spinner_text);
// snprintf(spinner_text,
// sizeof(spinner_text),
// "%s%s%s",
// SPINNER_TEXT_PART_1,
// G_swap_ctx.payin_binary_name,
// SPINNER_TEXT_PART_2);
// nbgl_useCaseSpinner(spinner_text);
nbgl_useCaseSpinner("Processing");
reply_success();
G_swap_ctx.state = WAITING_SIGNING;
}
Expand Down Expand Up @@ -106,23 +162,88 @@ static void continue_review(void) {
pair_list.pairs = pairs;

info_long_press.icon = &C_icon_exchange_64x64;
info_long_press.text = "Sign transaction";
info_long_press.text = review_confirm;
info_long_press.longPressText = "Hold to sign";

nbgl_useCaseStaticReview(&pair_list, &info_long_press, "Reject", review_choice);
nbgl_useCaseStaticReview(&pair_list, &info_long_press, "Reject transaction", review_choice);
}

void ui_validate_amounts(void) {
// The "to" is on the first line
char delimitor_1 = ' ';
char delimitor_2 = '\n';
char delimitor_3 = ' ';
const char *dyn_string_1;
const char *dyn_string_2;
const char *p3;
const char *p4;
switch (G_swap_ctx.subcommand) {
case SWAP:
dyn_string_1 = G_swap_ctx.received_transaction.currency_from;
dyn_string_2 = G_swap_ctx.received_transaction.currency_to;
p3 = REVIEW_P3_SWAP;
p4 = REVIEW_P4_SWAP;
break;
case SELL:
dyn_string_1 = G_swap_ctx.sell_transaction.in_currency;
dyn_string_2 = G_swap_ctx.sell_transaction.out_currency;
p3 = REVIEW_P3_SELL;
p4 = REVIEW_P4_SELL;
break;
case FUND:
dyn_string_1 = "";
dyn_string_2 = G_swap_ctx.fund_transaction.in_currency;
p3 = REVIEW_P3_FUND;
p4 = REVIEW_P4_FUND;
break;
}

// Detect if we shoud display on 2 or 3 lines.
if (G_swap_ctx.subcommand == FUND || strlen(dyn_string_1) + strlen(dyn_string_2) >= 10) {
PRINTF("Review title and confirm on 3 lines\n");
// Move the "to" to the second line with the operation
delimitor_1 = '\n';
delimitor_2 = ' ';
delimitor_3 = '\n';
}

snprintf(review_title,
sizeof(review_title),
"%s%c%s%c%s%s%c%s%s",
REVIEW_P1_TITLE,
delimitor_1,
REVIEW_P2,
delimitor_2,
p3,
dyn_string_1,
delimitor_3,
p4,
dyn_string_2);

snprintf(review_confirm,
sizeof(review_confirm),
"%s%c%s%c%s%s%c%s%s%s",
REVIEW_P1_CONFIRM,
delimitor_1,
REVIEW_P2,
delimitor_2,
p3,
dyn_string_1,
delimitor_3,
p4,
dyn_string_2,
REVIEW_P5_CONFIRM);

nbgl_useCaseReviewStart(&C_icon_exchange_64x64,
"Review transaction",
review_title,
NULL,
"Reject",
"Reject transaction",
continue_review,
rejectUseCaseChoice);
}

void display_signing_success(void) {
nbgl_useCaseStatus("TRANSACTION\nSUCCESS", true, ui_idle);
nbgl_useCaseStatus("TRANSACTION\nSIGNED", true, ui_idle);
}

void display_signing_failure(const char *appname) {
Expand Down
16 changes: 8 additions & 8 deletions test/python/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
configuration.OPTIONAL.APP_NAME = "Exchange"

configuration.OPTIONAL.SIDELOADED_APPS = {
"bitcoin": "Bitcoin",
"bitcoin_legacy": "Bitcoin Legacy",
# "bitcoin": "Bitcoin",
# "bitcoin_legacy": "Bitcoin Legacy",
"ethereum": "Ethereum",
"ethereum_classic": "Ethereum Classic",
"tezos": "Tezos Wallet",
"xrp": "XRP",
"litecoin": "Litecoin",
"stellar": "Stellar",
# "ethereum_classic": "Ethereum Classic",
# "tezos": "Tezos Wallet",
# "xrp": "XRP",
# "litecoin": "Litecoin",
# "stellar": "Stellar",
"solana": "Solana",
"bsc": "Binance Smart Chain",
# "bsc": "Binance Smart Chain",
}

configuration.OPTIONAL.SIDELOADED_APPS_DIR = "test/python/lib_binaries/"
Expand Down
Binary file modified test/python/snapshots/nanos/test_solana_fund_ok/00003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/python/snapshots/stax/test_solana_fund_ok/00000.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/python/snapshots/stax/test_solana_fund_ok/00001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/python/snapshots/stax/test_solana_fund_ok/00002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/python/snapshots/stax/test_solana_fund_ok/00003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/python/snapshots/stax/test_solana_sell_ok/00000.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/python/snapshots/stax/test_solana_sell_ok/00001.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/python/snapshots/stax/test_solana_sell_ok/00002.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/python/snapshots/stax/test_solana_sell_ok/00003.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 8 additions & 1 deletion test/python/test_solana_fund.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Swap transaction infos for valid ETH <-> SOL exchanges. Tamper the values to generate errors
VALID_FUND_SOL_TX_INFOS = {
"user_id": "Daft Punk",
"account_name": "Account 0",
"account_name": "Acc 0",
"in_currency": "SOL",
"in_amount": SOL.AMOUNT_BYTES,
"in_address": SOL.FOREIGN_ADDRESS
Expand Down Expand Up @@ -49,6 +49,7 @@ def valid_fund(backend, navigator, test_name, tx_infos, fees):
ex.start_signing_transaction()
# On Stax, wait for the called app modal
if backend.firmware.device == "stax":
backend.wait_for_text_on_screen("Processing")
backend.wait_for_text_on_screen("Signing")


Expand All @@ -63,6 +64,12 @@ def test_solana_fund_ok(backend, navigator, test_name):
# Instant rapdu expected
pass

if backend.firmware.device == "stax":
navigator.navigate_and_compare(path=ROOT_SCREENSHOT_PATH,
test_case_name=test_name + "/final/",
instructions=[NavInsID.USE_CASE_REVIEW_TAP],
screen_change_before_first_instruction=False)

signature: bytes = sol.get_async_response().data
verify_signature(SOL.OWNED_PUBLIC_KEY, message, signature)

Expand Down

0 comments on commit 84ef759

Please sign in to comment.