From d814f0b34ba6be8d1e6274012399a2589d2e057d Mon Sep 17 00:00:00 2001 From: shufps Date: Wed, 7 Feb 2024 14:25:47 +0100 Subject: [PATCH 1/2] removed all remains of chrysalis --- src/api.c | 18 +- src/api.h | 3 +- src/iota/abstraction.c | 35 +--- src/iota/constants.h | 6 +- src/iota/essence_chrysalis.c | 369 ----------------------------------- src/iota/essence_chrysalis.h | 5 - 6 files changed, 6 insertions(+), 430 deletions(-) delete mode 100644 src/iota/essence_chrysalis.c delete mode 100644 src/iota/essence_chrysalis.h diff --git a/src/api.c b/src/api.c index 9cbb378..4c0fb7c 100644 --- a/src/api.c +++ b/src/api.c @@ -39,8 +39,8 @@ void api_initialize(APP_MODE_TYPE app_mode, uint32_t account_index) // app-modes // IOTA App - // 0x00: (107a) IOTA + Chrysalis (default, backwards compatible) - // 0x80: (1) IOTA + Chrysalis Testnet + // 0x00: unused (formerly IOTA + Chrysalis) + // 0x80: unused (formerly IOTA + Chrysalis Testnet) // 0x01: (107a) IOTA + Stardust // 0x81: (1) IOTA + Stardust Testnet @@ -52,12 +52,6 @@ void api_initialize(APP_MODE_TYPE app_mode, uint32_t account_index) switch (app_mode & 0x7f) { #if defined(APP_IOTA) - case APP_MODE_IOTA_CHRYSALIS: - // iota - api.bip32_path[BIP32_COIN_INDEX] = BIP32_COIN_IOTA; - api.protocol = PROTOCOL_CHRYSALIS; - api.coin = COIN_IOTA; - break; case APP_MODE_IOTA_STARDUST: // iota api.bip32_path[BIP32_COIN_INDEX] = BIP32_COIN_IOTA; @@ -422,9 +416,7 @@ uint32_t api_prepare_signing(uint8_t has_remainder, const uint8_t *data, THROW(SW_COMMAND_INVALID_DATA); } - if ((api.protocol == PROTOCOL_CHRYSALIS && - req.remainder_index >= OUTPUTS_MAX_COUNT_CHRYSALIS) || - (api.protocol == PROTOCOL_STARDUST && + if ((api.protocol == PROTOCOL_STARDUST && req.remainder_index >= OUTPUTS_MAX_COUNT_STARDUST)) { THROW(SW_COMMAND_INVALID_DATA); } @@ -537,8 +529,6 @@ uint32_t api_user_confirm_essence() api.essence.length >= API_BUFFER_SIZE_BYTES || api.data.length < api.essence.length || api.essence.inputs_count < INPUTS_MIN_COUNT || - (api.protocol == PROTOCOL_CHRYSALIS && - api.essence.inputs_count > INPUTS_MAX_COUNT_CHRYSALIS) || (api.protocol == PROTOCOL_STARDUST && api.essence.inputs_count > INPUTS_MAX_COUNT_STARDUST)) { THROW(SW_UNKNOWN); @@ -601,8 +591,6 @@ uint32_t api_sign(uint8_t p1) api.essence.length >= API_BUFFER_SIZE_BYTES || api.data.length < api.essence.length || api.essence.inputs_count < INPUTS_MIN_COUNT || - (api.protocol == PROTOCOL_CHRYSALIS && - api.essence.inputs_count > INPUTS_MAX_COUNT_CHRYSALIS) || (api.protocol == PROTOCOL_STARDUST && api.essence.inputs_count > INPUTS_MAX_COUNT_STARDUST)) { THROW(SW_UNKNOWN); diff --git a/src/api.h b/src/api.h index 62b6974..6db1c5c 100644 --- a/src/api.h +++ b/src/api.h @@ -22,13 +22,12 @@ typedef enum { } DATA_TYPE; typedef enum { - APP_MODE_IOTA_CHRYSALIS = 0, APP_MODE_IOTA_STARDUST = 1, APP_MODE_SHIMMER_CLAIMING = 2, APP_MODE_SHIMMER = 3 } APP_MODE_TYPE; -typedef enum { PROTOCOL_CHRYSALIS = 0, PROTOCOL_STARDUST = 1 } PROTOCOL_TYPE; +typedef enum { PROTOCOL_STARDUST = 1 } PROTOCOL_TYPE; typedef enum { COIN_IOTA = 0, COIN_SHIMMER = 1 } COIN_TYPE; diff --git a/src/iota/abstraction.c b/src/iota/abstraction.c index 3b3cfd2..d7c65b4 100644 --- a/src/iota/abstraction.c +++ b/src/iota/abstraction.c @@ -6,7 +6,6 @@ #include "os.h" -#include "essence_chrysalis.h" #include "essence_stardust.h" #include "abstraction.h" #include "ui_common.h" @@ -33,13 +32,6 @@ const uint8_t *get_output_address_ptr(const API_CTX *api, uint8_t index) ret = &tmp[index].address_type; break; } - case PROTOCOL_CHRYSALIS: { - SIG_LOCKED_SINGLE_OUTPUT *tmp = - (SIG_LOCKED_SINGLE_OUTPUT *)api->essence.outputs; - // address follows the address_type in a pact struct - ret = &tmp[index].address_type; - break; - } default: THROW(SW_UNKNOWN); break; @@ -59,12 +51,6 @@ uint64_t get_output_amount(const API_CTX *api, uint8_t index) memcpy(&amount, &tmp[index].amount, sizeof(uint64_t)); break; } - case PROTOCOL_CHRYSALIS: { - SIG_LOCKED_SINGLE_OUTPUT *tmp = - (SIG_LOCKED_SINGLE_OUTPUT *)api->essence.outputs; - memcpy(&amount, &tmp[index].amount, sizeof(uint64_t)); - break; - } default: THROW(SW_UNKNOWN); break; @@ -108,10 +94,6 @@ uint8_t essence_parse_and_validate(API_CTX *api) MUST(essence_parse_and_validate_stardust(api)); break; } - case PROTOCOL_CHRYSALIS: { - MUST(essence_parse_and_validate_chryslis(api)); - break; - } default: THROW(SW_UNKNOWN); break; @@ -129,22 +111,7 @@ uint8_t get_amount(const API_CTX *api, int index, char *dst, size_t dst_len, switch (api->coin) { case COIN_IOTA: { - // IOTA + Chrysalis uses metric units - if (api->protocol == PROTOCOL_CHRYSALIS) { - // show IOTA in full or short mode - if (full) { // full - // max supply is 2779530283277761 - this fits nicely in one line - // on the Ledger nano s always cut after the 16th char to not - // make a page with a single 'i'. - format_value_full(dst, dst_len, amount); - } - else { // short - format_value_short(dst, dst_len, amount); - } - } - else { - format_value_full_decimals(dst, dst_len, amount); - } + format_value_full_decimals(dst, dst_len, amount); break; } case COIN_SHIMMER: { diff --git a/src/iota/constants.h b/src/iota/constants.h index c57ef80..ac7b62f 100644 --- a/src/iota/constants.h +++ b/src/iota/constants.h @@ -17,11 +17,9 @@ #define TOTAL_AMOUNT_MAX 2779530283277761ull -#define INPUTS_MAX_COUNT_CHRYSALIS 127 #define INPUTS_MAX_COUNT_STARDUST 128 #define INPUTS_MIN_COUNT 1 -#define OUTPUTS_MAX_COUNT_CHRYSALIS 127 #define OUTPUTS_MAX_COUNT_STARDUST 128 #define OUTPUTS_MIN_COUNT 1 @@ -46,7 +44,7 @@ #define BIP32_COIN_TESTNET 0x80000001 #if defined(APP_IOTA) -#define APP_MODE_INIT APP_MODE_IOTA_CHRYSALIS +#define APP_MODE_INIT APP_MODE_IOTA_STARDUST #elif defined(APP_SHIMMER) #define APP_MODE_INIT APP_MODE_SHIMMER #else @@ -93,8 +91,6 @@ #define TRANSACTION_ESSENCE_TYPE_STARDUST 1 -#define TRANSACTION_ESSENCE_TYPE_CHRYSALIS 0 - // following constants are valid with bech32 encoding (address_type included) #define ADDRESS_SIZE_BASE32 ((ADDRESS_WITH_TYPE_SIZE_BYTES * 8 + 4) / 5) diff --git a/src/iota/essence_chrysalis.c b/src/iota/essence_chrysalis.c deleted file mode 100644 index b6e2c85..0000000 --- a/src/iota/essence_chrysalis.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * message_validator.c - * - * Created on: 15.10.2020 - * Author: thomas - */ - -// validation based on: -// https://github.com/iotaledger/tips/blob/main/tips/TIP-0007/tip-0007.md - -#include -#include - -#include "os.h" -#include "cx.h" -#include "api.h" - -#include "macros.h" -#include "essence_chrysalis.h" -#include "internal_transfer.h" - -#ifndef FUZZING -#include "iota_io.h" -#include "iota/ed25519.h" -#endif - -#pragma GCC diagnostic error "-Wall" -#pragma GCC diagnostic error "-Wextra" -#pragma GCC diagnostic error "-Wmissing-prototypes" - -static inline uint8_t get_uint32(const uint8_t *data, uint32_t *idx, - uint32_t *v) -{ - MUST(*idx + sizeof(uint32_t) < API_BUFFER_SIZE_BYTES); - memcpy(v, &data[*idx], - sizeof(uint32_t)); // copy to avoid unaligned access - *idx = *idx + sizeof(uint32_t); - return 1; -} -static inline uint8_t get_uint16(const uint8_t *data, uint32_t *idx, - uint16_t *v) -{ - MUST(*idx + sizeof(uint16_t) < API_BUFFER_SIZE_BYTES); - memcpy(v, &data[*idx], - sizeof(uint16_t)); // copy to avoid unaligned access - *idx = *idx + sizeof(uint16_t); - return 1; -} - -static inline uint8_t get_uint8(const uint8_t *data, uint32_t *idx, uint8_t *v) -{ - MUST(*idx + sizeof(uint8_t) < API_BUFFER_SIZE_BYTES); - *v = data[*idx]; - *idx = *idx + sizeof(uint8_t); - return 1; -} - - -// --- validate inputs --- -static uint8_t validate_inputs(const uint8_t *data, uint32_t *idx, - UTXO_INPUT **inputs_ptr, uint16_t *inputs_count) -{ - // uses safe getter macro that returns an error in case of invalid access - MUST(get_uint16(data, idx, inputs_count)); - - // Inputs Count must be 0 < x ≤ 127. - // At least one input must be specified. - MUST(*inputs_count >= INPUTS_MIN_COUNT && - *inputs_count <= INPUTS_MAX_COUNT_CHRYSALIS); - - *inputs_ptr = (UTXO_INPUT *)&data[*idx]; - - for (uint32_t i = 0; i < *inputs_count; i++) { - MUST(*idx + sizeof(UTXO_INPUT) < API_BUFFER_SIZE_BYTES); - - UTXO_INPUT tmp; - memcpy(&tmp, &data[*idx], - sizeof(UTXO_INPUT)); // copy to avoid unaligned access - - // Input Type value must be 0, denoting an UTXO Input. - MUST(tmp.input_type == INPUT_TYPE_UTXO); - - // Transaction Output Index must be 0 ≤ x < 127. - MUST(/*tmp.transaction_output_id >= 0 &&*/ tmp.transaction_output_id < - OUTPUTS_MAX_COUNT_CHRYSALIS); - - *idx = *idx + sizeof(UTXO_INPUT); - } - return 1; -} - -// --- validate outputs --- -static uint8_t validate_outputs(const uint8_t *data, uint32_t *idx, - SIG_LOCKED_SINGLE_OUTPUT **outputs_ptr, - uint16_t *outputs_count) -{ - // uses safe getter macro that returns an error in case of invalid access - MUST(get_uint16(data, idx, outputs_count)); - - // Outputs Count must be 0 < x ≤ 127. - // At least one output must be specified. - MUST(*outputs_count >= OUTPUTS_MIN_COUNT && - *outputs_count <= OUTPUTS_MAX_COUNT_CHRYSALIS); - - *outputs_ptr = (SIG_LOCKED_SINGLE_OUTPUT *)&data[*idx]; - uint64_t total_amount = 0ull; - - for (uint32_t i = 0; i < *outputs_count; i++) { - MUST(*idx + sizeof(SIG_LOCKED_SINGLE_OUTPUT) < API_BUFFER_SIZE_BYTES); - - SIG_LOCKED_SINGLE_OUTPUT tmp; - memcpy( - &tmp, &data[*idx], - sizeof(SIG_LOCKED_SINGLE_OUTPUT)); // copy to avoid unaligned access - - // Output Type must be 0, denoting a SigLockedSingleOutput. - MUST(tmp.output_type == OUTPUT_TYPE_SIGLOCKEDSINGLEOUTPUT); - - // Address Type must denote a Ed25519 address . - MUST(tmp.address_type == ADDRESS_TYPE_ED25519); // address_type - - // Amount must be > 0. - MUST(tmp.amount > 0); - - total_amount += tmp.amount; - - // detect overflows - MUST(total_amount >= tmp.amount); - - *idx = *idx + sizeof(SIG_LOCKED_SINGLE_OUTPUT); - } - - // Accumulated output balance must not exceed the total supply of tokens - // 2'779'530'283'277'761. - MUST(total_amount <= TOTAL_AMOUNT_MAX); - - return 1; -} - -// validate payload -static uint8_t validate_payload(const uint8_t *data, uint32_t *idx) -{ - // uses safe getter macro that returns an error in case of invalid access - uint32_t payload_length; - MUST(get_uint32(data, idx, &payload_length)); - - // wrap-around-safe - MUST_SUM_LOWER_THAN(*idx, payload_length, API_BUFFER_SIZE_BYTES); - - *idx = *idx + payload_length; - return 1; -} - -// validate if there are enough bip32 fragments -static uint8_t -validate_inputs_bip32(const uint8_t *data, uint32_t *idx, uint16_t inputs_count, - API_INPUT_BIP32_INDEX **inputs_bip32_indices) -{ - *inputs_bip32_indices = (API_INPUT_BIP32_INDEX *)&data[*idx]; - // check if there are as many bip32-paths as inputs - for (uint32_t i = 0; i < inputs_count; i++) { - MUST(*idx + sizeof(API_INPUT_BIP32_INDEX) < API_BUFFER_SIZE_BYTES); - - API_INPUT_BIP32_INDEX tmp; - memcpy(&tmp, &data[*idx], - sizeof(API_INPUT_BIP32_INDEX)); // copy to avoid unaligned access - - // check is MSBs set - MUST(tmp.bip32_index & 0x80000000); - MUST(tmp.bip32_change & 0x80000000); - - *idx = *idx + sizeof(API_INPUT_BIP32_INDEX); - } - return 1; -} - -// --- CHECK INPUTS FOR DUPLICATES --- -static uint8_t validate_inputs_duplicates(const UTXO_INPUT *inputs, - uint16_t inputs_count) -{ - // Every combination of Transaction ID + Transaction Output Index must be - // unique in the inputs set. - for (uint32_t i = 0; i < inputs_count; i++) { - for (uint32_t j = i + 1; j < inputs_count; j++) { - // we can check all bytes because first is the input_type that must - // always be 0 - if (!memcmp(&inputs[i], &inputs[j], sizeof(UTXO_INPUT))) { - return 0; - } - } - } - return 1; -} - -// --- CHECK OUTPUTS FOR DUPLICATES --- -static uint8_t -validate_outputs_duplicates(const SIG_LOCKED_SINGLE_OUTPUT *outputs, - uint16_t outputs_count) -{ - // The Address must be unique in the set of SigLockedSingleOutputs. - for (uint32_t i = 0; i < outputs_count; i++) { - for (uint32_t j = i + 1; j < outputs_count; j++) { - // check address (+1 for output_type, +1 for address_type) - if (!memcmp(&outputs[i], &outputs[j], 1 + 1 + ADDRESS_SIZE_BYTES)) { - return 0; - } - } - } - return 1; -} - -// --- CHECK INPUTS FOR LEXICOGRAPHICAL ORDER -static uint8_t validate_inputs_lexical_order(const UTXO_INPUT *inputs, - uint16_t inputs_count) -{ - // at least 2 needed for check - if (inputs_count < 2) { - return 1; - } - - for (uint32_t i = 0; i < inputs_count - 1; i++) { - // Inputs must be in lexicographical order of their serialized form. - if (memcmp((uint8_t *)&inputs[i], (uint8_t *)&inputs[i + 1], - sizeof(UTXO_INPUT)) >= 0) { - return 0; - } - } - return 1; -} - -// --- CHECK OUTPUTS FOR LEXICOGRAPHICAL ORDER -static uint8_t -validate_outputs_lexical_order(const SIG_LOCKED_SINGLE_OUTPUT *outputs, - uint16_t outputs_count) -{ - // at least 2 needed for check - if (outputs_count < 2) { - return 1; - } - - for (uint32_t i = 0; i < outputs_count - 1; i++) { - // Outputs must be in lexicographical order by their serialized form. - if (memcmp((uint8_t *)&outputs[i], (uint8_t *)&outputs[i + 1], - sizeof(SIG_LOCKED_SINGLE_OUTPUT)) >= 0) { - return 0; - } - } - return 1; -} - -static uint8_t essence_verify_remainder_address( - uint32_t *bip32_path, SIG_LOCKED_SINGLE_OUTPUT *outputs, - uint32_t outputs_count, uint16_t remainder_index, - API_REMAINDER_BIP32_INDEX *remainder_bip32) -{ - // check remainder_index - MUST(remainder_index < outputs_count); - - // check bip32 index - MUST(remainder_bip32->bip32_change & 0x80000000); - MUST(remainder_bip32->bip32_index & 0x80000000); - - SIG_LOCKED_SINGLE_OUTPUT tmp; - - explicit_bzero(&tmp, sizeof(SIG_LOCKED_SINGLE_OUTPUT)); - - // set bip32 index - bip32_path[BIP32_ADDRESS_INDEX] = remainder_bip32->bip32_index; - bip32_path[BIP32_CHANGE_INDEX] = remainder_bip32->bip32_change; - - // Block below cannot be fuzzed without going through crypto APIs -#ifndef FUZZING - // address generate generates with address - MUST(address_generate(bip32_path, BIP32_PATH_LEN, &tmp.address_type)); - - // verify, the address is the same - // relies on packed struct - MUST(!memcmp(&outputs[remainder_index].address_type, &tmp.address_type, - ADDRESS_WITH_TYPE_SIZE_BYTES)); -#else - (void)outputs; -#endif - return 1; -} - -static uint8_t essence_hash(API_CTX *api) -{ - // Block below cannot be fuzzed without going through crypto APIs -#ifndef FUZZING - cx_blake2b_t blake2b; - MUST(cx_blake2b_init_no_throw(&blake2b, BLAKE2B_SIZE_BYTES * 8) == CX_OK); - MUST(cx_hash_no_throw(&blake2b.header, CX_LAST, api->data.buffer, - api->essence.length, api->essence.hash, - ADDRESS_SIZE_BYTES) == CX_OK); -#else - (void)api; -#endif - return 1; -} - -uint8_t essence_parse_and_validate_chryslis(API_CTX *api) -{ - uint32_t idx = 0; - - // Transaction Essence Type value must be 0, denoting an Transaction - // Essence. uses safe getter macro that returns an error in case of invalid - // access - uint8_t transaction_essence_type; - MUST(get_uint8(api->data.buffer, &idx, &transaction_essence_type)); - MUST(transaction_essence_type == TRANSACTION_ESSENCE_TYPE_CHRYSALIS); - - // parse data - MUST(validate_inputs(api->data.buffer, &idx, &api->essence.inputs, - &api->essence.inputs_count)); - - MUST(validate_outputs(api->data.buffer, &idx, - (SIG_LOCKED_SINGLE_OUTPUT **)&api->essence.outputs, - &api->essence.outputs_count)); - - MUST(validate_payload(api->data.buffer, &idx)); - - // save essence length - api->essence.length = idx; - - // bip32 indices don't belong to the essence - MUST(validate_inputs_bip32(api->data.buffer, &idx, - api->essence.inputs_count, - &api->essence.inputs_bip32_index)); - - // save data length - api->data.length = idx; - - // if remainder output, check the address - if (api->essence.has_remainder) { - MUST(essence_verify_remainder_address( - api->bip32_path, (SIG_LOCKED_SINGLE_OUTPUT *)api->essence.outputs, - api->essence.outputs_count, api->essence.remainder_index, - &api->essence.remainder_bip32)); -#if 0 - // technically, this is valid ... so don't block it but keep this notice for documentation - // essence with only remainder and no other output - MUST(api->essence.outputs_count > 1); -#endif - } - - // additional validation steps of parsed data - MUST(validate_inputs_duplicates(api->essence.inputs, - api->essence.inputs_count)); - - MUST(validate_outputs_duplicates( - (SIG_LOCKED_SINGLE_OUTPUT *)api->essence.outputs, - api->essence.outputs_count)); - - MUST(validate_inputs_lexical_order(api->essence.inputs, - api->essence.inputs_count)); - MUST(validate_outputs_lexical_order( - (SIG_LOCKED_SINGLE_OUTPUT *)api->essence.outputs, - api->essence.outputs_count)); - - // everything fine - calculate the hash - MUST(essence_hash(api)); - - // check if it's a sweeping transaction - if (check_for_internal_transfer(api)) { - api->essence.is_internal_transfer = 1; - } - - return 1; -} diff --git a/src/iota/essence_chrysalis.h b/src/iota/essence_chrysalis.h deleted file mode 100644 index 1666040..0000000 --- a/src/iota/essence_chrysalis.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "api.h" - -uint8_t essence_parse_and_validate_chryslis(API_CTX *api); \ No newline at end of file From 364897b851218f17f5a94e5ae45f039eb392d7aa Mon Sep 17 00:00:00 2001 From: shufps Date: Wed, 7 Feb 2024 15:08:43 +0100 Subject: [PATCH 2/2] removed remains of chrysalis; removed automatic toggeling between short and full format --- src/iota/abstraction.c | 3 +- src/iota/abstraction.h | 3 +- src/ui/nano/flow_user_confirm_transaction.c | 42 +-------------------- 3 files changed, 4 insertions(+), 44 deletions(-) diff --git a/src/iota/abstraction.c b/src/iota/abstraction.c index d7c65b4..4d3719e 100644 --- a/src/iota/abstraction.c +++ b/src/iota/abstraction.c @@ -101,8 +101,7 @@ uint8_t essence_parse_and_validate(API_CTX *api) return 1; } -uint8_t get_amount(const API_CTX *api, int index, char *dst, size_t dst_len, - uint8_t full) +uint8_t get_amount(const API_CTX *api, int index, char *dst, size_t dst_len) { uint64_t amount; diff --git a/src/iota/abstraction.h b/src/iota/abstraction.h index 389f121..69cc7da 100644 --- a/src/iota/abstraction.h +++ b/src/iota/abstraction.h @@ -13,5 +13,4 @@ uint8_t address_encode_bech32(const API_CTX *api, const uint8_t *addr_with_type, uint8_t essence_parse_and_validate(API_CTX *api); -uint8_t get_amount(const API_CTX *api, int index, char *dst, size_t dst_len, - uint8_t full); +uint8_t get_amount(const API_CTX *api, int index, char *dst, size_t dst_len); diff --git a/src/ui/nano/flow_user_confirm_transaction.c b/src/ui/nano/flow_user_confirm_transaction.c index 6da34e8..0fcfee1 100644 --- a/src/ui/nano/flow_user_confirm_transaction.c +++ b/src/ui/nano/flow_user_confirm_transaction.c @@ -52,8 +52,6 @@ extern flowdata_t flow_data; -static void cb_value_toggle(); - static void cb_accept(); static void cb_reject(); static void cb_continue_claiming(); @@ -69,19 +67,12 @@ static void cb_back(); static void cb_next_dataset(); static void cb_prev_dataset(); -static void ui_confirm_output_value_toggle(); - static void get_read_index(); //------------------------------------------------------------------------ // clang-format off -UX_FLOW_CALL( - ux_flow_datasets_value_toggle, - cb_value_toggle() -) - // review output [...] UX_STEP_NOCB_INIT( ux_step_review, @@ -92,17 +83,10 @@ UX_STEP_NOCB_INIT( } ); -UX_FLOW_CALL( - ux_flow_confirm_output_value_toggle, - ui_confirm_output_value_toggle() -) - -UX_STEP_TIMEOUT_INIT( +UX_STEP_NOCB_INIT( ux_step_amount, bn, cb_amount_preinit(), - 2500, - ux_flow_confirm_output_value_toggle, { (const char*) flow_data.scratch[1], (const char*) flow_data.scratch[0] @@ -310,9 +294,6 @@ static void cb_next_dataset() } get_read_index(); - // reset toggle flag - flow_data.amount_toggle = 0; - ux_flow_init(0, ux_flow_base, &ux_step_review); } @@ -325,9 +306,6 @@ static void cb_prev_dataset() } get_read_index(); - // reset toggle flag - flow_data.amount_toggle = 0; - if (flow_data.flow_outputs_index_current == flow_data.num_non_remainder_outputs - 1) { ux_flow_init(0, ux_flow_has_accept_reject, &ux_step_reject); @@ -337,13 +315,6 @@ static void cb_prev_dataset() } } -// gets called by a timer to toggle the short and full view -static void ui_confirm_output_value_toggle() -{ - flow_data.amount_toggle = 1 - flow_data.amount_toggle; - ux_flow_init(0, ux_flow_base, &ux_step_amount); -} - static void cb_back() { ux_flow_init(0, ux_flow_base, &ux_step_amount); @@ -378,8 +349,7 @@ static void cb_amount_preinit() memset(flow_data.scratch[0], 0, sizeof(flow_data.scratch[0])); MUST_THROW(get_amount(flow_data.api, flow_data.read_index, - flow_data.scratch[0], sizeof(flow_data.scratch[0]), - flow_data.amount_toggle)); + flow_data.scratch[0], sizeof(flow_data.scratch[0]))); // copy header after writing amount if (flow_data.api->coin == COIN_SHIMMER) { @@ -458,14 +428,6 @@ static void get_read_index() } } -// gets called by a timer to toggle the short and full view -static void cb_value_toggle() -{ - flow_data.amount_toggle = 1 - flow_data.amount_toggle; - ux_flow_init(0, ux_flow_base, &ux_step_amount); -} - - void flow_start_user_confirm_transaction(const API_CTX *api, accept_cb_t accept_cb, reject_cb_t reject_cb,