Add Swap feature
This commit is contained in:
@@ -56,12 +56,12 @@ typedef enum chain_kind_e {
|
||||
} chain_kind_t;
|
||||
|
||||
typedef struct chain_config_s {
|
||||
const char* coinName; // ticker
|
||||
char coinName[10]; // ticker
|
||||
uint32_t chainId;
|
||||
chain_kind_t kind;
|
||||
#ifdef TARGET_BLUE
|
||||
const char* header_text;
|
||||
unsigned int color_header;
|
||||
char header_text[13];
|
||||
unsigned int color_dashboard;
|
||||
#endif // TARGET_BLUE
|
||||
|
||||
|
||||
70
src/handle_check_address.c
Normal file
70
src/handle_check_address.c
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "handle_check_address.h"
|
||||
#include "os.h"
|
||||
#include "shared_context.h"
|
||||
#include "ethUtils.h"
|
||||
#include "string.h"
|
||||
|
||||
#define ZERO(x) os_memset(x, 0, sizeof(x))
|
||||
|
||||
void handle_check_address(check_address_parameters_t* params, chain_config_t* chain_config) {
|
||||
PRINTF("Params on the address %d\n",(unsigned int)params);
|
||||
PRINTF("Address to check %s\n",params->address_to_check);
|
||||
PRINTF("Inside handle_check_address\n");
|
||||
params->result = 0;
|
||||
if (params->address_to_check == 0) {
|
||||
PRINTF("Address to check == 0\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t i;
|
||||
uint8_t *bip32_path_ptr = params->address_parameters;
|
||||
uint8_t bip32PathLength = *(bip32_path_ptr++);
|
||||
cx_sha3_t local_sha3;
|
||||
|
||||
// Common memory is used for locals that are not used concurrently
|
||||
union group1
|
||||
{
|
||||
uint32_t bip32Path[MAX_BIP32_PATH];
|
||||
cx_ecfp_private_key_t privateKey;
|
||||
char address[51];
|
||||
} locals_union1;
|
||||
union group2
|
||||
{
|
||||
uint8_t privateKeyData[32];
|
||||
cx_ecfp_public_key_t publicKey;
|
||||
} locals_union2;
|
||||
|
||||
|
||||
if ((bip32PathLength < 0x01) ||
|
||||
(bip32PathLength > MAX_BIP32_PATH) ||
|
||||
(bip32PathLength*4 != params->address_parameters_length - 1)) {
|
||||
PRINTF("Invalid path\n");
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < bip32PathLength; i++) {
|
||||
locals_union1.bip32Path[i] = U4BE(bip32_path_ptr, 0);
|
||||
bip32_path_ptr += 4;
|
||||
}
|
||||
os_perso_derive_node_bip32(CX_CURVE_256K1, locals_union1.bip32Path, bip32PathLength, locals_union2.privateKeyData, NULL);
|
||||
ZERO(&locals_union1);
|
||||
cx_ecfp_init_private_key(CX_CURVE_256K1, locals_union2.privateKeyData, 32, &locals_union1.privateKey);
|
||||
ZERO(&locals_union2);
|
||||
cx_ecfp_generate_pair(CX_CURVE_256K1, &locals_union2.publicKey, &locals_union1.privateKey, 1);
|
||||
ZERO(&locals_union1);
|
||||
getEthAddressStringFromKey(&locals_union2.publicKey, (uint8_t*)locals_union1.address, &local_sha3, chain_config);
|
||||
ZERO(&locals_union2);
|
||||
|
||||
uint8_t offset_0x = 0;
|
||||
if(memcmp(params->address_to_check, "0x", 2) == 0){
|
||||
offset_0x = 2;
|
||||
}
|
||||
|
||||
if ((strlen(locals_union1.address) != strlen(params->address_to_check + offset_0x)) ||
|
||||
os_memcmp(locals_union1.address, params->address_to_check + offset_0x, strlen(locals_union1.address)) != 0) {
|
||||
os_memcpy(params->address_to_check, locals_union1.address, 45);
|
||||
PRINTF("Addresses doesn't match\n");
|
||||
return;
|
||||
}
|
||||
PRINTF("Addresses match\n");
|
||||
params->result = 1;
|
||||
}
|
||||
9
src/handle_check_address.h
Normal file
9
src/handle_check_address.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef _HANDLE_CHECK_ADDRESS_H_
|
||||
#define _HANDLE_CHECK_ADDRESS_H_
|
||||
|
||||
#include "swap_lib_calls.h"
|
||||
#include "chainConfig.h"
|
||||
|
||||
void handle_check_address(check_address_parameters_t* check_address_params, chain_config_t* chain_config);
|
||||
|
||||
#endif // _HANDLE_CHECK_ADDRESS_H_
|
||||
33
src/handle_get_printable_amount.c
Normal file
33
src/handle_get_printable_amount.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "handle_get_printable_amount.h"
|
||||
#include "shared_context.h"
|
||||
#include "ethUtils.h"
|
||||
#include "utils.h"
|
||||
#include "uint256.h"
|
||||
#include "string.h"
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
void handle_get_printable_amount( get_printable_amount_parameters_t* params, chain_config_t *config) {
|
||||
uint8_t decimals;
|
||||
char ticker[MAX_TICKER_LEN];
|
||||
os_memset(params->printable_amount, 0, sizeof(params->printable_amount));
|
||||
if (params->amount_length > 32) {
|
||||
PRINTF("Amount is too big, 32 bytes max but buffer has %u bytes", params->amount_length);
|
||||
os_lib_end();
|
||||
}
|
||||
if(!parse_swap_config(params->coin_configuration, params->coin_configuration_length, ticker, &decimals)){
|
||||
PRINTF("Error while parsing config\n");
|
||||
os_lib_end();
|
||||
}
|
||||
|
||||
// If the amount is a fee, its value is nominated in ETH even if we're doing an ERC20 swap
|
||||
if(params->is_fee){
|
||||
uint8_t ticker_len = strnlen(config->coinName, sizeof(config->coinName));
|
||||
memcpy(ticker, config->coinName, ticker_len);
|
||||
ticker[ticker_len] = ' ';
|
||||
ticker[ticker_len+1] = '\0';
|
||||
decimals = WEI_TO_ETHER;
|
||||
}
|
||||
|
||||
amountToString(params->amount, params->amount_length, decimals, ticker, params->printable_amount, sizeof(params->printable_amount));
|
||||
}
|
||||
9
src/handle_get_printable_amount.h
Normal file
9
src/handle_get_printable_amount.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef _HANDLE_GET_PRINTABLE_AMOUNT_H_
|
||||
#define _HANDLE_GET_PRINTABLE_AMOUNT_H_
|
||||
|
||||
#include "swap_lib_calls.h"
|
||||
#include "chainConfig.h"
|
||||
|
||||
void handle_get_printable_amount(get_printable_amount_parameters_t* get_printable_amount_params, chain_config_t *config);
|
||||
|
||||
#endif // _HANDLE_GET_PRINTABLE_AMOUNT_H_
|
||||
67
src/handle_swap_sign_transaction.c
Normal file
67
src/handle_swap_sign_transaction.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "handle_swap_sign_transaction.h"
|
||||
#include "usbd_core.h"
|
||||
#include "ux.h"
|
||||
#include "shared_context.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
void copy_transaction_parameters(create_transaction_parameters_t* sign_transaction_params, chain_config_t *config) {
|
||||
// first copy parameters to stack, and then to global data.
|
||||
// We need this "trick" as the input data position can overlap with app-ethereum globals
|
||||
txStringProperties_t stack_data;
|
||||
memset(&stack_data, 0, sizeof(stack_data));
|
||||
strncpy(stack_data.fullAddress, sign_transaction_params->destination_address, sizeof(stack_data.fullAddress));
|
||||
if ((stack_data.fullAddress[sizeof(stack_data.fullAddress) - 1] != '\0') ||
|
||||
(sign_transaction_params->amount_length > 8) ||
|
||||
(sign_transaction_params->fee_amount_length > 8)) {
|
||||
os_lib_end();
|
||||
}
|
||||
|
||||
uint8_t decimals;
|
||||
char ticker[MAX_TICKER_LEN];
|
||||
if(!parse_swap_config(sign_transaction_params->coin_configuration, sign_transaction_params->coin_configuration_length, ticker, &decimals)){
|
||||
PRINTF("Error while parsing config\n");
|
||||
os_lib_end();
|
||||
}
|
||||
amountToString(sign_transaction_params->amount, sign_transaction_params->amount_length, decimals, ticker, stack_data.fullAmount, sizeof(stack_data.fullAmount));
|
||||
|
||||
// If the amount is a fee, its value is nominated in ETH even if we're doing an ERC20 swap
|
||||
strcpy(ticker, config->coinName);
|
||||
decimals = WEI_TO_ETHER;
|
||||
amountToString(sign_transaction_params->fee_amount, sign_transaction_params->fee_amount_length, decimals, ticker, stack_data.maxFee, sizeof(stack_data.maxFee));
|
||||
|
||||
memcpy(&strings.common, &stack_data, sizeof(stack_data));
|
||||
}
|
||||
|
||||
void handle_swap_sign_transaction(create_transaction_parameters_t* sign_transaction_params, chain_config_t *config) {
|
||||
copy_transaction_parameters(sign_transaction_params, config);
|
||||
chainConfig = config;
|
||||
reset_app_context();
|
||||
called_from_swap = true;
|
||||
io_seproxyhal_init();
|
||||
|
||||
if (N_storage.initialized != 0x01) {
|
||||
internalStorage_t storage;
|
||||
storage.dataAllowed = 0x00;
|
||||
storage.contractDetails = 0x00;
|
||||
storage.initialized = 0x01;
|
||||
nvm_write((void*)&N_storage, (void*)&storage, sizeof(internalStorage_t));
|
||||
}
|
||||
dataAllowed = N_storage.dataAllowed;
|
||||
contractDetails = N_storage.contractDetails;
|
||||
|
||||
UX_INIT();
|
||||
USB_power(0);
|
||||
USB_power(1);
|
||||
//ui_idle();
|
||||
PRINTF("USB power ON/OFF\n");
|
||||
#ifdef TARGET_NANOX
|
||||
// grab the current plane mode setting
|
||||
G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0);
|
||||
#endif // TARGET_NANOX
|
||||
#ifdef HAVE_BLE
|
||||
BLE_power(0, NULL);
|
||||
BLE_power(1, "Nano X");
|
||||
#endif // HAVE_BLE
|
||||
app_main();
|
||||
}
|
||||
9
src/handle_swap_sign_transaction.h
Normal file
9
src/handle_swap_sign_transaction.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef _HANDLE_SWAP_SIGN_TRANSACTION_H_
|
||||
#define _HANDLE_SWAP_SIGN_TRANSACTION_H_
|
||||
|
||||
#include "swap_lib_calls.h"
|
||||
#include "chainConfig.h"
|
||||
|
||||
void handle_swap_sign_transaction(create_transaction_parameters_t* get_printable_amount_params, chain_config_t *config);
|
||||
|
||||
#endif // _HANDLE_SWAP_SIGN_TRANSACTION_H_
|
||||
240
src/main.c
240
src/main.c
@@ -30,6 +30,11 @@
|
||||
#include "glyphs.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "swap_lib_calls.h"
|
||||
#include "handle_swap_sign_transaction.h"
|
||||
#include "handle_get_printable_amount.h"
|
||||
#include "handle_check_address.h"
|
||||
|
||||
#ifdef HAVE_STARKWARE
|
||||
#include "stark_crypto.h"
|
||||
#endif
|
||||
@@ -46,8 +51,7 @@ txContext_t txContext;
|
||||
tmpContent_t tmpContent;
|
||||
dataContext_t dataContext;
|
||||
strings_t strings;
|
||||
|
||||
cx_sha3_t sha3;
|
||||
cx_sha3_t global_sha3;
|
||||
|
||||
uint8_t dataAllowed;
|
||||
uint8_t contractDetails;
|
||||
@@ -57,6 +61,7 @@ char addressSummary[32];
|
||||
#endif
|
||||
bool dataPresent;
|
||||
contract_call_t contractProvisioned;
|
||||
bool called_from_swap;
|
||||
#ifdef HAVE_STARKWARE
|
||||
bool quantumSet;
|
||||
#endif
|
||||
@@ -83,13 +88,14 @@ static const char const CONTRACT_ADDRESS[] = "New contract";
|
||||
chain_config_t *chainConfig;
|
||||
|
||||
void reset_app_context() {
|
||||
PRINTF("!!RESET_APP_CONTEXT\n");
|
||||
//PRINTF("!!RESET_APP_CONTEXT\n");
|
||||
appState = APP_STATE_IDLE;
|
||||
os_memset(tmpCtx.transactionContext.tokenSet, 0, MAX_TOKEN);
|
||||
contractProvisioned = CONTRACT_NONE;
|
||||
#ifdef HAVE_STARKWARE
|
||||
called_from_swap = false;
|
||||
#ifdef HAVE_STARKWARE
|
||||
quantumSet = false;
|
||||
#endif
|
||||
#endif
|
||||
os_memset((uint8_t*)&txContext, 0, sizeof(txContext));
|
||||
os_memset((uint8_t*)&tmpContent, 0, sizeof(tmpContent));
|
||||
}
|
||||
@@ -506,10 +512,10 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
|
||||
break;
|
||||
}
|
||||
CLOSE_TRY;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (G_io_apdu_buffer[OFFSET_CLA] != CLA) {
|
||||
THROW(0x6E00);
|
||||
@@ -579,7 +585,7 @@ void handleApdu(unsigned int *flags, unsigned int *tx) {
|
||||
END_TRY;
|
||||
}
|
||||
|
||||
void sample_main(void) {
|
||||
void app_main(void) {
|
||||
unsigned int rx = 0;
|
||||
unsigned int tx = 0;
|
||||
unsigned int flags = 0;
|
||||
@@ -611,7 +617,7 @@ void sample_main(void) {
|
||||
handleApdu(&flags, &tx);
|
||||
}
|
||||
CATCH(EXCEPTION_IO_RESET) {
|
||||
THROW(EXCEPTION_IO_RESET);
|
||||
THROW(EXCEPTION_IO_RESET);
|
||||
}
|
||||
CATCH_OTHER(e) {
|
||||
switch (e & 0xF000) {
|
||||
@@ -686,7 +692,7 @@ unsigned char io_event(unsigned char channel) {
|
||||
{
|
||||
});
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// close the event if not done previously (by a display or whatever)
|
||||
@@ -698,7 +704,7 @@ unsigned char io_event(unsigned char channel) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void app_exit(void) {
|
||||
void app_exit() {
|
||||
|
||||
BEGIN_TRY_L(exit) {
|
||||
TRY_L(exit) {
|
||||
@@ -711,65 +717,13 @@ void app_exit(void) {
|
||||
END_TRY_L(exit);
|
||||
}
|
||||
|
||||
chain_config_t const C_chain_config = {
|
||||
.coinName = CHAINID_COINNAME " ",
|
||||
.chainId = CHAIN_ID,
|
||||
.kind = CHAIN_KIND,
|
||||
#ifdef TARGET_BLUE
|
||||
.color_header = COLOR_APP,
|
||||
.color_dashboard = COLOR_APP_LIGHT,
|
||||
.header_text = CHAINID_UPCASE,
|
||||
#endif // TARGET_BLUE
|
||||
};
|
||||
|
||||
__attribute__((section(".boot"))) int main(int arg0) {
|
||||
#ifdef USE_LIB_ETHEREUM
|
||||
chain_config_t local_chainConfig;
|
||||
os_memmove(&local_chainConfig, &C_chain_config, sizeof(chain_config_t));
|
||||
unsigned int libcall_params[3];
|
||||
unsigned char coinName[sizeof(CHAINID_COINNAME)];
|
||||
strcpy(coinName, CHAINID_COINNAME);
|
||||
#ifdef TARGET_BLUE
|
||||
unsigned char coinNameUP[sizeof(CHAINID_UPCASE)];
|
||||
strcpy(coinNameUP, CHAINID_UPCASE);
|
||||
local_chainConfig.header_text = coinNameUP;
|
||||
#endif // TARGET_BLUE
|
||||
local_chainConfig.coinName = coinName;
|
||||
BEGIN_TRY {
|
||||
TRY {
|
||||
// ensure syscall will accept us
|
||||
check_api_level(CX_COMPAT_APILEVEL);
|
||||
// delegate to Ethereum app/lib
|
||||
libcall_params[0] = "Ethereum";
|
||||
libcall_params[1] = 0x100; // use the Init call, as we won't exit
|
||||
libcall_params[2] = &local_chainConfig;
|
||||
os_lib_call(&libcall_params);
|
||||
}
|
||||
FINALLY {
|
||||
app_exit();
|
||||
}
|
||||
}
|
||||
END_TRY;
|
||||
#else
|
||||
// exit critical section
|
||||
__asm volatile("cpsie i");
|
||||
|
||||
if (arg0) {
|
||||
if (((unsigned int *)arg0)[0] != 0x100) {
|
||||
os_lib_throw(INVALID_PARAMETER);
|
||||
}
|
||||
chainConfig = (chain_config_t *)((unsigned int *)arg0)[1];
|
||||
}
|
||||
else {
|
||||
chainConfig = (chain_config_t *)PIC(&C_chain_config);
|
||||
}
|
||||
void coin_main_with_config(chain_config_t *config) {
|
||||
|
||||
chainConfig = config;
|
||||
reset_app_context();
|
||||
tmpCtx.transactionContext.currentTokenIndex = 0;
|
||||
|
||||
// ensure exception will work as planned
|
||||
os_boot();
|
||||
|
||||
for (;;) {
|
||||
UX_INIT();
|
||||
|
||||
@@ -783,11 +737,11 @@ __attribute__((section(".boot"))) int main(int arg0) {
|
||||
#endif // TARGET_NANOX
|
||||
|
||||
if (N_storage.initialized != 0x01) {
|
||||
internalStorage_t storage;
|
||||
storage.dataAllowed = 0x00;
|
||||
storage.contractDetails = 0x00;
|
||||
storage.initialized = 0x01;
|
||||
nvm_write((void*)&N_storage, (void*)&storage, sizeof(internalStorage_t));
|
||||
internalStorage_t storage;
|
||||
storage.dataAllowed = 0x00;
|
||||
storage.contractDetails = 0x00;
|
||||
storage.initialized = 0x01;
|
||||
nvm_write((void*)&N_storage, (void*)&storage, sizeof(internalStorage_t));
|
||||
}
|
||||
dataAllowed = N_storage.dataAllowed;
|
||||
contractDetails = N_storage.contractDetails;
|
||||
@@ -801,28 +755,156 @@ __attribute__((section(".boot"))) int main(int arg0) {
|
||||
BLE_power(0, NULL);
|
||||
BLE_power(1, "Nano X");
|
||||
#endif // HAVE_BLE
|
||||
#if defined(TARGET_BLUE)
|
||||
|
||||
#if defined(TARGET_BLUE)
|
||||
// setup the status bar colors (remembered after wards, even more if another app does not resetup after app switch)
|
||||
UX_SET_STATUS_BAR_COLOR(0xFFFFFF, chainConfig->color_header);
|
||||
#endif // #if defined(TARGET_BLUE)
|
||||
#endif // #if defined(TARGET_BLUE)
|
||||
|
||||
sample_main();
|
||||
app_main();
|
||||
}
|
||||
CATCH(EXCEPTION_IO_RESET) {
|
||||
// reset IO and UX before continuing
|
||||
CLOSE_TRY;
|
||||
continue;
|
||||
// reset IO and UX before continuing
|
||||
CLOSE_TRY;
|
||||
continue;
|
||||
}
|
||||
CATCH_ALL {
|
||||
CLOSE_TRY;
|
||||
break;
|
||||
CLOSE_TRY;
|
||||
break;
|
||||
}
|
||||
FINALLY {
|
||||
}
|
||||
}
|
||||
END_TRY;
|
||||
}
|
||||
app_exit();
|
||||
app_exit();
|
||||
}
|
||||
|
||||
void init_coin_config(chain_config_t *coin_config) {
|
||||
os_memset(coin_config, 0, sizeof(chain_config_t));
|
||||
strcpy(coin_config->coinName, CHAINID_COINNAME " ");
|
||||
coin_config->chainId = CHAIN_ID;
|
||||
coin_config->kind = CHAIN_KIND;
|
||||
#ifdef TARGET_BLUE
|
||||
coin_config.color_header = COLOR_APP;
|
||||
coin_config.color_dashboard = COLOR_APP_LIGHT;
|
||||
strcpy(coin_config->header_text, CHAINID_UPCASE);
|
||||
#endif // TARGET_BLUE
|
||||
}
|
||||
|
||||
void coin_main() {
|
||||
chain_config_t coin_config;
|
||||
init_coin_config(&coin_config);
|
||||
coin_main_with_config(&coin_config);
|
||||
}
|
||||
|
||||
void library_main_with_config(chain_config_t *config, unsigned int command, unsigned int* call_parameters) {
|
||||
BEGIN_TRY {
|
||||
TRY {
|
||||
check_api_level(CX_COMPAT_APILEVEL);
|
||||
PRINTF("Inside a library \n");
|
||||
switch (command) {
|
||||
case CHECK_ADDRESS:
|
||||
handle_check_address((check_address_parameters_t*)call_parameters, config);
|
||||
break;
|
||||
case SIGN_TRANSACTION:
|
||||
handle_swap_sign_transaction((create_transaction_parameters_t*)call_parameters, config);
|
||||
break;
|
||||
case GET_PRINTABLE_AMOUNT:
|
||||
handle_get_printable_amount((get_printable_amount_parameters_t*)call_parameters, config);
|
||||
break;
|
||||
}
|
||||
os_lib_end();
|
||||
}
|
||||
FINALLY {}
|
||||
}
|
||||
END_TRY;
|
||||
}
|
||||
|
||||
void library_main(unsigned int call_id, unsigned int* call_parameters) {
|
||||
chain_config_t coin_config;
|
||||
init_coin_config(&coin_config);
|
||||
library_main_with_config(&coin_config, call_id, call_parameters);
|
||||
}
|
||||
|
||||
__attribute__((section(".boot"))) int main(int arg0) {
|
||||
#ifdef USE_LIB_ETHEREUM
|
||||
BEGIN_TRY {
|
||||
TRY {
|
||||
unsigned int libcall_params[5];
|
||||
chain_config_t local_chainConfig;
|
||||
init_coin_config(&local_chainConfig);
|
||||
PRINTF("Hello from Eth-clone\n");
|
||||
check_api_level(CX_COMPAT_APILEVEL);
|
||||
// delegate to Ethereum app/lib
|
||||
libcall_params[0] = "Ethereum";
|
||||
libcall_params[1] = 0x100;
|
||||
libcall_params[2] = RUN_APPLICATION;
|
||||
libcall_params[3] = &local_chainConfig;
|
||||
libcall_params[4] = 0;
|
||||
if (arg0) {
|
||||
// call as a library
|
||||
libcall_params[2] = ((unsigned int *)arg0)[1];
|
||||
libcall_params[4] = ((unsigned int *)arg0)[3]; // library arguments
|
||||
os_lib_call(&libcall_params);
|
||||
((unsigned int *)arg0)[0] = libcall_params[1];
|
||||
os_lib_end();
|
||||
}
|
||||
else {
|
||||
// launch coin application
|
||||
libcall_params[1] = 0x100; // use the Init call, as we won't exit
|
||||
os_lib_call(&libcall_params);
|
||||
}
|
||||
}
|
||||
FINALLY {}
|
||||
}
|
||||
END_TRY;
|
||||
// no return
|
||||
#else
|
||||
// exit critical section
|
||||
__asm volatile("cpsie i");
|
||||
|
||||
// ensure exception will work as planned
|
||||
os_boot();
|
||||
|
||||
if (!arg0) {
|
||||
// called from dashboard as standalone eth app
|
||||
coin_main();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((unsigned int *)arg0)[0] != 0x100) {
|
||||
app_exit();
|
||||
return 0;
|
||||
}
|
||||
unsigned int command = ((unsigned int *)arg0)[1];
|
||||
chain_config_t * chain_config = ((unsigned int *)arg0)[2];
|
||||
switch (command) {
|
||||
case RUN_APPLICATION:
|
||||
// coin application launched from dashboard
|
||||
if (chain_config == NULL)
|
||||
app_exit();
|
||||
else
|
||||
coin_main_with_config(chain_config);
|
||||
break;
|
||||
default:
|
||||
if (chain_config == NULL)
|
||||
// Called as standalone eth library
|
||||
library_main(command, ((unsigned int *)arg0)[3]);// called as bitcoin library
|
||||
else
|
||||
// Called as a library from an altcoin
|
||||
library_main_with_config(chain_config, command, ((unsigned int *)arg0)[3]);// called as coin library
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -125,11 +125,11 @@ typedef enum {
|
||||
#endif
|
||||
} contract_call_t;
|
||||
|
||||
typedef struct strData_t {
|
||||
typedef struct txStringProperties_t {
|
||||
char fullAddress[43];
|
||||
char fullAmount[50];
|
||||
char maxFee[50];
|
||||
} strData_t;
|
||||
} txStringProperties_t;
|
||||
|
||||
typedef struct strDataTmp_t {
|
||||
char tmp[100];
|
||||
@@ -137,7 +137,7 @@ typedef struct strDataTmp_t {
|
||||
} strDataTmp_t;
|
||||
|
||||
typedef union {
|
||||
strData_t common;
|
||||
txStringProperties_t common;
|
||||
strDataTmp_t tmp;
|
||||
} strings_t;
|
||||
|
||||
@@ -148,7 +148,7 @@ extern txContext_t txContext;
|
||||
extern tmpContent_t tmpContent;
|
||||
extern dataContext_t dataContext;
|
||||
extern strings_t strings;
|
||||
extern cx_sha3_t sha3;
|
||||
extern cx_sha3_t global_sha3;
|
||||
extern const internalStorage_t N_storage_real;
|
||||
|
||||
#ifdef TARGET_BLUE
|
||||
@@ -156,6 +156,9 @@ extern bagl_element_t tmp_element;
|
||||
extern char addressSummary[32];
|
||||
#endif
|
||||
|
||||
extern bool called_from_swap;
|
||||
extern uint8_t dataAllowed;
|
||||
extern uint8_t contractDetails;
|
||||
extern bool dataPresent;
|
||||
extern uint8_t appState;
|
||||
extern contract_call_t contractProvisioned;
|
||||
|
||||
52
src/swap_lib_calls.h
Normal file
52
src/swap_lib_calls.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef SWAP_LIB_CALLS
|
||||
#define SWAP_LIB_CALLS
|
||||
|
||||
#include "stdbool.h"
|
||||
|
||||
#define RUN_APPLICATION 1
|
||||
|
||||
#define SIGN_TRANSACTION 2
|
||||
|
||||
#define CHECK_ADDRESS 3
|
||||
|
||||
#define GET_PRINTABLE_AMOUNT 4
|
||||
|
||||
// structure that should be send to specific coin application to get address
|
||||
typedef struct check_address_parameters_s {
|
||||
// IN
|
||||
unsigned char* coin_configuration;
|
||||
unsigned char coin_configuration_length;
|
||||
// serialized path, segwit, version prefix, hash used, dictionary etc.
|
||||
// fields and serialization format depends on spesific coin app
|
||||
unsigned char* address_parameters;
|
||||
unsigned char address_parameters_length;
|
||||
char *address_to_check;
|
||||
char *extra_id_to_check;
|
||||
// OUT
|
||||
int result;
|
||||
} check_address_parameters_t;
|
||||
|
||||
// structure that should be send to specific coin application to get printable amount
|
||||
typedef struct get_printable_amount_parameters_s {
|
||||
// IN
|
||||
unsigned char* coin_configuration;
|
||||
unsigned char coin_configuration_length;
|
||||
unsigned char* amount;
|
||||
unsigned char amount_length;
|
||||
bool is_fee;
|
||||
// OUT
|
||||
char printable_amount[30];
|
||||
} get_printable_amount_parameters_t;
|
||||
|
||||
typedef struct create_transaction_parameters_s {
|
||||
unsigned char* coin_configuration;
|
||||
unsigned char coin_configuration_length;
|
||||
unsigned char* amount;
|
||||
unsigned char amount_length;
|
||||
unsigned char* fee_amount;
|
||||
unsigned char fee_amount_length;
|
||||
char *destination_address;
|
||||
char *destination_address_extra_id;
|
||||
} create_transaction_parameters_t;
|
||||
|
||||
#endif
|
||||
@@ -20,12 +20,14 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_TICKER_LEN 12 // 10 characters + ' ' + '\0'
|
||||
|
||||
typedef struct tokenDefinition_t {
|
||||
#ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR
|
||||
uint8_t contractName[20];
|
||||
#endif
|
||||
uint8_t address[20];
|
||||
uint8_t ticker[12]; // 10 characters + ' \0'
|
||||
uint8_t ticker[MAX_TICKER_LEN];
|
||||
uint8_t decimals;
|
||||
} tokenDefinition_t;
|
||||
|
||||
|
||||
@@ -39,13 +39,13 @@ UX_FLOW_DEF_VALID(
|
||||
&C_icon_dashboard_x,
|
||||
"Quit",
|
||||
});
|
||||
const ux_flow_step_t * const ux_idle_flow [] = {
|
||||
UX_FLOW(ux_idle_flow,
|
||||
&ux_idle_flow_1_step,
|
||||
&ux_idle_flow_2_step,
|
||||
&ux_idle_flow_3_step,
|
||||
&ux_idle_flow_4_step,
|
||||
FLOW_END_STEP,
|
||||
};
|
||||
FLOW_LOOP
|
||||
);
|
||||
|
||||
#if defined(TARGET_NANOS)
|
||||
|
||||
|
||||
38
src/utils.c
38
src/utils.c
@@ -19,7 +19,9 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "ethUstream.h"
|
||||
#include "ethUtils.h"
|
||||
#include "uint256.h"
|
||||
#include "tokens.h"
|
||||
|
||||
static const unsigned char hex_digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
@@ -75,4 +77,40 @@ uint32_t getV(txContent_t *txContent) {
|
||||
THROW(EXCEPTION);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
void amountToString(uint8_t* amount, uint8_t amount_size, uint8_t decimals, char* ticker, char* out_buffer, uint8_t out_buffer_size){
|
||||
uint256_t amount_256;
|
||||
char tmp_buffer[100];
|
||||
convertUint256BE(amount, amount_size, &amount_256);
|
||||
tostring256(&amount_256, 10, tmp_buffer, 100);
|
||||
|
||||
uint8_t amount_len = strnlen(tmp_buffer, sizeof(tmp_buffer));
|
||||
uint8_t ticker_len = strnlen(ticker, MAX_TICKER_LEN);
|
||||
|
||||
memcpy(out_buffer, ticker, MIN(out_buffer_size, ticker_len));
|
||||
|
||||
adjustDecimals(tmp_buffer, amount_len, out_buffer + ticker_len, out_buffer_size - ticker_len -1, decimals);
|
||||
out_buffer[out_buffer_size-1] = '\0';
|
||||
}
|
||||
|
||||
bool parse_swap_config(uint8_t* config, uint8_t config_len, char* ticker, uint8_t* decimals){
|
||||
uint8_t ticker_len, offset = 0;
|
||||
if (config_len == 0){
|
||||
return false;
|
||||
}
|
||||
ticker_len = config[offset++];
|
||||
if(ticker_len == 0 || ticker_len > MAX_TICKER_LEN - 2 || config_len - offset < ticker_len){
|
||||
return false;
|
||||
}
|
||||
memcpy(ticker, config+offset, ticker_len);
|
||||
offset += ticker_len;
|
||||
ticker[ticker_len] = ' ';
|
||||
ticker[ticker_len+1] = '\0';
|
||||
|
||||
if(config_len - offset < 1){
|
||||
return false;
|
||||
}
|
||||
*decimals = config[offset];
|
||||
return true;
|
||||
}
|
||||
@@ -30,4 +30,8 @@ int local_strchr(char *string, char ch);
|
||||
|
||||
uint32_t getV(txContent_t *txContent);
|
||||
|
||||
void amountToString(uint8_t* amount, uint8_t amount_len, uint8_t decimals, char* ticker, char* out_buffer, uint8_t out_buffer_size);
|
||||
|
||||
bool parse_swap_config(uint8_t* config, uint8_t config_len, char* ticker, uint8_t* decimals);
|
||||
|
||||
#endif /* _UTILS_H_ */
|
||||
Reference in New Issue
Block a user