Merge remote-tracking branch 'origin/develop' into HEAD
1
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)
|
||||
|
||||
BIN
icons/nanos_app_apothemnetwork.gif
Normal file
|
After Width: | Height: | Size: 67 B |
BIN
icons/nanos_app_meter.gif
Normal file
|
After Width: | Height: | Size: 84 B |
BIN
icons/nanos_app_multivac.gif
Normal file
|
After Width: | Height: | Size: 75 B |
BIN
icons/nanos_app_tecracoin.gif
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/nanos_app_tecratestnet.gif
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/nanos_app_xdcnetwork.gif
Normal file
|
After Width: | Height: | Size: 67 B |
BIN
icons/nanox_app_apothemnetwork.gif
Normal file
|
After Width: | Height: | Size: 65 B |
BIN
icons/nanox_app_meter.gif
Normal file
|
After Width: | Height: | Size: 79 B |
BIN
icons/nanox_app_multivac.gif
Normal file
|
After Width: | Height: | Size: 74 B |
BIN
icons/nanox_app_tecracoin.gif
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/nanox_app_tecratestnet.gif
Executable file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/nanox_app_xdcnetwork.gif
Normal file
|
After Width: | Height: | Size: 65 B |
3
makefile_conf/chain/apothemnetwork.mk
Normal file
@@ -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"
|
||||
3
makefile_conf/chain/meter.mk
Normal file
@@ -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"
|
||||
3
makefile_conf/chain/multivac.mk
Normal file
@@ -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"
|
||||
3
makefile_conf/chain/tecracoin.mk
Normal file
@@ -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"
|
||||
3
makefile_conf/chain/tecratestnet.mk
Normal file
@@ -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"
|
||||
3
makefile_conf/chain/xdcnetwork.mk
Normal file
@@ -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"
|
||||
@@ -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 {
|
||||
|
||||
24
src/common_ui.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef _COMMON_UI_H_
|
||||
#define _COMMON_UI_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
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 <string.h>
|
||||
|
||||
#endif // _COMMON_UI_H_
|
||||
@@ -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},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
51
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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
10
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
|
||||
|
||||
10
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 */
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
77
src_bagl/common_ui.c
Normal file
@@ -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
|
||||
@@ -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[];
|
||||
@@ -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(
|
||||
@@ -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,
|
||||
@@ -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),
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
243
src_plugins/compound/compound_plugin.c
Normal file
@@ -0,0 +1,243 @@
|
||||
#include <string.h>
|
||||
#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);
|
||||
}
|
||||
}
|
||||