diff --git a/app/Makefile b/app/Makefile index 76840ea3..470996b4 100755 --- a/app/Makefile +++ b/app/Makefile @@ -54,7 +54,7 @@ ifndef COIN COIN=ICP endif -APPVERSION_M=10 +APPVERSION_M=1 APPVERSION_N=0 APPVERSION_P=0 @@ -82,7 +82,7 @@ APP_LOAD_PARAMS = --appFlags 0x200 --delete $(COMMON_LOAD_PARAMS) --path ${APPPA DEFINES += HAVE_PENDING_REVIEW_SCREEN ifeq ($(TARGET_NAME),TARGET_NANOS) -APP_STACK_SIZE:=1892 +APP_STACK_SIZE:=2500 ICONNAME:=$(CURDIR)/nanos_icon.gif OUTPUT_ELF ?= $(CURDIR)/output/app_s.elf OUTPUT_INSTALLER := $(CURDIR)/pkg/installer_s.sh @@ -90,8 +90,8 @@ DEFINES += CBOR_PARSER_MAX_RECURSIONS=4 endif ifeq ($(TARGET_NAME),TARGET_NANOX) -ICONNAME:=$(CURDIR)/nanox_icon.gif SCRIPT_LD:=$(CURDIR)/script_x.ld +ICONNAME:=$(CURDIR)/nanox_icon.gif OUTPUT_ELF ?= $(CURDIR)/output/app_x.elf OUTPUT_INSTALLER:= $(CURDIR)/pkg/installer_x.sh DEFINES += CBOR_PARSER_MAX_RECURSIONS=16 @@ -173,7 +173,7 @@ endif ######################### CC := $(CLANGPATH)clang -CFLAGS += -O3 -Os -Wno-unknown-pragmas -Wno-implicit-fallthrough +CFLAGS += -O3 -Os -Wno-unknown-pragmas -Wvla -Wno-implicit-fallthrough AS := $(GCCPATH)arm-none-eabi-gcc AFLAGS += @@ -188,12 +188,12 @@ GLYPH_SRC_DIR = glyphs INCLUDES_PATH += $(MY_DIR)/glyphs include $(BOLOS_SDK)/Makefile.glyphs +APP_SOURCE_PATH += $(MY_DIR)/../deps/picohash/ APP_SOURCE_PATH += $(MY_DIR)/src APP_SOURCE_PATH += $(MY_DIR)/glyphs APP_SOURCE_PATH += $(MY_DIR)/../deps/ledger-zxlib/include APP_SOURCE_PATH += $(MY_DIR)/../deps/ledger-zxlib/src APP_SOURCE_PATH += $(MY_DIR)/../deps/ledger-zxlib/app/common -APP_SOURCE_PATH += $(MY_DIR)/../deps/picohash/ SDK_SOURCE_PATH += lib_stusb lib_stusb_impl SDK_SOURCE_PATH += lib_ux diff --git a/deps/ledger-zxlib/app/common/view.c b/deps/ledger-zxlib/app/common/view.c index de8eb4eb..695547dc 100644 --- a/deps/ledger-zxlib/app/common/view.c +++ b/deps/ledger-zxlib/app/common/view.c @@ -239,7 +239,10 @@ zxerr_t h_review_update_data() { if (viewdata.pageCount > 1) { uint8_t keyLen = strlen(viewdata.key); if (keyLen < MAX_CHARS_PER_KEY_LINE) { - snprintf(viewdata.key + keyLen, MAX_CHARS_PER_KEY_LINE - keyLen, "[%d/%d]", viewdata.pageIdx + 1, + snprintf(viewdata.key + keyLen, + MAX_CHARS_PER_KEY_LINE - keyLen, + "[%d/%d]", + viewdata.pageIdx + 1, viewdata.pageCount); } } diff --git a/deps/ledger-zxlib/dockerized_build.mk b/deps/ledger-zxlib/dockerized_build.mk index 7eeb5f06..4ef30356 100644 --- a/deps/ledger-zxlib/dockerized_build.mk +++ b/deps/ledger-zxlib/dockerized_build.mk @@ -40,7 +40,7 @@ $(info EXAMPLE_VUE_DIR : $(EXAMPLE_VUE_DIR)) $(info TESTS_JS_DIR : $(TESTS_JS_DIR)) $(info TESTS_JS_PACKAGE : $(TESTS_JS_PACKAGE)) -DOCKER_IMAGE=zondax/builder-bolos:e7a7395770addca0583dc7401a7284b805b41149 +DOCKER_IMAGE=zondax/builder-bolos:latest ifdef INTERACTIVE INTERACTIVE_SETTING:="-i" diff --git a/deps/ledger-zxlib/include/zxerror.h b/deps/ledger-zxlib/include/zxerror.h index c2504d8f..eff7cbc9 100644 --- a/deps/ledger-zxlib/include/zxerror.h +++ b/deps/ledger-zxlib/include/zxerror.h @@ -15,6 +15,7 @@ ********************************************************************************/ #pragma once +#include "zxmacros.h" #ifdef __cplusplus extern "C" { diff --git a/deps/ledger-zxlib/include/zxformat.h b/deps/ledger-zxlib/include/zxformat.h index ed9a1938..7c499c92 100644 --- a/deps/ledger-zxlib/include/zxformat.h +++ b/deps/ledger-zxlib/include/zxformat.h @@ -43,6 +43,8 @@ extern "C" { return NULL; \ } +NUM_TO_STR(int32) + NUM_TO_STR(int64) NUM_TO_STR(uint64) diff --git a/deps/ledger-zxlib/include/zxmacros.h b/deps/ledger-zxlib/include/zxmacros.h index b5e32d3b..4976fc6c 100644 --- a/deps/ledger-zxlib/include/zxmacros.h +++ b/deps/ledger-zxlib/include/zxmacros.h @@ -82,15 +82,15 @@ void zemu_log_stack(const char *ctx); __Z_INLINE void zemu_log(const char *buf) { -#if defined(ZEMU_LOGGING) - #if defined (TARGET_NANOS) || defined(TARGET_NANOX) +#if defined(ZEMU_LOGGING) && (defined (TARGET_NANOS) || defined(TARGET_NANOX)) asm volatile ( "movs r0, #0x04\n" "movs r1, %0\n" "svc 0xab\n" :: "r"(buf) : "r0", "r1" ); - #endif +#else + UNUSED(buf); #endif } diff --git a/deps/ledger-zxlib/include/zxmacros_ledger.h b/deps/ledger-zxlib/include/zxmacros_ledger.h index 04e36cc0..06887c01 100644 --- a/deps/ledger-zxlib/include/zxmacros_ledger.h +++ b/deps/ledger-zxlib/include/zxmacros_ledger.h @@ -22,30 +22,25 @@ #define MEMCPY_NV nvm_write +// This macros are kept for backwards compatibility +// the most recent SDK has unified implementations and deprecated the original os_*** +#define MEMCPY memmove +#define MEMMOVE memmove +#define MEMSET memset +#define MEMCMP memcmp +#define MEMZERO explicit_bzero + #if defined(TARGET_NANOX) #include "ux.h" #define NV_CONST const #define NV_VOLATILE volatile #define IS_UX_ALLOWED (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE) - - #define MEMMOVE os_memmove - #define MEMSET os_memset - #define MEMCPY os_memcpy - #define MEMCMP os_memcmp - #define MEMZERO explicit_bzero #else #include "ux.h" #include "os_io_seproxyhal.h" #define NV_CONST #define NV_VOLATILE #define IS_UX_ALLOWED (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE) - - #define MEMCPY memmove - #define MEMMOVE memmove - #define MEMSET memset - #define MEMCMP memcmp - #define MEMZERO explicit_bzero - #endif #define CHECK_APP_CANARY() check_app_canary(); @@ -59,5 +54,4 @@ extern unsigned int app_stack_canary; WAIT_EVENT(); \ io_seproxyhal_general_status(); \ WAIT_EVENT() - #endif diff --git a/deps/ledger-zxlib/include/zxmacros_x64.h b/deps/ledger-zxlib/include/zxmacros_x64.h index 7a13c512..d868eca5 100644 --- a/deps/ledger-zxlib/include/zxmacros_x64.h +++ b/deps/ledger-zxlib/include/zxmacros_x64.h @@ -17,6 +17,8 @@ #if !defined (TARGET_NANOS) && !defined(TARGET_NANOX) +// This macros are kept for backwards compatibility +// the most recent SDK has unified implementations and deprecated the original os_*** #define MEMMOVE memmove #define MEMSET memset #define MEMCPY memcpy diff --git a/deps/ledger-zxlib/include/zxversion.h b/deps/ledger-zxlib/include/zxversion.h index f01950f8..671b34c9 100644 --- a/deps/ledger-zxlib/include/zxversion.h +++ b/deps/ledger-zxlib/include/zxversion.h @@ -15,6 +15,6 @@ ********************************************************************************/ #pragma once -#define ZXLIB_MAJOR 8 -#define ZXLIB_MINOR 0 +#define ZXLIB_MAJOR 9 +#define ZXLIB_MINOR 1 #define ZXLIB_PATCH 0 diff --git a/deps/ledger-zxlib/src/zxmacros.c b/deps/ledger-zxlib/src/zxmacros.c index f820714e..62e027ab 100644 --- a/deps/ledger-zxlib/src/zxmacros.c +++ b/deps/ledger-zxlib/src/zxmacros.c @@ -51,5 +51,8 @@ void zemu_trace(const char *file, uint32_t line) { char buf[200]; snprintf(buf, sizeof(buf), "|TRACE| %s:%d\n", file, line); zemu_log(buf); +#else + UNUSED(file); + UNUSED(line); #endif } diff --git a/tests_zemu/snapshots/s-mainmenu/00004.png b/tests_zemu/snapshots/s-mainmenu/00004.png index 8b2f01e8..8b8195c4 100644 Binary files a/tests_zemu/snapshots/s-mainmenu/00004.png and b/tests_zemu/snapshots/s-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/s-mainmenu/00011.png b/tests_zemu/snapshots/s-mainmenu/00011.png index 8b2f01e8..8b8195c4 100644 Binary files a/tests_zemu/snapshots/s-mainmenu/00011.png and b/tests_zemu/snapshots/s-mainmenu/00011.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00004.png b/tests_zemu/snapshots/x-mainmenu/00004.png index 95312b57..9f89ff70 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00004.png and b/tests_zemu/snapshots/x-mainmenu/00004.png differ diff --git a/tests_zemu/snapshots/x-mainmenu/00011.png b/tests_zemu/snapshots/x-mainmenu/00011.png index 95312b57..9f89ff70 100644 Binary files a/tests_zemu/snapshots/x-mainmenu/00011.png and b/tests_zemu/snapshots/x-mainmenu/00011.png differ diff --git a/tests_zemu/tests/phase2.test.ts b/tests_zemu/tests/phase2.test.ts new file mode 100644 index 00000000..3965ebca --- /dev/null +++ b/tests_zemu/tests/phase2.test.ts @@ -0,0 +1,333 @@ +/** ****************************************************************************** + * (c) 2020 Zondax GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************* */ + +import Zemu, { DEFAULT_START_OPTIONS, DeviceModel } from '@zondax/zemu' +import InternetComputerApp from '@zondax/ledger-icp' +import * as secp256k1 from 'secp256k1' +import {SIGN_VALUES_P2} from "@zondax/ledger-icp/dist/common"; + +const sha256 = require('js-sha256') + +const Resolve = require('path').resolve +const APP_PATH_S = Resolve('../app/output/app_s.elf') +const APP_PATH_X = Resolve('../app/output/app_x.elf') + +const APP_SEED = 'equip will roof matter pink blind book anxiety banner elbow sun young' + +const defaultOptions = { + ...DEFAULT_START_OPTIONS, + logging: true, + custom: `-s "${APP_SEED}"`, + X11: false, +} + +jest.setTimeout(60000) + +const models: DeviceModel[] = [ + { name: 'nanos', prefix: 'S', path: APP_PATH_S }, + { name: 'nanox', prefix: 'X', path: APP_PATH_X }, +] + +beforeAll(async () => { + await Zemu.checkAndPullImage() +}) + +describe('Phase2', function () { + test.each(models)('sign normal -- Increase Neuron Timer', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + const pkhex = + '0410d34980a51af89d3331ad5fa80fe30d8868ad87526460b3b3e15596ee58e812422987d8589ba61098264df5bb9c2d3ff6fe061746b4b31a44ec26636632b835' + + const txBlobStr = + 'd9d9f7a367636f6e74656e74a76c726571756573745f747970656463616c6c656e6f6e636550732123f52b79b4a4de9b89e0cc3de7586e696e67726573735f6578706972791b1674db8a3bb843006673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e3026b63616e69737465725f69644a000000000000000101016b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f7062636172674c0a02107b12060a040880a3056d73656e6465725f7075626b657958583056301006072a8648ce3d020106052b8104000a03420004e1142e1fbc940344d9161709196bb8bd151f94379c48dd507ab99a0776109128b94b5303cf2b2d28e25a779da175b62f8a975599b20c63d5193202640576ec5e6a73656e6465725f7369675840953620923534b8840d057341bfaf4511dfa73f57372e7946aed83bfde737e44c5c3005b6f19d4342b9e46c78b2c6fa4f67cf203d6a7cab51a84aa486b459536b' + const txBlob = Buffer.from(txBlobStr, 'hex') + + const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + + await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_increaseTimer_normal`, m.name === 'nanos' ? 3 : 4) + + const signatureResponse = await respRequest + console.log(signatureResponse) + + expect(signatureResponse.returnCode).toEqual(0x9000) + expect(signatureResponse.errorMessage).toEqual('No errors') + + const hash = sha256.hex(signatureResponse.preSignHash) + + const pk = Uint8Array.from(Buffer.from(pkhex, 'hex')) + expect(pk.byteLength).toEqual(65) + const digest = Uint8Array.from(Buffer.from(hash, 'hex')) + const signature = Uint8Array.from(signatureResponse.signatureRS) + //const signature = secp256k1.signatureImport(Uint8Array.from(signatureResponse.signatureDER)); + expect(signature.byteLength).toEqual(64) + + const signatureOk = secp256k1.ecdsaVerify(signature, digest, pk) + expect(signatureOk).toEqual(true) + } finally { + await sim.close() + } + }) + + test.each(models)('sign normal -- stake transfer', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + const expected_pk = + '0410d34980a51af89d3331ad5fa80fe30d8868ad87526460b3b3e15596ee58e812422987d8589ba61098264df5bb9c2d3ff6fe061746b4b31a44ec26636632b835' + + const txBlobStr = + 'd9d9f7a167636f6e74656e74a663617267583e0a0a08f2d4a0eca697869f0812070a050880c2d72f1a0308904e2a220a20a8a1abecdb66f57eb6eba44c3b5f11a6c433fe932680a9519b064b80ca8794e16b63616e69737465725f69644a000000000000000201016e696e67726573735f6578706972791b16985a582755f1806b6d6574686f645f6e616d656773656e645f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' + + const txBlob = Buffer.from(txBlobStr, 'hex') + + const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.STAKE_TX) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + + await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_staketx_normal`, m.name === 'nanos' ? 8 : 9) + + const signatureResponse = await respRequest + console.log(signatureResponse) + + expect(signatureResponse.returnCode).toEqual(0x9000) + expect(signatureResponse.errorMessage).toEqual('No errors') + + const hash = sha256.hex(signatureResponse.preSignHash) + + const pk = Uint8Array.from(Buffer.from(expected_pk, 'hex')) + const digest = Uint8Array.from(Buffer.from(hash, 'hex')) + const signature = Uint8Array.from(signatureResponse.signatureRS) + expect(signature.byteLength).toEqual(64) + + const signatureOk = secp256k1.ecdsaVerify(signature, digest, pk) + expect(signatureOk).toEqual(true) + } finally { + await sim.close() + } + }) + + test.each(models)('sign normal -- add hotkey', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + const txBlobStr = + 'd9d9f7a167636f6e74656e74a6636172675832620b10b98488e0c7a8cec9bd01122322210a1f0a1d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e3026b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b1698b4cd1475e3c06b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' + + const txBlob = Buffer.from(txBlobStr, 'hex') + + const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + + await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_addHotkey`, m.name === 'nanos' ? 4 : 5) + + const signatureResponse = await respRequest + console.log(signatureResponse) + + expect(signatureResponse.returnCode).toEqual(0x9000) + expect(signatureResponse.errorMessage).toEqual('No errors') + + } finally { + await sim.close() + } + }) + + test.each(models)('sign normal -- remove hotkey', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + const txBlobStr = + 'd9d9f7a167636f6e74656e74a6636172675832620b10b98488e0c7a8cec9bd0112232a210a1f0a1d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e3026b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b1698b5366ada7f006b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' + + const txBlob = Buffer.from(txBlobStr, 'hex') + + const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + + await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_removeHotkey`, m.name === 'nanos' ? 4 : 5) + + const signatureResponse = await respRequest + console.log(signatureResponse) + + expect(signatureResponse.returnCode).toEqual(0x9000) + expect(signatureResponse.errorMessage).toEqual('No errors') + + } finally { + await sim.close() + } + }) + + + test.each(models)('sign normal -- start dissolve', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + const txBlobStr = + 'd9d9f7a167636f6e74656e74a66361726751620b10e387b497ee96e3a8f201120212006b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b1698b7b6ae33de406b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' + + const txBlob = Buffer.from(txBlobStr, 'hex') + + const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + + await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_startdissolve`, m.name === 'nanos' ? 2 : 3) + + const signatureResponse = await respRequest + console.log(signatureResponse) + + expect(signatureResponse.returnCode).toEqual(0x9000) + expect(signatureResponse.errorMessage).toEqual('No errors') + + } finally { + await sim.close() + } + }) + + test.each(models)('sign normal -- stop dissolve', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + const txBlobStr = + 'd9d9f7a167636f6e74656e74a66361726751620b10e387b497ee96e3a8f20112021a006b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b1698b7bc219b61006b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' + + const txBlob = Buffer.from(txBlobStr, 'hex') + + const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + + await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_stopdissolve`, m.name === 'nanos' ? 2 : 3) + + const signatureResponse = await respRequest + console.log(signatureResponse) + + expect(signatureResponse.returnCode).toEqual(0x9000) + expect(signatureResponse.errorMessage).toEqual('No errors') + + } finally { + await sim.close() + } + }) + + test.each(models)('sign normal -- disburse', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + const txBlobStr = + 'd9d9f7a167636f6e74656e74a6636172675839620a10a7d18aaad3a2a2c6131a2b0a0508959aef3a12220a2068d518e2fd2be6566e62c36611b9794dfcbc04eb4227eefb73ab3c7a2d0ae5776b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b169bc8985c330d006b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' + + const txBlob = Buffer.from(txBlobStr, 'hex') + + const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + + await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_disburse`, m.name === 'nanos' ? 5 : 6) + + const signatureResponse = await respRequest + console.log(signatureResponse) + + expect(signatureResponse.returnCode).toEqual(0x9000) + expect(signatureResponse.errorMessage).toEqual('No errors') + + } finally { + await sim.close() + } + }) + + test.each(models)('sign normal -- list neurons', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + const txBlobStr = + 'd9d9f7a167636f6e74656e74a6636172674210016b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b169bc0d5904b7e806b6d6574686f645f6e616d656f6c6973745f6e6575726f6e735f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' + const txBlob = Buffer.from(txBlobStr, 'hex') + + const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + + await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_listneurons`, m.name === 'nanos' ? 1 : 2) + + const signatureResponse = await respRequest + console.log(signatureResponse) + + expect(signatureResponse.returnCode).toEqual(0x9000) + expect(signatureResponse.errorMessage).toEqual('No errors') + + } finally { + await sim.close() + } + }) + + test.each(models)('sign normal -- spawn', async function (m) { + const sim = new Zemu(m.path) + try { + await sim.start({ ...defaultOptions, model: m.name }) + const app = new InternetComputerApp(sim.getTransport()) + + const txBlobStr = + 'd9d9f7a167636f6e74656e74a6636172674f620b10f5c88584a9f98ded910122006b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b169bc108342f99006b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' + const txBlob = Buffer.from(txBlobStr, 'hex') + + const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) + + // Wait until we are not in the main menu + await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) + + await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_spawn`, m.name === 'nanos' ? 3 : 4) + + const signatureResponse = await respRequest + console.log(signatureResponse) + + expect(signatureResponse.returnCode).toEqual(0x9000) + expect(signatureResponse.errorMessage).toEqual('No errors') + + } finally { + await sim.close() + } + }) +}) diff --git a/tests_zemu/tests/standard.test.ts b/tests_zemu/tests/standard.test.ts index f2d0d865..e8632931 100644 --- a/tests_zemu/tests/standard.test.ts +++ b/tests_zemu/tests/standard.test.ts @@ -374,289 +374,4 @@ describe('Standard', function () { await sim.close() } }) - - test.each(models)('sign normal -- Increase Neuron Timer', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...defaultOptions, model: m.name }) - const app = new InternetComputerApp(sim.getTransport()) - - const pkhex = - '0410d34980a51af89d3331ad5fa80fe30d8868ad87526460b3b3e15596ee58e812422987d8589ba61098264df5bb9c2d3ff6fe061746b4b31a44ec26636632b835' - - const txBlobStr = - 'd9d9f7a367636f6e74656e74a76c726571756573745f747970656463616c6c656e6f6e636550732123f52b79b4a4de9b89e0cc3de7586e696e67726573735f6578706972791b1674db8a3bb843006673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e3026b63616e69737465725f69644a000000000000000101016b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f7062636172674c0a02107b12060a040880a3056d73656e6465725f7075626b657958583056301006072a8648ce3d020106052b8104000a03420004e1142e1fbc940344d9161709196bb8bd151f94379c48dd507ab99a0776109128b94b5303cf2b2d28e25a779da175b62f8a975599b20c63d5193202640576ec5e6a73656e6465725f7369675840953620923534b8840d057341bfaf4511dfa73f57372e7946aed83bfde737e44c5c3005b6f19d4342b9e46c78b2c6fa4f67cf203d6a7cab51a84aa486b459536b' - const txBlob = Buffer.from(txBlobStr, 'hex') - - const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - - await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_increaseTimer_normal`, m.name === 'nanos' ? 3 : 4) - - const signatureResponse = await respRequest - console.log(signatureResponse) - - expect(signatureResponse.returnCode).toEqual(0x9000) - expect(signatureResponse.errorMessage).toEqual('No errors') - - const hash = sha256.hex(signatureResponse.preSignHash) - - const pk = Uint8Array.from(Buffer.from(pkhex, 'hex')) - expect(pk.byteLength).toEqual(65) - const digest = Uint8Array.from(Buffer.from(hash, 'hex')) - const signature = Uint8Array.from(signatureResponse.signatureRS) - //const signature = secp256k1.signatureImport(Uint8Array.from(signatureResponse.signatureDER)); - expect(signature.byteLength).toEqual(64) - - const signatureOk = secp256k1.ecdsaVerify(signature, digest, pk) - expect(signatureOk).toEqual(true) - } finally { - await sim.close() - } - }) - - test.each(models)('sign normal -- stake transfer', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...defaultOptions, model: m.name }) - const app = new InternetComputerApp(sim.getTransport()) - - const expected_pk = - '0410d34980a51af89d3331ad5fa80fe30d8868ad87526460b3b3e15596ee58e812422987d8589ba61098264df5bb9c2d3ff6fe061746b4b31a44ec26636632b835' - - const txBlobStr = - 'd9d9f7a167636f6e74656e74a663617267583e0a0a08f2d4a0eca697869f0812070a050880c2d72f1a0308904e2a220a20a8a1abecdb66f57eb6eba44c3b5f11a6c433fe932680a9519b064b80ca8794e16b63616e69737465725f69644a000000000000000201016e696e67726573735f6578706972791b16985a582755f1806b6d6574686f645f6e616d656773656e645f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' - - const txBlob = Buffer.from(txBlobStr, 'hex') - - const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.STAKE_TX) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - - await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_staketx_normal`, m.name === 'nanos' ? 8 : 9) - - const signatureResponse = await respRequest - console.log(signatureResponse) - - expect(signatureResponse.returnCode).toEqual(0x9000) - expect(signatureResponse.errorMessage).toEqual('No errors') - - const hash = sha256.hex(signatureResponse.preSignHash) - - const pk = Uint8Array.from(Buffer.from(expected_pk, 'hex')) - const digest = Uint8Array.from(Buffer.from(hash, 'hex')) - const signature = Uint8Array.from(signatureResponse.signatureRS) - expect(signature.byteLength).toEqual(64) - - const signatureOk = secp256k1.ecdsaVerify(signature, digest, pk) - expect(signatureOk).toEqual(true) - } finally { - await sim.close() - } - }) - - test.each(models)('sign normal -- add hotkey', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...defaultOptions, model: m.name }) - const app = new InternetComputerApp(sim.getTransport()) - - const txBlobStr = - 'd9d9f7a167636f6e74656e74a6636172675832620b10b98488e0c7a8cec9bd01122322210a1f0a1d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e3026b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b1698b4cd1475e3c06b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' - - const txBlob = Buffer.from(txBlobStr, 'hex') - - const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - - await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_addHotkey`, m.name === 'nanos' ? 4 : 5) - - const signatureResponse = await respRequest - console.log(signatureResponse) - - expect(signatureResponse.returnCode).toEqual(0x9000) - expect(signatureResponse.errorMessage).toEqual('No errors') - - } finally { - await sim.close() - } - }) - - test.each(models)('sign normal -- remove hotkey', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...defaultOptions, model: m.name }) - const app = new InternetComputerApp(sim.getTransport()) - - const txBlobStr = - 'd9d9f7a167636f6e74656e74a6636172675832620b10b98488e0c7a8cec9bd0112232a210a1f0a1d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e3026b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b1698b5366ada7f006b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' - - const txBlob = Buffer.from(txBlobStr, 'hex') - - const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - - await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_removeHotkey`, m.name === 'nanos' ? 4 : 5) - - const signatureResponse = await respRequest - console.log(signatureResponse) - - expect(signatureResponse.returnCode).toEqual(0x9000) - expect(signatureResponse.errorMessage).toEqual('No errors') - - } finally { - await sim.close() - } - }) - - - test.each(models)('sign normal -- start dissolve', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...defaultOptions, model: m.name }) - const app = new InternetComputerApp(sim.getTransport()) - - const txBlobStr = - 'd9d9f7a167636f6e74656e74a66361726751620b10e387b497ee96e3a8f201120212006b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b1698b7b6ae33de406b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' - - const txBlob = Buffer.from(txBlobStr, 'hex') - - const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - - await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_startdissolve`, m.name === 'nanos' ? 2 : 3) - - const signatureResponse = await respRequest - console.log(signatureResponse) - - expect(signatureResponse.returnCode).toEqual(0x9000) - expect(signatureResponse.errorMessage).toEqual('No errors') - - } finally { - await sim.close() - } - }) - - test.each(models)('sign normal -- stop dissolve', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...defaultOptions, model: m.name }) - const app = new InternetComputerApp(sim.getTransport()) - - const txBlobStr = - 'd9d9f7a167636f6e74656e74a66361726751620b10e387b497ee96e3a8f20112021a006b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b1698b7bc219b61006b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' - - const txBlob = Buffer.from(txBlobStr, 'hex') - - const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - - await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_stopdissolve`, m.name === 'nanos' ? 2 : 3) - - const signatureResponse = await respRequest - console.log(signatureResponse) - - expect(signatureResponse.returnCode).toEqual(0x9000) - expect(signatureResponse.errorMessage).toEqual('No errors') - - } finally { - await sim.close() - } - }) - - test.each(models)('sign normal -- disburse', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...defaultOptions, model: m.name }) - const app = new InternetComputerApp(sim.getTransport()) - - const txBlobStr = - 'd9d9f7a167636f6e74656e74a6636172675839620a10a7d18aaad3a2a2c6131a2b0a0508959aef3a12220a2068d518e2fd2be6566e62c36611b9794dfcbc04eb4227eefb73ab3c7a2d0ae5776b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b169bc8985c330d006b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' - - const txBlob = Buffer.from(txBlobStr, 'hex') - - const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - - await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_disburse`, m.name === 'nanos' ? 5 : 6) - - const signatureResponse = await respRequest - console.log(signatureResponse) - - expect(signatureResponse.returnCode).toEqual(0x9000) - expect(signatureResponse.errorMessage).toEqual('No errors') - - } finally { - await sim.close() - } - }) - - test.each(models)('sign normal -- list neurons', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...defaultOptions, model: m.name }) - const app = new InternetComputerApp(sim.getTransport()) - - const txBlobStr = - 'd9d9f7a167636f6e74656e74a6636172674210016b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b169bc0d5904b7e806b6d6574686f645f6e616d656f6c6973745f6e6575726f6e735f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' - const txBlob = Buffer.from(txBlobStr, 'hex') - - const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - - await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_listneurons`, m.name === 'nanos' ? 1 : 2) - - const signatureResponse = await respRequest - console.log(signatureResponse) - - expect(signatureResponse.returnCode).toEqual(0x9000) - expect(signatureResponse.errorMessage).toEqual('No errors') - - } finally { - await sim.close() - } - }) - - test.each(models)('sign normal -- spawn', async function (m) { - const sim = new Zemu(m.path) - try { - await sim.start({ ...defaultOptions, model: m.name }) - const app = new InternetComputerApp(sim.getTransport()) - - const txBlobStr = - 'd9d9f7a167636f6e74656e74a6636172674f620b10f5c88584a9f98ded910122006b63616e69737465725f69644a000000000000000101016e696e67726573735f6578706972791b169bc108342f99006b6d6574686f645f6e616d65706d616e6167655f6e6575726f6e5f70626c726571756573745f747970656463616c6c6673656e646572581d19aa3d42c048dd7d14f0cfa0df69a1c1381780f6e9a137abaa6a82e302' - const txBlob = Buffer.from(txBlobStr, 'hex') - - const respRequest = app.sign("m/44'/223'/0'/0/0", txBlob, SIGN_VALUES_P2.DEFAULT) - - // Wait until we are not in the main menu - await sim.waitUntilScreenIsNot(sim.getMainMenuSnapshot()) - - await sim.compareSnapshotsAndAccept('.', `${m.prefix.toLowerCase()}-sign_spawn`, m.name === 'nanos' ? 3 : 4) - - const signatureResponse = await respRequest - console.log(signatureResponse) - - expect(signatureResponse.returnCode).toEqual(0x9000) - expect(signatureResponse.errorMessage).toEqual('No errors') - - } finally { - await sim.close() - } - }) })