feat: unit-test with cmocka

- Test only 1 function which is in utils2.c
    - Because is not inlude nano sdk
- Move zemu's into functional folder
    - Change path of zemu's test in CI and Makefile
This commit is contained in:
Alexandre Paillier
2022-06-28 14:38:19 +02:00
committed by Coline
parent 4eb7109b86
commit ad8334e54c
356 changed files with 573 additions and 11 deletions

View File

@@ -114,13 +114,13 @@ jobs:
- uses: actions/checkout@v2
- name: Build testing binaries
run: cd tests && ./build_local_test_elfs.sh
run: cd tests/functional/ && ./build_local_test_elfs.sh
- name: Upload app binaries
uses: actions/upload-artifact@v2
with:
name: e2e_elfs
path: ./tests/elfs/
path: ./tests/functional/elfs/
jobs-e2e-tests:
name: E2E tests
@@ -146,10 +146,10 @@ jobs:
run: npm install -g yarn
- name: Build/Install build js deps
run: cd tests && yarn install
run: cd tests/functional/ && yarn install
- name: Create tmp folder for artifacts
run: mkdir tests/elfs
run: mkdir tests/functional/elfs
- name: Download app binaries
uses: actions/download-artifact@v2
@@ -157,7 +157,7 @@ jobs:
path: tmp/
- name: Gather elfs
run: cp `find tmp/e2e_elfs/ -name "*.elf"` tests/elfs/
run: cp `find tmp/e2e_elfs/ -name "*.elf"` tests/functional/elfs/
- name: Run zemu tests
run: cd tests && yarn test
run: cd tests/functional/ && yarn test

1
.gitignore vendored
View File

