diff --git a/src/common_ui.h b/src/common_ui.h index 3bca6b9..9b2b0dc 100644 --- a/src/common_ui.h +++ b/src/common_ui.h @@ -25,6 +25,11 @@ void ui_191_switch_to_message_end(void); void ui_191_switch_to_sign(void); void ui_191_switch_to_question(void); +// EIP-712 +void ui_712_start(void); +void ui_712_switch_to_message(void); +void ui_712_switch_to_sign(void); + #include "ui_callbacks.h" #include diff --git a/src_bagl/ui_flow_712.c b/src_bagl/ui_flow_712.c deleted file mode 100644 index 182a89a..0000000 --- a/src_bagl/ui_flow_712.c +++ /dev/null @@ -1,57 +0,0 @@ -#ifdef HAVE_EIP712_FULL_SUPPORT - -#include "ui_flow_712.h" -#include "ui_logic.h" -#include "shared_context.h" // strings - -// clang-format off -UX_STEP_NOCB( - ux_712_step_review, - pnn, - { - &C_icon_eye, - "Review", - "typed message", - }); -UX_STEP_NOCB( - ux_712_step_dynamic, - bnnn_paging, - { - .title = strings.tmp.tmp2, - .text = strings.tmp.tmp, - } -); -UX_STEP_INIT( - ux_712_step_dummy, - NULL, - NULL, - { - ui_712_next_field(); - } -); -UX_STEP_CB( - ux_712_step_approve, - pb, - ui_712_approve(NULL), - { - &C_icon_validate_14, - "Approve", - }); -UX_STEP_CB( - ux_712_step_reject, - pb, - ui_712_reject(NULL), - { - &C_icon_crossmark, - "Reject", - }); -// clang-format on - -UX_FLOW(ux_712_flow, - &ux_712_step_review, - &ux_712_step_dynamic, - &ux_712_step_dummy, - &ux_712_step_approve, - &ux_712_step_reject); - -#endif // HAVE_EIP712_FULL_SUPPORT diff --git a/src_bagl/ui_flow_712.h b/src_bagl/ui_flow_712.h deleted file mode 100644 index 25016de..0000000 --- a/src_bagl/ui_flow_712.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef UI_FLOW_712_H_ -#define UI_FLOW_712_H_ - -#ifdef HAVE_EIP712_FULL_SUPPORT - -#include "ux_flow_engine.h" - -extern const ux_flow_step_t* const ux_712_flow[]; - -#endif // HAVE_EIP712_FULL_SUPPORT - -#endif // UI_FLOW_712_H_ diff --git a/src_bagl/ui_flow_signMessage712.c b/src_bagl/ui_flow_signMessage712.c index 230852e..8e0ee75 100644 --- a/src_bagl/ui_flow_signMessage712.c +++ b/src_bagl/ui_flow_signMessage712.c @@ -1,72 +1,87 @@ -#include "shared_context.h" -#include "ui_callbacks.h" -#include "common_712.h" -#include "ethUtils.h" +#ifdef HAVE_EIP712_FULL_SUPPORT -void prepare_domain_hash_v0() { - snprintf(strings.tmp.tmp, - sizeof(strings.tmp.tmp), - "0x%.*H", - KECCAK256_HASH_BYTESIZE, - tmpCtx.messageSigningContext712.domainHash); -} +#include "ui_logic.h" +#include "shared_context.h" // strings -void prepare_message_hash_v0() { - snprintf(strings.tmp.tmp, - sizeof(strings.tmp.tmp), - "0x%.*H", - KECCAK256_HASH_BYTESIZE, - tmpCtx.messageSigningContext712.messageHash); +enum { UI_712_POS_REVIEW, UI_712_POS_END }; +static uint8_t ui_pos; + +static void dummy_cb(void) { + if (!ui_712_next_field()) { + if (ui_pos == UI_712_POS_REVIEW) { + ux_flow_next(); + ui_pos = UI_712_POS_END; + } else // UI_712_POS_END + { + ux_flow_prev(); + ui_pos = UI_712_POS_REVIEW; + } + } } // clang-format off UX_STEP_NOCB( - ux_sign_712_v0_flow_1_step, + ux_712_step_review, pnn, { - &C_icon_certificate, - "Sign", + &C_icon_eye, + "Review", "typed message", }); -UX_STEP_NOCB_INIT( - ux_sign_712_v0_flow_2_step, - bnnn_paging, - prepare_domain_hash_v0(), - { - .title = "Domain hash", +UX_STEP_NOCB( + ux_712_step_dynamic, + bnnn_paging, + { + .title = strings.tmp.tmp2, .text = strings.tmp.tmp, - }); -UX_STEP_NOCB_INIT( - ux_sign_712_v0_flow_3_step, - bnnn_paging, - prepare_message_hash_v0(), - { - .title = "Message hash", - .text = strings.tmp.tmp, - }); + } +); +UX_STEP_INIT( + ux_712_step_dummy, + NULL, + NULL, + { + dummy_cb(); + } +); UX_STEP_CB( - ux_sign_712_v0_flow_4_step, - pbb, - ui_712_approve_cb(NULL), + ux_712_step_approve, + pb, + ui_712_approve(NULL), { &C_icon_validate_14, - "Sign", - "message", + "Approve", }); UX_STEP_CB( - ux_sign_712_v0_flow_5_step, - pbb, - ui_712_reject_cb(NULL), + ux_712_step_reject, + pb, + ui_712_reject(NULL), { &C_icon_crossmark, - "Cancel", - "signature", + "Reject", }); // clang-format on -UX_FLOW(ux_sign_712_v0_flow, - &ux_sign_712_v0_flow_1_step, - &ux_sign_712_v0_flow_2_step, - &ux_sign_712_v0_flow_3_step, - &ux_sign_712_v0_flow_4_step, - &ux_sign_712_v0_flow_5_step); +UX_FLOW(ux_712_flow, + &ux_712_step_review, + &ux_712_step_dynamic, + &ux_712_step_dummy, + &ux_712_step_approve, + &ux_712_step_reject); + +void ui_712_start(void) { + ux_flow_init(0, ux_712_flow, NULL); + ui_pos = UI_712_POS_REVIEW; +} + +void ui_712_switch_to_message(void) { + ux_flow_init(0, ux_712_flow, &ux_712_step_dynamic); + ui_pos = UI_712_POS_REVIEW; +} + +void ui_712_switch_to_sign(void) { + ux_flow_init(0, ux_712_flow, &ux_712_step_approve); + ui_pos = UI_712_POS_END; +} + +#endif // HAVE_EIP712_FULL_SUPPORT diff --git a/src_bagl/ui_flow_signMessage712_v0.c b/src_bagl/ui_flow_signMessage712_v0.c new file mode 100644 index 0000000..230852e --- /dev/null +++ b/src_bagl/ui_flow_signMessage712_v0.c @@ -0,0 +1,72 @@ +#include "shared_context.h" +#include "ui_callbacks.h" +#include "common_712.h" +#include "ethUtils.h" + +void prepare_domain_hash_v0() { + snprintf(strings.tmp.tmp, + sizeof(strings.tmp.tmp), + "0x%.*H", + KECCAK256_HASH_BYTESIZE, + tmpCtx.messageSigningContext712.domainHash); +} + +void prepare_message_hash_v0() { + snprintf(strings.tmp.tmp, + sizeof(strings.tmp.tmp), + "0x%.*H", + KECCAK256_HASH_BYTESIZE, + tmpCtx.messageSigningContext712.messageHash); +} + +// clang-format off +UX_STEP_NOCB( + ux_sign_712_v0_flow_1_step, + pnn, + { + &C_icon_certificate, + "Sign", + "typed message", + }); +UX_STEP_NOCB_INIT( + ux_sign_712_v0_flow_2_step, + bnnn_paging, + prepare_domain_hash_v0(), + { + .title = "Domain hash", + .text = strings.tmp.tmp, + }); +UX_STEP_NOCB_INIT( + ux_sign_712_v0_flow_3_step, + bnnn_paging, + prepare_message_hash_v0(), + { + .title = "Message hash", + .text = strings.tmp.tmp, + }); +UX_STEP_CB( + ux_sign_712_v0_flow_4_step, + pbb, + ui_712_approve_cb(NULL), + { + &C_icon_validate_14, + "Sign", + "message", + }); +UX_STEP_CB( + ux_sign_712_v0_flow_5_step, + pbb, + ui_712_reject_cb(NULL), + { + &C_icon_crossmark, + "Cancel", + "signature", + }); +// clang-format on + +UX_FLOW(ux_sign_712_v0_flow, + &ux_sign_712_v0_flow_1_step, + &ux_sign_712_v0_flow_2_step, + &ux_sign_712_v0_flow_3_step, + &ux_sign_712_v0_flow_4_step, + &ux_sign_712_v0_flow_5_step); diff --git a/src_features/signMessageEIP712/ui_logic.c b/src_features/signMessageEIP712/ui_logic.c index 1589b19..6243134 100644 --- a/src_features/signMessageEIP712/ui_logic.c +++ b/src_features/signMessageEIP712/ui_logic.c @@ -6,8 +6,6 @@ #include "mem.h" #include "mem_utils.h" #include "os_io.h" -#include "ux_flow_engine.h" -#include "ui_flow_712.h" #include "shared_context.h" #include "ethUtils.h" // getEthDisplayableAddress #include "utils.h" // uint256_to_decimal @@ -18,6 +16,7 @@ #include "apdu_constants.h" // APDU response codes #include "typed_data.h" #include "commands_712.h" +#include "common_ui.h" static t_ui_context *ui_ctx = NULL; @@ -106,43 +105,34 @@ void ui_712_set_value(const char *const str, uint8_t length) { void ui_712_redraw_generic_step(void) { if (!ui_ctx->shown) // Initialize if it is not already { - ux_flow_init(0, ux_712_flow, NULL); + ui_712_start(); ui_ctx->shown = true; } else { - // not pretty, manually changes the internal state of the UX flow - // so that we always land on the first screen of a paging step without any visible - // screen glitching (quick screen switching) - G_ux.flow_stack[G_ux.stack_count - 1].index = 0; - // since the flow now thinks we are displaying the first step, do next - ux_flow_next(); + ui_712_switch_to_message(); } } /** - * Called on the intermediate dummy screen between the dynamic step - * && the approve/reject screen + * Called to fetch the next field if they have not all been processed yet + * + * @return whether there will be a next field */ -void ui_712_next_field(void) { +bool ui_712_next_field(void) { + bool next = false; + if (ui_ctx == NULL) { apdu_response_code = APDU_RESPONSE_CONDITION_NOT_SATISFIED; - return; - } - if (ui_ctx->structs_to_review > 0) { - ui_712_review_struct(path_get_nth_field_to_last(ui_ctx->structs_to_review)); - ui_ctx->structs_to_review -= 1; } else { + if (ui_ctx->structs_to_review > 0) { + ui_712_review_struct(path_get_nth_field_to_last(ui_ctx->structs_to_review)); + ui_ctx->structs_to_review -= 1; + } if (!ui_ctx->end_reached) { handle_eip712_return_code(true); - } else { - if (ui_ctx->pos == UI_712_POS_REVIEW) { - ux_flow_next(); - ui_ctx->pos = UI_712_POS_END; - } else { - ux_flow_prev(); - ui_ctx->pos = UI_712_POS_REVIEW; - } + next = true; } } + return next; } /** @@ -419,7 +409,7 @@ void ui_712_end_sign(void) { ui_ctx->end_reached = true; if (N_storage.verbose_eip712 || (ui_ctx->filtering_mode == EIP712_FILTERING_FULL)) { - ui_712_next_field(); + ui_712_switch_to_sign(); } } @@ -430,7 +420,6 @@ bool ui_712_init(void) { if ((ui_ctx = MEM_ALLOC_AND_ALIGN_TYPE(*ui_ctx))) { ui_ctx->shown = false; ui_ctx->end_reached = false; - ui_ctx->pos = UI_712_POS_REVIEW; ui_ctx->filtering_mode = EIP712_FILTERING_BASIC; } else { apdu_response_code = APDU_RESPONSE_INSUFFICIENT_MEMORY; diff --git a/src_features/signMessageEIP712/ui_logic.h b/src_features/signMessageEIP712/ui_logic.h index 72224b0..7ebb4b6 100644 --- a/src_features/signMessageEIP712/ui_logic.h +++ b/src_features/signMessageEIP712/ui_logic.h @@ -11,12 +11,9 @@ typedef enum { EIP712_FILTERING_BASIC, EIP712_FILTERING_FULL } e_eip712_filtering_mode; -typedef enum { UI_712_POS_REVIEW, UI_712_POS_END } e_ui_position; - typedef struct { bool shown; bool end_reached; - e_ui_position pos; uint8_t filtering_mode; uint8_t filters_to_process; uint8_t field_flags; @@ -25,7 +22,7 @@ typedef struct { bool ui_712_init(void); void ui_712_deinit(void); -void ui_712_next_field(void); +bool ui_712_next_field(void); void ui_712_review_struct(const void *const struct_ptr); bool ui_712_new_field(const void *const field_ptr, const uint8_t *const data, uint8_t length); void ui_712_end_sign(void);