diff --git a/src/handle_swap_sign_transaction.c b/src/handle_swap_sign_transaction.c index ebb0040..24bb2ed 100644 --- a/src/handle_swap_sign_transaction.c +++ b/src/handle_swap_sign_transaction.c @@ -60,6 +60,7 @@ void handle_swap_sign_transaction(chain_config_t* config) { storage.dataAllowed = 0x00; storage.contractDetails = 0x00; storage.initialized = 0x01; + storage.displayNonce = 0x00; nvm_write((void*) &N_storage, (void*) &storage, sizeof(internalStorage_t)); } diff --git a/src/main.c b/src/main.c index d939aff..5932d99 100644 --- a/src/main.c +++ b/src/main.c @@ -714,6 +714,7 @@ void coin_main(chain_config_t *coin_config) { internalStorage_t storage; storage.dataAllowed = 0x00; storage.contractDetails = 0x00; + storage.displayNonce = 0x00; storage.initialized = 0x01; nvm_write((void *) &N_storage, (void *) &storage, sizeof(internalStorage_t)); } diff --git a/src/shared_context.h b/src/shared_context.h index a858227..63db781 100644 --- a/src/shared_context.h +++ b/src/shared_context.h @@ -27,6 +27,7 @@ typedef struct internalStorage_t { unsigned char dataAllowed; unsigned char contractDetails; + unsigned char displayNonce; uint8_t initialized; } internalStorage_t; @@ -157,6 +158,7 @@ typedef struct txStringProperties_t { char fullAddress[43]; char fullAmount[50]; char maxFee[50]; + char nonce[8]; // 10M tx per account ought to be enough for everybody } txStringProperties_t; typedef struct strDataTmp_t { diff --git a/src/ui_flow.c b/src/ui_flow.c index 26f8c7c..6bac181 100644 --- a/src/ui_flow.c +++ b/src/ui_flow.c @@ -1,9 +1,10 @@ #include "shared_context.h" #include "ui_callbacks.h" -void display_settings(void); +void display_settings(const ux_flow_step_t* const start_step); void switch_settings_contract_data(void); void switch_settings_display_data(void); +void switch_settings_display_nonce(void); ////////////////////////////////////////////////////////////////////// // clang-format off @@ -25,7 +26,7 @@ UX_STEP_NOCB( UX_STEP_CB( ux_idle_flow_3_step, pb, - display_settings(), + display_settings(NULL), { &C_icon_eye, "Settings", @@ -65,7 +66,16 @@ UX_STEP_CB( switch_settings_display_data(), { .title = "Debug data", - .text = strings.common.fullAddress + 20 + .text = strings.common.fullAddress + 12 + }); + +UX_STEP_CB( + ux_settings_flow_3_step, + bnnn_paging, + switch_settings_display_nonce(), + { + .title = "Account nonce", + .text = strings.common.fullAddress + 26 }); #else @@ -89,13 +99,24 @@ UX_STEP_CB( "Debug data", "Display contract data", "details", - strings.common.fullAddress + 20 + strings.common.fullAddress + 12 + }); + + UX_STEP_CB( + ux_settings_flow_3_step, + bnnn, + switch_settings_display_nonce(), + { + "Nonce", + "Display account nonce", + "in transactions", + strings.common.fullAddress + 26 }); #endif UX_STEP_CB( - ux_settings_flow_3_step, + ux_settings_flow_4_step, pb, ui_idle(), { @@ -107,23 +128,32 @@ UX_STEP_CB( UX_FLOW(ux_settings_flow, &ux_settings_flow_1_step, &ux_settings_flow_2_step, - &ux_settings_flow_3_step); + &ux_settings_flow_3_step, + &ux_settings_flow_4_step); -void display_settings() { +void display_settings(const ux_flow_step_t* const start_step) { strcpy(strings.common.fullAddress, (N_storage.dataAllowed ? "Allowed" : "NOT Allowed")); - strcpy(strings.common.fullAddress + 20, + strcpy(strings.common.fullAddress + 12, (N_storage.contractDetails ? "Displayed" : "NOT Displayed")); - ux_flow_init(0, ux_settings_flow, NULL); + strcpy(strings.common.fullAddress + 26, + (N_storage.displayNonce ? "Displayed" : "NOT Displayed")); + ux_flow_init(0, ux_settings_flow, start_step); } void switch_settings_contract_data() { uint8_t value = (N_storage.dataAllowed ? 0 : 1); nvm_write((void*) &N_storage.dataAllowed, (void*) &value, sizeof(uint8_t)); - display_settings(); + display_settings(&ux_settings_flow_1_step); } void switch_settings_display_data() { uint8_t value = (N_storage.contractDetails ? 0 : 1); nvm_write((void*) &N_storage.contractDetails, (void*) &value, sizeof(uint8_t)); - display_settings(); + display_settings(&ux_settings_flow_2_step); +} + +void switch_settings_display_nonce() { + uint8_t value = (N_storage.displayNonce ? 0 : 1); + nvm_write((void*) &N_storage.displayNonce, (void*) &value, sizeof(uint8_t)); + display_settings(&ux_settings_flow_3_step); } diff --git a/src/ui_flow.h b/src/ui_flow.h index cd06ff0..4e8f321 100644 --- a/src/ui_flow.h +++ b/src/ui_flow.h @@ -12,10 +12,6 @@ extern const ux_flow_step_t* const ux_confirm_selector_flow[]; extern const ux_flow_step_t* const ux_confirm_parameter_flow[]; -extern const ux_flow_step_t* const ux_approval_tx_flow[]; - -extern const ux_flow_step_t* const ux_approval_tx_data_warning_flow[]; - extern const ux_flow_step_t* const ux_approval_allowance_flow[]; extern const ux_flow_step_t* const ux_sign_flow[]; diff --git a/src_common/ethUstream.c b/src_common/ethUstream.c index f6f0ecd..ee8296f 100644 --- a/src_common/ethUstream.c +++ b/src_common/ethUstream.c @@ -117,9 +117,10 @@ static void processNonce(txContext_t *context) { if (context->currentFieldPos < context->currentFieldLength) { uint32_t copySize = MIN(context->commandLength, context->currentFieldLength - context->currentFieldPos); - copyTxData(context, NULL, copySize); + copyTxData(context, context->content->nonce.value, copySize); } if (context->currentFieldPos == context->currentFieldLength) { + context->content->nonce.length = context->currentFieldLength; context->currentField++; context->processingField = false; } diff --git a/src_common/ethUstream.h b/src_common/ethUstream.h index 80f57f9..ff5c28e 100644 --- a/src_common/ethUstream.h +++ b/src_common/ethUstream.h @@ -69,6 +69,7 @@ typedef struct txContent_t { txInt256_t gasprice; txInt256_t startgas; txInt256_t value; + txInt256_t nonce; uint8_t destination[20]; uint8_t destinationLength; uint8_t v[4]; diff --git a/src_features/signTx/logic_signTx.c b/src_features/signTx/logic_signTx.c index 1f4d087..cfbfa8a 100644 --- a/src_features/signTx/logic_signTx.c +++ b/src_features/signTx/logic_signTx.c @@ -353,6 +353,15 @@ void finalizeParsing(bool direct) { sizeof(displayBuffer)); compareOrCopy(strings.common.fullAmount, displayBuffer, called_from_swap); } + // Prepare nonce to display + if (genericUI) { + uint256_t nonce; + convertUint256BE(tmpContent.txContent.nonce.value, + tmpContent.txContent.nonce.length, + &nonce); + tostring256(&nonce, 10, displayBuffer, sizeof(displayBuffer)); + strncpy(strings.common.nonce, displayBuffer, sizeof(strings.common.nonce)); + } // Compute maximum fee if (genericUI) { computeFees(displayBuffer, sizeof(displayBuffer)); @@ -371,11 +380,7 @@ void finalizeParsing(bool direct) { io_seproxyhal_touch_tx_ok(NULL); } else { if (genericUI) { - ux_flow_init( - 0, - ((dataPresent && !N_storage.contractDetails) ? ux_approval_tx_data_warning_flow - : ux_approval_tx_flow), - NULL); + ux_approve_tx(dataPresent); } else { plugin_ui_start(); } diff --git a/src_features/signTx/ui_flow_signTx.c b/src_features/signTx/ui_flow_signTx.c index 09c55e2..477a25a 100644 --- a/src_features/signTx/ui_flow_signTx.c +++ b/src_features/signTx/ui_flow_signTx.c @@ -131,6 +131,14 @@ UX_STEP_CB( "Reject", }); +UX_STEP_NOCB( + ux_approval_tx_display_nonce_step, + bnnn_paging, + { + .title = "Nonce", + .text = strings.common.nonce, + }); + UX_STEP_NOCB(ux_approval_tx_data_warning_step, pbb, { @@ -140,19 +148,23 @@ UX_STEP_NOCB(ux_approval_tx_data_warning_step, }); // clang-format on -UX_FLOW(ux_approval_tx_flow, - &ux_approval_tx_1_step, - &ux_approval_tx_2_step, - &ux_approval_tx_3_step, - &ux_approval_tx_4_step, - &ux_approval_tx_5_step, - &ux_approval_tx_6_step); +const ux_flow_step_t *ux_approval_tx_flow_[9]; -UX_FLOW(ux_approval_tx_data_warning_flow, - &ux_approval_tx_1_step, - &ux_approval_tx_data_warning_step, - &ux_approval_tx_2_step, - &ux_approval_tx_3_step, - &ux_approval_tx_4_step, - &ux_approval_tx_5_step, - &ux_approval_tx_6_step); \ No newline at end of file +void ux_approve_tx(bool dataPresent) { + int step = 0; + ux_approval_tx_flow_[step++] = &ux_approval_tx_1_step; + if (dataPresent && !N_storage.contractDetails) { + ux_approval_tx_flow_[step++] = &ux_approval_tx_data_warning_step; + } + ux_approval_tx_flow_[step++] = &ux_approval_tx_2_step; + ux_approval_tx_flow_[step++] = &ux_approval_tx_3_step; + if (N_storage.displayNonce) { + ux_approval_tx_flow_[step++] = &ux_approval_tx_display_nonce_step; + } + ux_approval_tx_flow_[step++] = &ux_approval_tx_4_step; + ux_approval_tx_flow_[step++] = &ux_approval_tx_5_step; + ux_approval_tx_flow_[step++] = &ux_approval_tx_6_step; + ux_approval_tx_flow_[step++] = FLOW_END_STEP; + + ux_flow_init(0, ux_approval_tx_flow_, NULL); +} \ No newline at end of file