Merge pull request #183 from LedgerHQ/bigger_chainid
Improve display for big chainIDs
6
.github/workflows/ci-workflow.yml
vendored
@@ -124,13 +124,17 @@ jobs:
|
|||||||
- name: Build/Install build js deps
|
- name: Build/Install build js deps
|
||||||
run: |
|
run: |
|
||||||
cd tests && yarn install
|
cd tests && yarn install
|
||||||
|
- name: Create tmp folder for artifacts
|
||||||
|
run: |
|
||||||
|
mkdir tests/elfs
|
||||||
- name: Download app binaries
|
- name: Download app binaries
|
||||||
uses: actions/download-artifact@v2
|
uses: actions/download-artifact@v2
|
||||||
with:
|
with:
|
||||||
path: tests/elfs
|
path: tests/elfs
|
||||||
- name: Gather elfs
|
- name: Gather elfs
|
||||||
run: |
|
run: |
|
||||||
cp `find . -name "*.elf"` ./tests/elfs
|
cd tests/elfs
|
||||||
|
cp `find . -name "*.elf"` .
|
||||||
- name: Run zemu tests
|
- name: Run zemu tests
|
||||||
run: |
|
run: |
|
||||||
cd tests && yarn test
|
cd tests && yarn test
|
||||||
|
|||||||
3
.gitignore
vendored
@@ -14,6 +14,7 @@ obj/
|
|||||||
tests/node_modules
|
tests/node_modules
|
||||||
tests/lib
|
tests/lib
|
||||||
tests/yarn-error.log
|
tests/yarn-error.log
|
||||||
|
tests/elfs/*
|
||||||
|
tests/snapshots/tmp/*
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
|
|||||||
15
CHANGELOG.md
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## [1.9.3](https://github.com/ledgerhq/app-ethereum/compare/1.9.2...1.9.3) - 2021-9-03
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added better display for bigger chainIDs.
|
||||||
|
- Added support for Songbird.
|
||||||
|
- Added support for Celo.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Small refactor of `getEthDisplayableAddress` helper
|
||||||
|
- Improve Zemu tests to get parallelization
|
||||||
|
- Increased plugin interface to version 2
|
||||||
|
- Remove support for Theta and Flare
|
||||||
|
|
||||||
## [1.9.2](https://github.com/ledgerhq/app-ethereum/compare/1.9.0...1.9.2) - 2021-8-11
|
## [1.9.2](https://github.com/ledgerhq/app-ethereum/compare/1.9.0...1.9.2) - 2021-8-11
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
14
Makefile
@@ -30,7 +30,7 @@ APP_LOAD_PARAMS += --path "1517992542'/1101353413'"
|
|||||||
|
|
||||||
APPVERSION_M=1
|
APPVERSION_M=1
|
||||||
APPVERSION_N=9
|
APPVERSION_N=9
|
||||||
APPVERSION_P=2
|
APPVERSION_P=3
|
||||||
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
|
APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)
|
||||||
APP_LOAD_FLAGS= --appFlags 0x240 --dep Ethereum:$(APPVERSION)
|
APP_LOAD_FLAGS= --appFlags 0x240 --dep Ethereum:$(APPVERSION)
|
||||||
|
|
||||||
@@ -203,17 +203,17 @@ else ifeq ($(CHAIN),flare_coston)
|
|||||||
APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'"
|
APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'"
|
||||||
DEFINES += CHAINID_UPCASE=\"FLARE\" CHAINID_COINNAME=\"FLR\" CHAIN_KIND=CHAIN_KIND_FLARE CHAIN_ID=16
|
DEFINES += CHAINID_UPCASE=\"FLARE\" CHAINID_COINNAME=\"FLR\" CHAIN_KIND=CHAIN_KIND_FLARE CHAIN_ID=16
|
||||||
APPNAME = "Flare Coston"
|
APPNAME = "Flare Coston"
|
||||||
else ifeq ($(CHAIN),theta)
|
|
||||||
APP_LOAD_PARAMS += --path "44'/500'"
|
|
||||||
DEFINES += CHAINID_UPCASE=\"THETA\" CHAINID_COINNAME=\"THETA\" CHAIN_KIND=CHAIN_KIND_THETA CHAIN_ID=500
|
|
||||||
APPNAME = "Theta"
|
|
||||||
else ifeq ($(CHAIN),bsc)
|
else ifeq ($(CHAIN),bsc)
|
||||||
APP_LOAD_PARAMS += --path "44'/60'"
|
APP_LOAD_PARAMS += --path "44'/60'"
|
||||||
DEFINES += CHAINID_UPCASE=\"BSC\" CHAINID_COINNAME=\"BNB\" CHAIN_KIND=CHAIN_KIND_BSC CHAIN_ID=56
|
DEFINES += CHAINID_UPCASE=\"BSC\" CHAINID_COINNAME=\"BNB\" CHAIN_KIND=CHAIN_KIND_BSC CHAIN_ID=56
|
||||||
APPNAME = "Binance Smart Chain"
|
APPNAME = "Binance Smart Chain"
|
||||||
|
else ifeq ($(CHAIN),songbird)
|
||||||
|
APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'"
|
||||||
|
DEFINES += CHAINID_UPCASE=\"SONGBIRD\" CHAINID_COINNAME=\"SGB\" CHAIN_KIND=CHAIN_KIND_SONGBIRD CHAIN_ID=19
|
||||||
|
APPNAME = "Songbird"
|
||||||
else
|
else
|
||||||
ifeq ($(filter clean,$(MAKECMDGOALS)),)
|
ifeq ($(filter clean,$(MAKECMDGOALS)),)
|
||||||
$(error Unsupported CHAIN - use ethereum, ropsten, ethereum_classic, expanse, poa, artis_sigma1, artis_tau1, rsk, rsk_testnet, ubiq, wanchain, kusd, musicoin, pirl, akroma, atheios, callisto, ethersocial, ellaism, ether1, ethergem, gochain, mix, reosc, hpb, tomochain, tobalaba, dexon, volta, ewc, webchain, thundercore, flare, flare_coston, theta)
|
$(error Unsupported CHAIN - use ethereum, ropsten, ethereum_classic, expanse, poa, artis_sigma1, artis_tau1, rsk, rsk_testnet, ubiq, wanchain, kusd, musicoin, pirl, akroma, atheios, callisto, ethersocial, ellaism, ether1, ethergem, gochain, mix, reosc, hpb, tomochain, tobalaba, dexon, volta, ewc, webchain, thundercore, bsc, songbird)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -384,4 +384,4 @@ include $(BOLOS_SDK)/Makefile.rules
|
|||||||
dep/%.d: %.c Makefile
|
dep/%.d: %.c Makefile
|
||||||
|
|
||||||
listvariants:
|
listvariants:
|
||||||
@echo VARIANTS CHAIN ethereum ropsten ethereum_classic expanse poa rsk rsk_testnet ubiq wanchain pirl akroma atheios callisto ethersocial ether1 gochain musicoin ethergem mix ellaism reosc hpb tomochain dexon volta ewc thundercore flare flare_coston theta bsc
|
@echo VARIANTS CHAIN ethereum ropsten ethereum_classic expanse poa rsk rsk_testnet ubiq wanchain pirl akroma atheios callisto ethersocial ether1 gochain musicoin ethergem mix ellaism reosc hpb tomochain dexon volta ewc thundercore bsc songbird
|
||||||
|
|||||||
@@ -17,8 +17,15 @@ Testing is done via the open-source framework [zemu](https://github.com/Zondax/z
|
|||||||
## Running tests
|
## Running tests
|
||||||
|
|
||||||
First [install yarn](https://classic.yarnpkg.com/en/docs/install/#debian-stable).
|
First [install yarn](https://classic.yarnpkg.com/en/docs/install/#debian-stable).
|
||||||
|
Open `tests/build_local_test_elfs.sh` and add your BOLOS SDKs path to `NANOS_SDK` and `NANOX_SDK`.
|
||||||
|
This helper script will build the applications required by the test suite and move them at the right place.
|
||||||
|
```
|
||||||
|
cd test
|
||||||
|
./build_local_test_elfs.sh
|
||||||
|
```
|
||||||
Then you can install the project by simply running:
|
Then you can install the project by simply running:
|
||||||
```
|
```
|
||||||
|
cd ..
|
||||||
make test
|
make test
|
||||||
```
|
```
|
||||||
This will run `make install_tests` and `make run_tests`
|
This will run `make install_tests` and `make run_tests`
|
||||||
|
|||||||
@@ -520,7 +520,7 @@ The following standard Status Words are returned for all APDUs - some specific S
|
|||||||
|===============================================================================================
|
|===============================================================================================
|
||||||
| *SW* | *Description*
|
| *SW* | *Description*
|
||||||
| 6501 | TransactionType not supported
|
| 6501 | TransactionType not supported
|
||||||
| 6502 | Output buffer too small for snprintf input
|
| 6502 | Output buffer too small for chainId conversion
|
||||||
| 6503 | Plugin error
|
| 6503 | Plugin error
|
||||||
| 6504 | Failed to convert from int256
|
| 6504 | Failed to convert from int256
|
||||||
| 6700 | Incorrect length
|
| 6700 | Incorrect length
|
||||||
|
|||||||
BIN
icons/nanos_app_songbird.gif
Normal file
|
After Width: | Height: | Size: 73 B |
BIN
icons/nanox_app_songbird.gif
Normal file
|
After Width: | Height: | Size: 57 B |
BIN
icons/songbird.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
@@ -54,13 +54,13 @@ typedef enum chain_kind_e {
|
|||||||
CHAIN_KIND_WEBCHAIN,
|
CHAIN_KIND_WEBCHAIN,
|
||||||
CHAIN_KIND_THUNDERCORE,
|
CHAIN_KIND_THUNDERCORE,
|
||||||
CHAIN_KIND_FLARE,
|
CHAIN_KIND_FLARE,
|
||||||
CHAIN_KIND_THETA,
|
CHAIN_KIND_BSC,
|
||||||
CHAIN_KIND_BSC
|
CHAIN_KIND_SONGBIRD
|
||||||
} chain_kind_t;
|
} chain_kind_t;
|
||||||
|
|
||||||
typedef struct chain_config_s {
|
typedef struct chain_config_s {
|
||||||
char coinName[10]; // ticker
|
char coinName[10]; // ticker
|
||||||
uint32_t chainId;
|
uint64_t chainId;
|
||||||
chain_kind_t kind;
|
chain_kind_t kind;
|
||||||
} chain_config_t;
|
} chain_config_t;
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ eth_plugin_result_t eth_plugin_call(int method, void *parameter) {
|
|||||||
case ETH_PLUGIN_INIT_CONTRACT:
|
case ETH_PLUGIN_INIT_CONTRACT:
|
||||||
PRINTF("-- PLUGIN INIT CONTRACT --\n");
|
PRINTF("-- PLUGIN INIT CONTRACT --\n");
|
||||||
((ethPluginInitContract_t *) parameter)->interfaceVersion =
|
((ethPluginInitContract_t *) parameter)->interfaceVersion =
|
||||||
ETH_PLUGIN_INTERFACE_VERSION_1;
|
ETH_PLUGIN_INTERFACE_VERSION_LATEST;
|
||||||
((ethPluginInitContract_t *) parameter)->result = ETH_PLUGIN_RESULT_UNAVAILABLE;
|
((ethPluginInitContract_t *) parameter)->result = ETH_PLUGIN_RESULT_UNAVAILABLE;
|
||||||
((ethPluginInitContract_t *) parameter)->pluginSharedRW = &pluginRW;
|
((ethPluginInitContract_t *) parameter)->pluginSharedRW = &pluginRW;
|
||||||
((ethPluginInitContract_t *) parameter)->pluginSharedRO = &pluginRO;
|
((ethPluginInitContract_t *) parameter)->pluginSharedRO = &pluginRO;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
// Interface version. To be updated everytime we introduce breaking changes to the plugin interface.
|
// Interface version. To be updated everytime we introduce breaking changes to the plugin interface.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ETH_PLUGIN_INTERFACE_VERSION_1 = 1, // Version 1
|
ETH_PLUGIN_INTERFACE_VERSION_1 = 1, // Version 1
|
||||||
|
ETH_PLUGIN_INTERFACE_VERSION_LATEST = 2,
|
||||||
} eth_plugin_interface_version_t;
|
} eth_plugin_interface_version_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ int handle_check_address(check_address_parameters_t* params, chain_config_t* cha
|
|||||||
getEthAddressStringFromKey(&locals_union2.publicKey,
|
getEthAddressStringFromKey(&locals_union2.publicKey,
|
||||||
locals_union1.address,
|
locals_union1.address,
|
||||||
&local_sha3,
|
&local_sha3,
|
||||||
chain_config);
|
chain_config->chainId);
|
||||||
ZERO(locals_union2);
|
ZERO(locals_union2);
|
||||||
|
|
||||||
uint8_t offset_0x = 0;
|
uint8_t offset_0x = 0;
|
||||||
|
|||||||
20
src/main.c
@@ -250,12 +250,12 @@ tokenDefinition_t *getKnownToken(uint8_t *contractAddress) {
|
|||||||
case CHAIN_KIND_FLARE:
|
case CHAIN_KIND_FLARE:
|
||||||
numTokens = NUM_TOKENS_FLARE;
|
numTokens = NUM_TOKENS_FLARE;
|
||||||
break;
|
break;
|
||||||
case CHAIN_KIND_THETA:
|
|
||||||
numTokens = NUM_TOKENS_THETA;
|
|
||||||
break;
|
|
||||||
case CHAIN_KIND_BSC:
|
case CHAIN_KIND_BSC:
|
||||||
numTokens = NUM_TOKENS_BSC;
|
numTokens = NUM_TOKENS_BSC;
|
||||||
break;
|
break;
|
||||||
|
case CHAIN_KIND_SONGBIRD:
|
||||||
|
numTokens = NUM_TOKENS_SONGBIRD;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
for (i = 0; i < numTokens; i++) {
|
for (i = 0; i < numTokens; i++) {
|
||||||
switch (chainConfig->kind) {
|
switch (chainConfig->kind) {
|
||||||
@@ -352,12 +352,12 @@ tokenDefinition_t *getKnownToken(uint8_t *contractAddress) {
|
|||||||
case CHAIN_KIND_FLARE:
|
case CHAIN_KIND_FLARE:
|
||||||
currentToken = (tokenDefinition_t *) PIC(&TOKENS_FLARE[i]);
|
currentToken = (tokenDefinition_t *) PIC(&TOKENS_FLARE[i]);
|
||||||
break;
|
break;
|
||||||
case CHAIN_KIND_THETA:
|
|
||||||
currentToken = (tokenDefinition_t *) PIC(&TOKENS_THETA[i]);
|
|
||||||
break;
|
|
||||||
case CHAIN_KIND_BSC:
|
case CHAIN_KIND_BSC:
|
||||||
currentToken = (tokenDefinition_t *) PIC(&TOKENS_BSC[i]);
|
currentToken = (tokenDefinition_t *) PIC(&TOKENS_BSC[i]);
|
||||||
break;
|
break;
|
||||||
|
case CHAIN_KIND_SONGBIRD:
|
||||||
|
currentToken = (tokenDefinition_t *) PIC(&TOKENS_SONGBIRD[i]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (memcmp(currentToken->address, tmpContent.txContent.destination, ADDRESS_LENGTH) == 0) {
|
if (memcmp(currentToken->address, tmpContent.txContent.destination, ADDRESS_LENGTH) == 0) {
|
||||||
return currentToken;
|
return currentToken;
|
||||||
@@ -876,22 +876,22 @@ __attribute__((section(".boot"))) int main(int arg0) {
|
|||||||
PRINTF("Hello from Eth-clone\n");
|
PRINTF("Hello from Eth-clone\n");
|
||||||
check_api_level(CX_COMPAT_APILEVEL);
|
check_api_level(CX_COMPAT_APILEVEL);
|
||||||
// delegate to Ethereum app/lib
|
// delegate to Ethereum app/lib
|
||||||
libcall_params[0] = "Ethereum";
|
libcall_params[0] = (unsigned int) "Ethereum";
|
||||||
libcall_params[1] = 0x100;
|
libcall_params[1] = 0x100;
|
||||||
libcall_params[2] = RUN_APPLICATION;
|
libcall_params[2] = RUN_APPLICATION;
|
||||||
libcall_params[3] = &local_chainConfig;
|
libcall_params[3] = (unsigned int) &local_chainConfig;
|
||||||
libcall_params[4] = 0;
|
libcall_params[4] = 0;
|
||||||
if (arg0) {
|
if (arg0) {
|
||||||
// call as a library
|
// call as a library
|
||||||
libcall_params[2] = ((unsigned int *) arg0)[1];
|
libcall_params[2] = ((unsigned int *) arg0)[1];
|
||||||
libcall_params[4] = ((unsigned int *) arg0)[3]; // library arguments
|
libcall_params[4] = ((unsigned int *) arg0)[3]; // library arguments
|
||||||
os_lib_call(&libcall_params);
|
os_lib_call((unsigned int *) &libcall_params);
|
||||||
((unsigned int *) arg0)[0] = libcall_params[1];
|
((unsigned int *) arg0)[0] = libcall_params[1];
|
||||||
os_lib_end();
|
os_lib_end();
|
||||||
} else {
|
} else {
|
||||||
// launch coin application
|
// launch coin application
|
||||||
libcall_params[1] = 0x100; // use the Init call, as we won't exit
|
libcall_params[1] = 0x100; // use the Init call, as we won't exit
|
||||||
os_lib_call(&libcall_params);
|
os_lib_call((unsigned int *) &libcall_params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FINALLY {
|
FINALLY {
|
||||||
|
|||||||
@@ -162,14 +162,14 @@ typedef enum {
|
|||||||
#endif
|
#endif
|
||||||
} contract_call_t;
|
} contract_call_t;
|
||||||
|
|
||||||
#define NETWORK_NAME_MAX_SIZE 12
|
#define NETWORK_STRING_MAX_SIZE 16
|
||||||
|
|
||||||
typedef struct txStringProperties_t {
|
typedef struct txStringProperties_t {
|
||||||
char fullAddress[43];
|
char fullAddress[43];
|
||||||
char fullAmount[50];
|
char fullAmount[50];
|
||||||
char maxFee[50];
|
char maxFee[50];
|
||||||
char nonce[8]; // 10M tx per account ought to be enough for everybody
|
char nonce[8]; // 10M tx per account ought to be enough for everybody
|
||||||
char network_name[NETWORK_NAME_MAX_SIZE];
|
char network_name[NETWORK_STRING_MAX_SIZE];
|
||||||
} txStringProperties_t;
|
} txStringProperties_t;
|
||||||
|
|
||||||
#define SHARED_CTX_FIELD_1_SIZE 100
|
#define SHARED_CTX_FIELD_1_SIZE 100
|
||||||
|
|||||||
@@ -3853,10 +3853,6 @@ const tokenDefinition_t const TOKENS_ETHEREUM[NUM_TOKENS_ETHEREUM] = {
|
|||||||
0x91, 0x9a, 0xbc, 0x23, 0x5c, 0xa4, 0xfd, 0x7f, 0x72, 0xc1},
|
0x91, 0x9a, 0xbc, 0x23, 0x5c, 0xa4, 0xfd, 0x7f, 0x72, 0xc1},
|
||||||
"TGT ",
|
"TGT ",
|
||||||
1},
|
1},
|
||||||
{{0x38, 0x83, 0xf5, 0xe1, 0x81, 0xfc, 0xca, 0xf8, 0x41, 0x0f,
|
|
||||||
0xa6, 0x1e, 0x12, 0xb5, 0x9b, 0xad, 0x96, 0x3f, 0xb6, 0x45},
|
|
||||||
"THETA ",
|
|
||||||
18},
|
|
||||||
{{0x1c, 0xb3, 0x20, 0x9d, 0x45, 0xb2, 0xa6, 0x0b, 0x7f, 0xbc,
|
{{0x1c, 0xb3, 0x20, 0x9d, 0x45, 0xb2, 0xa6, 0x0b, 0x7f, 0xbc,
|
||||||
0xa1, 0xcc, 0xdb, 0xf8, 0x7f, 0x67, 0x42, 0x37, 0xa4, 0xaa},
|
0xa1, 0xcc, 0xdb, 0xf8, 0x7f, 0x67, 0x42, 0x37, 0xa4, 0xaa},
|
||||||
"THR ",
|
"THR ",
|
||||||
@@ -4564,8 +4560,8 @@ const tokenDefinition_t const TOKENS_THUNDERCORE[NUM_TOKENS_THUNDERCORE] = {};
|
|||||||
|
|
||||||
const tokenDefinition_t const TOKENS_FLARE[NUM_TOKENS_FLARE] = {};
|
const tokenDefinition_t const TOKENS_FLARE[NUM_TOKENS_FLARE] = {};
|
||||||
|
|
||||||
const tokenDefinition_t const TOKENS_THETA[NUM_TOKENS_THETA] = {};
|
|
||||||
|
|
||||||
const tokenDefinition_t const TOKENS_BSC[NUM_TOKENS_BSC] = {};
|
const tokenDefinition_t const TOKENS_BSC[NUM_TOKENS_BSC] = {};
|
||||||
|
|
||||||
|
const tokenDefinition_t const TOKENS_SONGBIRD[NUM_TOKENS_SONGBIRD] = {};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -95,8 +95,8 @@ static const uint8_t LEDGER_SIGNATURE_PUBLIC_KEY[] = {
|
|||||||
#define NUM_TOKENS_WEBCHAIN 0
|
#define NUM_TOKENS_WEBCHAIN 0
|
||||||
#define NUM_TOKENS_THUNDERCORE 0
|
#define NUM_TOKENS_THUNDERCORE 0
|
||||||
#define NUM_TOKENS_FLARE 0
|
#define NUM_TOKENS_FLARE 0
|
||||||
#define NUM_TOKENS_THETA 0
|
|
||||||
#define NUM_TOKENS_BSC 0
|
#define NUM_TOKENS_BSC 0
|
||||||
|
#define NUM_TOKENS_SONGBIRD 0
|
||||||
|
|
||||||
extern tokenDefinition_t const TOKENS_AKROMA[NUM_TOKENS_AKROMA];
|
extern tokenDefinition_t const TOKENS_AKROMA[NUM_TOKENS_AKROMA];
|
||||||
extern tokenDefinition_t const TOKENS_ELLAISM[NUM_TOKENS_ELLAISM];
|
extern tokenDefinition_t const TOKENS_ELLAISM[NUM_TOKENS_ELLAISM];
|
||||||
@@ -129,8 +129,8 @@ extern tokenDefinition_t const TOKENS_ARTIS_TAU1[NUM_TOKENS_ARTIS_TAU1];
|
|||||||
extern tokenDefinition_t const TOKENS_WEBCHAIN[NUM_TOKENS_WEBCHAIN];
|
extern tokenDefinition_t const TOKENS_WEBCHAIN[NUM_TOKENS_WEBCHAIN];
|
||||||
extern tokenDefinition_t const TOKENS_THUNDERCORE[NUM_TOKENS_THUNDERCORE];
|
extern tokenDefinition_t const TOKENS_THUNDERCORE[NUM_TOKENS_THUNDERCORE];
|
||||||
extern tokenDefinition_t const TOKENS_FLARE[NUM_TOKENS_FLARE];
|
extern tokenDefinition_t const TOKENS_FLARE[NUM_TOKENS_FLARE];
|
||||||
extern tokenDefinition_t const TOKENS_THETA[NUM_TOKENS_THETA];
|
|
||||||
extern tokenDefinition_t const TOKENS_BSC[NUM_TOKENS_BSC];
|
extern tokenDefinition_t const TOKENS_BSC[NUM_TOKENS_BSC];
|
||||||
|
extern tokenDefinition_t const TOKENS_SONGBIRD[NUM_TOKENS_SONGBIRD];
|
||||||
|
|
||||||
#endif /* HAVE_TOKENS_LIST */
|
#endif /* HAVE_TOKENS_LIST */
|
||||||
|
|
||||||
|
|||||||
22
src/utils.c
@@ -54,19 +54,17 @@ int local_strchr(char *string, char ch) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t u32_from_BE(uint8_t *in, uint8_t size) {
|
uint64_t u64_from_BE(uint8_t *in, uint8_t size) {
|
||||||
switch (size) {
|
uint8_t i = 0;
|
||||||
case 0:
|
uint64_t res = 0;
|
||||||
return 0;
|
|
||||||
case 1:
|
while (i < size && i < sizeof(res)) {
|
||||||
return in[0];
|
res <<= 8;
|
||||||
case 2:
|
res |= in[i];
|
||||||
return (in[0] << 8) | in[1];
|
i++;
|
||||||
case 3:
|
|
||||||
return (in[0] << 16) | (in[1] << 8) | in[2];
|
|
||||||
default:
|
|
||||||
return (in[0] << 24) | (in[1] << 16) | (in[2] << 8) | in[3];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len) {
|
bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ void convertUint256BE(uint8_t* data, uint32_t length, uint256_t* target);
|
|||||||
|
|
||||||
int local_strchr(char* string, char ch);
|
int local_strchr(char* string, char ch);
|
||||||
|
|
||||||
uint32_t u32_from_BE(uint8_t* in, uint8_t size);
|
uint64_t u64_from_BE(uint8_t* in, uint8_t size);
|
||||||
|
|
||||||
bool uint256_to_decimal(const uint8_t* value, size_t value_len, char* out, size_t out_len);
|
bool uint256_to_decimal(const uint8_t* value, size_t value_len, char* out, size_t out_len);
|
||||||
|
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ typedef struct txContent_t {
|
|||||||
txInt256_t chainID;
|
txInt256_t chainID;
|
||||||
uint8_t destination[ADDRESS_LENGTH];
|
uint8_t destination[ADDRESS_LENGTH];
|
||||||
uint8_t destinationLength;
|
uint8_t destinationLength;
|
||||||
uint8_t v[4];
|
uint8_t v[8];
|
||||||
uint8_t vLength;
|
uint8_t vLength;
|
||||||
bool dataPresent;
|
bool dataPresent;
|
||||||
} txContent_t;
|
} txContent_t;
|
||||||
|
|||||||
@@ -126,17 +126,45 @@ void getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3
|
|||||||
void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey,
|
void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey,
|
||||||
char *out,
|
char *out,
|
||||||
cx_sha3_t *sha3Context,
|
cx_sha3_t *sha3Context,
|
||||||
chain_config_t *chain_config) {
|
uint64_t chainId) {
|
||||||
uint8_t hashAddress[INT256_LENGTH];
|
uint8_t hashAddress[INT256_LENGTH];
|
||||||
cx_keccak_init(sha3Context, 256);
|
cx_keccak_init(sha3Context, 256);
|
||||||
cx_hash((cx_hash_t *) sha3Context, CX_LAST, publicKey->W + 1, 64, hashAddress, 32);
|
cx_hash((cx_hash_t *) sha3Context, CX_LAST, publicKey->W + 1, 64, hashAddress, 32);
|
||||||
getEthAddressStringFromBinary(hashAddress + 12, out, sha3Context, chain_config);
|
getEthAddressStringFromBinary(hashAddress + 12, out, sha3Context, chainId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void u64_to_string(uint64_t src, char *dst, uint8_t dst_size) {
|
||||||
|
// Copy the numbers in ASCII format.
|
||||||
|
uint8_t i = 0;
|
||||||
|
do {
|
||||||
|
// Checking `i + 1` to make sure we have enough space for '\0'.
|
||||||
|
if (i + 1 >= dst_size) {
|
||||||
|
THROW(0x6502);
|
||||||
|
}
|
||||||
|
dst[i] = src % 10 + '0';
|
||||||
|
src /= 10;
|
||||||
|
i++;
|
||||||
|
} while (src);
|
||||||
|
|
||||||
|
// Null terminate string
|
||||||
|
dst[i] = '\0';
|
||||||
|
|
||||||
|
// Revert the string
|
||||||
|
i--;
|
||||||
|
uint8_t j = 0;
|
||||||
|
while (j < i) {
|
||||||
|
char tmp = dst[i];
|
||||||
|
dst[i] = dst[j];
|
||||||
|
dst[j] = tmp;
|
||||||
|
i--;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void getEthAddressStringFromBinary(uint8_t *address,
|
void getEthAddressStringFromBinary(uint8_t *address,
|
||||||
char *out,
|
char *out,
|
||||||
cx_sha3_t *sha3Context,
|
cx_sha3_t *sha3Context,
|
||||||
chain_config_t *chain_config) {
|
uint64_t chainId) {
|
||||||
// save some precious stack space
|
// save some precious stack space
|
||||||
union locals_union {
|
union locals_union {
|
||||||
uint8_t hashChecksum[INT256_LENGTH];
|
uint8_t hashChecksum[INT256_LENGTH];
|
||||||
@@ -146,18 +174,17 @@ void getEthAddressStringFromBinary(uint8_t *address,
|
|||||||
uint8_t i;
|
uint8_t i;
|
||||||
bool eip1191 = false;
|
bool eip1191 = false;
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
switch (chain_config->chainId) {
|
switch (chainId) {
|
||||||
case 30:
|
case 30:
|
||||||
case 31:
|
case 31:
|
||||||
eip1191 = true;
|
eip1191 = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (eip1191) {
|
if (eip1191) {
|
||||||
snprintf((char *) locals_union.tmp,
|
u64_to_string(chainId, (char *) locals_union.tmp, sizeof(locals_union.tmp));
|
||||||
sizeof(locals_union.tmp),
|
offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp));
|
||||||
"%d0x",
|
strlcat((char *) locals_union.tmp + offset, "0x", sizeof(locals_union.tmp) - offset);
|
||||||
chain_config->chainId);
|
offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp));
|
||||||
offset = strlen((char *) locals_union.tmp);
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < 20; i++) {
|
for (i = 0; i < 20; i++) {
|
||||||
uint8_t digit = address[i];
|
uint8_t digit = address[i];
|
||||||
@@ -192,6 +219,24 @@ void getEthAddressStringFromBinary(uint8_t *address,
|
|||||||
out[40] = '\0';
|
out[40] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fills the `out` buffer with the lowercase string representation of the pubkey passed in as binary
|
||||||
|
format by `in`. (eg: uint8_t*:0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB ->
|
||||||
|
char*:"0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB\0" )
|
||||||
|
`sha3` context doesn't have have to be initialized prior to call.*/
|
||||||
|
void getEthDisplayableAddress(uint8_t *in,
|
||||||
|
char *out,
|
||||||
|
size_t out_len,
|
||||||
|
cx_sha3_t *sha3,
|
||||||
|
uint64_t chainId) {
|
||||||
|
if (out_len < 43) {
|
||||||
|
strlcpy(out, "ERROR", out_len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
out[0] = '0';
|
||||||
|
out[1] = 'x';
|
||||||
|
getEthAddressStringFromBinary(in, out + 2, sha3, chainId);
|
||||||
|
}
|
||||||
|
|
||||||
bool adjustDecimals(char *src,
|
bool adjustDecimals(char *src,
|
||||||
uint32_t srcLength,
|
uint32_t srcLength,
|
||||||
char *target,
|
char *target,
|
||||||
|
|||||||
@@ -42,12 +42,20 @@ void getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3
|
|||||||
void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey,
|
void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey,
|
||||||
char *out,
|
char *out,
|
||||||
cx_sha3_t *sha3Context,
|
cx_sha3_t *sha3Context,
|
||||||
chain_config_t *chain_config);
|
uint64_t chainId);
|
||||||
|
|
||||||
|
void u64_to_string(uint64_t src, char *dst, uint8_t dst_size);
|
||||||
|
|
||||||
void getEthAddressStringFromBinary(uint8_t *address,
|
void getEthAddressStringFromBinary(uint8_t *address,
|
||||||
char *out,
|
char *out,
|
||||||
cx_sha3_t *sha3Context,
|
cx_sha3_t *sha3Context,
|
||||||
chain_config_t *chain_config);
|
uint64_t chainId);
|
||||||
|
|
||||||
|
void getEthDisplayableAddress(uint8_t *in,
|
||||||
|
char *out,
|
||||||
|
size_t out_len,
|
||||||
|
cx_sha3_t *sha3,
|
||||||
|
uint64_t chainId);
|
||||||
|
|
||||||
bool adjustDecimals(char *src,
|
bool adjustDecimals(char *src,
|
||||||
uint32_t srcLength,
|
uint32_t srcLength,
|
||||||
|
|||||||
@@ -19,30 +19,33 @@ const network_info_t NETWORK_MAPPING[] = {
|
|||||||
{.chain_id = 100, .name = "xDai", .ticker = "xDAI "},
|
{.chain_id = 100, .name = "xDai", .ticker = "xDAI "},
|
||||||
{.chain_id = 137, .name = "Polygon", .ticker = "MATIC "},
|
{.chain_id = 137, .name = "Polygon", .ticker = "MATIC "},
|
||||||
{.chain_id = 250, .name = "Fantom", .ticker = "FTM "},
|
{.chain_id = 250, .name = "Fantom", .ticker = "FTM "},
|
||||||
{.chain_id = 43114, .name = "Avalanche", .ticker = "AVAX "}};
|
{.chain_id = 42220, .name = "Celo", .ticker = "CELO "},
|
||||||
|
{.chain_id = 43114, .name = "Avalanche", .ticker = "AVAX "},
|
||||||
|
{.chain_id = 44787, .name = "Celo Alfajores", .ticker = "aCELO "},
|
||||||
|
{.chain_id = 62320, .name = "Celo Baklava", .ticker = "bCELO "},
|
||||||
|
{.chain_id = 11297108109, .name = "Palm Network", .ticker = "PALM "}};
|
||||||
|
|
||||||
uint32_t get_chain_id(void) {
|
uint64_t get_chain_id(void) {
|
||||||
uint32_t chain_id = 0;
|
uint64_t chain_id = 0;
|
||||||
|
|
||||||
switch (txContext.txType) {
|
switch (txContext.txType) {
|
||||||
case LEGACY:
|
case LEGACY:
|
||||||
chain_id = u32_from_BE(txContext.content->v, txContext.content->vLength);
|
chain_id = u64_from_BE(txContext.content->v, txContext.content->vLength);
|
||||||
break;
|
break;
|
||||||
case EIP2930:
|
case EIP2930:
|
||||||
case EIP1559:
|
case EIP1559:
|
||||||
chain_id = u32_from_BE(tmpContent.txContent.chainID.value,
|
chain_id = u64_from_BE(tmpContent.txContent.chainID.value,
|
||||||
tmpContent.txContent.chainID.length);
|
tmpContent.txContent.chainID.length);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PRINTF("Txtype `%d` not supported while generating chainID\n", txContext.txType);
|
PRINTF("Txtype `%d` not supported while generating chainID\n", txContext.txType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PRINTF("ChainID: %d\n", chain_id);
|
|
||||||
return chain_id;
|
return chain_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
network_info_t *get_network(void) {
|
network_info_t *get_network(void) {
|
||||||
uint32_t chain_id = get_chain_id();
|
uint64_t chain_id = get_chain_id();
|
||||||
for (uint8_t i = 0; i < sizeof(NETWORK_MAPPING) / sizeof(*NETWORK_MAPPING); i++) {
|
for (uint8_t i = 0; i < sizeof(NETWORK_MAPPING) / sizeof(*NETWORK_MAPPING); i++) {
|
||||||
if (NETWORK_MAPPING[i].chain_id == chain_id) {
|
if (NETWORK_MAPPING[i].chain_id == chain_id) {
|
||||||
return (network_info_t *) PIC(&NETWORK_MAPPING[i]);
|
return (network_info_t *) PIC(&NETWORK_MAPPING[i]);
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "tokens.h"
|
#include "tokens.h"
|
||||||
|
#include "shared_context.h"
|
||||||
#define NETWORK_STRING_MAX_SIZE 12
|
|
||||||
|
|
||||||
typedef struct network_info_s {
|
typedef struct network_info_s {
|
||||||
const char name[NETWORK_STRING_MAX_SIZE];
|
const char name[NETWORK_STRING_MAX_SIZE];
|
||||||
const char ticker[MAX_TICKER_LEN];
|
const char ticker[MAX_TICKER_LEN];
|
||||||
uint32_t chain_id;
|
uint64_t chain_id;
|
||||||
} network_info_t;
|
} network_info_t;
|
||||||
|
|
||||||
// Returns the current chain id. Defaults to 0 if txType was not found.
|
// Returns the current chain id. Defaults to 0 if txType was not found.
|
||||||
uint32_t get_chain_id(void);
|
uint64_t get_chain_id(void);
|
||||||
// Returns a pointer to the network struct, or NULL if there is none.
|
// Returns a pointer to the network struct, or NULL if there is none.
|
||||||
network_info_t *get_network(void);
|
network_info_t *get_network(void);
|
||||||
// Returns a pointer to the network name, or NULL if there is none.
|
// Returns a pointer to the network name, or NULL if there is none.
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ void handleGetPublicKey(uint8_t p1,
|
|||||||
getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey,
|
getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey,
|
||||||
tmpCtx.publicKeyContext.address,
|
tmpCtx.publicKeyContext.address,
|
||||||
&global_sha3,
|
&global_sha3,
|
||||||
chainConfig);
|
chainConfig->chainId);
|
||||||
#ifndef NO_CONSENT
|
#ifndef NO_CONSENT
|
||||||
if (p1 == P1_NON_CONFIRM)
|
if (p1 == P1_NON_CONFIRM)
|
||||||
#endif // NO_CONSENT
|
#endif // NO_CONSENT
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void handleSign(uint8_t p1,
|
|||||||
} else {
|
} else {
|
||||||
txContext.txType = LEGACY;
|
txContext.txType = LEGACY;
|
||||||
}
|
}
|
||||||
PRINTF("TxType: %d\n", txContext.txType);
|
PRINTF("TxType: %x\n", txContext.txType);
|
||||||
} else if (p1 != P1_MORE) {
|
} else if (p1 != P1_MORE) {
|
||||||
THROW(0x6B00);
|
THROW(0x6B00);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "eth_plugin_handler.h"
|
#include "eth_plugin_handler.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
#include "ethUtils.h"
|
||||||
|
|
||||||
#define ERR_SILENT_MODE_CHECK_FAILED 0x6001
|
#define ERR_SILENT_MODE_CHECK_FAILED 0x6001
|
||||||
|
|
||||||
@@ -261,16 +262,8 @@ void prepareNetworkDisplay() {
|
|||||||
char *name = get_network_name();
|
char *name = get_network_name();
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
// No network name found so simply copy the chain ID as the network name.
|
// No network name found so simply copy the chain ID as the network name.
|
||||||
uint32_t chain_id = get_chain_id();
|
uint64_t chain_id = get_chain_id();
|
||||||
uint8_t res = snprintf(strings.common.network_name,
|
u64_to_string(chain_id, strings.common.network_name, sizeof(strings.common.network_name));
|
||||||
sizeof(strings.common.network_name),
|
|
||||||
"%d",
|
|
||||||
chain_id);
|
|
||||||
if (res >= sizeof(strings.common.network_name)) {
|
|
||||||
// If the return value is higher or equal to the size passed in as parameter, then
|
|
||||||
// the output was truncated. Return the appropriate error code.
|
|
||||||
THROW(0x6502);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Network name found, simply copy it.
|
// Network name found, simply copy it.
|
||||||
strlcpy(strings.common.network_name, name, sizeof(strings.common.network_name));
|
strlcpy(strings.common.network_name, name, sizeof(strings.common.network_name));
|
||||||
@@ -308,7 +301,7 @@ void finalizeParsing(bool direct) {
|
|||||||
// Verify the chain
|
// Verify the chain
|
||||||
if (chainConfig->chainId != ETHEREUM_MAINNET_CHAINID) {
|
if (chainConfig->chainId != ETHEREUM_MAINNET_CHAINID) {
|
||||||
// TODO: Could we remove above check?
|
// TODO: Could we remove above check?
|
||||||
uint32_t id = get_chain_id();
|
uint64_t id = get_chain_id();
|
||||||
|
|
||||||
if (chainConfig->chainId != id) {
|
if (chainConfig->chainId != id) {
|
||||||
PRINTF("Invalid chainID %u expected %u\n", id, chainConfig->chainId);
|
PRINTF("Invalid chainID %u expected %u\n", id, chainConfig->chainId);
|
||||||
@@ -422,12 +415,11 @@ void finalizeParsing(bool direct) {
|
|||||||
// Prepare destination address to display
|
// Prepare destination address to display
|
||||||
if (genericUI) {
|
if (genericUI) {
|
||||||
if (tmpContent.txContent.destinationLength != 0) {
|
if (tmpContent.txContent.destinationLength != 0) {
|
||||||
displayBuffer[0] = '0';
|
getEthDisplayableAddress(tmpContent.txContent.destination,
|
||||||
displayBuffer[1] = 'x';
|
displayBuffer,
|
||||||
getEthAddressStringFromBinary(tmpContent.txContent.destination,
|
sizeof(displayBuffer),
|
||||||
displayBuffer + 2,
|
&global_sha3,
|
||||||
&global_sha3,
|
chainConfig->chainId);
|
||||||
chainConfig);
|
|
||||||
compareOrCopy(strings.common.fullAddress,
|
compareOrCopy(strings.common.fullAddress,
|
||||||
sizeof(strings.common.fullAddress),
|
sizeof(strings.common.fullAddress),
|
||||||
displayBuffer,
|
displayBuffer,
|
||||||
@@ -459,9 +451,11 @@ void finalizeParsing(bool direct) {
|
|||||||
|
|
||||||
// Compute maximum fee
|
// Compute maximum fee
|
||||||
prepareFeeDisplay();
|
prepareFeeDisplay();
|
||||||
|
PRINTF("Fees displayed: %s\n", strings.common.maxFee);
|
||||||
|
|
||||||
// Prepare chainID field
|
// Prepare chainID field
|
||||||
prepareNetworkDisplay();
|
prepareNetworkDisplay();
|
||||||
|
PRINTF("Network: %s\n", strings.common.network_name);
|
||||||
|
|
||||||
bool no_consent;
|
bool no_consent;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_elemen
|
|||||||
uint8_t signature[100];
|
uint8_t signature[100];
|
||||||
cx_ecfp_private_key_t privateKey;
|
cx_ecfp_private_key_t privateKey;
|
||||||
uint32_t tx = 0;
|
uint32_t tx = 0;
|
||||||
uint32_t v = u32_from_BE(tmpContent.txContent.v, tmpContent.txContent.vLength);
|
|
||||||
io_seproxyhal_io_heartbeat();
|
io_seproxyhal_io_heartbeat();
|
||||||
os_perso_derive_node_bip32(CX_CURVE_256K1,
|
os_perso_derive_node_bip32(CX_CURVE_256K1,
|
||||||
tmpCtx.transactionContext.bip32Path,
|
tmpCtx.transactionContext.bip32Path,
|
||||||
@@ -40,7 +39,12 @@ unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_elemen
|
|||||||
G_io_apdu_buffer[0] = 27;
|
G_io_apdu_buffer[0] = 27;
|
||||||
} else {
|
} else {
|
||||||
// New API
|
// New API
|
||||||
// Note that this is wrong for a large v, but the client can always recover
|
// Note that this is wrong for a large v, but ledgerjs will recover.
|
||||||
|
|
||||||
|
// Taking only the 4 highest bytes to not introduce breaking changes. In the future,
|
||||||
|
// this should be updated.
|
||||||
|
uint32_t v = (uint32_t) u64_from_BE(tmpContent.txContent.v,
|
||||||
|
MIN(4, tmpContent.txContent.vLength));
|
||||||
G_io_apdu_buffer[0] = (v * 2) + 35;
|
G_io_apdu_buffer[0] = (v * 2) + 35;
|
||||||
}
|
}
|
||||||
if (info & CX_ECCINFO_PARITY_ODD) {
|
if (info & CX_ECCINFO_PARITY_ODD) {
|
||||||
|
|||||||
@@ -222,9 +222,8 @@ void ux_approve_tx(bool fromPlugin) {
|
|||||||
ux_approval_tx_flow[step++] = &ux_approval_nonce_step;
|
ux_approval_tx_flow[step++] = &ux_approval_nonce_step;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t chain_id = get_chain_id();
|
uint64_t chain_id = get_chain_id();
|
||||||
if (chainConfig->chainId == ETHEREUM_MAINNET_CHAINID && chain_id != chainConfig->chainId) {
|
if (chainConfig->chainId == ETHEREUM_MAINNET_CHAINID && chain_id != chainConfig->chainId) {
|
||||||
// TODO: do we need the `&&` above?
|
|
||||||
ux_approval_tx_flow[step++] = &ux_approval_network_step;
|
ux_approval_tx_flow[step++] = &ux_approval_network_step;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,16 +13,6 @@ void stark_sign_display_master_account() {
|
|||||||
dataContext.starkContext.transferDestination);
|
dataContext.starkContext.transferDestination);
|
||||||
}
|
}
|
||||||
|
|
||||||
void stark_sign_display_condition_address() {
|
|
||||||
strings.tmp.tmp[0] = '0';
|
|
||||||
strings.tmp.tmp[1] = 'x';
|
|
||||||
getEthAddressStringFromBinary(dataContext.starkContext.conditionAddress,
|
|
||||||
strings.tmp.tmp + 2,
|
|
||||||
&global_sha3,
|
|
||||||
chainConfig);
|
|
||||||
strings.tmp.tmp[42] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
void stark_sign_display_condition_fact() {
|
void stark_sign_display_condition_fact() {
|
||||||
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.fact);
|
snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.fact);
|
||||||
}
|
}
|
||||||
@@ -189,7 +179,11 @@ UX_STEP_NOCB_INIT(
|
|||||||
UX_STEP_NOCB_INIT(
|
UX_STEP_NOCB_INIT(
|
||||||
ux_stark_conditional_transfer_8_step,
|
ux_stark_conditional_transfer_8_step,
|
||||||
bnnn_paging,
|
bnnn_paging,
|
||||||
stark_sign_display_condition_address(),
|
getEthDisplayableAddress(dataContext.starkContext.conditionAddress,
|
||||||
|
strings.tmp.tmp,
|
||||||
|
sizeof(strings.tmp.tmp),
|
||||||
|
&global_sha3,
|
||||||
|
chainConfig->chainId),
|
||||||
{
|
{
|
||||||
.title = "Cond. Address",
|
.title = "Cond. Address",
|
||||||
.text = strings.tmp.tmp
|
.text = strings.tmp.tmp
|
||||||
|
|||||||
@@ -212,12 +212,11 @@ void erc20_plugin_call(int message, void *parameters) {
|
|||||||
strlcpy(msg->msg, context->contract_name, msg->msgLength);
|
strlcpy(msg->msg, context->contract_name, msg->msgLength);
|
||||||
} else {
|
} else {
|
||||||
strlcpy(msg->title, "Address", msg->titleLength);
|
strlcpy(msg->title, "Address", msg->titleLength);
|
||||||
msg->msg[0] = '0';
|
getEthDisplayableAddress(context->destinationAddress,
|
||||||
msg->msg[1] = 'x';
|
msg->msg,
|
||||||
getEthAddressStringFromBinary(context->destinationAddress,
|
msg->msgLength,
|
||||||
msg->msg + 2,
|
msg->pluginSharedRW->sha3,
|
||||||
msg->pluginSharedRW->sha3,
|
chainConfig->chainId);
|
||||||
chainConfig);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
#include "ethUtils.h"
|
#include "ethUtils.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
void starkware_print_stark_key(uint8_t *starkKey, char *destination);
|
|
||||||
void starkware_print_eth_address(uint8_t *address, char *destination);
|
|
||||||
|
|
||||||
typedef struct erc721_parameters_t {
|
typedef struct erc721_parameters_t {
|
||||||
uint8_t selectorIndex;
|
uint8_t selectorIndex;
|
||||||
uint8_t address[ADDRESS_LENGTH];
|
uint8_t address[ADDRESS_LENGTH];
|
||||||
@@ -119,19 +116,27 @@ void erc721_plugin_call(int message, void *parameters) {
|
|||||||
switch (msg->screenIndex) {
|
switch (msg->screenIndex) {
|
||||||
case 0:
|
case 0:
|
||||||
strlcpy(msg->title, "Contract Name", msg->titleLength);
|
strlcpy(msg->title, "Contract Name", msg->titleLength);
|
||||||
starkware_print_eth_address(tmpContent.txContent.destination, msg->msg);
|
getEthDisplayableAddress(tmpContent.txContent.destination,
|
||||||
|
msg->msg,
|
||||||
|
msg->msgLength,
|
||||||
|
&global_sha3,
|
||||||
|
chainConfig->chainId);
|
||||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
strlcpy(msg->title, "NFT Contract", msg->titleLength);
|
strlcpy(msg->title, "NFT Contract", msg->titleLength);
|
||||||
starkware_print_eth_address(context->address, msg->msg);
|
getEthDisplayableAddress(context->address,
|
||||||
|
msg->msg,
|
||||||
|
msg->msgLength,
|
||||||
|
&global_sha3,
|
||||||
|
chainConfig->chainId);
|
||||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
strlcpy(msg->title, "TokenID", msg->titleLength);
|
strlcpy(msg->title, "TokenID", msg->titleLength);
|
||||||
starkware_print_stark_key(context->tokenId, msg->msg);
|
snprintf(msg->msg, 70, "0x%.*H", 32, context->tokenId);
|
||||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -32,19 +32,6 @@ typedef struct eth2_deposit_parameters_t {
|
|||||||
char deposit_address[ETH2_DEPOSIT_PUBKEY_LENGTH];
|
char deposit_address[ETH2_DEPOSIT_PUBKEY_LENGTH];
|
||||||
} eth2_deposit_parameters_t;
|
} eth2_deposit_parameters_t;
|
||||||
|
|
||||||
// Fills the `out` buffer with the lowercase string representation of the pubkey passed in as binary
|
|
||||||
// format by `in`. Does not check the size, so expects `out` to be big enough to hold the string
|
|
||||||
// representation. Returns the length of string (counting the null terminating character).
|
|
||||||
static int getEthDisplayableAddress(char *out, uint8_t *in, cx_sha3_t *sha3) {
|
|
||||||
out[0] = '0';
|
|
||||||
out[1] = 'x';
|
|
||||||
getEthAddressStringFromBinary(in, out + 2, sha3, chainConfig);
|
|
||||||
|
|
||||||
uint8_t destinationLen = strlen(out) + 1; // Adding one to account for \0.
|
|
||||||
|
|
||||||
return destinationLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void eth2_plugin_call(int message, void *parameters) {
|
void eth2_plugin_call(int message, void *parameters) {
|
||||||
switch (message) {
|
switch (message) {
|
||||||
case ETH_PLUGIN_INIT_CONTRACT: {
|
case ETH_PLUGIN_INIT_CONTRACT: {
|
||||||
@@ -130,9 +117,11 @@ void eth2_plugin_call(int message, void *parameters) {
|
|||||||
|
|
||||||
// Use a temporary buffer to store the string representation.
|
// Use a temporary buffer to store the string representation.
|
||||||
char tmp[ETH2_DEPOSIT_PUBKEY_LENGTH];
|
char tmp[ETH2_DEPOSIT_PUBKEY_LENGTH];
|
||||||
getEthDisplayableAddress(tmp,
|
getEthDisplayableAddress((uint8_t *) context->deposit_address,
|
||||||
(uint8_t *) context->deposit_address,
|
tmp,
|
||||||
msg->pluginSharedRW->sha3);
|
sizeof(tmp),
|
||||||
|
msg->pluginSharedRW->sha3,
|
||||||
|
chainConfig->chainId);
|
||||||
|
|
||||||
// Copy back the string to the global variable.
|
// Copy back the string to the global variable.
|
||||||
strlcpy(context->deposit_address, tmp, ETH2_DEPOSIT_PUBKEY_LENGTH);
|
strlcpy(context->deposit_address, tmp, ETH2_DEPOSIT_PUBKEY_LENGTH);
|
||||||
|
|||||||
@@ -279,18 +279,6 @@ void starkware_print_stark_key(uint8_t *starkKey, char *destination) {
|
|||||||
snprintf(destination, 70, "0x%.*H", 32, starkKey);
|
snprintf(destination, 70, "0x%.*H", 32, starkKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : rewrite as independant code
|
|
||||||
void starkware_print_eth_address(uint8_t *address, char *destination, size_t destinationLength) {
|
|
||||||
if (destinationLength < 43) {
|
|
||||||
strlcpy(destination, "ERROR", destinationLength);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
destination[0] = '0';
|
|
||||||
destination[1] = 'x';
|
|
||||||
getEthAddressStringFromBinary(address, destination + 2, &global_sha3, chainConfig);
|
|
||||||
destination[42] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO : rewrite as independant code
|
// TODO : rewrite as independant code
|
||||||
void starkware_print_amount(uint8_t *amountData,
|
void starkware_print_amount(uint8_t *amountData,
|
||||||
char *destination,
|
char *destination,
|
||||||
@@ -348,7 +336,11 @@ void starkware_print_asset_contract(char *destination, size_t destinationLength)
|
|||||||
if (dataContext.tokenContext.quantumIndex != MAX_TOKEN) {
|
if (dataContext.tokenContext.quantumIndex != MAX_TOKEN) {
|
||||||
tokenDefinition_t *token =
|
tokenDefinition_t *token =
|
||||||
&tmpCtx.transactionContext.tokens[dataContext.tokenContext.quantumIndex];
|
&tmpCtx.transactionContext.tokens[dataContext.tokenContext.quantumIndex];
|
||||||
starkware_print_eth_address(token->address, destination, destinationLength);
|
getEthDisplayableAddress(token->address,
|
||||||
|
destination,
|
||||||
|
destinationLength,
|
||||||
|
&global_sha3,
|
||||||
|
chainConfig->chainId);
|
||||||
} else {
|
} else {
|
||||||
strlcpy(destination, "UNKNOWN", destinationLength);
|
strlcpy(destination, "UNKNOWN", destinationLength);
|
||||||
}
|
}
|
||||||
@@ -372,7 +364,7 @@ void starkware_get_source_address(char *destination) {
|
|||||||
io_seproxyhal_io_heartbeat();
|
io_seproxyhal_io_heartbeat();
|
||||||
destination[0] = '0';
|
destination[0] = '0';
|
||||||
destination[1] = 'x';
|
destination[1] = 'x';
|
||||||
getEthAddressStringFromKey(&publicKey, destination + 2, &global_sha3, chainConfig);
|
getEthAddressStringFromKey(&publicKey, destination + 2, &global_sha3, chainConfig->chainId);
|
||||||
destination[42] = '\0';
|
destination[42] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -708,9 +700,11 @@ void starkware_plugin_call(int message, void *parameters) {
|
|||||||
if (is_deversify_contract(tmpContent.txContent.destination)) {
|
if (is_deversify_contract(tmpContent.txContent.destination)) {
|
||||||
strlcpy(msg->msg, "DeversiFi", msg->msgLength);
|
strlcpy(msg->msg, "DeversiFi", msg->msgLength);
|
||||||
} else {
|
} else {
|
||||||
starkware_print_eth_address(tmpContent.txContent.destination,
|
getEthDisplayableAddress(tmpContent.txContent.destination,
|
||||||
msg->msg,
|
msg->msg,
|
||||||
msg->msgLength);
|
msg->msgLength,
|
||||||
|
&global_sha3,
|
||||||
|
chainConfig->chainId);
|
||||||
}
|
}
|
||||||
msg->result = ETH_PLUGIN_RESULT_OK;
|
msg->result = ETH_PLUGIN_RESULT_OK;
|
||||||
break;
|
break;
|
||||||
@@ -720,7 +714,11 @@ void starkware_plugin_call(int message, void *parameters) {
|
|||||||
case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN:
|
case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN:
|
||||||
case STARKWARE_REGISTER_AND_DEPOSIT_ETH:
|
case STARKWARE_REGISTER_AND_DEPOSIT_ETH:
|
||||||
strlcpy(msg->title, "From ETH Address", msg->titleLength);
|
strlcpy(msg->title, "From ETH Address", msg->titleLength);
|
||||||
starkware_print_eth_address(context->amount, msg->msg, msg->msgLength);
|
getEthDisplayableAddress(context->amount,
|
||||||
|
msg->msg,
|
||||||
|
msg->msgLength,
|
||||||
|
&global_sha3,
|
||||||
|
chainConfig->chainId);
|
||||||
break;
|
break;
|
||||||
case STARKWARE_ESCAPE:
|
case STARKWARE_ESCAPE:
|
||||||
strlcpy(msg->title, "Amount", msg->titleLength);
|
strlcpy(msg->title, "Amount", msg->titleLength);
|
||||||
@@ -784,7 +782,11 @@ void starkware_plugin_call(int message, void *parameters) {
|
|||||||
case STARKWARE_WITHDRAW_TO:
|
case STARKWARE_WITHDRAW_TO:
|
||||||
case STARKWARE_WITHDRAW_NFT_TO:
|
case STARKWARE_WITHDRAW_NFT_TO:
|
||||||
strlcpy(msg->title, "To ETH Address", msg->titleLength);
|
strlcpy(msg->title, "To ETH Address", msg->titleLength);
|
||||||
starkware_print_eth_address(context->amount, msg->msg, msg->msgLength);
|
getEthDisplayableAddress(context->amount,
|
||||||
|
msg->msg,
|
||||||
|
msg->msgLength,
|
||||||
|
&global_sha3,
|
||||||
|
chainConfig->chainId);
|
||||||
break;
|
break;
|
||||||
case STARKWARE_WITHDRAW_AND_MINT:
|
case STARKWARE_WITHDRAW_AND_MINT:
|
||||||
strlcpy(msg->title, "Asset Contract", msg->titleLength);
|
strlcpy(msg->title, "Asset Contract", msg->titleLength);
|
||||||
|
|||||||
34
tests/build_local_test_elfs.sh
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# FILL THESE WITH YOUR OWN SDKs PATHS
|
||||||
|
NANOS_SDK=$TWO
|
||||||
|
NANOX_SDK=$X
|
||||||
|
|
||||||
|
# list of apps required by tests that we want to build here
|
||||||
|
appnames=("ethereum" "ethereum_classic")
|
||||||
|
|
||||||
|
# create elfs folder if it doesn't exist
|
||||||
|
mkdir -p elfs
|
||||||
|
|
||||||
|
# move to repo's root to build apps
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
echo "*Building elfs for Nano S..."
|
||||||
|
for app in "${appnames[@]}"
|
||||||
|
do
|
||||||
|
echo "**Building $app for Nano S..."
|
||||||
|
make clean BOLOS_SDK=$NANOS_SDK
|
||||||
|
make -j DEBUG=1 ALLOW_DATA=1 BOLOS_SDK=$NANOS_SDK CHAIN=$app
|
||||||
|
cp bin/app.elf "tests/elfs/${app}_nanos.elf"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "*Building elfs for Nano X..."
|
||||||
|
for app in "${appnames[@]}"
|
||||||
|
do
|
||||||
|
echo "**Building $app for Nano X..."
|
||||||
|
make clean BOLOS_SDK=$NANOX_SDK
|
||||||
|
make -j DEBUG=1 ALLOW_DATA=1 BOLOS_SDK=$NANOX_SDK CHAIN=$app
|
||||||
|
cp bin/app.elf "tests/elfs/${app}_nanox.elf"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "done"
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import Zemu from "@zondax/zemu";
|
import Zemu from "@zondax/zemu";
|
||||||
|
import fsExtra from "fs-extra";
|
||||||
|
|
||||||
const catchExit = async () => {
|
const catchExit = async () => {
|
||||||
process.on("SIGINT", () => {
|
process.on("SIGINT", () => {
|
||||||
@@ -12,4 +13,5 @@ module.exports = async () => {
|
|||||||
await catchExit();
|
await catchExit();
|
||||||
await Zemu.checkAndPullImage();
|
await Zemu.checkAndPullImage();
|
||||||
await Zemu.stopAllEmuContainers();
|
await Zemu.stopAllEmuContainers();
|
||||||
|
fsExtra.emptyDirSync("snapshots/tmp")
|
||||||
};
|
};
|
||||||
@@ -30,4 +30,10 @@ module.exports = {
|
|||||||
"**/?(*.)+(spec|test).[tj]s?(x)",
|
"**/?(*.)+(spec|test).[tj]s?(x)",
|
||||||
"**/?(*.)+(ispec|test).[tj]s?(x)",
|
"**/?(*.)+(ispec|test).[tj]s?(x)",
|
||||||
],
|
],
|
||||||
|
|
||||||
|
// Path of the file where tests can be """decorated"""
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
|
||||||
|
|
||||||
|
// Stop immediatly when a test fail
|
||||||
|
bail: true,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,14 +12,15 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
||||||
"@ledgerhq/hw-app-eth": "^5.52.1",
|
"@ledgerhq/hw-app-eth": "^6.5.0",
|
||||||
"@ledgerhq/hw-transport-http": "^4.74.2",
|
"@ledgerhq/hw-transport-http": "^4.74.2",
|
||||||
"@ledgerhq/logs": "^5.50.0",
|
"@ledgerhq/logs": "^5.50.0",
|
||||||
"@zondax/zemu": "0.13.0",
|
"@zondax/zemu": "0.16.5",
|
||||||
"bignumber.js": "^9.0.0",
|
"bignumber.js": "^9.0.0",
|
||||||
"bip32-path": "^0.4.2",
|
"bip32-path": "^0.4.2",
|
||||||
"core-js": "^3.7.0",
|
"core-js": "^3.7.0",
|
||||||
"ethereum-tx-decoder": "^3.0.0",
|
"ethereum-tx-decoder": "^3.0.0",
|
||||||
|
"fs-extra": "^10.0.0",
|
||||||
"google-protobuf": "^3.11.0",
|
"google-protobuf": "^3.11.0",
|
||||||
"jest-serial-runner": "^1.1.0",
|
"jest-serial-runner": "^1.1.0",
|
||||||
"js-sha256": "^0.9.0",
|
"js-sha256": "^0.9.0",
|
||||||
|
|||||||
19
tests/setupTests.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import expect from 'expect'
|
||||||
|
|
||||||
|
expect.extend({
|
||||||
|
toMatchSnapshot(received, original) {
|
||||||
|
|
||||||
|
if(received.data.equals(original.data)){
|
||||||
|
return {
|
||||||
|
message: () => `snapshots are equal`,
|
||||||
|
pass: true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("snapshots are not equal")
|
||||||
|
return {
|
||||||
|
message: () => `snapshots are not equal`,
|
||||||
|
pass: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 674 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 612 B After Width: | Height: | Size: 619 B |
|
Before Width: | Height: | Size: 730 B After Width: | Height: | Size: 737 B |
|
Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 559 B After Width: | Height: | Size: 566 B |
BIN
tests/snapshots/chainid/nanos/accept.png
Normal file
|
After Width: | Height: | Size: 582 B |
BIN
tests/snapshots/chainid/nanos/address_1.png
Normal file
|
After Width: | Height: | Size: 809 B |
BIN
tests/snapshots/chainid/nanos/address_2.png
Normal file
|
After Width: | Height: | Size: 837 B |
BIN
tests/snapshots/chainid/nanos/address_3.png
Normal file
|
After Width: | Height: | Size: 567 B |
BIN
tests/snapshots/chainid/nanos/amount_1.png
Normal file
|
After Width: | Height: | Size: 474 B |
BIN
tests/snapshots/chainid/nanos/amount_1_palm.png
Normal file
|
After Width: | Height: | Size: 507 B |
BIN
tests/snapshots/chainid/nanos/amount_2.png
Normal file
|
After Width: | Height: | Size: 759 B |
BIN
tests/snapshots/chainid/nanos/amount_3.png
Normal file
|
After Width: | Height: | Size: 479 B |
BIN
tests/snapshots/chainid/nanos/fees.png
Normal file
|
After Width: | Height: | Size: 561 B |
BIN
tests/snapshots/chainid/nanos/fees_palm.png
Normal file
|
After Width: | Height: | Size: 594 B |
BIN
tests/snapshots/chainid/nanos/network.png
Normal file
|
After Width: | Height: | Size: 628 B |
BIN
tests/snapshots/chainid/nanos/palm.png
Normal file
|
After Width: | Height: | Size: 572 B |
BIN
tests/snapshots/chainid/nanos/review.png
Normal file
|
After Width: | Height: | Size: 541 B |
BIN
tests/snapshots/chainid/nanox/accept.png
Normal file
|
After Width: | Height: | Size: 674 B |
BIN
tests/snapshots/chainid/nanox/address.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
tests/snapshots/chainid/nanox/amount.png
Normal file
|
After Width: | Height: | Size: 866 B |
BIN
tests/snapshots/chainid/nanox/amount_palm.png
Normal file
|
After Width: | Height: | Size: 897 B |
BIN
tests/snapshots/chainid/nanox/fees.png
Normal file
|
After Width: | Height: | Size: 692 B |
BIN
tests/snapshots/chainid/nanox/fees_palm.png
Normal file
|
After Width: | Height: | Size: 721 B |
BIN
tests/snapshots/chainid/nanox/network.png
Normal file
|
After Width: | Height: | Size: 737 B |
BIN
tests/snapshots/chainid/nanox/palm.png
Normal file
|
After Width: | Height: | Size: 680 B |
BIN
tests/snapshots/chainid/nanox/review.png
Normal file
|
After Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 674 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 530 B After Width: | Height: | Size: 537 B |
|
Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 600 B |
|
Before Width: | Height: | Size: 745 B After Width: | Height: | Size: 752 B |
|
Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 674 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 514 B After Width: | Height: | Size: 521 B |
|
Before Width: | Height: | Size: 659 B After Width: | Height: | Size: 666 B |
|
Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 674 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 860 B After Width: | Height: | Size: 866 B |
|
Before Width: | Height: | Size: 685 B After Width: | Height: | Size: 692 B |
|
Before Width: | Height: | Size: 585 B After Width: | Height: | Size: 592 B |
|
Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 674 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 884 B After Width: | Height: | Size: 891 B |
|
Before Width: | Height: | Size: 692 B After Width: | Height: | Size: 699 B |
|
Before Width: | Height: | Size: 555 B After Width: | Height: | Size: 561 B |
|
Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 667 B After Width: | Height: | Size: 674 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 869 B After Width: | Height: | Size: 875 B |
|
Before Width: | Height: | Size: 688 B After Width: | Height: | Size: 695 B |
|
Before Width: | Height: | Size: 633 B After Width: | Height: | Size: 636 B |
1
tests/snapshots/tmp/nanos/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
*.png
|
|
||||||
1
tests/snapshots/tmp/nanox/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
*.png
|
|
||||||
@@ -6,22 +6,19 @@ import Zemu from "@zondax/zemu";
|
|||||||
import { TransportStatusError } from "@ledgerhq/errors";
|
import { TransportStatusError } from "@ledgerhq/errors";
|
||||||
import { expect } from "../jest";
|
import { expect } from "../jest";
|
||||||
|
|
||||||
const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox, TIMEOUT} = require("generic.js");
|
const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox, TIMEOUT, getTmpPath} = require("generic.js");
|
||||||
|
|
||||||
const ORIGINAL_SNAPSHOT_PATH_PREFIX = "snapshots/approve/";
|
const ORIGINAL_SNAPSHOT_PATH_PREFIX = "snapshots/approve/";
|
||||||
const SNAPSHOT_PATH_PREFIX = "snapshots/tmp/";
|
|
||||||
|
|
||||||
const ORIGINAL_SNAPSHOT_PATH_NANOS = ORIGINAL_SNAPSHOT_PATH_PREFIX + "nanos/";
|
const ORIGINAL_SNAPSHOT_PATH_NANOS = ORIGINAL_SNAPSHOT_PATH_PREFIX + "nanos/";
|
||||||
const ORIGINAL_SNAPSHOT_PATH_NANOX = ORIGINAL_SNAPSHOT_PATH_PREFIX + "nanox/";
|
const ORIGINAL_SNAPSHOT_PATH_NANOX = ORIGINAL_SNAPSHOT_PATH_PREFIX + "nanox/";
|
||||||
|
|
||||||
const SNAPSHOT_PATH_NANOS = SNAPSHOT_PATH_PREFIX + "nanos/";
|
|
||||||
const SNAPSHOT_PATH_NANOX = SNAPSHOT_PATH_PREFIX + "nanox/";
|
|
||||||
|
|
||||||
|
|
||||||
test("Approve DAI tokens nanos", async () => {
|
test("Approve DAI tokens nanos", async () => {
|
||||||
jest.setTimeout(TIMEOUT);
|
jest.setTimeout(TIMEOUT);
|
||||||
const sim = new Zemu(NANOS_ELF_PATH);
|
const sim = new Zemu(NANOS_ELF_PATH);
|
||||||
|
|
||||||
|
let tmpPath = getTmpPath(expect.getState().currentTestName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await sim.start(sim_options_nanos);
|
await sim.start(sim_options_nanos);
|
||||||
|
|
||||||
@@ -40,59 +37,59 @@ test("Approve DAI tokens nanos", async () => {
|
|||||||
|
|
||||||
// Review tx
|
// Review tx
|
||||||
filename = "review.png";
|
filename = "review.png";
|
||||||
await sim.snapshot(SNAPSHOT_PATH_NANOS + filename);
|
await sim.snapshot(tmpPath + filename);
|
||||||
const review = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOS + filename);
|
const review = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_review = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
const expected_review = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
expect(review).toEqual(expected_review);
|
expect(review).toMatchSnapshot(expected_review);
|
||||||
|
|
||||||
// Type
|
// Type
|
||||||
filename = "type.png";
|
filename = "type.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOS + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const type = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOS + filename);
|
const type = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_type = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
const expected_type = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
expect(type).toEqual(expected_type);
|
expect(type).toMatchSnapshot(expected_type);
|
||||||
|
|
||||||
// Amount
|
// Amount
|
||||||
filename = "amount.png";
|
filename = "amount.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOS + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const amount = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOS + filename);
|
const amount = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_amount = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
const expected_amount = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
expect(amount).toEqual(expected_amount);
|
expect(amount).toMatchSnapshot(expected_amount);
|
||||||
|
|
||||||
// Address 1/3
|
// Address 1/3
|
||||||
filename = "address_1.png";
|
filename = "address_1.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOS + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const address_1 = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOS + filename);
|
const address_1 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_address_1 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
const expected_address_1 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
expect(address_1).toEqual(expected_address_1);
|
expect(address_1).toMatchSnapshot(expected_address_1);
|
||||||
|
|
||||||
// Address 2/3
|
// Address 2/3
|
||||||
filename = "address_2.png";
|
filename = "address_2.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOS + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const address_2 = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOS + filename);
|
const address_2 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_address_2 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
const expected_address_2 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
expect(address_2).toEqual(expected_address_2);
|
expect(address_2).toMatchSnapshot(expected_address_2);
|
||||||
|
|
||||||
// Address 3/3
|
// Address 3/3
|
||||||
filename = "address_3.png";
|
filename = "address_3.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOS + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const address_3 = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOS + filename);
|
const address_3 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_address_3 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
const expected_address_3 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
expect(address_3).toEqual(expected_address_3);
|
expect(address_3).toMatchSnapshot(expected_address_3);
|
||||||
|
|
||||||
// Max Fees
|
// Max Fees
|
||||||
filename = "fees.png";
|
filename = "fees.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOS + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const fees = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOS + filename);
|
const fees = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_fees = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
const expected_fees = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
expect(fees).toEqual(expected_fees);
|
expect(fees).toMatchSnapshot(expected_fees);
|
||||||
|
|
||||||
// Accept
|
// Accept
|
||||||
filename = "accept.png";
|
filename = "accept.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOS + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const accept = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOS + filename);
|
const accept = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_accept = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
const expected_accept = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
expect(accept).toEqual(expected_accept);
|
expect(accept).toMatchSnapshot(expected_accept);
|
||||||
|
|
||||||
await sim.clickBoth();
|
await sim.clickBoth();
|
||||||
|
|
||||||
@@ -108,6 +105,8 @@ test("Approve DAI token nanox", async () => {
|
|||||||
jest.setTimeout(TIMEOUT);
|
jest.setTimeout(TIMEOUT);
|
||||||
const sim = new Zemu(NANOX_ELF_PATH);
|
const sim = new Zemu(NANOX_ELF_PATH);
|
||||||
|
|
||||||
|
let tmpPath = getTmpPath(expect.getState().currentTestName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await sim.start(sim_options_nanox);
|
await sim.start(sim_options_nanox);
|
||||||
|
|
||||||
@@ -125,45 +124,45 @@ test("Approve DAI token nanox", async () => {
|
|||||||
await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot());
|
await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot());
|
||||||
// Review tx
|
// Review tx
|
||||||
filename = "review.png";
|
filename = "review.png";
|
||||||
await sim.snapshot(SNAPSHOT_PATH_NANOX + filename);
|
await sim.snapshot(tmpPath + filename);
|
||||||
const review = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOX + filename);
|
const review = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_review = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
const expected_review = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
expect(review).toEqual(expected_review);
|
expect(review).toMatchSnapshot(expected_review);
|
||||||
|
|
||||||
// Type
|
// Type
|
||||||
filename = "type.png";
|
filename = "type.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOX + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const type = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOX + filename);
|
const type = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_type = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
const expected_type = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
expect(type).toEqual(expected_type);
|
expect(type).toMatchSnapshot(expected_type);
|
||||||
|
|
||||||
// Amount
|
// Amount
|
||||||
filename = "amount.png";
|
filename = "amount.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOX + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const amount = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOX + filename);
|
const amount = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_amount = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
const expected_amount = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
expect(amount).toEqual(expected_amount);
|
expect(amount).toMatchSnapshot(expected_amount);
|
||||||
|
|
||||||
// Address
|
// Address
|
||||||
filename = "address.png";
|
filename = "address.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOX + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const address = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOX + filename);
|
const address = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_address = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
const expected_address = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
expect(address).toEqual(expected_address);
|
expect(address).toMatchSnapshot(expected_address);
|
||||||
|
|
||||||
// Max Fees
|
// Max Fees
|
||||||
filename = "fees.png";
|
filename = "fees.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOX + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const fees = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOX + filename);
|
const fees = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_fees = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
const expected_fees = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
expect(fees).toEqual(expected_fees);
|
expect(fees).toMatchSnapshot(expected_fees);
|
||||||
|
|
||||||
// Accept
|
// Accept
|
||||||
filename = "accept.png";
|
filename = "accept.png";
|
||||||
await sim.clickRight(SNAPSHOT_PATH_NANOX + filename);
|
await sim.clickRight(tmpPath + filename);
|
||||||
const accept = Zemu.LoadPng2RGB(SNAPSHOT_PATH_NANOX + filename);
|
const accept = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
const expected_accept = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
const expected_accept = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
expect(accept).toEqual(expected_accept);
|
expect(accept).toMatchSnapshot(expected_accept);
|
||||||
|
|
||||||
await sim.clickBoth();
|
await sim.clickBoth();
|
||||||
|
|
||||||
|
|||||||
370
tests/src/chainid.test.js
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
import "core-js/stable";
|
||||||
|
import "regenerator-runtime/runtime";
|
||||||
|
import Eth from "@ledgerhq/hw-app-eth";
|
||||||
|
import { byContractAddress } from "@ledgerhq/hw-app-eth/erc20";
|
||||||
|
import Zemu from "@zondax/zemu";
|
||||||
|
import { TransportStatusError } from "@ledgerhq/errors";
|
||||||
|
import { expect } from "../jest";
|
||||||
|
|
||||||
|
const {NANOS_ELF_PATH, NANOX_ELF_PATH, sim_options_nanos, sim_options_nanox, TIMEOUT, getTmpPath} = require("generic.js");
|
||||||
|
|
||||||
|
const ORIGINAL_SNAPSHOT_PATH_PREFIX = "snapshots/chainid/";
|
||||||
|
|
||||||
|
const ORIGINAL_SNAPSHOT_PATH_NANOS = ORIGINAL_SNAPSHOT_PATH_PREFIX + "nanos/";
|
||||||
|
const ORIGINAL_SNAPSHOT_PATH_NANOX = ORIGINAL_SNAPSHOT_PATH_PREFIX + "nanox/";
|
||||||
|
|
||||||
|
test("Transfer on network 112233445566 on Ethereum nanos", async () => {
|
||||||
|
jest.setTimeout(TIMEOUT);
|
||||||
|
const sim = new Zemu(NANOS_ELF_PATH);
|
||||||
|
let tmpPath = getTmpPath(expect.getState().currentTestName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await sim.start(sim_options_nanos);
|
||||||
|
|
||||||
|
let transport = await sim.getTransport();
|
||||||
|
let eth = new Eth(transport);
|
||||||
|
|
||||||
|
// Send transaction
|
||||||
|
let tx = eth.signTransaction(
|
||||||
|
"44'/60'/0'/0/0",
|
||||||
|
"f044850306dc4200825208945a321744667052affa8386ed49e00ef223cbffc3876f9c9e7bf6181880851a21a278be8080"
|
||||||
|
)
|
||||||
|
let filename;
|
||||||
|
|
||||||
|
await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot());
|
||||||
|
// Review tx
|
||||||
|
filename = "review.png";
|
||||||
|
await sim.snapshot(tmpPath + filename);
|
||||||
|
const review = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_review = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(review).toMatchSnapshot(expected_review);
|
||||||
|
|
||||||
|
// Amount 1/3
|
||||||
|
filename = "amount_1.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const amount_1 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_amount_1 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(amount_1).toMatchSnapshot(expected_amount_1);
|
||||||
|
|
||||||
|
// Amount 2/3
|
||||||
|
filename = "amount_2.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const amount_2 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_amount_2 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(amount_2).toMatchSnapshot(expected_amount_2);
|
||||||
|
|
||||||
|
// Amount 3/3
|
||||||
|
filename = "amount_3.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const amount_3 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_amount_3 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(amount_3).toMatchSnapshot(expected_amount_3);
|
||||||
|
|
||||||
|
// Address 1/3
|
||||||
|
filename = "address_1.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const address_1 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_address_1 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(address_1).toMatchSnapshot(expected_address_1);
|
||||||
|
|
||||||
|
// Address 2/3
|
||||||
|
filename = "address_2.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const address_2 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_address_2 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(address_2).toMatchSnapshot(expected_address_2);
|
||||||
|
|
||||||
|
// Address 3/3
|
||||||
|
filename = "address_3.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const address_3 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_address_3 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(address_3).toMatchSnapshot(expected_address_3);
|
||||||
|
|
||||||
|
// Network
|
||||||
|
filename = "network.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const network = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_network = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(network).toMatchSnapshot(expected_network);
|
||||||
|
|
||||||
|
// Max Fees
|
||||||
|
filename = "fees.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const fees = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_fees = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(fees).toMatchSnapshot(expected_fees);
|
||||||
|
|
||||||
|
// Accept
|
||||||
|
filename = "accept.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const accept = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_accept = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(accept).toMatchSnapshot(expected_accept);
|
||||||
|
|
||||||
|
await sim.clickBoth();
|
||||||
|
|
||||||
|
await expect(tx).resolves.toEqual(
|
||||||
|
{
|
||||||
|
"r": "31fca443b3cad62f3ce18e287f3cf4892ac2669379cc21b5cf198561f0511d1e",
|
||||||
|
"s": "3cf21485cd8b86e1acddbcc641e16a3efad18aaeb5ae96a650f1a8b291078494",
|
||||||
|
"v": "344344f1a0",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await sim.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Transfer on palm network on Ethereum nanos", async () => {
|
||||||
|
jest.setTimeout(TIMEOUT);
|
||||||
|
const sim = new Zemu(NANOS_ELF_PATH);
|
||||||
|
let tmpPath = getTmpPath(expect.getState().currentTestName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await sim.start(sim_options_nanos);
|
||||||
|
|
||||||
|
let transport = await sim.getTransport();
|
||||||
|
let eth = new Eth(transport);
|
||||||
|
|
||||||
|
// Send transaction
|
||||||
|
let tx = eth.signTransaction(
|
||||||
|
"44'/60'/0'/0/0",
|
||||||
|
"f044850306dc4200825208945a321744667052affa8386ed49e00ef223cbffc3876f9c9e7bf61818808502a15c308d8080"
|
||||||
|
);
|
||||||
|
let filename;
|
||||||
|
|
||||||
|
await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot());
|
||||||
|
// Review tx
|
||||||
|
filename = "review.png";
|
||||||
|
await sim.snapshot(tmpPath + filename);
|
||||||
|
const review = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_review = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(review).toMatchSnapshot(expected_review);
|
||||||
|
|
||||||
|
// Amount 1/3
|
||||||
|
filename = "amount_1_palm.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const amount_1 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_amount_1 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(amount_1).toMatchSnapshot(expected_amount_1);
|
||||||
|
|
||||||
|
// Amount 2/3
|
||||||
|
filename = "amount_2.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const amount_2 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_amount_2 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(amount_2).toMatchSnapshot(expected_amount_2);
|
||||||
|
|
||||||
|
// Amount 3/3
|
||||||
|
filename = "amount_3.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const amount_3 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_amount_3 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(amount_3).toMatchSnapshot(expected_amount_3);
|
||||||
|
|
||||||
|
// Address 1/3
|
||||||
|
filename = "address_1.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const address_1 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_address_1 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(address_1).toMatchSnapshot(expected_address_1);
|
||||||
|
|
||||||
|
// Address 2/3
|
||||||
|
filename = "address_2.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const address_2 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_address_2 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(address_2).toMatchSnapshot(expected_address_2);
|
||||||
|
|
||||||
|
// Address 3/3
|
||||||
|
filename = "address_3.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const address_3 = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_address_3 = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(address_3).toMatchSnapshot(expected_address_3);
|
||||||
|
|
||||||
|
// Network
|
||||||
|
filename = "palm.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const network = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_network = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(network).toMatchSnapshot(expected_network);
|
||||||
|
|
||||||
|
// Max Fees
|
||||||
|
filename = "fees_palm.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const fees = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_fees = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(fees).toMatchSnapshot(expected_fees);
|
||||||
|
|
||||||
|
// Accept
|
||||||
|
filename = "accept.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const accept = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_accept = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOS + filename);
|
||||||
|
expect(accept).toMatchSnapshot(expected_accept);
|
||||||
|
|
||||||
|
await sim.clickBoth();
|
||||||
|
|
||||||
|
await expect(tx).resolves.toEqual(
|
||||||
|
{
|
||||||
|
"r": "f9b5d903c47c34027156e869bda5aa002233d6cca583ad53d125612fc0795f3b",
|
||||||
|
"s": "00da038129414e5ae6f7c1529c6067e82484e3694c84c16d575e77162f631c27",
|
||||||
|
"v": "0542b8613d",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await sim.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Transfer on network 112233445566 on Ethereum nanox", async () => {
|
||||||
|
jest.setTimeout(TIMEOUT);
|
||||||
|
const sim = new Zemu(NANOX_ELF_PATH);
|
||||||
|
let tmpPath = getTmpPath(expect.getState().currentTestName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await sim.start(sim_options_nanox);
|
||||||
|
|
||||||
|
let transport = await sim.getTransport();
|
||||||
|
let eth = new Eth(transport);
|
||||||
|
|
||||||
|
// Send transaction
|
||||||
|
let tx = eth.signTransaction(
|
||||||
|
"44'/60'/0'/0/0",
|
||||||
|
"f044850306dc4200825208945a321744667052affa8386ed49e00ef223cbffc3876f9c9e7bf6181880851a21a278be8080"
|
||||||
|
)
|
||||||
|
let filename;
|
||||||
|
|
||||||
|
await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot());
|
||||||
|
// Review tx
|
||||||
|
filename = "review.png";
|
||||||
|
await sim.snapshot(tmpPath + filename);
|
||||||
|
const review = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_review = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(review).toMatchSnapshot(expected_review);
|
||||||
|
|
||||||
|
// Amount
|
||||||
|
filename = "amount.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const amount = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_amount = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(amount).toMatchSnapshot(expected_amount);
|
||||||
|
|
||||||
|
// Address
|
||||||
|
filename = "address.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const address = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_address = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(address).toMatchSnapshot(expected_address);
|
||||||
|
|
||||||
|
// Network
|
||||||
|
filename = "network.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const network = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_network = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(network).toMatchSnapshot(expected_network);
|
||||||
|
|
||||||
|
// Max Fees
|
||||||
|
filename = "fees.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const fees = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_fees = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(fees).toMatchSnapshot(expected_fees);
|
||||||
|
|
||||||
|
// Accept
|
||||||
|
filename = "accept.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const accept = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_accept = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(accept).toMatchSnapshot(expected_accept);
|
||||||
|
|
||||||
|
await sim.clickBoth();
|
||||||
|
|
||||||
|
await expect(tx).resolves.toEqual(
|
||||||
|
{
|
||||||
|
"r": "31fca443b3cad62f3ce18e287f3cf4892ac2669379cc21b5cf198561f0511d1e",
|
||||||
|
"s": "3cf21485cd8b86e1acddbcc641e16a3efad18aaeb5ae96a650f1a8b291078494",
|
||||||
|
"v": "344344f1a0",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await sim.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Transfer on palm network on Ethereum nanox", async () => {
|
||||||
|
jest.setTimeout(TIMEOUT);
|
||||||
|
const sim = new Zemu(NANOX_ELF_PATH);
|
||||||
|
let tmpPath = getTmpPath(expect.getState().currentTestName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await sim.start(sim_options_nanox);
|
||||||
|
|
||||||
|
let transport = await sim.getTransport();
|
||||||
|
let eth = new Eth(transport);
|
||||||
|
|
||||||
|
// Send transaction
|
||||||
|
let tx = eth.signTransaction(
|
||||||
|
"44'/60'/0'/0/0",
|
||||||
|
"f044850306dc4200825208945a321744667052affa8386ed49e00ef223cbffc3876f9c9e7bf61818808502a15c308d8080"
|
||||||
|
);
|
||||||
|
let filename;
|
||||||
|
|
||||||
|
await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot());
|
||||||
|
// Review tx
|
||||||
|
filename = "review.png";
|
||||||
|
await sim.snapshot(tmpPath + filename);
|
||||||
|
const review = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_review = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(review).toMatchSnapshot(expected_review);
|
||||||
|
|
||||||
|
// Amount
|
||||||
|
filename = "amount_palm.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const amount = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_amount = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(amount).toMatchSnapshot(expected_amount);
|
||||||
|
|
||||||
|
// Address
|
||||||
|
filename = "address.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const address = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_address = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(address).toMatchSnapshot(expected_address);
|
||||||
|
|
||||||
|
// Network
|
||||||
|
filename = "palm.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const network = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_network = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(network).toMatchSnapshot(expected_network);
|
||||||
|
|
||||||
|
// Max Fees
|
||||||
|
filename = "fees_palm.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const fees = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_fees = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(fees).toMatchSnapshot(expected_fees);
|
||||||
|
|
||||||
|
// Accept
|
||||||
|
filename = "accept.png";
|
||||||
|
await sim.clickRight(tmpPath + filename);
|
||||||
|
const accept = Zemu.LoadPng2RGB(tmpPath + filename);
|
||||||
|
const expected_accept = Zemu.LoadPng2RGB(ORIGINAL_SNAPSHOT_PATH_NANOX + filename);
|
||||||
|
expect(accept).toMatchSnapshot(expected_accept);
|
||||||
|
|
||||||
|
await sim.clickBoth();
|
||||||
|
|
||||||
|
await expect(tx).resolves.toEqual(
|
||||||
|
{
|
||||||
|
"r": "f9b5d903c47c34027156e869bda5aa002233d6cca583ad53d125612fc0795f3b",
|
||||||
|
"s": "00da038129414e5ae6f7c1529c6067e82484e3694c84c16d575e77162f631c27",
|
||||||
|
"v": "0542b8613d",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
await sim.close();
|
||||||
|
}
|
||||||
|
});
|
||||||