@@ -18,3 +18,4 @@ tests/elfs/*
tests/snapshots-tmp
.vscode
.idea

View File

@@ -222,13 +222,16 @@ delete:
python3 -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS)
install_tests:
cd tests && (yarn install || sudo yarn install)
cd tests/functional/ && (yarn install || sudo yarn install)
run_tests:
cd tests && (yarn test || sudo yarn test)
cd tests/functional/ && (yarn test || sudo yarn test)
test: install_tests run_tests
unit-test:
make -C tests/unit
# import generic rules from the sdk
include $(BOLOS_SDK)/Makefile.rules

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

22
tests/functional/jest.js Normal file
View File

@@ -0,0 +1,22 @@
export default jest;
export const { expect, test } = global;
export const sim_options_s = {
model: "nanos",
logging: true,
start_delay: 2000,
X11: true,
custom: "",
};
export const sim_options_x = {
model: "nanox",
logging: true,
start_delay: 2000,
X11: true,
custom: "",
};
export const Resolve = require("path").resolve;
export const NANOS_ELF_PATH = Resolve("elfs/ethereum_nanos.elf");
export const NANOX_ELF_PATH = Resolve("elfs/ethereum_nanox.elf");

View File

@@ -0,0 +1,22 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _test = require("./test.fixture");
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Approve DAI tokens', (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/1'/0/0", 'F869468506A8B15E0082EBEB946B175474E89094C44DA98B954EEDEAC495271D0F80B844095EA7B30000000000000000000000007D2768DE32B0B80B7A3454C06BDAC94A69DDC7A9FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF018080');
let clicks;
if (model.letter === 'S') clicks = 8;else clicks = 6;
await (0, _test.waitForAppScreen)(sim);
await sim.navigateAndCompareSnapshots('.', model.name + '_approve_dai_tokens', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "92243511396b65a4faa735a5472ea99b3ce0f7f2338eab426206730bc0ddc57f",
"s": "161bc0f861064d840de4f4304cfd19a571017e62df7d8f70cf605c0f025593b6",
"v": "25"
});
}));
});

View File

@@ -0,0 +1,24 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _test = require("./test.fixture");
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Deposit ETH on compound, blind sign', (0, _test.zemu)(model, async (sim, eth) => {
// Enable blind-signing
await sim.navigateAndCompareSnapshots('.', model.name + '_enable_blind_signing', [-2, 0, 0, 3, 0]);
const tx = eth.signTransaction("44'/60'/1'/0/0", 'f8924685028fa6ae008306599594cc9a0b7c43dc2a5f023bb9b738e45b0ef6b06e0488016345785d8a0000b864474cf53d0000000000000000000000007d2768de32b0b80b7a3454c06bdac94a69ddc7a900000000000000000000000070bc641723fad48be2df6cf63dc6270ee2f897430000000000000000000000000000000000000000000000000000000000000000018080');
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = 8;else clicks = 6;
await sim.navigateAndCompareSnapshots('.', model.name + '_deposit_eth_compound_blind', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "b5ae3a011eb50e7d1fe9f5e6f6d91ca9f4dfca5f73805fc4866d49e72ead2f5c",
"s": "3c6e55db5925586bb58e434b58b2c04756f662131597f98c1aa2418b16992b81",
"v": "26"
});
}));
});

View File

@@ -0,0 +1,37 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _test = require("./test.fixture");
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Transfer on network 112233445566 on Ethereum', (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/1'/0/0", 'f044850306dc4200825208945a321744667052affa8386ed49e00ef223cbffc3876f9c9e7bf6181880851a21a278be8080');
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = 10;else clicks = 6;
await sim.navigateAndCompareSnapshots('.', model.name + '_transfer_112233445566_network', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "509981d8dfb66757e25ff47c009b9b5bc5db0f169473e4735f5212b144f1c069",
"s": "5db989d81025de3c846e41a9ce01a3f9fd0982e2d827f1b88ffc95d73a48d04c",
"v": "344344f19f"
});
}));
});
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Transfer on palm network on Ethereum', (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/1'/0/0", 'f044850306dc4200825208945a321744667052affa8386ed49e00ef223cbffc3876f9c9e7bf61818808502a15c308d8080');
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = 10;else clicks = 6;
await sim.navigateAndCompareSnapshots('.', model.name + '_transfer_palm_network', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "946700c4972b3da24ddaa95e590ad25a8f905da62e2bd053285a4cc17f93f490",
"s": "3698e84564e58477a49f7a9cea572ef5d672a5538db08f3ee42df5eb75a1b907",
"v": "0542b8613d"
});
}));
});

View File

@@ -0,0 +1,30 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _jest = require("../jest");
var _errors = require("@ledgerhq/errors");
var _test = require("./test.fixture");
var _zemu = _interopRequireDefault(require("@zondax/zemu"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Try to blind sign with setting disabled', (0, _test.zemu)(model, async (sim, eth) => {
// we can't use eth.signTransaction because it detects that contract data is disabled and fails early
let transport = await sim.getTransport();
let buffer = Buffer.from("058000002c8000003c800000010000000000000000f849208506fc23ac008303dc3194f650c3d88d12db855b8bf7d11be6c55a4e07dcc980a4a1712d6800000000000000000000000000000000000000000000000000000000000acbc7018080", "hex");
let tx = transport.send(0xe0, 0x04, 0x00, 0x00, buffer);
await (0, _jest.expect)(tx).rejects.toEqual(new _errors.TransportStatusError(0x6a80));
await _zemu.default.sleep(1000);
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = [1, 0];else clicks = [0];
await sim.navigateAndCompareSnapshots('.', model.name + '_try_to_blind_sign_with_setting_disabled', clicks);
}));
});

View File

@@ -0,0 +1,22 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _test = require("./test.fixture");
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Transfer eip1559', (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/0'/0/0", '02f87001018502540be4008502540be40086246139ca800094cccccccccccccccccccccccccccccccccccccccc8000c001a0e07fb8a64ea3786c9a6649e54429e2786af3ea31c6d06165346678cf8ce44f9ba00e4a0526db1e905b7164a858fd5ebd2f1759e22e6955499448bd276a6aa62830');
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = 7;else clicks = 5;
await sim.navigateAndCompareSnapshots('.', model.name + '_transfer_eip1559', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "3d6dfabc6c52374bfa34cb2c433856a0bcd9484870dd1b50249f7164a5fce052",
"s": "0548a774dd0b63930d83cb2e1a836fe3ef24444e8b758b00585d9a076c0e98a8",
"v": "01"
});
}));
});

View File

@@ -0,0 +1,65 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _zemu = _interopRequireDefault(require("@zondax/zemu"));
var _errors = require("@ledgerhq/errors");
var _test = require("./test.fixture");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Only LNX
const model = _test.nano_models[1];
{
const set_plugin = (0, _test.apdu_as_string)('e01600007401010745524331313535495f947276749ce646f68ac8c248420045cb7b5ef242432a00000000000000010001473045022100ec4377d17e8d98d424bf16b29c691bc1a010825fb5b8a35de0268a9dc22eab2402206701b016fe6718bf519d18cc12e9838e9ef898cc4c143017839023c3260b2d74');
const provide_nft_info = (0, _test.apdu_as_string)('e01400007b0101124f70656e53656120436f6c6c656374696f6e495f947276749ce646f68ac8c248420045cb7b5e0000000000000001000147304502210083e357a828f13d574b1296214a3749c194ab1df1f8a243655c053b1c72f91e0c02201ed93cfac7e87759445c4da2e4bfd6e1cf0405ea37c7293bc965948f51bef5cc');
const sign_first = (0, _test.apdu_as_string)('e004000096058000002c8000003c800000000000000000000000f901090b8520b673dd0082bcb394495f947276749ce646f68ac8c248420045cb7b5e80b8e4f242432a0000000000000000000000006cbcd73cd8e8a42844662f0a0e76d7f79afd933d000000000000000000000000c2907efcce4011c491bbeda8a0fa63ba7aab596cabf06640f8ca8fc5e0ed471b10befcdf65a33e4300000000');
const sign_more = (0, _test.apdu_as_string)('e00480008b00006a0000000064000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000043078303000000000000000000000000000000000000000000000000000000000018080');
test('[Nano ' + model.letter + '] Transfer ERC-1155', (0, _test.zemu)(model, async (sim, eth) => {
const current_screen = sim.getMainMenuSnapshot();
await (0, _test.send_apdu)(eth.transport, set_plugin);
await (0, _test.send_apdu)(eth.transport, provide_nft_info);
await (0, _test.send_apdu)(eth.transport, sign_first);
let sign_promise = (0, _test.send_apdu)(eth.transport, sign_more);
await (0, _test.waitForAppScreen)(sim, current_screen);
await sim.navigateAndCompareSnapshots('.', model.name + '_erc1155_transfer', [10, -1, 0]);
await sign_promise;
}));
test('[Nano ' + model.letter + '] Transfer ERC-1155 w/o PROVIDE_NFT_INFORMATION', (0, _test.zemu)(model, async (sim, eth) => {
const current_screen = sim.getMainMenuSnapshot();
await (0, _test.send_apdu)(eth.transport, set_plugin);
await (0, _test.send_apdu)(eth.transport, sign_first);
let sign_promise = (0, _test.send_apdu)(eth.transport, sign_more);
await (0, _test.waitForAppScreen)(sim, current_screen);
await sim.navigateAndCompareSnapshots('.', model.name + '_erc1155_transfer_wo_info', [10, -1, 0]);
await sign_promise;
}));
test('[Nano ' + model.letter + '] Transfer ERC-1155 w/o SET_PLUGIN', (0, _test.zemu)(model, async (sim, eth) => {
const current_screen = sim.getMainMenuSnapshot();
await (0, _test.send_apdu)(eth.transport, provide_nft_info);
let sign_tx = (0, _test.send_apdu)(eth.transport, sign_first);
await expect(sign_tx).rejects.toEqual(new _errors.TransportStatusError(0x6a80));
}));
}
test('[Nano ' + model.letter + '] Batch transfer ERC-1155', (0, _test.zemu)(model, async (sim, eth) => {
const set_plugin = (0, _test.apdu_as_string)('e01600007401010745524331313535495f947276749ce646f68ac8c248420045cb7b5e2eb2c2d60000000000000001000147304502210087b35cefc53fd94e25404933eb0d5ff08f20ba655d181de3b24ff0099dc3317f02204a216aa9e0b84bef6e20fcb036bd49647bf0cab66732b99b49ec277ffb682aa1');
const provide_nft_info = (0, _test.apdu_as_string)('e0140000820101194f70656e536561205368617265642053746f726566726f6e74495f947276749ce646f68ac8c248420045cb7b5e00000000000000010001473045022100c74cd613a27a9f4887210f5a3a0e12745e1ba0ab3a0d284cb6485d89c3cce4e602205a13e62a91164985cf58a838f8f531c0b91b980d206a5ba8df28270023ef93a3');
const sign_first = (0, _test.apdu_as_string)('e004000096058000002c8000003c800000000000000000000000f9020b0e850d8cfd86008301617d94495f947276749ce646f68ac8c248420045cb7b5e80b901e42eb2c2d60000000000000000000000006cbcd73cd8e8a42844662f0a0e76d7f79afd933d000000000000000000000000c2907efcce4011c491bbeda8a0fa63ba7aab596c00000000000000000000000000000000000000000000');
const sign_more_1 = (0, _test.apdu_as_string)('e004800096000000000000000000a0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000003abf06640f8ca8fc5e0ed471b10befcdf65a33e430000000000006a0000000064def9d99ff495856496c028c0');
const sign_more_2 = (0, _test.apdu_as_string)('e00480009689732473fcd0bbbe000000000000a30000000001abf06640f8ca8fc5e0ed471b10befcdf65a33e430000000000006a00000000640000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000010000');
const sign_more_3 = (0, _test.apdu_as_string)('e00480006100000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000043078303000000000000000000000000000000000000000000000000000000000018080');
const current_screen = sim.getMainMenuSnapshot();
await (0, _test.send_apdu)(eth.transport, set_plugin);
await (0, _test.send_apdu)(eth.transport, provide_nft_info);
await (0, _test.send_apdu)(eth.transport, sign_first);
await (0, _test.send_apdu)(eth.transport, sign_more_1);
await (0, _test.send_apdu)(eth.transport, sign_more_2);
let sign_promise = (0, _test.send_apdu)(eth.transport, sign_more_3);
await (0, _test.waitForAppScreen)(sim, current_screen);
await sim.navigateAndCompareSnapshots('.', model.name + '_erc1155_batch_transfer', [8, -1, 0]);
await sign_promise;
}));

View File

@@ -0,0 +1,45 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _zemu = _interopRequireDefault(require("@zondax/zemu"));
var _errors = require("@ledgerhq/errors");
var _test = require("./test.fixture");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Only LNX
const model = _test.nano_models[1];
const set_plugin = (0, _test.apdu_as_string)('e01600007301010645524337323160f80121c31a0d46b5279700f9df786054aa5ee542842e0e0000000000000001000147304502202e2282d7d3ea714da283010f517af469e1d59654aaee0fc438f017aa557eaea50221008b369679381065bbe01135723a4f9adb229295017d37c4d30138b90a51cf6ab6');
const provide_nft_info = (0, _test.apdu_as_string)('e01400007001010752617269626c6560f80121c31a0d46b5279700f9df786054aa5ee500000000000000010001473045022025696986ef5f0ee2f72d9c6e41d7e2bf2e4f06373ab26d73ebe326c7fd4c7a6602210084f6b064d8750ae68ed5dd012296f37030390ec06ff534c5da6f0f4a4460af33');
const sign_first = (0, _test.apdu_as_string)('e004000096058000002c8000003c800000000000000000000000f88a0a852c3ce1ec008301f5679460f80121c31a0d46b5279700f9df786054aa5ee580b86442842e0e0000000000000000000000006cbcd73cd8e8a42844662f0a0e76d7f79afd933d000000000000000000000000c2907efcce4011c491bbeda8a0fa63ba7aab596c000000000000000000000000000000000000000000000000');
const sign_more = (0, _test.apdu_as_string)('e00480000b0000000000112999018080');
test('[Nano ' + model.letter + '] Transfer ERC-721', (0, _test.zemu)(model, async (sim, eth) => {
const current_screen = sim.getMainMenuSnapshot();
await (0, _test.send_apdu)(eth.transport, set_plugin);
await (0, _test.send_apdu)(eth.transport, provide_nft_info);
await (0, _test.send_apdu)(eth.transport, sign_first);
let sign_promise = (0, _test.send_apdu)(eth.transport, sign_more);
await (0, _test.waitForAppScreen)(sim, current_screen);
await sim.navigateAndCompareSnapshots('.', model.name + '_erc721_transfer', [8, -1, 0]);
await sign_promise;
}));
test('[Nano ' + model.letter + '] Transfer ERC-721 w/o NFT_PROVIDE_INFORMATION', (0, _test.zemu)(model, async (sim, eth) => {
const current_screen = sim.getMainMenuSnapshot();
await (0, _test.send_apdu)(eth.transport, set_plugin);
await (0, _test.send_apdu)(eth.transport, sign_first);
let sign_promise = (0, _test.send_apdu)(eth.transport, sign_more);
await (0, _test.waitForAppScreen)(sim, current_screen);
await sim.navigateAndCompareSnapshots('.', model.name + '_erc721_transfer_wo_info', [8, -1, 0]);
await sign_promise;
}));
test('[Nano ' + model.letter + '] Transfer ERC-721 w/o SET_PLUGIN', (0, _test.zemu)(model, async (sim, eth) => {
const current_screen = sim.getMainMenuSnapshot();
await (0, _test.send_apdu)(eth.transport, provide_nft_info);
let sign_tx = (0, _test.send_apdu)(eth.transport, sign_first);
await expect(sign_tx).rejects.toEqual(new _errors.TransportStatusError(0x6a80));
}));

View File

@@ -0,0 +1,46 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _test = require("./test.fixture");
var _errors = require("@ledgerhq/errors");
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Transfer Ether on Ethereum app', (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/1'/0/0", 'EB44850306DC4200825208945A321744667052AFFA8386ED49E00EF223CBFFC3876F9C9E7BF6181880018080');
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = 9;else clicks = 5;
await sim.navigateAndCompareSnapshots('.', model.name + '_transfer_ethereum', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "6f389d15320f0501383526ed03de917c14212716f09a262dbc98431086a5db49",
"s": "0dc994b7b97230bb35fdf6fec2f4d8ff4cfb8bfeb2a652c364c738ff033c05dd",
"v": "26"
});
}));
});
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Transfer amount >= 2^87 Eth on Ethereum app should fail', (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/1'/0/0", 'f83f268e02cc9be5c53ea44bd43c289dcddc82520894dac17f958d2ee523a2206206994597c13d831ec7928db8b0861b8f7fe5df83cd553a829878000080018080');
await expect(tx).rejects.toEqual(new _errors.TransportStatusError(0x6807));
}));
});
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Transfer Ether on network 5234 on Ethereum app', (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/1'/0/0", 'ED44850306DC4200825208945A321744667052AFFA8386ED49E00EF223CBFFC3876F9C9E7BF61818808214728080');
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = 10;else clicks = 6;
await sim.navigateAndCompareSnapshots('.', model.name + '_transfer_ethereum_5234_network', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "07a7982dfd16360c96a03467877d0cf9c36f799deff4dace250cdb18e28a3b90",
"s": "773318a93da2e32c1cf308ddd6add1e8c0d285973e541520a05fb4dc720e4fb1",
"v": "2908"
});
}));
});

View File

@@ -0,0 +1,22 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _test = require("./test.fixture");
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Transfer bsc', (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/1'/0/0", 'EB0185012A05F200825208945A321744667052AFFA8386ED49E00EF223CBFFC3876F9C9E7BF6181880388080');
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = 10;else clicks = 6;
await sim.navigateAndCompareSnapshots('.', model.name + '_transfer_bsc', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "f667cc34e9815df4f052fb3463cdbe355fff5c1acf4e919b3539806521a059ad",
"s": "6b35492b7108d9d9e1cc7aede536ed6b3173197b56dd873cbc3b43e041d6f407",
"v": "93"
});
}));
});

View File

@@ -0,0 +1,31 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _errors = require("@ledgerhq/errors");
var _test = require("./test.fixture");
_test.nano_models.forEach(function (model) {
test("[Nano " + model.letter + "] Transfer on Ethereum clone app", (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/0'/0/0", 'EB44850306DC4200825208945A321744667052AFFA8386ED49E00EF223CBFFC3876F9C9E7BF61818803D8080');
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = 9;else clicks = 5;
await sim.navigateAndCompareSnapshots('.', model.name + '_transfer_ethereum_clone', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "60df850d297e355596f87dc313a742032de4b59c5579186b3d59bdf31402fec0",
"s": "23c3a2beacabc1943d487a2e1d545e4c46c718b1e70e9d1c11a98828c9338927",
"v": "9e"
});
}, true));
});
_test.nano_models.forEach(function (model) {
test("[Nano " + model.letter + "] Transfer on network 5234 on Ethereum clone", (0, _test.zemu)(model, async (sim, eth) => {
const tx = eth.signTransaction("44'/60'/0'/0/0", 'ED44850306DC4200825208945A321744667052AFFA8386ED49E00EF223CBFFC3876F9C9E7BF61818808214728080');
await expect(tx).rejects.toEqual(new _errors.EthAppPleaseEnableContractData("Please enable Contract data on the Ethereum app Settings"));
}, true));
});

View File

@@ -0,0 +1,32 @@
"use strict";
require("core-js/stable");
require("regenerator-runtime/runtime");
var _test = require("./test.fixture");
var _erc = require("@ledgerhq/hw-app-eth/erc20");
var _bignumber = require("bignumber.js");
_test.nano_models.forEach(function (model) {
test('[Nano ' + model.letter + '] Transfer Ether on Ethereum app', (0, _test.zemu)(model, async (sim, eth) => {
// Provide USDT token info to the app
const usdt_info = (0, _erc.byContractAddressAndChainId)("0xdac17f958d2ee523a2206206994597c13d831ec7", 1);
await eth.provideERC20TokenInformation(usdt_info); // Provide Stark quantum
const quantization = new _bignumber.BigNumber(1);
await eth.starkProvideQuantum_v2("0xdac17f958d2ee523a2206206994597c13d831ec7", "erc20", quantization, null);
const tx = eth.signTransaction("44'/60'/1'/0/0", 'f8b5018a0472698b413b43200000825208940102030405060708090a0b0c0d0e0f1011121314872bd72a24874000b8842505c3d9010101010101010102020202020202020303030303030303040404040404040402ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000030d40808080');
await (0, _test.waitForAppScreen)(sim);
let clicks;
if (model.letter === 'S') clicks = 14;else clicks = 10;
await sim.navigateAndCompareSnapshots('.', model.name + '_starkware_usdt_deposit', [clicks, -1, 0]);
await expect(tx).resolves.toEqual({
"r": "14c368c0d32e399470d6113cf796c5f4cd70300766337d8b0ba71ecad21b3d52",
"s": "4207c027959e84fc2242a1f4fd955603f137ba28f67268ffc91fef5d65071b0a",
"v": "1c"
});
}));
});

View File

@@ -0,0 +1,138 @@
"use strict";
var _zemu = _interopRequireWildcard(require("@zondax/zemu"));
var _hwAppEth = _interopRequireDefault(require("@ledgerhq/hw-app-eth"));
var _utils = require("ethers/lib/utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
const transactionUploadDelay = 60000;
async function waitForAppScreen(sim, current_screen = null) {
if (current_screen === null) current_screen = sim.getMainMenuSnapshot();
await sim.waitUntilScreenIsNot(current_screen, transactionUploadDelay);
}
const sim_options_nano = { ..._zemu.DEFAULT_START_OPTIONS,
logging: true,
X11: true,
startText: 'is ready'
};
const Resolve = require('path').resolve;
const NANOS_ELF_PATH = Resolve('elfs/ethereum_nanos.elf');
const NANOX_ELF_PATH = Resolve('elfs/ethereum_nanox.elf');
const NANOS_CLONE_ELF_PATH = Resolve("elfs/ethereum_classic_nanos.elf");
const NANOX_CLONE_ELF_PATH = Resolve("elfs/ethereum_classic_nanox.elf");
const nano_models = [{
name: 'nanos',
letter: 'S',
path: NANOS_ELF_PATH,
clone_path: NANOS_CLONE_ELF_PATH
}, {
name: 'nanox',
letter: 'X',
path: NANOX_ELF_PATH,
clone_path: NANOX_CLONE_ELF_PATH
}];
const TIMEOUT = 1000000; // useful to take an apdu as a hex string and convert its JS representation
function apdu_as_string(str) {
let buffer = [];
for (let i = 0; i < str.length; i += 2) {
const str_extract = str.substring(i, i + 2);
buffer[i / 2] = parseInt(str_extract, 16);
}
return {
cla: buffer[0],
ins: buffer[1],
p1: buffer[2],
p2: buffer[3],
data: Buffer.from(buffer.slice(5))
};
}
async function send_apdu(ts, apdu) {
return ts.send(apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.data);
} // Generates a serializedTransaction from a rawHexTransaction copy pasted from etherscan.
function txFromEtherscan(rawTx) {
// Remove 0x prefix
rawTx = rawTx.slice(2);
let txType = rawTx.slice(0, 2);
if (txType == "02" || txType == "01") {
// Remove "02" prefix
rawTx = rawTx.slice(2);
} else {
txType = "";
}
let decoded = _utils.RLP.decode("0x" + rawTx);
if (txType != "") {
decoded = decoded.slice(0, decoded.length - 3); // remove v, r, s
} else {
decoded[decoded.length - 1] = "0x"; // empty
decoded[decoded.length - 2] = "0x"; // empty
decoded[decoded.length - 3] = "0x01"; // chainID 1
} // Encode back the data, drop the '0x' prefix
let encoded = _utils.RLP.encode(decoded).slice(2); // Don't forget to prepend the txtype
return txType + encoded;
}
function zemu(device, func, start_clone = false) {
return async () => {
jest.setTimeout(TIMEOUT);
let elf_path;
let lib_elf;
if (start_clone) {
elf_path = device.clone_path;
lib_elf = {
'Ethereum': device.path
};
} else {
elf_path = device.path;
}
const sim = new _zemu.default(elf_path, lib_elf);
try {
await sim.start({ ...sim_options_nano,
model: device.name
});
const transport = await sim.getTransport();
await func(sim, new _hwAppEth.default(transport));
} finally {
await sim.close();
}
};
}
module.exports = {
zemu,
waitForAppScreen,
sim_options_nano,
nano_models,
TIMEOUT,
txFromEtherscan,
apdu_as_string,
send_apdu
};

View File

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 374 B

View File

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 321 B

View File

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 346 B

View File

Before

Width:  |  Height:  |  Size: 469 B

After

Width:  |  Height:  |  Size: 469 B

View File

Before

Width:  |  Height:  |  Size: 511 B

After

Width:  |  Height:  |  Size: 511 B

View File

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 391 B

View File

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

View File

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 414 B

View File

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 340 B

View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

View File

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 374 B

View File

Before

Width:  |  Height:  |  Size: 399 B

After

Width:  |  Height:  |  Size: 399 B

View File

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 305 B

View File

Before

Width:  |  Height:  |  Size: 502 B

After

Width:  |  Height:  |  Size: 502 B

View File

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 485 B

View File

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 387 B

View File

Before

Width:  |  Height:  |  Size: 410 B

After

Width:  |  Height:  |  Size: 410 B

View File

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 414 B

View File

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 340 B

View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

View File

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 531 B

View File

Before

Width:  |  Height:  |  Size: 344 B

After

Width:  |  Height:  |  Size: 344 B

View File

Before

Width:  |  Height:  |  Size: 480 B

After

Width:  |  Height:  |  Size: 480 B

View File

Before

Width:  |  Height:  |  Size: 514 B

After

Width:  |  Height:  |  Size: 514 B

View File

Before

Width:  |  Height:  |  Size: 566 B

After

Width:  |  Height:  |  Size: 566 B

View File

Before

Width:  |  Height:  |  Size: 614 B

After

Width:  |  Height:  |  Size: 614 B

View File

Before

Width:  |  Height:  |  Size: 628 B

After

Width:  |  Height:  |  Size: 628 B

View File

Before

Width:  |  Height:  |  Size: 338 B

After

Width:  |  Height:  |  Size: 338 B

View File

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 531 B

View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

View File

Before

Width:  |  Height:  |  Size: 274 B

After

Width:  |  Height:  |  Size: 274 B

View File

Before

Width:  |  Height:  |  Size: 357 B

After

Width:  |  Height:  |  Size: 357 B

View File

Before

Width:  |  Height:  |  Size: 396 B

After

Width:  |  Height:  |  Size: 396 B

View File

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 361 B

View File

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 434 B

View File

Before

Width:  |  Height:  |  Size: 411 B

After

Width:  |  Height:  |  Size: 411 B

View File

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 281 B

View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

View File

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 374 B

View File

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 359 B

View File

Before

Width:  |  Height:  |  Size: 488 B

After

Width:  |  Height:  |  Size: 488 B

View File

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 477 B

View File

Before

Width:  |  Height:  |  Size: 408 B

After

Width:  |  Height:  |  Size: 408 B

View File

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 391 B

View File

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 420 B

View File

Before

Width:  |  Height:  |  Size: 429 B

After

Width:  |  Height:  |  Size: 429 B

View File

Before

Width:  |  Height:  |  Size: 409 B

After

Width:  |  Height:  |  Size: 409 B

View File

Before

Width:  |  Height:  |  Size: 313 B

After

Width:  |  Height:  |  Size: 313 B

View File

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 315 B

View File

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 281 B

View File

Before

Width:  |  Height:  |  Size: 357 B

After

Width:  |  Height:  |  Size: 357 B

View File

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 414 B

View File

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 340 B

View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

View File

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 374 B

View File

Before

Width:  |  Height:  |  Size: 330 B

After

Width:  |  Height:  |  Size: 330 B

View File

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 451 B

View File

Before

Width:  |  Height:  |  Size: 320 B

After

Width:  |  Height:  |  Size: 320 B

View File

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 497 B

View File

Before

Width:  |  Height:  |  Size: 504 B

After

Width:  |  Height:  |  Size: 504 B

View File

Before

Width:  |  Height:  |  Size: 373 B

After

Width:  |  Height:  |  Size: 373 B

View File

Before

Width:  |  Height:  |  Size: 380 B

After

Width:  |  Height:  |  Size: 380 B

View File

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 367 B

View File

Before

Width:  |  Height:  |  Size: 414 B

After

Width:  |  Height:  |  Size: 414 B

View File

Before

Width:  |  Height:  |  Size: 340 B

After

Width:  |  Height:  |  Size: 340 B

View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

View File

Before

Width:  |  Height:  |  Size: 374 B

After

Width:  |  Height:  |  Size: 374 B

View File

Before

Width:  |  Height:  |  Size: 337 B

After

Width:  |  Height:  |  Size: 337 B

View File

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 451 B

Some files were not shown because too many files have changed in this diff Show More