diff --git a/Makefile b/Makefile index f818084..28b1a6d 100644 --- a/Makefile +++ b/Makefile @@ -210,6 +210,7 @@ SDK_SOURCE_PATH += lib_ux ifeq ($(TARGET_NAME),TARGET_NANOX) SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl endif +APP_SOURCE_PATH += src_bagl ### initialize plugin SDK submodule if needed, rebuild it, and warn if a difference is noticed ifeq ($(CHAIN),ethereum) diff --git a/icons/nanos_app_apothemnetwork.gif b/icons/nanos_app_apothemnetwork.gif new file mode 100644 index 0000000..cccda60 Binary files /dev/null and b/icons/nanos_app_apothemnetwork.gif differ diff --git a/icons/nanos_app_meter.gif b/icons/nanos_app_meter.gif new file mode 100644 index 0000000..7da65b4 Binary files /dev/null and b/icons/nanos_app_meter.gif differ diff --git a/icons/nanos_app_multivac.gif b/icons/nanos_app_multivac.gif new file mode 100644 index 0000000..f8853eb Binary files /dev/null and b/icons/nanos_app_multivac.gif differ diff --git a/icons/nanos_app_tecracoin.gif b/icons/nanos_app_tecracoin.gif new file mode 100755 index 0000000..367ccf4 Binary files /dev/null and b/icons/nanos_app_tecracoin.gif differ diff --git a/icons/nanos_app_tecratestnet.gif b/icons/nanos_app_tecratestnet.gif new file mode 100755 index 0000000..367ccf4 Binary files /dev/null and b/icons/nanos_app_tecratestnet.gif differ diff --git a/icons/nanos_app_xdcnetwork.gif b/icons/nanos_app_xdcnetwork.gif new file mode 100644 index 0000000..cccda60 Binary files /dev/null and b/icons/nanos_app_xdcnetwork.gif differ diff --git a/icons/nanox_app_apothemnetwork.gif b/icons/nanox_app_apothemnetwork.gif new file mode 100644 index 0000000..387354d Binary files /dev/null and b/icons/nanox_app_apothemnetwork.gif differ diff --git a/icons/nanox_app_meter.gif b/icons/nanox_app_meter.gif new file mode 100644 index 0000000..d67c25f Binary files /dev/null and b/icons/nanox_app_meter.gif differ diff --git a/icons/nanox_app_multivac.gif b/icons/nanox_app_multivac.gif new file mode 100644 index 0000000..77bf0f0 Binary files /dev/null and b/icons/nanox_app_multivac.gif differ diff --git a/icons/nanox_app_tecracoin.gif b/icons/nanox_app_tecracoin.gif new file mode 100755 index 0000000..596fa38 Binary files /dev/null and b/icons/nanox_app_tecracoin.gif differ diff --git a/icons/nanox_app_tecratestnet.gif b/icons/nanox_app_tecratestnet.gif new file mode 100755 index 0000000..596fa38 Binary files /dev/null and b/icons/nanox_app_tecratestnet.gif differ diff --git a/icons/nanox_app_xdcnetwork.gif b/icons/nanox_app_xdcnetwork.gif new file mode 100644 index 0000000..387354d Binary files /dev/null and b/icons/nanox_app_xdcnetwork.gif differ diff --git a/makefile_conf/chain/apothemnetwork.mk b/makefile_conf/chain/apothemnetwork.mk new file mode 100644 index 0000000..23816b5 --- /dev/null +++ b/makefile_conf/chain/apothemnetwork.mk @@ -0,0 +1,3 @@ +APP_LOAD_PARAMS += --path "44'/550'" +DEFINES += CHAINID_UPCASE=\"APOTHEMNETWORK\" CHAINID_COINNAME=\"TXDC\" CHAIN_KIND=CHAIN_KIND_APOTHEMNETWORK CHAIN_ID=51 +APPNAME = "ApothemNetwork" diff --git a/makefile_conf/chain/meter.mk b/makefile_conf/chain/meter.mk new file mode 100644 index 0000000..fcf2f36 --- /dev/null +++ b/makefile_conf/chain/meter.mk @@ -0,0 +1,3 @@ +APP_LOAD_PARAMS += --path "44'/60'" +DEFINES += CHAINID_UPCASE=\"METER\" CHAINID_COINNAME=\"MTR\" CHAIN_KIND=CHAIN_KIND_METER CHAIN_ID=82 +APPNAME = "Meter" \ No newline at end of file diff --git a/makefile_conf/chain/multivac.mk b/makefile_conf/chain/multivac.mk new file mode 100644 index 0000000..043299b --- /dev/null +++ b/makefile_conf/chain/multivac.mk @@ -0,0 +1,3 @@ +APP_LOAD_PARAMS += --path "44'/60'" +DEFINES += CHAINID_UPCASE=\"MULTIVAC\" CHAINID_COINNAME=\"MTV\" CHAIN_KIND=CHAIN_KIND_MULTIVAC CHAIN_ID=62621 +APPNAME = "MultiVAC" diff --git a/makefile_conf/chain/tecracoin.mk b/makefile_conf/chain/tecracoin.mk new file mode 100644 index 0000000..e51df37 --- /dev/null +++ b/makefile_conf/chain/tecracoin.mk @@ -0,0 +1,3 @@ +APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'" +DEFINES += CHAINID_UPCASE=\"TECRA\" CHAINID_COINNAME=\"TCR\" CHAIN_KIND=CHAIN_KIND_TECRA CHAIN_ID=20531812 +APPNAME = "TecraCoin" \ No newline at end of file diff --git a/makefile_conf/chain/tecratestnet.mk b/makefile_conf/chain/tecratestnet.mk new file mode 100644 index 0000000..8091b89 --- /dev/null +++ b/makefile_conf/chain/tecratestnet.mk @@ -0,0 +1,3 @@ +APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'" +DEFINES += CHAINID_UPCASE=\"TECRATESTNET\" CHAINID_COINNAME=\"TCR\" CHAIN_KIND=CHAIN_KIND_TECRA CHAIN_ID=20531811 +APPNAME = "TecraTestnet" \ No newline at end of file diff --git a/makefile_conf/chain/xdcnetwork.mk b/makefile_conf/chain/xdcnetwork.mk new file mode 100644 index 0000000..0bea527 --- /dev/null +++ b/makefile_conf/chain/xdcnetwork.mk @@ -0,0 +1,3 @@ +APP_LOAD_PARAMS += --path "44'/550'" +DEFINES += CHAINID_UPCASE=\"XDCNETWORK\" CHAINID_COINNAME=\"XDC\" CHAIN_KIND=CHAIN_KIND_XDCNETWORK CHAIN_ID=50 +APPNAME = "XDC Network" \ No newline at end of file diff --git a/src/chainConfig.h b/src/chainConfig.h index 155e335..ab91aa6 100644 --- a/src/chainConfig.h +++ b/src/chainConfig.h @@ -67,7 +67,12 @@ typedef enum chain_kind_e { CHAIN_KIND_OKC, CHAIN_KIND_CUBE, CHAIN_KIND_SHIDEN, - CHAIN_KIND_ASTAR + CHAIN_KIND_ASTAR, + CHAIN_KIND_XDCNETWORK, + CHAIN_KIND_METER, + CHAIN_KIND_MULTIVAC, + CHAIN_KIND_TECRA, + CHAIN_KIND_APOTHEMNETWORK } chain_kind_t; typedef struct chain_config_s { diff --git a/src/common_ui.h b/src/common_ui.h new file mode 100644 index 0000000..9b65600 --- /dev/null +++ b/src/common_ui.h @@ -0,0 +1,24 @@ +#ifndef _COMMON_UI_H_ +#define _COMMON_UI_H_ + +#include + +void ui_idle(void); +void ui_warning_contract_data(void); +void ui_display_public_eth2(void); +void ui_display_privacy_public_key(void); +void ui_display_privacy_shared_secret(void); +void ui_display_public_key(void); +void ui_display_sign(void); +void ui_sign_712_v0(void); +void ui_display_stark_public(void); +void ui_confirm_selector(void); +void ui_confirm_parameter(void); +void ui_stark_limit_order(void); +void ui_stark_unsafe_sign(void); +void ui_stark_transfer(bool selfTransfer, bool conditional); + +#include "ui_callbacks.h" +#include + +#endif // _COMMON_UI_H_ \ No newline at end of file diff --git a/src/eth_plugin_internal.c b/src/eth_plugin_internal.c index b266969..0e28ca6 100644 --- a/src/eth_plugin_internal.c +++ b/src/eth_plugin_internal.c @@ -4,6 +4,7 @@ bool erc20_plugin_available_check(void); void erc20_plugin_call(int message, void* parameters); +void compound_plugin_call(int message, void* parameters); void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) { uint8_t copy_size = MIN(dst_size, ADDRESS_LENGTH); @@ -28,6 +29,17 @@ static const uint8_t ERC20_APPROVE_SELECTOR[SELECTOR_SIZE] = {0x09, 0x5e, 0xa7, const uint8_t* const ERC20_SELECTORS[NUM_ERC20_SELECTORS] = {ERC20_TRANSFER_SELECTOR, ERC20_APPROVE_SELECTOR}; +static const uint8_t COMPOUND_REDEEM_UNDERLYING_SELECTOR[SELECTOR_SIZE] = {0x85, 0x2a, 0x12, 0xe3}; +static const uint8_t COMPOUND_REDEEM_SELECTOR[SELECTOR_SIZE] = {0xdb, 0x00, 0x6a, 0x75}; +static const uint8_t COMPOUND_MINT_SELECTOR[SELECTOR_SIZE] = {0xa0, 0x71, 0x2d, 0x68}; +static const uint8_t CETH_MINT_SELECTOR[SELECTOR_SIZE] = {0x12, 0x49, 0xc5, 0x8b}; + +const uint8_t* const COMPOUND_SELECTORS[NUM_COMPOUND_SELECTORS] = { + COMPOUND_REDEEM_UNDERLYING_SELECTOR, + COMPOUND_REDEEM_SELECTOR, + COMPOUND_MINT_SELECTOR, + CETH_MINT_SELECTOR}; + #ifdef HAVE_ETH2 static const uint8_t ETH2_DEPOSIT_SELECTOR[SELECTOR_SIZE] = {0x22, 0x89, 0x51, 0x18}; @@ -99,6 +111,12 @@ const internalEthPlugin_t INTERNAL_ETH_PLUGINS[] = { "-erc20", erc20_plugin_call}, + {NULL, + (const uint8_t**) COMPOUND_SELECTORS, + NUM_COMPOUND_SELECTORS, + "-cmpd", + compound_plugin_call}, + #ifdef HAVE_ETH2 {NULL, (const uint8_t**) ETH2_SELECTORS, NUM_ETH2_SELECTORS, "-eth2", eth2_plugin_call}, diff --git a/src/eth_plugin_internal.h b/src/eth_plugin_internal.h index 1ad8382..4d26130 100644 --- a/src/eth_plugin_internal.h +++ b/src/eth_plugin_internal.h @@ -29,6 +29,9 @@ typedef struct internalEthPlugin_t { #define NUM_ERC20_SELECTORS 2 extern const uint8_t* const ERC20_SELECTORS[NUM_ERC20_SELECTORS]; +#define NUM_COMPOUND_SELECTORS 4 +extern const uint8_t* const COMPOUND_SELECTORS[NUM_COMPOUND_SELECTORS]; + #ifdef HAVE_ETH2 #define NUM_ETH2_SELECTORS 1 diff --git a/src/eth_plugin_ui.c b/src/eth_plugin_ui.c index 681ef66..d4bdc15 100644 --- a/src/eth_plugin_ui.c +++ b/src/eth_plugin_ui.c @@ -1,8 +1,4 @@ #include "shared_context.h" -#ifdef HAVE_UX_FLOW -#include "ui_flow.h" -#endif -#include "ui_callbacks.h" #include "eth_plugin_handler.h" #include "ux.h" #include "feature_signTx.h" diff --git a/src/main.c b/src/main.c index e9c3505..f3b37bc 100644 --- a/src/main.c +++ b/src/main.c @@ -17,8 +17,7 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_callbacks.h" -#include "ui_flow.h" +#include "common_ui.h" #include "os_io_seproxyhal.h" @@ -86,24 +85,6 @@ void reset_app_context() { memset((uint8_t *) &tmpContent, 0, sizeof(tmpContent)); } -void ui_idle(void) { - // reserve a display stack slot if none yet - if (G_ux.stack_count == 0) { - ux_stack_push(); - } - ux_flow_init(0, ux_idle_flow, NULL); -} - -void ui_warning_contract_data(void) { - ux_flow_init(0, ux_warning_contract_data_flow, NULL); -} - -unsigned int io_seproxyhal_touch_exit(__attribute__((unused)) const bagl_element_t *e) { - // Go back to the dashboard - os_sched_exit(0); - return 0; // do not redraw the widget -} - void io_seproxyhal_send_status(uint32_t sw) { G_io_apdu_buffer[0] = ((sw >> 8) & 0xff); G_io_apdu_buffer[1] = (sw & 0xff); @@ -298,6 +279,21 @@ extraInfo_t *getKnownToken(uint8_t *contractAddress) { case CHAIN_KIND_ASTAR: numTokens = NUM_TOKENS_ASTAR; break; + case CHAIN_KIND_XDCNETWORK: + numTokens = NUM_TOKENS_XDCNETWORK; + break; + case CHAIN_KIND_METER: + numTokens = NUM_TOKENS_METER; + break; + case CHAIN_KIND_MULTIVAC: + numTokens = NUM_TOKENS_MULTIVAC; + break; + case CHAIN_KIND_TECRA: + numTokens = NUM_TOKENS_TECRA; + break; + case CHAIN_KIND_APOTHEMNETWORK: + numTokens = NUM_TOKENS_APOTHEMNETWORK; + break; } for (i = 0; i < numTokens; i++) { switch (chainConfig->kind) { @@ -436,6 +432,21 @@ extraInfo_t *getKnownToken(uint8_t *contractAddress) { case CHAIN_KIND_ASTAR: currentToken = (tokenDefinition_t *) PIC(&TOKENS_ASTAR[i]); break; + case CHAIN_KIND_XDCNETWORK: + currentToken = (tokenDefinition_t *) PIC(&TOKENS_XDCNETWORK[i]); + break; + case CHAIN_KIND_METER: + currentToken = (tokenDefinition_t *) PIC(&TOKENS_METER[i]); + break; + case CHAIN_KIND_MULTIVAC: + currentToken = (tokenDefinition_t *) PIC(&TOKENS_MULTIVAC[i]); + break; + case CHAIN_KIND_TECRA: + currentToken = (tokenDefinition_t *) PIC(&TOKENS_TECRA[i]); + break; + case CHAIN_KIND_APOTHEMNETWORK: + currentToken = (tokenDefinition_t *) PIC(&TOKENS_APOTHEMNETWORK[i]); + break; } if (memcmp(currentToken->address, tmpContent.txContent.destination, ADDRESS_LENGTH) == 0) { return currentToken; diff --git a/src/stark_crypto.c b/src/stark_crypto.c index 8f33a01..ca738c9 100644 --- a/src/stark_crypto.c +++ b/src/stark_crypto.c @@ -2,10 +2,11 @@ #include "shared_context.h" #include "stark_utils.h" -#include "ui_callbacks.h" #include "utils.h" #include "ethUtils.h" +extraInfo_t *getKnownToken(uint8_t *contractAddress); + static unsigned char const C_cx_Stark256_n[] = { // n: 0x0800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, diff --git a/src/tokens.c b/src/tokens.c index 44e3cb3..20ae6f8 100644 --- a/src/tokens.c +++ b/src/tokens.c @@ -212,4 +212,14 @@ const tokenDefinition_t const TOKENS_ASTAR[NUM_TOKENS_ASTAR] = {}; const tokenDefinition_t const TOKENS_SHIDEN[NUM_TOKENS_SHIDEN] = {}; +const tokenDefinition_t const TOKENS_XDCNETWORK[NUM_TOKENS_XDCNETWORK] = {}; + +const tokenDefinition_t const TOKENS_METER[NUM_TOKENS_METER] = {}; + +const tokenDefinition_t const TOKENS_MULTIVAC[NUM_TOKENS_MULTIVAC] = {}; + +const tokenDefinition_t const TOKENS_TECRA[NUM_TOKENS_TECRA] = {}; + +const tokenDefinition_t const TOKENS_APOTHEMNETWORK[NUM_TOKENS_APOTHEMNETWORK] = {}; + #endif diff --git a/src/tokens.h b/src/tokens.h index a0a8666..7aa38f6 100644 --- a/src/tokens.h +++ b/src/tokens.h @@ -110,6 +110,11 @@ static const uint8_t LEDGER_SIGNATURE_PUBLIC_KEY[] = { #define NUM_TOKENS_CUBE 0 #define NUM_TOKENS_ASTAR 0 #define NUM_TOKENS_SHIDEN 0 +#define NUM_TOKENS_XDCNETWORK 0 +#define NUM_TOKENS_METER 0 +#define NUM_TOKENS_MULTIVAC 0 +#define NUM_TOKENS_TECRA 0 +#define NUM_TOKENS_APOTHEMNETWORK 0 extern tokenDefinition_t const TOKENS_AKROMA[NUM_TOKENS_AKROMA]; extern tokenDefinition_t const TOKENS_ELLAISM[NUM_TOKENS_ELLAISM]; @@ -155,6 +160,11 @@ extern tokenDefinition_t const TOKENS_WETHIO[NUM_TOKENS_WETHIO]; extern tokenDefinition_t const TOKENS_CUBE[NUM_TOKENS_CUBE]; extern tokenDefinition_t const TOKENS_ASTAR[NUM_TOKENS_ASTAR]; extern tokenDefinition_t const TOKENS_SHIDEN[NUM_TOKENS_SHIDEN]; +extern tokenDefinition_t const TOKENS_XDCNETWORK[NUM_TOKENS_XDCNETWORK]; +extern tokenDefinition_t const TOKENS_METER[NUM_TOKENS_METER]; +extern tokenDefinition_t const TOKENS_MULTIVAC[NUM_TOKENS_MULTIVAC]; +extern tokenDefinition_t const TOKENS_TECRA[NUM_TOKENS_TECRA]; +extern tokenDefinition_t const TOKENS_APOTHEMNETWORK[NUM_TOKENS_APOTHEMNETWORK]; #endif /* HAVE_TOKENS_LIST */ diff --git a/src/ui_callbacks.h b/src/ui_callbacks.h index f1b1339..a2512c4 100644 --- a/src/ui_callbacks.h +++ b/src/ui_callbacks.h @@ -17,6 +17,9 @@ unsigned int io_seproxyhal_touch_data_cancel(const bagl_element_t *e); unsigned int io_seproxyhal_touch_eth2_address_ok(const bagl_element_t *e); unsigned int io_seproxyhal_touch_privacy_ok(const bagl_element_t *e); unsigned int io_seproxyhal_touch_privacy_cancel(const bagl_element_t *e); +unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(const bagl_element_t *e); +unsigned int io_seproxyhal_touch_stark_pubkey_ok(const bagl_element_t *e); +unsigned int io_seproxyhal_touch_stark_ok(const bagl_element_t *e); void ui_idle(void); void ui_warning_contract_data(void); diff --git a/src_bagl/common_ui.c b/src_bagl/common_ui.c new file mode 100644 index 0000000..57be492 --- /dev/null +++ b/src_bagl/common_ui.c @@ -0,0 +1,77 @@ +#ifdef HAVE_BAGL + +#include "common_ui.h" +#include "ux.h" +#include "ui_flow.h" + +void ui_idle(void) { + // reserve a display stack slot if none yet + if (G_ux.stack_count == 0) { + ux_stack_push(); + } + ux_flow_init(0, ux_idle_flow, NULL); +} + +void ui_warning_contract_data(void) { + ux_flow_init(0, ux_warning_contract_data_flow, NULL); +} + +void ui_display_public_eth2(void) { + ux_flow_init(0, ux_display_public_eth2_flow, NULL); +} + +void ui_display_privacy_public_key(void) { + ux_flow_init(0, ux_display_privacy_public_key_flow, NULL); +} + +void ui_display_privacy_shared_secret(void) { + ux_flow_init(0, ux_display_privacy_shared_secret_flow, NULL); +} + +void ui_display_public_key(void) { + ux_flow_init(0, ux_display_public_flow, NULL); +} + +void ui_display_sign(void) { + ux_flow_init(0, ux_sign_flow, NULL); +} + +void ui_sign_712_v0(void) { + ux_flow_init(0, ux_sign_712_v0_flow, NULL); +} + +#ifdef HAVE_STARKWARE +void ui_display_stark_public(void) { + ux_flow_init(0, ux_display_stark_public_flow, NULL); +} +void ui_stark_limit_order(void) { + ux_flow_init(0, ux_stark_limit_order_flow, NULL); +} + +void ui_stark_unsafe_sign(void) { + ux_flow_init(0, ux_stark_unsafe_sign_flow, NULL); +} + +void ui_stark_transfer(bool selfTransfer, bool conditional) { + if (selfTransfer) { + ux_flow_init( + 0, + (conditional ? ux_stark_self_transfer_conditional_flow : ux_stark_self_transfer_flow), + NULL); + } else { + ux_flow_init(0, + (conditional ? ux_stark_transfer_conditional_flow : ux_stark_transfer_flow), + NULL); + } +} +#endif // HAVE_STARKWARE + +void ui_confirm_selector(void) { + ux_flow_init(0, ux_confirm_selector_flow, NULL); +} + +void ui_confirm_parameter(void) { + ux_flow_init(0, ux_confirm_parameter_flow, NULL); +} + +#endif // HAVE_BAGL \ No newline at end of file diff --git a/src/ui_flow.c b/src_bagl/ui_flow.c similarity index 100% rename from src/ui_flow.c rename to src_bagl/ui_flow.c diff --git a/src/ui_flow.h b/src_bagl/ui_flow.h similarity index 97% rename from src/ui_flow.h rename to src_bagl/ui_flow.h index 796e4da..7b18286 100644 --- a/src/ui_flow.h +++ b/src_bagl/ui_flow.h @@ -30,6 +30,8 @@ extern const ux_flow_step_t* const ux_display_privacy_public_key_flow[]; extern const ux_flow_step_t* const ux_display_privacy_shared_secret_flow[]; +extern const ux_flow_step_t* ux_approval_tx_flow[15]; + #ifdef HAVE_STARKWARE extern const ux_flow_step_t* const ux_display_stark_public_flow[]; diff --git a/src_features/erc20_approval/ui_flow_erc20_approval.c b/src_bagl/ui_flow_erc20_approval.c similarity index 100% rename from src_features/erc20_approval/ui_flow_erc20_approval.c rename to src_bagl/ui_flow_erc20_approval.c diff --git a/src_features/getEth2PublicKey/ui_flow_getEth2PublicKey.c b/src_bagl/ui_flow_getEth2PublicKey.c similarity index 100% rename from src_features/getEth2PublicKey/ui_flow_getEth2PublicKey.c rename to src_bagl/ui_flow_getEth2PublicKey.c diff --git a/src_features/getPublicKey/ui_flow_getPublicKey.c b/src_bagl/ui_flow_getPublicKey.c similarity index 100% rename from src_features/getPublicKey/ui_flow_getPublicKey.c rename to src_bagl/ui_flow_getPublicKey.c diff --git a/src_features/performPrivacyOperation/ui_flow_performPrivacyOperation.c b/src_bagl/ui_flow_performPrivacyOperation.c similarity index 100% rename from src_features/performPrivacyOperation/ui_flow_performPrivacyOperation.c rename to src_bagl/ui_flow_performPrivacyOperation.c diff --git a/src_features/signMessage/ui_flow_signMessage.c b/src_bagl/ui_flow_signMessage.c similarity index 100% rename from src_features/signMessage/ui_flow_signMessage.c rename to src_bagl/ui_flow_signMessage.c diff --git a/src_features/signMessageEIP712_v0/ui_flow_signMessage712.c b/src_bagl/ui_flow_signMessage712.c similarity index 100% rename from src_features/signMessageEIP712_v0/ui_flow_signMessage712.c rename to src_bagl/ui_flow_signMessage712.c diff --git a/src_features/signTx/ui_flow_signTx.c b/src_bagl/ui_flow_signTx.c similarity index 99% rename from src_features/signTx/ui_flow_signTx.c rename to src_bagl/ui_flow_signTx.c index 8f6a974..6d05d6d 100644 --- a/src_features/signTx/ui_flow_signTx.c +++ b/src_bagl/ui_flow_signTx.c @@ -6,6 +6,7 @@ #include "network.h" #include "eth_plugin_handler.h" #include "ui_plugin.h" +#include "common_ui.h" // clang-format off UX_STEP_NOCB( diff --git a/src_features/stark_getPublicKey/ui_flow_stark_getPublicKey.c b/src_bagl/ui_flow_stark_getPublicKey.c similarity index 92% rename from src_features/stark_getPublicKey/ui_flow_stark_getPublicKey.c rename to src_bagl/ui_flow_stark_getPublicKey.c index 7f7b374..958874f 100644 --- a/src_features/stark_getPublicKey/ui_flow_stark_getPublicKey.c +++ b/src_bagl/ui_flow_stark_getPublicKey.c @@ -3,8 +3,6 @@ #include "shared_context.h" #include "ui_callbacks.h" -unsigned int io_seproxyhal_touch_stark_pubkey_ok(const bagl_element_t *e); - // clang-format off UX_STEP_NOCB( ux_display_stark_public_flow_1_step, diff --git a/src_features/stark_sign/ui_flow_stark_sign.c b/src_bagl/ui_flow_stark_sign.c similarity index 98% rename from src_features/stark_sign/ui_flow_stark_sign.c rename to src_bagl/ui_flow_stark_sign.c index 23c9319..df3c6a1 100644 --- a/src_features/stark_sign/ui_flow_stark_sign.c +++ b/src_bagl/ui_flow_stark_sign.c @@ -4,8 +4,6 @@ #include "ui_callbacks.h" #include "ethUtils.h" -unsigned int io_seproxyhal_touch_stark_ok(const bagl_element_t *e); - void stark_sign_display_master_account() { snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), diff --git a/src_features/stark_unsafe_sign/ui_flow_stark_unsafe_sign.c b/src_bagl/ui_flow_stark_unsafe_sign.c similarity index 100% rename from src_features/stark_unsafe_sign/ui_flow_stark_unsafe_sign.c rename to src_bagl/ui_flow_stark_unsafe_sign.c diff --git a/src_features/signTx/ui_plugin.c b/src_bagl/ui_plugin.c similarity index 100% rename from src_features/signTx/ui_plugin.c rename to src_bagl/ui_plugin.c diff --git a/src_features/signTx/ui_plugin.h b/src_bagl/ui_plugin.h similarity index 100% rename from src_features/signTx/ui_plugin.h rename to src_bagl/ui_plugin.h diff --git a/src_common/network.c b/src_common/network.c index 2d090b9..5bd29f7 100644 --- a/src_common/network.c +++ b/src_common/network.c @@ -27,7 +27,28 @@ const network_info_t NETWORK_MAPPING[] = { {.chain_id = 11297108109, .name = "Palm Network", .ticker = "PALM "}, {.chain_id = 1818, .name = "Cube", .ticker = "CUBE "}, {.chain_id = 336, .name = "Shiden", .ticker = "SDN "}, - {.chain_id = 592, .name = "Astar", .ticker = "ASTR "}}; + {.chain_id = 592, .name = "Astar", .ticker = "ASTR "}, + {.chain_id = 50, .name = "XDC", .ticker = "XDC "}, + {.chain_id = 82, .name = "Meter", .ticker = "MTR "}, + {.chain_id = 62621, .name = "Multivac", .ticker = "MTV "}, + {.chain_id = 20531812, .name = "Tecra", .ticker = "TCR "}, + {.chain_id = 20531811, .name = "TecraTestnet", .ticker = "TCR "}, + {.chain_id = 51, .name = "Apothemnetwork", .ticker = "XDC "}, + {.chain_id = 199, .name = "BTTC", .ticker = "BTT "}, + {.chain_id = 1030, .name = "Conflux", .ticker = "CFX "}, + {.chain_id = 61, .name = "Ethereum Classic", .ticker = "ETC "}, + {.chain_id = 246, .name = "EnergyWebChain", .ticker = "EWC "}, + {.chain_id = 14, .name = "Flare", .ticker = "FLR "}, + {.chain_id = 16, .name = "Flare Coston", .ticker = "FLR "}, + {.chain_id = 24, .name = "KardiaChain", .ticker = "KAI "}, + {.chain_id = 1284, .name = "Moonbeam", .ticker = "GLMR "}, + {.chain_id = 1285, .name = "Moonriver", .ticker = "MOVR "}, + {.chain_id = 66, .name = "OKXChain", .ticker = "OKT "}, + {.chain_id = 99, .name = "POA", .ticker = "POA "}, + {.chain_id = 7341, .name = "Shyft", .ticker = "SHFT "}, + {.chain_id = 19, .name = "Songbird", .ticker = "SGB "}, + {.chain_id = 73799, .name = "Volta", .ticker = "VOLTA "}, + {.chain_id = 25, .name = "Cronos", .ticker = "CRO "}}; uint64_t get_chain_id(void) { uint64_t chain_id = 0; diff --git a/src_features/getAppConfiguration/cmd_getAppConfiguration.c b/src_features/getAppConfiguration/cmd_getAppConfiguration.c index e850774..39489b7 100644 --- a/src_features/getAppConfiguration/cmd_getAppConfiguration.c +++ b/src_features/getAppConfiguration/cmd_getAppConfiguration.c @@ -1,8 +1,6 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_flow.h" - void handleGetAppConfiguration(uint8_t p1, uint8_t p2, const uint8_t *workBuffer, diff --git a/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c b/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c index 32964f3..853d834 100644 --- a/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c +++ b/src_features/getEth2PublicKey/cmd_getEth2PublicKey.c @@ -3,8 +3,9 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_flow.h" #include "feature_getEth2PublicKey.h" +#include "common_ui.h" +#include "os_io_seproxyhal.h" static const uint8_t BLS12_381_FIELD_MODULUS[] = { 0x1a, 0x01, 0x11, 0xea, 0x39, 0x7f, 0xe6, 0x9a, 0x4b, 0x1b, 0xa7, 0xb6, 0x43, 0x4b, 0xac, 0xd7, @@ -75,7 +76,7 @@ void handleGetEth2PublicKey(uint8_t p1, } #ifndef NO_CONSENT else { - ux_flow_init(0, ux_display_public_eth2_flow, NULL); + ui_display_public_eth2(); *flags |= IO_ASYNCH_REPLY; } diff --git a/src_features/getPublicKey/cmd_getPublicKey.c b/src_features/getPublicKey/cmd_getPublicKey.c index 339f0ce..07bab1d 100644 --- a/src_features/getPublicKey/cmd_getPublicKey.c +++ b/src_features/getPublicKey/cmd_getPublicKey.c @@ -1,9 +1,10 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_flow.h" #include "feature_getPublicKey.h" #include "ethUtils.h" +#include "common_ui.h" +#include "os_io_seproxyhal.h" void handleGetPublicKey(uint8_t p1, uint8_t p2, @@ -64,7 +65,7 @@ void handleGetPublicKey(uint8_t p1, "0x%.*s", 40, tmpCtx.publicKeyContext.address); - ux_flow_init(0, ux_display_public_flow, NULL); + ui_display_public_key(); *flags |= IO_ASYNCH_REPLY; } diff --git a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c index bd5933b..5cb9552 100644 --- a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c +++ b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c @@ -2,8 +2,8 @@ #include "apdu_constants.h" #include "ethUtils.h" -#include "ui_flow.h" #include "feature_performPrivacyOperation.h" +#include "common_ui.h" #define P2_PUBLIC_ENCRYPTION_KEY 0x00 #define P2_SHARED_SECRET 0x01 @@ -108,9 +108,9 @@ void handlePerformPrivacyOperation(uint8_t p1, 32, privateKeyData); if (p2 == P2_PUBLIC_ENCRYPTION_KEY) { - ux_flow_init(0, ux_display_privacy_public_key_flow, NULL); + ui_display_privacy_public_key(); } else { - ux_flow_init(0, ux_display_privacy_shared_secret_flow, NULL); + ui_display_privacy_shared_secret(); } *flags |= IO_ASYNCH_REPLY; diff --git a/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c b/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c index fa1bd19..1340966 100644 --- a/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c +++ b/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c @@ -1,7 +1,8 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_flow.h" #include "tokens.h" +#include "common_ui.h" +#include "os_io_seproxyhal.h" #ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR diff --git a/src_features/provideNFTInformation/cmd_provideNFTInfo.c b/src_features/provideNFTInformation/cmd_provideNFTInfo.c index f8b90c0..3030095 100644 --- a/src_features/provideNFTInformation/cmd_provideNFTInfo.c +++ b/src_features/provideNFTInformation/cmd_provideNFTInfo.c @@ -2,9 +2,10 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_flow.h" #include "tokens.h" #include "utils.h" +#include "common_ui.h" +#include "os_io_seproxyhal.h" #define TYPE_SIZE 1 #define VERSION_SIZE 1 diff --git a/src_features/setExternalPlugin/cmd_setExternalPlugin.c b/src_features/setExternalPlugin/cmd_setExternalPlugin.c index b5ea1ac..4a94356 100644 --- a/src_features/setExternalPlugin/cmd_setExternalPlugin.c +++ b/src_features/setExternalPlugin/cmd_setExternalPlugin.c @@ -1,9 +1,10 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_flow.h" #include "tokens.h" #include "eth_plugin_interface.h" #include "eth_plugin_internal.h" +#include "common_ui.h" +#include "os_io_seproxyhal.h" void handleSetExternalPlugin(uint8_t p1, uint8_t p2, diff --git a/src_features/setPlugin/cmd_setPlugin.c b/src_features/setPlugin/cmd_setPlugin.c index 850eed5..8cdb806 100644 --- a/src_features/setPlugin/cmd_setPlugin.c +++ b/src_features/setPlugin/cmd_setPlugin.c @@ -1,10 +1,11 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_flow.h" #include "tokens.h" #include "eth_plugin_interface.h" #include "eth_plugin_internal.h" #include "utils.h" +#include "common_ui.h" +#include "os_io_seproxyhal.h" // Supported internal plugins #define ERC721_STR "ERC721" diff --git a/src_features/signMessage/cmd_signMessage.c b/src_features/signMessage/cmd_signMessage.c index 3940c70..68e17b5 100644 --- a/src_features/signMessage/cmd_signMessage.c +++ b/src_features/signMessage/cmd_signMessage.c @@ -2,7 +2,7 @@ #include "shared_context.h" #include "apdu_constants.h" #include "utils.h" -#include "ui_flow.h" +#include "common_ui.h" static const char SIGN_MAGIC[] = "\x19" @@ -188,7 +188,7 @@ void handleSignPersonalMessage(uint8_t p1, #ifdef NO_CONSENT io_seproxyhal_touch_signMessage_ok(NULL); #else // NO_CONSENT - ux_flow_init(0, ux_sign_flow, NULL); + ui_display_sign(); #endif // NO_CONSENT *flags |= IO_ASYNCH_REPLY; diff --git a/src_features/signTx/cmd_signTx.c b/src_features/signTx/cmd_signTx.c index e14751a..d42631b 100644 --- a/src_features/signTx/cmd_signTx.c +++ b/src_features/signTx/cmd_signTx.c @@ -1,6 +1,5 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_flow.h" #include "feature_signTx.h" #include "eth_plugin_interface.h" diff --git a/src_features/signTx/logic_signTx.c b/src_features/signTx/logic_signTx.c index 774d1a1..1c41646 100644 --- a/src_features/signTx/logic_signTx.c +++ b/src_features/signTx/logic_signTx.c @@ -1,7 +1,5 @@ #include "shared_context.h" #include "utils.h" -#include "ui_callbacks.h" -#include "ui_flow.h" #include "feature_signTx.h" #ifdef HAVE_STARKWARE #include "stark_utils.h" @@ -9,6 +7,8 @@ #include "eth_plugin_handler.h" #include "network.h" #include "ethUtils.h" +#include "common_ui.h" +#include "ui_callbacks.h" #define ERR_SILENT_MODE_CHECK_FAILED 0x6001 @@ -144,7 +144,7 @@ customStatus_e customProcessor(txContext_t *context) { dataContext.tokenContext.fieldOffset = 0; if (fieldPos == 0) { array_hexstr(strings.tmp.tmp, dataContext.tokenContext.data, 4); - ux_flow_init(0, ux_confirm_selector_flow, NULL); + ui_confirm_selector(); } else { uint32_t offset = 0; uint32_t i; @@ -159,7 +159,7 @@ customStatus_e customProcessor(txContext_t *context) { strings.tmp.tmp[offset++] = ':'; } } - ux_flow_init(0, ux_confirm_parameter_flow, NULL); + ui_confirm_parameter(); } } else { return CUSTOM_HANDLED; diff --git a/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c b/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c index 4ec975c..7603188 100644 --- a/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c +++ b/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c @@ -4,7 +4,8 @@ #include "apdu_constants.h" #include "stark_utils.h" #include "feature_stark_getPublicKey.h" -#include "ui_flow.h" +#include "common_ui.h" +#include "os_io_seproxyhal.h" void handleStarkwareGetPublicKey(uint8_t p1, uint8_t p2, @@ -55,7 +56,7 @@ void handleStarkwareGetPublicKey(uint8_t p1, "0x%.*H", 32, tmpCtx.publicKeyContext.publicKey.W + 1); - ux_flow_init(0, ux_display_stark_public_flow, NULL); + ui_display_stark_public(); *flags |= IO_ASYNCH_REPLY; } diff --git a/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c b/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c index 5f91945..1755c93 100644 --- a/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c +++ b/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c @@ -2,8 +2,8 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ui_flow.h" #include "ethUtils.h" +#include "common_ui.h" void handleStarkwareProvideQuantum(uint8_t p1, __attribute__((unused)) uint8_t p2, diff --git a/src_features/stark_sign/cmd_stark_sign.c b/src_features/stark_sign/cmd_stark_sign.c index 2021176..311d9d7 100644 --- a/src_features/stark_sign/cmd_stark_sign.c +++ b/src_features/stark_sign/cmd_stark_sign.c @@ -3,10 +3,10 @@ #include "shared_context.h" #include "apdu_constants.h" #include "stark_utils.h" -#include "ui_flow.h" #include "poorstream.h" -#include "ui_callbacks.h" #include "ethUtils.h" +#include "common_ui.h" +#include "os_io_seproxyhal.h" #define U8BE(buf, off) \ (uint64_t)((((uint64_t) U4BE(buf, off)) << 32) | (((uint64_t) U4BE(buf, off + 4)) & 0xFFFFFFFF)) @@ -249,20 +249,9 @@ void handleStarkwareSignMessage(uint8_t p1, } } if (order) { - ux_flow_init(0, ux_stark_limit_order_flow, NULL); + ui_stark_limit_order(); } else { - if (selfTransfer) { - ux_flow_init( - 0, - (dataContext.starkContext.conditional ? ux_stark_self_transfer_conditional_flow - : ux_stark_self_transfer_flow), - NULL); - } else { - ux_flow_init(0, - (dataContext.starkContext.conditional ? ux_stark_transfer_conditional_flow - : ux_stark_transfer_flow), - NULL); - } + ui_stark_transfer(selfTransfer, dataContext.starkContext.conditional); } *flags |= IO_ASYNCH_REPLY; diff --git a/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c b/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c index 6067648..314fb22 100644 --- a/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c +++ b/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c @@ -3,8 +3,8 @@ #include "shared_context.h" #include "apdu_constants.h" #include "stark_utils.h" -#include "ui_flow.h" -#include "ui_callbacks.h" +#include "common_ui.h" +#include "os_io_seproxyhal.h" void handleStarkwareUnsafeSign(uint8_t p1, uint8_t p2, @@ -47,7 +47,7 @@ void handleStarkwareUnsafeSign(uint8_t p1, explicit_bzero(privateKeyData, sizeof(privateKeyData)); io_seproxyhal_io_heartbeat(); memmove(dataContext.starkContext.w1, publicKey.W + 1, 32); - ux_flow_init(0, ux_stark_unsafe_sign_flow, NULL); + ui_stark_unsafe_sign(); *flags |= IO_ASYNCH_REPLY; } diff --git a/src_plugins/compound/compound_plugin.c b/src_plugins/compound/compound_plugin.c new file mode 100644 index 0000000..cbb68dd --- /dev/null +++ b/src_plugins/compound/compound_plugin.c @@ -0,0 +1,243 @@ +#include +#include "eth_plugin_interface.h" +#include "shared_context.h" // TODO : rewrite as independant code +#include "eth_plugin_internal.h" // TODO : rewrite as independant code +#include "utils.h" +#include "ethUtils.h" + +typedef enum { + COMPOUND_REDEEM_UNDERLYING = 0, + COMPOUND_REDEEM, + COMPOUND_MINT, + CETH_MINT +} compoundSelector_t; + +static const uint8_t COMPOUND_EXPECTED_DATA_SIZE[] = { + 4 + 32, + 4 + 32, + 4 + 32, + 4, +}; + +// redeemUnderlying : redeemAmount (32) +// redeem underlying token +// redeem : redeemTokens (32) +// redeem Ctoken +// mint : mintAmount (32) +// lend some token +// mint : +// lend some Ether + +typedef struct compound_parameters_t { + uint8_t selectorIndex; + uint8_t amount[32]; + char ticker_1[MAX_TICKER_LEN]; + uint8_t decimals; +} compound_parameters_t; + +typedef struct underlying_asset_decimals_t { + char c_ticker[MAX_TICKER_LEN]; + uint8_t decimals; +} underlying_asset_decimals_t; + +/* Sadly, we don't have the information about the underlying asset's decimals, which can differ from +the cToken decimals. Therefore, we hardcode a binding table. If Compound adds a lot of token in the +future, we will have to move to a CAL based architecture instead, as this one doesn't scale well.*/ +#define NUM_COMPOUND_BINDINGS 9 +const underlying_asset_decimals_t UNDERLYING_ASSET_DECIMALS[NUM_COMPOUND_BINDINGS] = { + {"cDAI", 18}, + {"CETH", 18}, + {"CUSDC", 6}, + {"CZRX", 18}, + {"CUSDT", 6}, + {"CBTC", 8}, + {"CBAT", 18}, + {"CREP", 18}, + {"cSAI", 18}, +}; + +bool get_underlying_asset_decimals(char *compound_ticker, uint8_t *out_decimals) { + for (size_t i = 0; i < NUM_COMPOUND_BINDINGS; i++) { + underlying_asset_decimals_t *binding = + (underlying_asset_decimals_t *) PIC(&UNDERLYING_ASSET_DECIMALS[i]); + if (strncmp(binding->c_ticker, + compound_ticker, + strnlen(binding->c_ticker, MAX_TICKER_LEN)) == 0) { + *out_decimals = binding->decimals; + return true; + } + } + return false; +} + +void compound_plugin_call(int message, void *parameters) { + switch (message) { + case ETH_PLUGIN_INIT_CONTRACT: { + ethPluginInitContract_t *msg = (ethPluginInitContract_t *) parameters; + compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext; + size_t i; + for (i = 0; i < NUM_COMPOUND_SELECTORS; i++) { + if (memcmp((uint8_t *) PIC(COMPOUND_SELECTORS[i]), msg->selector, SELECTOR_SIZE) == + 0) { + context->selectorIndex = i; + break; + } + } + // enforce that ETH amount should be 0, except in ceth.mint case + if (!allzeroes(msg->pluginSharedRO->txContent->value.value, 32)) { + if (context->selectorIndex != CETH_MINT) { + PRINTF("Eth amount is not zero and token minted is not CETH!\n"); + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } + } + if (i == NUM_COMPOUND_SELECTORS) { + PRINTF("Unknown selector %.*H\n", SELECTOR_SIZE, msg->selector); + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } + if (msg->dataSize != COMPOUND_EXPECTED_DATA_SIZE[context->selectorIndex]) { + PRINTF("Unexpected data size for command %d expected %d got %d\n", + context->selectorIndex, + COMPOUND_EXPECTED_DATA_SIZE[context->selectorIndex], + msg->dataSize); + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } + if (context->selectorIndex == CETH_MINT) { + // ETH amount 0x1234 is stored 0x12340000...000 instead of 0x00....001234, so we + // strip the following zeroes when copying + memset(context->amount, 0, sizeof(context->amount)); + memmove(context->amount + sizeof(context->amount) - + msg->pluginSharedRO->txContent->value.length, + msg->pluginSharedRO->txContent->value.value, + msg->pluginSharedRO->txContent->value.length); + } + PRINTF("compound plugin inititialized\n"); + msg->result = ETH_PLUGIN_RESULT_OK; + } break; + + case ETH_PLUGIN_PROVIDE_PARAMETER: { + ethPluginProvideParameter_t *msg = (ethPluginProvideParameter_t *) parameters; + compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext; + PRINTF("compound plugin provide parameter %d %.*H\n", + msg->parameterOffset, + 32, + msg->parameter); + if (context->selectorIndex != CETH_MINT) { + switch (msg->parameterOffset) { + case 4: + memmove(context->amount, msg->parameter, 32); + msg->result = ETH_PLUGIN_RESULT_OK; + break; + default: + PRINTF("Unhandled parameter offset\n"); + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } + } else { + PRINTF("CETH contract expects no parameters\n"); + msg->result = ETH_PLUGIN_RESULT_ERROR; + } + } break; + + case ETH_PLUGIN_FINALIZE: { + ethPluginFinalize_t *msg = (ethPluginFinalize_t *) parameters; + PRINTF("compound plugin finalize\n"); + msg->tokenLookup1 = msg->pluginSharedRO->txContent->destination; + msg->numScreens = 2; + msg->uiType = ETH_UI_TYPE_GENERIC; + msg->result = ETH_PLUGIN_RESULT_OK; + } break; + + case ETH_PLUGIN_PROVIDE_INFO: { + ethPluginProvideInfo_t *msg = (ethPluginProvideInfo_t *) parameters; + compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext; + PRINTF("compound plugin provide token: %d\n", (msg->item1 != NULL)); + if (msg->item1 != NULL) { + strlcpy(context->ticker_1, msg->item1->token.ticker, MAX_TICKER_LEN); + switch (context->selectorIndex) { + case COMPOUND_REDEEM_UNDERLYING: + case COMPOUND_MINT: + case CETH_MINT: + msg->result = + get_underlying_asset_decimals(context->ticker_1, &context->decimals) + ? ETH_PLUGIN_RESULT_OK + : ETH_PLUGIN_RESULT_FALLBACK; + break; + + // Only case where we use the compound contract decimals + case COMPOUND_REDEEM: + context->decimals = msg->item1->token.decimals; + msg->result = ETH_PLUGIN_RESULT_OK; + break; + + default: + msg->result = ETH_PLUGIN_RESULT_FALLBACK; + break; + } + } else { + msg->result = ETH_PLUGIN_RESULT_FALLBACK; + } + } break; + + case ETH_PLUGIN_QUERY_CONTRACT_ID: { + ethQueryContractID_t *msg = (ethQueryContractID_t *) parameters; + compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext; + strlcpy(msg->name, "Type", msg->nameLength); + switch (context->selectorIndex) { + case COMPOUND_REDEEM_UNDERLYING: + case COMPOUND_REDEEM: + strlcpy(msg->version, "Redeem", msg->versionLength); + break; + + case COMPOUND_MINT: + case CETH_MINT: + strlcpy(msg->version, "Lend", msg->versionLength); + break; + + default: + break; + } + strlcat(msg->version, " Assets", msg->versionLength); + msg->result = ETH_PLUGIN_RESULT_OK; + } break; + + case ETH_PLUGIN_QUERY_CONTRACT_UI: { + ethQueryContractUI_t *msg = (ethQueryContractUI_t *) parameters; + compound_parameters_t *context = (compound_parameters_t *) msg->pluginContext; + switch (msg->screenIndex) { + case 0: { + strlcpy(msg->title, "Amount", msg->titleLength); + char *ticker_ptr = context->ticker_1; + /* skip "c" in front of cToken unless we use "redeem", as + redeem is the only operation dealing with a cToken amount */ + if (context->selectorIndex != COMPOUND_REDEEM) { + ticker_ptr++; + } + amountToString(context->amount, + sizeof(context->amount), + context->decimals, + ticker_ptr, + msg->msg, + 100); + msg->result = ETH_PLUGIN_RESULT_OK; + } break; + + case 1: + strlcpy(msg->title, "Contract", msg->titleLength); + strlcpy(msg->msg, "Compound ", msg->msgLength); + strlcat(msg->msg, + context->ticker_1 + 1, + msg->msgLength); // remove the 'c' char at beginning of compound ticker + msg->result = ETH_PLUGIN_RESULT_OK; + break; + default: + break; + } + } break; + + default: + PRINTF("Unhandled message %d\n", message); + } +}