From df88488956ed9911b60b4f1122806ff79a6ae12b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=82=B4=E2=B1=A033=E2=82=B1?= Date: Thu, 8 Jun 2023 16:46:54 -0400 Subject: [PATCH 1/9] refactor: app structure, tests and workflows (#2) --- .../workflows/build_and_functional_tests.yml | 36 ++ .github/workflows/ci-workflow.yml | 138 +---- .github/workflows/codeql_checks.yml | 46 ++ .github/workflows/coding_style_checks.yml | 26 + .../workflows/documentation_generation.yml | 31 + .github/workflows/guidelines_enforcer.yml | 26 + .github/workflows/lint-workflow.yml | 27 - .github/workflows/misspellings_checks.yml | 30 + .github/workflows/static_analysis.yml | 41 ++ .github/workflows/unit_tests.yml | 52 ++ .vscode/20-ledger.ledgerblue.rules | 1 + .vscode/c_cpp_properties.json | 2 +- .vscode/extensions.json | 5 + .vscode/settings.json | 10 +- .vscode/tasks.json | 190 +++++- Makefile | 143 ++--- README.md | 6 +- doc/APDU.md | 6 +- doc/COMMANDS.md | 60 +- doc/TRANSACTION.md | 8 +- .../TG01_T04_MULTISIGNATURE_REG.md | 60 -- doc/transactions/TG01_T05_IPFS.md | 28 +- doc/transactions/TG01_T06_TRANFER.md | 111 ++-- doc/transactions/TG01_T08_HTLC_LOCK.md | 62 -- doc/transactions/TG01_T09_HTLC_CLAIM.md | 68 --- doc/transactions/TG01_T10_HTLC_REFUND.md | 51 -- doc/transactions/TG02_T00_BURN.md | 24 +- doc/transactions/TG02_T02_VOTE.md | 44 +- ...nanox_app_solar.gif => app_solar_14px.gif} | Bin ...nanos_app_solar.gif => app_solar_16px.gif} | Bin src/address.c | 26 +- src/address.h | 33 +- src/apdu/dispatcher.c | 34 +- src/apdu/dispatcher.h | 27 +- src/apdu/parser.c | 46 -- src/apdu/parser.h | 22 - src/{main.c => app_main.c} | 94 +-- src/common/base58.c | 161 ----- src/common/base58.h | 52 -- src/common/bip32.c | 87 --- src/common/bip32.h | 47 -- src/common/buffer.c | 165 ------ src/common/buffer.h | 192 ------ src/common/format.c | 241 -------- src/common/format.h | 134 ----- src/common/macros.h | 6 - src/common/read.c | 64 -- src/common/read.h | 82 --- src/common/varint.c | 101 ---- src/common/varint.h | 52 -- src/common/write.c | 70 --- src/common/write.h | 82 --- src/constants.h | 67 +-- src/context.c | 3 +- src/context.h | 7 - src/crypto/crypto.c | 9 +- src/crypto/crypto.h | 25 +- src/globals.h | 6 +- src/handler/get_address.c | 46 +- src/handler/get_address.h | 10 +- src/handler/get_app_name.c | 30 +- src/handler/get_app_name.h | 2 - src/handler/get_public_key.c | 30 +- src/handler/get_public_key.h | 27 +- src/handler/get_version.c | 34 +- src/handler/sign_tx.c | 36 +- src/handler/sign_tx.h | 25 +- .../{send_reponse.c => send_response.c} | 32 +- src/helper/send_response.h | 25 +- src/io.c | 159 ----- src/io.h | 56 -- src/sw.h | 27 +- src/transaction/deserialise.c | 35 +- src/transaction/deserialise.h | 30 +- src/transaction/errors.h | 7 - src/transaction/transaction_utils.c | 118 ++++ src/transaction/transaction_utils.h | 63 ++ src/transaction/types.h | 43 +- src/transaction/types/burn.c | 6 +- src/transaction/types/burn.h | 12 +- src/transaction/types/htlc_claim.c | 42 -- src/transaction/types/htlc_claim.h | 31 - src/transaction/types/htlc_lock.c | 52 -- src/transaction/types/htlc_lock.h | 33 -- src/transaction/types/htlc_refund.c | 21 - src/transaction/types/htlc_refund.h | 28 - src/transaction/types/ipfs.c | 6 +- src/transaction/types/ipfs.h | 12 +- .../types/multi_signature_registration.c | 36 -- .../types/multi_signature_registration.h | 34 -- src/transaction/types/transfer.c | 6 +- src/transaction/types/transfer.h | 12 +- src/transaction/types/types.h | 23 +- src/transaction/types/vote.c | 10 +- src/transaction/types/vote.h | 14 +- src/transaction/utils.c | 39 -- src/transaction/utils.h | 44 -- src/types.h | 52 +- src/ui/action/validate.c | 28 +- src/ui/action/validate.h | 23 - src/ui/ctx.c | 5 +- src/ui/ctx.h | 17 +- src/ui/display.c | 76 +-- src/ui/display.h | 23 - src/ui/menu.c | 12 +- src/ui/transactions/burn_display.c | 18 +- src/ui/transactions/burn_display.h | 14 +- src/ui/transactions/htlc_claim_display.c | 49 -- src/ui/transactions/htlc_claim_display.h | 29 - src/ui/transactions/htlc_lock_display.c | 71 --- src/ui/transactions/htlc_lock_display.h | 29 - src/ui/transactions/htlc_refund_display.c | 41 -- src/ui/transactions/htlc_refund_display.h | 29 - src/ui/transactions/ipfs_display.c | 20 +- src/ui/transactions/ipfs_display.h | 14 +- .../multi_signature_registration_display.c | 55 -- .../multi_signature_registration_display.h | 29 - src/ui/transactions/transfer_display.c | 21 +- src/ui/transactions/transfer_display.h | 14 +- src/ui/transactions/vote_display.c | 103 ++-- src/ui/transactions/vote_display.h | 14 +- src/ui/ui_utils.c | 83 +++ src/ui/ui_utils.h | 29 + tests/functional/README.md | 79 ++- .../__init__.py | 0 tests/functional/application_client/py.typed | 0 .../solar_command_sender.py | 202 +++++++ .../solar_response_unpacker.py | 91 +++ .../solar_transaction.py} | 4 +- .../solar_utils.py} | 20 +- tests/functional/client/client_interface.py | 106 ---- tests/functional/client/cmd.py | 196 ------- tests/functional/client/cmd_builder.py | 304 ---------- tests/functional/client/exception/__init__.py | 39 -- .../client/exception/device_exception.py | 41 -- tests/functional/client/exception/errors.py | 67 --- tests/functional/conftest.py | 70 +-- tests/functional/constants.py | 7 + tests/functional/requirements.txt | 10 +- tests/functional/setup.cfg | 3 +- .../00000.png | Bin 0 -> 359 bytes .../00001.png | Bin 0 -> 495 bytes .../00002.png | Bin 0 -> 490 bytes .../00003.png | Bin 0 -> 336 bytes .../00004.png | Bin 0 -> 341 bytes .../00005.png | Bin 0 -> 389 bytes .../00000.png | Bin 0 -> 359 bytes .../00001.png | Bin 0 -> 495 bytes .../00002.png | Bin 0 -> 490 bytes .../00003.png | Bin 0 -> 336 bytes .../00004.png | Bin 0 -> 341 bytes .../00005.png | Bin 0 -> 340 bytes .../00006.png | Bin 0 -> 389 bytes .../00000.png | Bin 0 -> 377 bytes .../00001.png | Bin 0 -> 482 bytes .../00002.png | Bin 0 -> 481 bytes .../00003.png | Bin 0 -> 493 bytes .../00004.png | Bin 0 -> 475 bytes .../00005.png | Bin 0 -> 341 bytes .../00006.png | Bin 0 -> 389 bytes .../00000.png | Bin 0 -> 377 bytes .../00001.png | Bin 0 -> 482 bytes .../00002.png | Bin 0 -> 481 bytes .../00003.png | Bin 0 -> 493 bytes .../00004.png | Bin 0 -> 475 bytes .../00005.png | Bin 0 -> 341 bytes .../00006.png | Bin 0 -> 340 bytes .../00007.png | Bin 0 -> 389 bytes .../00000.png | Bin 0 -> 377 bytes .../00001.png | Bin 0 -> 482 bytes .../00002.png | Bin 0 -> 481 bytes .../00003.png | Bin 0 -> 493 bytes .../00004.png | Bin 0 -> 475 bytes .../00005.png | Bin 0 -> 341 bytes .../00006.png | Bin 0 -> 389 bytes .../nanos/test_sign_message_long/00000.png | Bin 0 -> 388 bytes .../nanos/test_sign_message_long/00001.png | Bin 0 -> 473 bytes .../nanos/test_sign_message_long/00002.png | Bin 0 -> 457 bytes .../nanos/test_sign_message_long/00003.png | Bin 0 -> 462 bytes .../nanos/test_sign_message_long/00004.png | Bin 0 -> 472 bytes .../nanos/test_sign_message_long/00005.png | Bin 0 -> 457 bytes .../nanos/test_sign_message_long/00006.png | Bin 0 -> 461 bytes .../nanos/test_sign_message_long/00007.png | Bin 0 -> 464 bytes .../nanos/test_sign_message_long/00008.png | Bin 0 -> 429 bytes .../nanos/test_sign_message_long/00009.png | Bin 0 -> 421 bytes .../nanos/test_sign_message_long/00010.png | Bin 0 -> 441 bytes .../nanos/test_sign_message_long/00011.png | Bin 0 -> 433 bytes .../nanos/test_sign_message_long/00012.png | Bin 0 -> 450 bytes .../nanos/test_sign_message_long/00013.png | Bin 0 -> 491 bytes .../nanos/test_sign_message_long/00014.png | Bin 0 -> 501 bytes .../nanos/test_sign_message_long/00015.png | Bin 0 -> 466 bytes .../nanos/test_sign_message_long/00016.png | Bin 0 -> 434 bytes .../nanos/test_sign_message_long/00017.png | Bin 0 -> 450 bytes .../nanos/test_sign_message_long/00018.png | Bin 0 -> 477 bytes .../nanos/test_sign_message_long/00019.png | Bin 0 -> 432 bytes .../nanos/test_sign_message_long/00020.png | Bin 0 -> 452 bytes .../nanos/test_sign_message_long/00021.png | Bin 0 -> 485 bytes .../nanos/test_sign_message_long/00022.png | Bin 0 -> 463 bytes .../nanos/test_sign_message_long/00023.png | Bin 0 -> 459 bytes .../nanos/test_sign_message_long/00024.png | Bin 0 -> 480 bytes .../nanos/test_sign_message_long/00025.png | Bin 0 -> 468 bytes .../nanos/test_sign_message_long/00026.png | Bin 0 -> 456 bytes .../nanos/test_sign_message_long/00027.png | Bin 0 -> 413 bytes .../nanos/test_sign_message_long/00028.png | Bin 0 -> 427 bytes .../nanos/test_sign_message_long/00029.png | Bin 0 -> 455 bytes .../nanos/test_sign_message_long/00030.png | Bin 0 -> 457 bytes .../nanos/test_sign_message_long/00031.png | Bin 0 -> 466 bytes .../nanos/test_sign_message_long/00032.png | Bin 0 -> 452 bytes .../nanos/test_sign_message_long/00033.png | Bin 0 -> 469 bytes .../nanos/test_sign_message_long/00034.png | Bin 0 -> 464 bytes .../nanos/test_sign_message_long/00035.png | Bin 0 -> 476 bytes .../nanos/test_sign_message_long/00036.png | Bin 0 -> 443 bytes .../nanos/test_sign_message_long/00037.png | Bin 0 -> 433 bytes .../nanos/test_sign_message_long/00038.png | Bin 0 -> 445 bytes .../nanos/test_sign_message_long/00039.png | Bin 0 -> 466 bytes .../nanos/test_sign_message_long/00040.png | Bin 0 -> 467 bytes .../nanos/test_sign_message_long/00041.png | Bin 0 -> 426 bytes .../nanos/test_sign_message_long/00042.png | Bin 0 -> 445 bytes .../nanos/test_sign_message_long/00043.png | Bin 0 -> 459 bytes .../nanos/test_sign_message_long/00044.png | Bin 0 -> 496 bytes .../nanos/test_sign_message_long/00045.png | Bin 0 -> 457 bytes .../nanos/test_sign_message_long/00046.png | Bin 0 -> 458 bytes .../nanos/test_sign_message_long/00047.png | Bin 0 -> 445 bytes .../nanos/test_sign_message_long/00048.png | Bin 0 -> 441 bytes .../nanos/test_sign_message_long/00049.png | Bin 0 -> 431 bytes .../nanos/test_sign_message_long/00050.png | Bin 0 -> 389 bytes .../nanos/test_sign_message_long/00051.png | Bin 0 -> 439 bytes .../nanos/test_sign_message_long/00052.png | Bin 0 -> 447 bytes .../nanos/test_sign_message_long/00053.png | Bin 0 -> 482 bytes .../nanos/test_sign_message_long/00054.png | Bin 0 -> 445 bytes .../nanos/test_sign_message_long/00055.png | Bin 0 -> 483 bytes .../nanos/test_sign_message_long/00056.png | Bin 0 -> 436 bytes .../nanos/test_sign_message_long/00057.png | Bin 0 -> 466 bytes .../nanos/test_sign_message_long/00058.png | Bin 0 -> 437 bytes .../nanos/test_sign_message_long/00059.png | Bin 0 -> 468 bytes .../nanos/test_sign_message_long/00060.png | Bin 0 -> 467 bytes .../nanos/test_sign_message_long/00061.png | Bin 0 -> 453 bytes .../nanos/test_sign_message_long/00062.png | Bin 0 -> 457 bytes .../nanos/test_sign_message_long/00063.png | Bin 0 -> 471 bytes .../nanos/test_sign_message_long/00064.png | Bin 0 -> 484 bytes .../nanos/test_sign_message_long/00065.png | Bin 0 -> 468 bytes .../nanos/test_sign_message_long/00066.png | Bin 0 -> 456 bytes .../nanos/test_sign_message_long/00067.png | Bin 0 -> 442 bytes .../nanos/test_sign_message_long/00068.png | Bin 0 -> 431 bytes .../nanos/test_sign_message_long/00069.png | Bin 0 -> 424 bytes .../nanos/test_sign_message_long/00070.png | Bin 0 -> 453 bytes .../nanos/test_sign_message_long/00071.png | Bin 0 -> 461 bytes .../nanos/test_sign_message_long/00072.png | Bin 0 -> 474 bytes .../nanos/test_sign_message_long/00073.png | Bin 0 -> 427 bytes .../nanos/test_sign_message_long/00074.png | Bin 0 -> 476 bytes .../nanos/test_sign_message_long/00075.png | Bin 0 -> 492 bytes .../nanos/test_sign_message_long/00076.png | Bin 0 -> 452 bytes .../nanos/test_sign_message_long/00077.png | Bin 0 -> 454 bytes .../nanos/test_sign_message_long/00078.png | Bin 0 -> 461 bytes .../nanos/test_sign_message_long/00079.png | Bin 0 -> 446 bytes .../nanos/test_sign_message_long/00080.png | Bin 0 -> 429 bytes .../nanos/test_sign_message_long/00081.png | Bin 0 -> 437 bytes .../nanos/test_sign_message_long/00082.png | Bin 0 -> 472 bytes .../nanos/test_sign_message_long/00083.png | Bin 0 -> 426 bytes .../nanos/test_sign_message_long/00084.png | Bin 0 -> 492 bytes .../nanos/test_sign_message_long/00085.png | Bin 0 -> 466 bytes .../nanos/test_sign_message_long/00086.png | Bin 0 -> 464 bytes .../nanos/test_sign_message_long/00087.png | Bin 0 -> 469 bytes .../nanos/test_sign_message_long/00088.png | Bin 0 -> 386 bytes .../nanos/test_sign_message_long/00089.png | Bin 0 -> 341 bytes .../nanos/test_sign_message_long/00090.png | Bin 0 -> 389 bytes .../nanos/test_sign_message_refused/00000.png | Bin 0 -> 388 bytes .../nanos/test_sign_message_refused/00001.png | Bin 0 -> 441 bytes .../nanos/test_sign_message_refused/00002.png | Bin 0 -> 405 bytes .../nanos/test_sign_message_refused/00003.png | Bin 0 -> 422 bytes .../nanos/test_sign_message_refused/00004.png | Bin 0 -> 386 bytes .../nanos/test_sign_message_refused/00005.png | Bin 0 -> 341 bytes .../nanos/test_sign_message_refused/00006.png | Bin 0 -> 340 bytes .../nanos/test_sign_message_refused/00007.png | Bin 0 -> 389 bytes .../nanos/test_sign_message_short/00000.png | Bin 0 -> 388 bytes .../nanos/test_sign_message_short/00001.png | Bin 0 -> 441 bytes .../nanos/test_sign_message_short/00002.png | Bin 0 -> 405 bytes .../nanos/test_sign_message_short/00003.png | Bin 0 -> 422 bytes .../nanos/test_sign_message_short/00004.png | Bin 0 -> 386 bytes .../nanos/test_sign_message_short/00005.png | Bin 0 -> 341 bytes .../nanos/test_sign_message_short/00006.png | Bin 0 -> 389 bytes .../test_sign_transaction_burn/00000.png | Bin 0 -> 326 bytes .../test_sign_transaction_burn/00001.png | Bin 0 -> 344 bytes .../test_sign_transaction_burn/00002.png | Bin 0 -> 295 bytes .../test_sign_transaction_burn/00003.png | Bin 0 -> 341 bytes .../test_sign_transaction_burn/00004.png | Bin 0 -> 389 bytes .../test_sign_transaction_ipfs/00000.png | Bin 0 -> 335 bytes .../test_sign_transaction_ipfs/00001.png | Bin 0 -> 507 bytes .../test_sign_transaction_ipfs/00002.png | Bin 0 -> 504 bytes .../test_sign_transaction_ipfs/00003.png | Bin 0 -> 443 bytes .../test_sign_transaction_ipfs/00004.png | Bin 0 -> 359 bytes .../test_sign_transaction_ipfs/00005.png | Bin 0 -> 341 bytes .../test_sign_transaction_ipfs/00006.png | Bin 0 -> 389 bytes .../test_sign_transaction_transfer/00000.png | Bin 0 -> 369 bytes .../test_sign_transaction_transfer/00001.png | Bin 0 -> 535 bytes .../test_sign_transaction_transfer/00002.png | Bin 0 -> 544 bytes .../test_sign_transaction_transfer/00003.png | Bin 0 -> 427 bytes .../test_sign_transaction_transfer/00004.png | Bin 0 -> 540 bytes .../test_sign_transaction_transfer/00005.png | Bin 0 -> 529 bytes .../test_sign_transaction_transfer/00006.png | Bin 0 -> 436 bytes .../test_sign_transaction_transfer/00007.png | Bin 0 -> 538 bytes .../test_sign_transaction_transfer/00008.png | Bin 0 -> 538 bytes .../test_sign_transaction_transfer/00009.png | Bin 0 -> 431 bytes .../test_sign_transaction_transfer/00010.png | Bin 0 -> 562 bytes .../test_sign_transaction_transfer/00011.png | Bin 0 -> 552 bytes .../test_sign_transaction_transfer/00012.png | Bin 0 -> 360 bytes .../test_sign_transaction_transfer/00013.png | Bin 0 -> 444 bytes .../test_sign_transaction_transfer/00014.png | Bin 0 -> 558 bytes .../test_sign_transaction_transfer/00015.png | Bin 0 -> 527 bytes .../test_sign_transaction_transfer/00016.png | Bin 0 -> 437 bytes .../test_sign_transaction_transfer/00017.png | Bin 0 -> 559 bytes .../test_sign_transaction_transfer/00018.png | Bin 0 -> 532 bytes .../test_sign_transaction_transfer/00019.png | Bin 0 -> 387 bytes .../test_sign_transaction_transfer/00020.png | Bin 0 -> 444 bytes .../test_sign_transaction_transfer/00021.png | Bin 0 -> 536 bytes .../test_sign_transaction_transfer/00022.png | Bin 0 -> 525 bytes .../test_sign_transaction_transfer/00023.png | Bin 0 -> 423 bytes .../test_sign_transaction_transfer/00024.png | Bin 0 -> 554 bytes .../test_sign_transaction_transfer/00025.png | Bin 0 -> 513 bytes .../test_sign_transaction_transfer/00026.png | Bin 0 -> 438 bytes .../test_sign_transaction_transfer/00027.png | Bin 0 -> 554 bytes .../test_sign_transaction_transfer/00028.png | Bin 0 -> 532 bytes .../test_sign_transaction_transfer/00029.png | Bin 0 -> 371 bytes .../test_sign_transaction_transfer/00030.png | Bin 0 -> 435 bytes .../test_sign_transaction_transfer/00031.png | Bin 0 -> 522 bytes .../test_sign_transaction_transfer/00032.png | Bin 0 -> 526 bytes .../test_sign_transaction_transfer/00033.png | Bin 0 -> 445 bytes .../test_sign_transaction_transfer/00034.png | Bin 0 -> 519 bytes .../test_sign_transaction_transfer/00035.png | Bin 0 -> 541 bytes .../test_sign_transaction_transfer/00036.png | Bin 0 -> 448 bytes .../test_sign_transaction_transfer/00037.png | Bin 0 -> 530 bytes .../test_sign_transaction_transfer/00038.png | Bin 0 -> 544 bytes .../test_sign_transaction_transfer/00039.png | Bin 0 -> 453 bytes .../test_sign_transaction_transfer/00040.png | Bin 0 -> 525 bytes .../test_sign_transaction_transfer/00041.png | Bin 0 -> 532 bytes .../test_sign_transaction_transfer/00042.png | Bin 0 -> 452 bytes .../test_sign_transaction_transfer/00043.png | Bin 0 -> 530 bytes .../test_sign_transaction_transfer/00044.png | Bin 0 -> 520 bytes .../test_sign_transaction_transfer/00045.png | Bin 0 -> 366 bytes .../test_sign_transaction_transfer/00046.png | Bin 0 -> 483 bytes .../test_sign_transaction_transfer/00047.png | Bin 0 -> 384 bytes .../test_sign_transaction_transfer/00048.png | Bin 0 -> 390 bytes .../test_sign_transaction_transfer/00049.png | Bin 0 -> 362 bytes .../test_sign_transaction_transfer/00050.png | Bin 0 -> 402 bytes .../test_sign_transaction_transfer/00051.png | Bin 0 -> 306 bytes .../test_sign_transaction_transfer/00052.png | Bin 0 -> 341 bytes .../test_sign_transaction_transfer/00053.png | Bin 0 -> 389 bytes .../test_sign_transaction_vote/00000.png | Bin 0 -> 346 bytes .../test_sign_transaction_vote/00001.png | Bin 0 -> 322 bytes .../test_sign_transaction_vote/00002.png | Bin 0 -> 355 bytes .../test_sign_transaction_vote/00003.png | Bin 0 -> 400 bytes .../test_sign_transaction_vote/00004.png | Bin 0 -> 374 bytes .../test_sign_transaction_vote/00005.png | Bin 0 -> 328 bytes .../test_sign_transaction_vote/00006.png | Bin 0 -> 358 bytes .../test_sign_transaction_vote/00007.png | Bin 0 -> 295 bytes .../test_sign_transaction_vote/00008.png | Bin 0 -> 341 bytes .../test_sign_transaction_vote/00009.png | Bin 0 -> 389 bytes .../00000.png | Bin 0 -> 396 bytes .../00001.png | Bin 0 -> 295 bytes .../00002.png | Bin 0 -> 341 bytes .../00003.png | Bin 0 -> 389 bytes .../00000.png | Bin 0 -> 375 bytes .../00001.png | Bin 0 -> 737 bytes .../00002.png | Bin 0 -> 364 bytes .../00003.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 375 bytes .../00001.png | Bin 0 -> 737 bytes .../00002.png | Bin 0 -> 364 bytes .../00003.png | Bin 0 -> 365 bytes .../00004.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 400 bytes .../00001.png | Bin 0 -> 891 bytes .../00002.png | Bin 0 -> 547 bytes .../00003.png | Bin 0 -> 364 bytes .../00004.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 400 bytes .../00001.png | Bin 0 -> 891 bytes .../00002.png | Bin 0 -> 547 bytes .../00003.png | Bin 0 -> 364 bytes .../00004.png | Bin 0 -> 365 bytes .../00005.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 400 bytes .../00001.png | Bin 0 -> 891 bytes .../00002.png | Bin 0 -> 547 bytes .../00003.png | Bin 0 -> 364 bytes .../00004.png | Bin 0 -> 441 bytes .../nanosp/test_sign_message_long/00000.png | Bin 0 -> 420 bytes .../nanosp/test_sign_message_long/00001.png | Bin 0 -> 866 bytes .../nanosp/test_sign_message_long/00002.png | Bin 0 -> 841 bytes .../nanosp/test_sign_message_long/00003.png | Bin 0 -> 770 bytes .../nanosp/test_sign_message_long/00004.png | Bin 0 -> 784 bytes .../nanosp/test_sign_message_long/00005.png | Bin 0 -> 906 bytes .../nanosp/test_sign_message_long/00006.png | Bin 0 -> 824 bytes .../nanosp/test_sign_message_long/00007.png | Bin 0 -> 794 bytes .../nanosp/test_sign_message_long/00008.png | Bin 0 -> 849 bytes .../nanosp/test_sign_message_long/00009.png | Bin 0 -> 767 bytes .../nanosp/test_sign_message_long/00010.png | Bin 0 -> 779 bytes .../nanosp/test_sign_message_long/00011.png | Bin 0 -> 842 bytes .../nanosp/test_sign_message_long/00012.png | Bin 0 -> 812 bytes .../nanosp/test_sign_message_long/00013.png | Bin 0 -> 804 bytes .../nanosp/test_sign_message_long/00014.png | Bin 0 -> 771 bytes .../nanosp/test_sign_message_long/00015.png | Bin 0 -> 834 bytes .../nanosp/test_sign_message_long/00016.png | Bin 0 -> 770 bytes .../nanosp/test_sign_message_long/00017.png | Bin 0 -> 718 bytes .../nanosp/test_sign_message_long/00018.png | Bin 0 -> 828 bytes .../nanosp/test_sign_message_long/00019.png | Bin 0 -> 821 bytes .../nanosp/test_sign_message_long/00020.png | Bin 0 -> 829 bytes .../nanosp/test_sign_message_long/00021.png | Bin 0 -> 837 bytes .../nanosp/test_sign_message_long/00022.png | Bin 0 -> 857 bytes .../nanosp/test_sign_message_long/00023.png | Bin 0 -> 765 bytes .../nanosp/test_sign_message_long/00024.png | Bin 0 -> 859 bytes .../nanosp/test_sign_message_long/00025.png | Bin 0 -> 836 bytes .../nanosp/test_sign_message_long/00026.png | Bin 0 -> 810 bytes .../nanosp/test_sign_message_long/00027.png | Bin 0 -> 781 bytes .../nanosp/test_sign_message_long/00028.png | Bin 0 -> 857 bytes .../nanosp/test_sign_message_long/00029.png | Bin 0 -> 867 bytes .../nanosp/test_sign_message_long/00030.png | Bin 0 -> 485 bytes .../nanosp/test_sign_message_long/00031.png | Bin 0 -> 364 bytes .../nanosp/test_sign_message_long/00032.png | Bin 0 -> 441 bytes .../test_sign_message_refused/00000.png | Bin 0 -> 420 bytes .../test_sign_message_refused/00001.png | Bin 0 -> 711 bytes .../test_sign_message_refused/00002.png | Bin 0 -> 467 bytes .../test_sign_message_refused/00003.png | Bin 0 -> 364 bytes .../test_sign_message_refused/00004.png | Bin 0 -> 365 bytes .../test_sign_message_refused/00005.png | Bin 0 -> 441 bytes .../nanosp/test_sign_message_short/00000.png | Bin 0 -> 420 bytes .../nanosp/test_sign_message_short/00001.png | Bin 0 -> 711 bytes .../nanosp/test_sign_message_short/00002.png | Bin 0 -> 467 bytes .../nanosp/test_sign_message_short/00003.png | Bin 0 -> 364 bytes .../nanosp/test_sign_message_short/00004.png | Bin 0 -> 441 bytes .../test_sign_transaction_burn/00000.png | Bin 0 -> 362 bytes .../test_sign_transaction_burn/00001.png | Bin 0 -> 392 bytes .../test_sign_transaction_burn/00002.png | Bin 0 -> 345 bytes .../test_sign_transaction_burn/00003.png | Bin 0 -> 364 bytes .../test_sign_transaction_burn/00004.png | Bin 0 -> 441 bytes .../test_sign_transaction_ipfs/00000.png | Bin 0 -> 374 bytes .../test_sign_transaction_ipfs/00001.png | Bin 0 -> 852 bytes .../test_sign_transaction_ipfs/00002.png | Bin 0 -> 399 bytes .../test_sign_transaction_ipfs/00003.png | Bin 0 -> 364 bytes .../test_sign_transaction_ipfs/00004.png | Bin 0 -> 441 bytes .../test_sign_transaction_transfer/00000.png | Bin 0 -> 409 bytes .../test_sign_transaction_transfer/00001.png | Bin 0 -> 767 bytes .../test_sign_transaction_transfer/00002.png | Bin 0 -> 477 bytes .../test_sign_transaction_transfer/00003.png | Bin 0 -> 766 bytes .../test_sign_transaction_transfer/00004.png | Bin 0 -> 497 bytes .../test_sign_transaction_transfer/00005.png | Bin 0 -> 759 bytes .../test_sign_transaction_transfer/00006.png | Bin 0 -> 502 bytes .../test_sign_transaction_transfer/00007.png | Bin 0 -> 804 bytes .../test_sign_transaction_transfer/00008.png | Bin 0 -> 492 bytes .../test_sign_transaction_transfer/00009.png | Bin 0 -> 770 bytes .../test_sign_transaction_transfer/00010.png | Bin 0 -> 506 bytes .../test_sign_transaction_transfer/00011.png | Bin 0 -> 771 bytes .../test_sign_transaction_transfer/00012.png | Bin 0 -> 504 bytes .../test_sign_transaction_transfer/00013.png | Bin 0 -> 762 bytes .../test_sign_transaction_transfer/00014.png | Bin 0 -> 493 bytes .../test_sign_transaction_transfer/00015.png | Bin 0 -> 762 bytes .../test_sign_transaction_transfer/00016.png | Bin 0 -> 506 bytes .../test_sign_transaction_transfer/00017.png | Bin 0 -> 777 bytes .../test_sign_transaction_transfer/00018.png | Bin 0 -> 506 bytes .../test_sign_transaction_transfer/00019.png | Bin 0 -> 752 bytes .../test_sign_transaction_transfer/00020.png | Bin 0 -> 510 bytes .../test_sign_transaction_transfer/00021.png | Bin 0 -> 754 bytes .../test_sign_transaction_transfer/00022.png | Bin 0 -> 498 bytes .../test_sign_transaction_transfer/00023.png | Bin 0 -> 778 bytes .../test_sign_transaction_transfer/00024.png | Bin 0 -> 510 bytes .../test_sign_transaction_transfer/00025.png | Bin 0 -> 731 bytes .../test_sign_transaction_transfer/00026.png | Bin 0 -> 522 bytes .../test_sign_transaction_transfer/00027.png | Bin 0 -> 768 bytes .../test_sign_transaction_transfer/00028.png | Bin 0 -> 612 bytes .../test_sign_transaction_transfer/00029.png | Bin 0 -> 400 bytes .../test_sign_transaction_transfer/00030.png | Bin 0 -> 471 bytes .../test_sign_transaction_transfer/00031.png | Bin 0 -> 364 bytes .../test_sign_transaction_transfer/00032.png | Bin 0 -> 441 bytes .../test_sign_transaction_vote/00000.png | Bin 0 -> 379 bytes .../test_sign_transaction_vote/00001.png | Bin 0 -> 381 bytes .../test_sign_transaction_vote/00002.png | Bin 0 -> 420 bytes .../test_sign_transaction_vote/00003.png | Bin 0 -> 470 bytes .../test_sign_transaction_vote/00004.png | Bin 0 -> 435 bytes .../test_sign_transaction_vote/00005.png | Bin 0 -> 408 bytes .../test_sign_transaction_vote/00006.png | Bin 0 -> 431 bytes .../test_sign_transaction_vote/00007.png | Bin 0 -> 345 bytes .../test_sign_transaction_vote/00008.png | Bin 0 -> 364 bytes .../test_sign_transaction_vote/00009.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 431 bytes .../00001.png | Bin 0 -> 345 bytes .../00002.png | Bin 0 -> 364 bytes .../00003.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 375 bytes .../00001.png | Bin 0 -> 737 bytes .../00002.png | Bin 0 -> 364 bytes .../00003.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 375 bytes .../00001.png | Bin 0 -> 737 bytes .../00002.png | Bin 0 -> 364 bytes .../00003.png | Bin 0 -> 365 bytes .../00004.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 400 bytes .../00001.png | Bin 0 -> 891 bytes .../00002.png | Bin 0 -> 547 bytes .../00003.png | Bin 0 -> 364 bytes .../00004.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 400 bytes .../00001.png | Bin 0 -> 891 bytes .../00002.png | Bin 0 -> 547 bytes .../00003.png | Bin 0 -> 364 bytes .../00004.png | Bin 0 -> 365 bytes .../00005.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 400 bytes .../00001.png | Bin 0 -> 891 bytes .../00002.png | Bin 0 -> 547 bytes .../00003.png | Bin 0 -> 364 bytes .../00004.png | Bin 0 -> 441 bytes .../nanox/test_sign_message_long/00000.png | Bin 0 -> 420 bytes .../nanox/test_sign_message_long/00001.png | Bin 0 -> 866 bytes .../nanox/test_sign_message_long/00002.png | Bin 0 -> 841 bytes .../nanox/test_sign_message_long/00003.png | Bin 0 -> 770 bytes .../nanox/test_sign_message_long/00004.png | Bin 0 -> 784 bytes .../nanox/test_sign_message_long/00005.png | Bin 0 -> 906 bytes .../nanox/test_sign_message_long/00006.png | Bin 0 -> 824 bytes .../nanox/test_sign_message_long/00007.png | Bin 0 -> 794 bytes .../nanox/test_sign_message_long/00008.png | Bin 0 -> 849 bytes .../nanox/test_sign_message_long/00009.png | Bin 0 -> 767 bytes .../nanox/test_sign_message_long/00010.png | Bin 0 -> 779 bytes .../nanox/test_sign_message_long/00011.png | Bin 0 -> 842 bytes .../nanox/test_sign_message_long/00012.png | Bin 0 -> 812 bytes .../nanox/test_sign_message_long/00013.png | Bin 0 -> 804 bytes .../nanox/test_sign_message_long/00014.png | Bin 0 -> 771 bytes .../nanox/test_sign_message_long/00015.png | Bin 0 -> 834 bytes .../nanox/test_sign_message_long/00016.png | Bin 0 -> 770 bytes .../nanox/test_sign_message_long/00017.png | Bin 0 -> 718 bytes .../nanox/test_sign_message_long/00018.png | Bin 0 -> 828 bytes .../nanox/test_sign_message_long/00019.png | Bin 0 -> 821 bytes .../nanox/test_sign_message_long/00020.png | Bin 0 -> 829 bytes .../nanox/test_sign_message_long/00021.png | Bin 0 -> 837 bytes .../nanox/test_sign_message_long/00022.png | Bin 0 -> 857 bytes .../nanox/test_sign_message_long/00023.png | Bin 0 -> 765 bytes .../nanox/test_sign_message_long/00024.png | Bin 0 -> 859 bytes .../nanox/test_sign_message_long/00025.png | Bin 0 -> 836 bytes .../nanox/test_sign_message_long/00026.png | Bin 0 -> 810 bytes .../nanox/test_sign_message_long/00027.png | Bin 0 -> 781 bytes .../nanox/test_sign_message_long/00028.png | Bin 0 -> 857 bytes .../nanox/test_sign_message_long/00029.png | Bin 0 -> 867 bytes .../nanox/test_sign_message_long/00030.png | Bin 0 -> 485 bytes .../nanox/test_sign_message_long/00031.png | Bin 0 -> 364 bytes .../nanox/test_sign_message_long/00032.png | Bin 0 -> 441 bytes .../nanox/test_sign_message_refused/00000.png | Bin 0 -> 420 bytes .../nanox/test_sign_message_refused/00001.png | Bin 0 -> 711 bytes .../nanox/test_sign_message_refused/00002.png | Bin 0 -> 467 bytes .../nanox/test_sign_message_refused/00003.png | Bin 0 -> 364 bytes .../nanox/test_sign_message_refused/00004.png | Bin 0 -> 365 bytes .../nanox/test_sign_message_refused/00005.png | Bin 0 -> 441 bytes .../nanox/test_sign_message_short/00000.png | Bin 0 -> 420 bytes .../nanox/test_sign_message_short/00001.png | Bin 0 -> 711 bytes .../nanox/test_sign_message_short/00002.png | Bin 0 -> 467 bytes .../nanox/test_sign_message_short/00003.png | Bin 0 -> 364 bytes .../nanox/test_sign_message_short/00004.png | Bin 0 -> 441 bytes .../test_sign_transaction_burn/00000.png | Bin 0 -> 362 bytes .../test_sign_transaction_burn/00001.png | Bin 0 -> 392 bytes .../test_sign_transaction_burn/00002.png | Bin 0 -> 345 bytes .../test_sign_transaction_burn/00003.png | Bin 0 -> 364 bytes .../test_sign_transaction_burn/00004.png | Bin 0 -> 441 bytes .../test_sign_transaction_ipfs/00000.png | Bin 0 -> 374 bytes .../test_sign_transaction_ipfs/00001.png | Bin 0 -> 852 bytes .../test_sign_transaction_ipfs/00002.png | Bin 0 -> 399 bytes .../test_sign_transaction_ipfs/00003.png | Bin 0 -> 364 bytes .../test_sign_transaction_ipfs/00004.png | Bin 0 -> 441 bytes .../test_sign_transaction_transfer/00000.png | Bin 0 -> 409 bytes .../test_sign_transaction_transfer/00001.png | Bin 0 -> 767 bytes .../test_sign_transaction_transfer/00002.png | Bin 0 -> 477 bytes .../test_sign_transaction_transfer/00003.png | Bin 0 -> 766 bytes .../test_sign_transaction_transfer/00004.png | Bin 0 -> 497 bytes .../test_sign_transaction_transfer/00005.png | Bin 0 -> 759 bytes .../test_sign_transaction_transfer/00006.png | Bin 0 -> 502 bytes .../test_sign_transaction_transfer/00007.png | Bin 0 -> 804 bytes .../test_sign_transaction_transfer/00008.png | Bin 0 -> 492 bytes .../test_sign_transaction_transfer/00009.png | Bin 0 -> 770 bytes .../test_sign_transaction_transfer/00010.png | Bin 0 -> 506 bytes .../test_sign_transaction_transfer/00011.png | Bin 0 -> 771 bytes .../test_sign_transaction_transfer/00012.png | Bin 0 -> 504 bytes .../test_sign_transaction_transfer/00013.png | Bin 0 -> 762 bytes .../test_sign_transaction_transfer/00014.png | Bin 0 -> 493 bytes .../test_sign_transaction_transfer/00015.png | Bin 0 -> 762 bytes .../test_sign_transaction_transfer/00016.png | Bin 0 -> 506 bytes .../test_sign_transaction_transfer/00017.png | Bin 0 -> 777 bytes .../test_sign_transaction_transfer/00018.png | Bin 0 -> 506 bytes .../test_sign_transaction_transfer/00019.png | Bin 0 -> 752 bytes .../test_sign_transaction_transfer/00020.png | Bin 0 -> 510 bytes .../test_sign_transaction_transfer/00021.png | Bin 0 -> 754 bytes .../test_sign_transaction_transfer/00022.png | Bin 0 -> 498 bytes .../test_sign_transaction_transfer/00023.png | Bin 0 -> 778 bytes .../test_sign_transaction_transfer/00024.png | Bin 0 -> 510 bytes .../test_sign_transaction_transfer/00025.png | Bin 0 -> 731 bytes .../test_sign_transaction_transfer/00026.png | Bin 0 -> 522 bytes .../test_sign_transaction_transfer/00027.png | Bin 0 -> 768 bytes .../test_sign_transaction_transfer/00028.png | Bin 0 -> 612 bytes .../test_sign_transaction_transfer/00029.png | Bin 0 -> 400 bytes .../test_sign_transaction_transfer/00030.png | Bin 0 -> 471 bytes .../test_sign_transaction_transfer/00031.png | Bin 0 -> 364 bytes .../test_sign_transaction_transfer/00032.png | Bin 0 -> 441 bytes .../test_sign_transaction_vote/00000.png | Bin 0 -> 379 bytes .../test_sign_transaction_vote/00001.png | Bin 0 -> 381 bytes .../test_sign_transaction_vote/00002.png | Bin 0 -> 420 bytes .../test_sign_transaction_vote/00003.png | Bin 0 -> 470 bytes .../test_sign_transaction_vote/00004.png | Bin 0 -> 435 bytes .../test_sign_transaction_vote/00005.png | Bin 0 -> 408 bytes .../test_sign_transaction_vote/00006.png | Bin 0 -> 431 bytes .../test_sign_transaction_vote/00007.png | Bin 0 -> 345 bytes .../test_sign_transaction_vote/00008.png | Bin 0 -> 364 bytes .../test_sign_transaction_vote/00009.png | Bin 0 -> 441 bytes .../00000.png | Bin 0 -> 431 bytes .../00001.png | Bin 0 -> 345 bytes .../00002.png | Bin 0 -> 364 bytes .../00003.png | Bin 0 -> 441 bytes tests/functional/test_address_cmd.py | 159 +++-- tests/functional/test_appname_cmd.py | 14 +- tests/functional/test_error_cmd.py | 183 ++---- tests/functional/test_message_sign_cmd.py | 136 ----- tests/functional/test_name_version.py | 22 +- tests/functional/test_pubkey_cmd.py | 185 ++++-- tests/functional/test_sign_cmd.py | 326 ----------- tests/functional/test_sign_message_cmd.py | 111 ++++ tests/functional/test_sign_transaction_cmd.py | 549 ++++++++++++++++++ tests/functional/test_status_word.py | 39 -- tests/functional/test_version_cmd.py | 19 +- tests/functional/transactions/burn.py | 4 +- tests/functional/transactions/htlc_claim.py | 53 -- tests/functional/transactions/htlc_lock.py | 61 -- tests/functional/transactions/htlc_refund.py | 30 - tests/functional/transactions/ipfs.py | 4 +- .../multi_signature_registration.py | 43 -- tests/functional/transactions/transfer.py | 4 +- tests/functional/transactions/vote.py | 4 +- tests/functional/utils.py | 28 + tests/unit-tests/CMakeLists.txt | 59 +- tests/unit-tests/README.md | 2 +- tests/unit-tests/test_apdu_parser.c | 41 -- tests/unit-tests/test_base58.c | 34 -- tests/unit-tests/test_bip32.c | 101 ---- tests/unit-tests/test_buffer.c | 155 ----- tests/unit-tests/test_format.c | 163 ------ tests/unit-tests/test_tx_parser.c | 425 +------------- tests/unit-tests/test_tx_utils.c | 68 ++- tests/unit-tests/test_write.c | 64 -- 643 files changed, 2966 insertions(+), 6820 deletions(-) create mode 100644 .github/workflows/build_and_functional_tests.yml create mode 100644 .github/workflows/codeql_checks.yml create mode 100644 .github/workflows/coding_style_checks.yml create mode 100644 .github/workflows/documentation_generation.yml create mode 100644 .github/workflows/guidelines_enforcer.yml delete mode 100644 .github/workflows/lint-workflow.yml create mode 100644 .github/workflows/misspellings_checks.yml create mode 100644 .github/workflows/static_analysis.yml create mode 100644 .github/workflows/unit_tests.yml create mode 100644 .vscode/20-ledger.ledgerblue.rules create mode 100644 .vscode/extensions.json delete mode 100644 doc/transactions/TG01_T04_MULTISIGNATURE_REG.md delete mode 100644 doc/transactions/TG01_T08_HTLC_LOCK.md delete mode 100644 doc/transactions/TG01_T09_HTLC_CLAIM.md delete mode 100644 doc/transactions/TG01_T10_HTLC_REFUND.md rename icons/{nanox_app_solar.gif => app_solar_14px.gif} (100%) rename icons/{nanos_app_solar.gif => app_solar_16px.gif} (100%) delete mode 100644 src/apdu/parser.c delete mode 100644 src/apdu/parser.h rename src/{main.c => app_main.c} (61%) delete mode 100644 src/common/base58.c delete mode 100644 src/common/base58.h delete mode 100644 src/common/bip32.c delete mode 100644 src/common/bip32.h delete mode 100644 src/common/buffer.c delete mode 100644 src/common/buffer.h delete mode 100644 src/common/format.c delete mode 100644 src/common/format.h delete mode 100644 src/common/macros.h delete mode 100644 src/common/read.c delete mode 100644 src/common/read.h delete mode 100644 src/common/varint.c delete mode 100644 src/common/varint.h delete mode 100644 src/common/write.c delete mode 100644 src/common/write.h rename src/helper/{send_reponse.c => send_response.c} (81%) delete mode 100644 src/io.c delete mode 100644 src/io.h create mode 100644 src/transaction/transaction_utils.c create mode 100644 src/transaction/transaction_utils.h delete mode 100644 src/transaction/types/htlc_claim.c delete mode 100644 src/transaction/types/htlc_claim.h delete mode 100644 src/transaction/types/htlc_lock.c delete mode 100644 src/transaction/types/htlc_lock.h delete mode 100644 src/transaction/types/htlc_refund.c delete mode 100644 src/transaction/types/htlc_refund.h delete mode 100644 src/transaction/types/multi_signature_registration.c delete mode 100644 src/transaction/types/multi_signature_registration.h delete mode 100644 src/transaction/utils.c delete mode 100644 src/transaction/utils.h delete mode 100644 src/ui/transactions/htlc_claim_display.c delete mode 100644 src/ui/transactions/htlc_claim_display.h delete mode 100644 src/ui/transactions/htlc_lock_display.c delete mode 100644 src/ui/transactions/htlc_lock_display.h delete mode 100644 src/ui/transactions/htlc_refund_display.c delete mode 100644 src/ui/transactions/htlc_refund_display.h delete mode 100644 src/ui/transactions/multi_signature_registration_display.c delete mode 100644 src/ui/transactions/multi_signature_registration_display.h create mode 100644 src/ui/ui_utils.c create mode 100644 src/ui/ui_utils.h rename tests/functional/{client => application_client}/__init__.py (100%) create mode 100644 tests/functional/application_client/py.typed create mode 100644 tests/functional/application_client/solar_command_sender.py create mode 100644 tests/functional/application_client/solar_response_unpacker.py rename tests/functional/{client/transaction.py => application_client/solar_transaction.py} (93%) rename tests/functional/{client/utils.py => application_client/solar_utils.py} (77%) delete mode 100644 tests/functional/client/client_interface.py delete mode 100644 tests/functional/client/cmd.py delete mode 100644 tests/functional/client/cmd_builder.py delete mode 100644 tests/functional/client/exception/__init__.py delete mode 100644 tests/functional/client/exception/device_exception.py delete mode 100644 tests/functional/client/exception/errors.py create mode 100644 tests/functional/constants.py create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00000.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00001.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00002.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00003.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00004.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00005.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_refused/00000.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_refused/00001.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_refused/00002.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_refused/00003.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_refused/00004.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_refused/00005.png create mode 100644 tests/functional/snapshots/nanos/test_get_address_confirm_refused/00006.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00000.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00001.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00002.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00003.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00004.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00005.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00006.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00000.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00001.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00002.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00003.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00004.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00005.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00006.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00007.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00000.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00001.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00002.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00003.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00004.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00005.png create mode 100644 tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00006.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00000.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00001.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00002.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00003.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00004.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00005.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00006.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00007.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00008.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00009.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00010.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00011.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00012.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00013.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00014.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00015.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00016.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00017.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00018.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00019.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00020.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00021.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00022.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00023.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00024.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00025.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00026.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00027.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00028.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00029.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00030.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00031.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00032.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00033.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00034.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00035.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00036.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00037.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00038.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00039.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00040.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00041.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00042.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00043.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00044.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00045.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00046.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00047.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00048.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00049.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00050.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00051.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00052.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00053.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00054.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00055.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00056.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00057.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00058.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00059.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00060.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00061.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00062.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00063.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00064.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00065.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00066.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00067.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00068.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00069.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00070.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00071.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00072.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00073.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00074.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00075.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00076.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00077.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00078.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00079.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00080.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00081.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00082.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00083.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00084.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00085.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00086.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00087.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00088.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00089.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_long/00090.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_refused/00000.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_refused/00001.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_refused/00002.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_refused/00003.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_refused/00004.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_refused/00005.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_refused/00006.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_refused/00007.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_short/00000.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_short/00001.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_short/00002.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_short/00003.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_short/00004.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_short/00005.png create mode 100644 tests/functional/snapshots/nanos/test_sign_message_short/00006.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_burn/00000.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_burn/00001.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_burn/00002.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_burn/00003.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_burn/00004.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00000.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00001.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00002.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00003.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00004.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00005.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00006.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00000.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00001.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00002.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00003.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00004.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00005.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00006.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00007.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00008.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00009.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00010.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00011.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00012.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00013.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00014.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00015.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00016.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00017.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00018.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00019.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00020.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00021.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00022.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00023.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00024.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00025.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00026.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00027.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00028.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00029.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00030.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00031.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00032.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00033.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00034.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00035.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00036.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00037.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00038.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00039.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00040.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00041.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00042.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00043.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00044.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00045.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00046.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00047.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00048.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00049.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00050.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00051.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00052.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_transfer/00053.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00000.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00001.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00002.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00003.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00004.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00005.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00006.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00007.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00008.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote/00009.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote_cancel/00000.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote_cancel/00001.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote_cancel/00002.png create mode 100644 tests/functional/snapshots/nanos/test_sign_transaction_vote_cancel/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_get_address_confirm_accepted/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_get_address_confirm_accepted/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_get_address_confirm_accepted/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_get_address_confirm_accepted/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_chaincode_confirm_accepted/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_chaincode_confirm_accepted/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_chaincode_confirm_accepted/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_chaincode_confirm_accepted/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_chaincode_confirm_accepted/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00005.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_no_chaincode_confirm_accepted/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_no_chaincode_confirm_accepted/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_no_chaincode_confirm_accepted/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_no_chaincode_confirm_accepted/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_get_public_key_no_chaincode_confirm_accepted/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00005.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00006.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00007.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00008.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00009.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00010.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00011.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00012.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00013.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00014.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00015.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00016.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00017.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00018.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00019.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00020.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00021.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00022.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00023.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00024.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00025.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00026.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00027.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00028.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00029.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00030.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00031.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_long/00032.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_refused/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_refused/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_refused/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_refused/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_refused/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_refused/00005.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_short/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_short/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_short/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_short/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_message_short/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_burn/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_burn/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_burn/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_burn/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_burn/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00005.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00006.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00007.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00008.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00009.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00010.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00011.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00012.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00013.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00014.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00015.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00016.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00017.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00018.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00019.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00020.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00021.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00022.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00023.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00024.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00025.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00026.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00027.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00028.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00029.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00030.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00031.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00032.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00003.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00004.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00005.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00006.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00007.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00008.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote/00009.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote_cancel/00000.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote_cancel/00001.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote_cancel/00002.png create mode 100644 tests/functional/snapshots/nanosp/test_sign_transaction_vote_cancel/00003.png create mode 100644 tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00000.png create mode 100644 tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00001.png create mode 100644 tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00002.png create mode 100644 tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00003.png create mode 100644 tests/functional/snapshots/nanox/test_get_address_confirm_refused/00000.png create mode 100644 tests/functional/snapshots/nanox/test_get_address_confirm_refused/00001.png create mode 100644 tests/functional/snapshots/nanox/test_get_address_confirm_refused/00002.png create mode 100644 tests/functional/snapshots/nanox/test_get_address_confirm_refused/00003.png create mode 100644 tests/functional/snapshots/nanox/test_get_address_confirm_refused/00004.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00000.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00001.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00002.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00003.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00004.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00000.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00001.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00002.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00003.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00004.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00005.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00000.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00001.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00002.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00003.png create mode 100644 tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00004.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00000.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00001.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00002.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00003.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00004.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00005.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00006.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00007.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00008.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00009.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00010.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00011.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00012.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00013.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00014.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00015.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00016.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00017.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00018.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00019.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00020.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00021.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00022.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00023.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00024.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00025.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00026.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00027.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00028.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00029.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00030.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00031.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_long/00032.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_refused/00000.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_refused/00001.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_refused/00002.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_refused/00003.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_refused/00004.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_refused/00005.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_short/00000.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_short/00001.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_short/00002.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_short/00003.png create mode 100644 tests/functional/snapshots/nanox/test_sign_message_short/00004.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_burn/00000.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_burn/00001.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_burn/00002.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_burn/00003.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_burn/00004.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00000.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00001.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00002.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00003.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00004.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00000.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00001.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00002.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00003.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00004.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00005.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00006.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00007.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00008.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00009.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00010.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00011.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00012.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00013.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00014.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00015.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00016.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00017.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00018.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00019.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00020.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00021.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00022.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00023.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00024.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00025.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00026.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00027.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00028.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00029.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00030.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00031.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_transfer/00032.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00000.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00001.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00002.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00003.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00004.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00005.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00006.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00007.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00008.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote/00009.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00000.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00001.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00002.png create mode 100644 tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00003.png delete mode 100644 tests/functional/test_message_sign_cmd.py delete mode 100644 tests/functional/test_sign_cmd.py create mode 100644 tests/functional/test_sign_message_cmd.py create mode 100644 tests/functional/test_sign_transaction_cmd.py delete mode 100644 tests/functional/test_status_word.py delete mode 100644 tests/functional/transactions/htlc_claim.py delete mode 100644 tests/functional/transactions/htlc_lock.py delete mode 100644 tests/functional/transactions/htlc_refund.py delete mode 100644 tests/functional/transactions/multi_signature_registration.py create mode 100644 tests/functional/utils.py delete mode 100644 tests/unit-tests/test_apdu_parser.c delete mode 100644 tests/unit-tests/test_base58.c delete mode 100644 tests/unit-tests/test_bip32.c delete mode 100644 tests/unit-tests/test_buffer.c delete mode 100644 tests/unit-tests/test_format.c delete mode 100644 tests/unit-tests/test_write.c diff --git a/.github/workflows/build_and_functional_tests.yml b/.github/workflows/build_and_functional_tests.yml new file mode 100644 index 00000000..7640e658 --- /dev/null +++ b/.github/workflows/build_and_functional_tests.yml @@ -0,0 +1,36 @@ +name: Build and run functional tests using ragger through reusable workflow + +# This workflow will build the app and then run functional tests using the Ragger framework upon Speculos emulation. +# It calls a reusable workflow developed by Ledger's internal developer team to build the application and upload the +# resulting binaries. +# It then calls another reusable workflow to run the Ragger tests on the compiled application binary. +# +# While this workflow is optional, having functional testing on your application is mandatory and this workflow and +# tooling environment is meant to be easy to use and adapt after forking your application + +on: + workflow_dispatch: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop +jobs: + build_application: + name: Build application using the reusable workflow + uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1 + with: + upload_app_binaries_artifact: "compiled_app_binaries" + run_for_devices: '["nanos", "nanox", "nanosp"]' + + ragger_tests: + name: Run ragger tests using the reusable workflow + needs: build_application + uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_ragger_tests.yml@v1 + with: + download_app_binaries_artifact: "compiled_app_binaries" + test_dir: tests/functional + run_for_devices: '["nanos", "nanox", "nanosp"]' diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index 2df16d6c..d3565e6c 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -1,4 +1,4 @@ -name: Compilation & tests +name: Compilation of build artifacts on: workflow_dispatch: @@ -16,14 +16,14 @@ jobs: runs-on: ubuntu-latest steps: - name: Parse short sha - uses: benjlevesque/short-sha@v1.2 + uses: benjlevesque/short-sha@v2.2 id: short-sha with: length: 7 outputs: sha7: ${{ steps.short-sha.outputs.sha }} - job_nanoS_build: + job_nanos_build: name: Build for the Nano S runs-on: ubuntu-latest needs: prepare @@ -33,40 +33,18 @@ jobs: steps: - name: Clone - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Build run: | make - name: Upload app binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: app-solar-nanos-${{ needs.prepare.outputs.sha7 }} path: bin - job_nanox_build: - name: Build for the Nano X - runs-on: ubuntu-latest - needs: prepare - - container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest - - steps: - - name: Clone - uses: actions/checkout@v2 - - - name: Build - run: | - make BOLOS_SDK=$NANOX_SDK - - - name: Upload app binary - uses: actions/upload-artifact@v2 - with: - name: app-solar-nanox-${{ needs.prepare.outputs.sha7 }} - path: bin - job_nanosp_build: name: Build for the Nano S Plus runs-on: ubuntu-latest @@ -77,81 +55,20 @@ jobs: steps: - name: Clone - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Build run: | make BOLOS_SDK=$NANOSP_SDK - name: Upload app binary - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: app-solar-nanosp-${{ needs.prepare.outputs.sha7 }} path: bin - job_scan_build: - name: Clang Static Analyser - runs-on: ubuntu-latest - needs: job_nanos_build - - container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest - - steps: - - uses: actions/checkout@v2 - - - name: Build with Clang Static Analyser - run: | - make clean - scan-build --use-cc=clang -analyze-headers -enable-checker security -enable-checker unix -enable-checker valist -o scan-build --status-bugs make default - - uses: actions/upload-artifact@v2 - if: failure() - with: - name: scan-build - path: scan-build - - job_unit_test: - name: Unit test - runs-on: ubuntu-latest - - container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest - - steps: - - name: Clone - uses: actions/checkout@v2 - - - name: Build unit tests - run: | - cd tests/unit-tests/ - cmake -Bbuild -H. && make -C build && make -C build test - - - name: Generate code coverage - run: | - cd tests/unit-tests/ - lcov --directory . -b "$(realpath build/)" --capture --initial -o coverage.base && \ - lcov --rc lcov_branch_coverage=1 --directory . -b "$(realpath build/)" --capture -o coverage.capture && \ - lcov --directory . -b "$(realpath build/)" --add-tracefile coverage.base --add-tracefile coverage.capture -o coverage.info && \ - lcov --directory . -b "$(realpath build/)" --remove coverage.info '*/unit-tests/*' -o coverage.info && \ - genhtml coverage.info -o coverage - - - uses: actions/upload-artifact@v2 - with: - name: code-coverage - path: tests/unit-tests/coverage - - - name: Upload to codecov.io - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - file: ./tests/unit-tests/coverage.info - flags: unittests - name: codecov-app-solar - fail_ci_if_error: true - verbose: true - - job_generate_doc: - name: Generate project documentation + job_nanox_build: + name: Build for the Nano X runs-on: ubuntu-latest needs: prepare @@ -160,37 +77,14 @@ jobs: steps: - name: Clone - uses: actions/checkout@v2 - - - name: HTML documentation - run: doxygen .doxygen/Doxyfile + uses: actions/checkout@v3 - - uses: actions/upload-artifact@v2 - with: - name: app-solar-docs-${{ needs.prepare.outputs.sha7 }} - path: doc/html - - job_functional: - name: Functional tests using Speculos - runs-on: ubuntu-latest - needs: [prepare, job_nanos_build] - - steps: - - name: Clone - uses: actions/checkout@v2 + - name: Build + run: | + make BOLOS_SDK=$NANOX_SDK - - name: Download app binary - uses: actions/download-artifact@v2 + - name: Upload app binary + uses: actions/upload-artifact@v3 with: - name: app-solar-nanos-${{ needs.prepare.outputs.sha7 }} + name: app-solar-nanox-${{ needs.prepare.outputs.sha7 }} path: bin - - - name: Install tests dependencies - run: | - sudo apt-get update && sudo apt-get install -y qemu-user-static - pip install --extra-index-url https://test.pypi.org/simple/ -r tests/functional/requirements.txt - - - name: Run test - env: - CTEST_OUTPUT_ON_FAILURE: 1 - run: pytest tests/functional/ --headless diff --git a/.github/workflows/codeql_checks.yml b/.github/workflows/codeql_checks.yml new file mode 100644 index 00000000..3e5b455b --- /dev/null +++ b/.github/workflows/codeql_checks.yml @@ -0,0 +1,46 @@ +name: "CodeQL" + +on: + workflow_dispatch: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop + # Excluded path: add the paths you want to ignore instead of deleting the workflow + paths-ignore: + - '.github/workflows/*.yml' + - 'tests/*' + +jobs: + analyse: + name: Analyse + strategy: + matrix: + sdk: [ "$NANOS_SDK", "$NANOX_SDK", "$NANOSP_SDK" ] + #'cpp' covers C and C++ + language: [ 'cpp' ] + runs-on: ubuntu-latest + container: + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-legacy:latest + + steps: + - name: Clone + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: security-and-quality + + # CodeQL will create the database during the compilation + - name: Build + run: | + make BOLOS_SDK=${{ matrix.sdk }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/coding_style_checks.yml b/.github/workflows/coding_style_checks.yml new file mode 100644 index 00000000..5c4cba0d --- /dev/null +++ b/.github/workflows/coding_style_checks.yml @@ -0,0 +1,26 @@ +name: Run coding style check through reusable workflow + +# This workflow will run linting checks to ensure a level of uniformization among all Ledger applications. +# +# The presence of this workflow is mandatory as a minimal level of linting is required. +# You are however free to modify the content of the .clang-format file and thus the coding style of your application. +# We simply ask you to not diverge too much from the linting of the Boilerplate application. + +on: + workflow_dispatch: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop +jobs: + check_linting: + name: Check linting using the reusable workflow + uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_lint.yml@v1 + with: + source: './src' + extensions: 'h,c' + version: 11 diff --git a/.github/workflows/documentation_generation.yml b/.github/workflows/documentation_generation.yml new file mode 100644 index 00000000..bcb474c6 --- /dev/null +++ b/.github/workflows/documentation_generation.yml @@ -0,0 +1,31 @@ +name: Generate project documentation + +on: + workflow_dispatch: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop + +jobs: + job_generate_doc: + name: Generate project documentation + runs-on: ubuntu-latest + container: + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest + + steps: + - name: Clone + uses: actions/checkout@v3 + + - name: HTML documentation + run: doxygen .doxygen/Doxyfile + + - uses: actions/upload-artifact@v3 + with: + name: app-solar-docs + path: doc/html diff --git a/.github/workflows/guidelines_enforcer.yml b/.github/workflows/guidelines_enforcer.yml new file mode 100644 index 00000000..bc4f213c --- /dev/null +++ b/.github/workflows/guidelines_enforcer.yml @@ -0,0 +1,26 @@ +name: Ensure compliance with Ledger guidelines + +# This workflow is mandatory in all applications +# It calls a reusable workflow guidelines_enforcer developed by Ledger's internal developer team. +# The successful completion of the reusable workflow is a mandatory step for an app to be available on the Ledger +# application store. +# +# More information on the guidelines can be found in the repository: +# LedgerHQ/ledger-app-workflows/ + +on: + workflow_dispatch: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop +jobs: + guidelines_enforcer: + name: Call Ledger guidelines_enforcer + uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_guidelines_enforcer.yml@v1 + with: + run_for_devices: '["nanos", "nanosp", "nanox"]' diff --git a/.github/workflows/lint-workflow.yml b/.github/workflows/lint-workflow.yml deleted file mode 100644 index bbf833c3..00000000 --- a/.github/workflows/lint-workflow.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Code style check - -on: - workflow_dispatch: - push: - branches: - - main - pull_request: - branches: - - main - - develop - -jobs: - job_lint: - name: Lint - runs-on: ubuntu-latest - - steps: - - name: Clone - uses: actions/checkout@v2 - - - name: Lint - uses: DoozyX/clang-format-lint-action@v0.11 - with: - source: './src' - extensions: 'h,c' - clangFormatVersion: 11 diff --git a/.github/workflows/misspellings_checks.yml b/.github/workflows/misspellings_checks.yml new file mode 100644 index 00000000..a1ade619 --- /dev/null +++ b/.github/workflows/misspellings_checks.yml @@ -0,0 +1,30 @@ +name: Misspellings checks + +# This workflow performs some misspelling checks on the repository +# It is there to help us maintain a level of quality in our codebase and does not have to be kept on forked +# applications. + +on: + workflow_dispatch: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop + +jobs: + misspell: + name: Check misspellings + runs-on: ubuntu-latest + steps: + - name: Clone + uses: actions/checkout@v3 + + - name: Check misspellings + uses: codespell-project/actions-codespell@v1 + with: + builtin: clear,rare + check_filenames: true diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml new file mode 100644 index 00000000..c6a2e687 --- /dev/null +++ b/.github/workflows/static_analysis.yml @@ -0,0 +1,41 @@ +name: Static analysis using clang + +on: + workflow_dispatch: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop + +jobs: + build_application: + name: Build application using the reusable workflow + uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1 + with: + upload_app_binaries_artifact: "compiled_app_binaries" + run_for_devices: '["nanos"]' + + job_scan_build: + name: Clang Static Analyser + runs-on: ubuntu-latest + needs: build_application + + container: + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest + + steps: + - uses: actions/checkout@v3 + + - name: Build with Clang Static Analyser + run: | + make clean + scan-build --use-cc=clang -analyze-headers -enable-checker security -enable-checker unix -enable-checker valist -o scan-build --status-bugs make default + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: scan-build + path: scan-build diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml new file mode 100644 index 00000000..898af82c --- /dev/null +++ b/.github/workflows/unit_tests.yml @@ -0,0 +1,52 @@ +name: Unit testing with Codecov coverage checking + +on: + workflow_dispatch: + push: + branches: + - main + pull_request: + branches: + - main + - develop + +jobs: + job_unit_test: + name: Unit test + runs-on: ubuntu-latest + + container: + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest + + steps: + - name: Clone + uses: actions/checkout@v3 + + - name: Build unit tests + run: | + cd tests/unit-tests/ + cmake -Bbuild -H. && make -C build && make -C build test + + - name: Generate code coverage + run: | + cd tests/unit-tests/ + lcov --directory . -b "$(realpath build/)" --capture --initial -o coverage.base && \ + lcov --rc lcov_branch_coverage=1 --directory . -b "$(realpath build/)" --capture -o coverage.capture && \ + lcov --directory . -b "$(realpath build/)" --add-tracefile coverage.base --add-tracefile coverage.capture -o coverage.info && \ + lcov --directory . -b "$(realpath build/)" --remove coverage.info '*/unit-tests/*' -o coverage.info && \ + genhtml coverage.info -o coverage + + - uses: actions/upload-artifact@v3 + with: + name: code-coverage + path: tests/unit-tests/coverage + + - name: Upload to codecov.io + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: ./tests/unit-tests/coverage.info + flags: unittests + name: codecov-app-solar + fail_ci_if_error: true + verbose: true diff --git a/.vscode/20-ledger.ledgerblue.rules b/.vscode/20-ledger.ledgerblue.rules new file mode 100644 index 00000000..945dd5be --- /dev/null +++ b/.vscode/20-ledger.ledgerblue.rules @@ -0,0 +1 @@ +SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c97", ATTRS{idProduct}=="0006|6000|6001|6002|6003|6004|6005|6006|6007|6008|6009|600a|600b|600c|600d|600e|600f|6010|6011|6012|6013|6014|6015|6016|6017|6018|6019|601a|601b|601c|601d|601e|601f", TAG+="uaccess", TAG+="udev-acl" diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 92693b7a..2fad6a93 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -46,4 +46,4 @@ } ], "version": 4 -} \ No newline at end of file +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..434dec92 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "ms-vscode.cpptools", + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 0efa0424..f6fecb84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,11 @@ "*.h": "c" }, "C_Cpp.clang_format_path": "/usr/bin/clang-format", - "editor.formatOnSave": true -} \ No newline at end of file + "editor.formatOnSave": false, + "task.autoDetect": "off", + "python.terminal.activateEnvironment": false, + "buid_dir_relative_path":".", + "linux_udev_ledgerblue_rule_file":"20-ledger.ledgerblue.rules", + "docker_image": "ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest", + "container_name": "${workspaceFolderBasename}-container", +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 167e70c4..d23162fc 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,33 +2,54 @@ "version": "2.0.0", "tasks": [ { - "label": "make", + "label": "Run dev-tools image (on Windows with PowerShell)", "type": "shell", - "command": "make clean && make", + //Checks if a container with the name ${config:container_name} exists, and if it does, it is stopped and removed before a new container is created using the same name and other specified configuration parameters + "command": "if (docker ps -a --format '{{.Names}}' | Select-String -Quiet ${config:container_name}) { docker container stop ${config:container_name}; docker container rm ${config:container_name} }; docker pull ${config:docker_image}; docker run --privileged -e DISPLAY='host.docker.internal:0' -v '${workspaceFolder}:/app' -t -d --name ${config:container_name} ${config:docker_image} ", "group": { "kind": "build", "isDefault": true }, - "problemMatcher": [ - "$gcc" - ] + "problemMatcher": [] }, { - "label": "[debug] make", + "label": "Run dev-tools image (on macOS)", "type": "shell", - "command": "make clean && make DEBUG=1", + // Checks if a container with the name ${config:container_name} exists, and if it does, it is stopped and removed before a new container is created using the same name and other specified configuration parameters. + "command": "docker ps -a --format '{{.Names}}' | grep -q ${config:container_name} && (docker container stop ${config:container_name} && docker container rm ${config:container_name}) ; docker pull ${config:docker_image} && docker run --user $(id -u):$(id -g) --privileged -e DISPLAY='host.docker.internal:0' -v '/tmp/.X11-unix:/tmp/.X11-unix' -v '${workspaceFolder}:/app' -t -d --name ${config:container_name} ${config:docker_image}", "group": { "kind": "build", "isDefault": true }, - "problemMatcher": [ - "$gcc" - ] + "problemMatcher": [] + }, + { + "label": "Run dev-tools image (on Linux)", + "type": "shell", + // Checks if a container with the name ${config:container_name} exists, and if it does, it is stopped and removed before a new container is created using the same name and other specified configuration parameters. + "command": "docker ps -a --format '{{.Names}}' | grep -q ${config:container_name} && (docker container stop ${config:container_name} && docker container rm ${config:container_name}) ; docker pull ${config:docker_image} && docker run --user $(id -u):$(id -g) --privileged -e DISPLAY=$DISPLAY -v '/dev/bus/usb:/dev/bus/usb' -v '/tmp/.X11-unix:/tmp/.X11-unix' -v '${workspaceFolder}:/app' -t -d --name ${config:container_name} ${config:docker_image}", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "Open dev-tools container terminal", + "type": "shell", + // Opens a terminal of the dev-tools container. + "command": "docker exec -it ${config:container_name} bash", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] }, { - "label": "make clean", + "label": "Build app", "type": "shell", - "command": "make clean", + // Builds the app in release mode using the make command, inside the docker container. + "command": "docker exec -it ${config:container_name} bash -c 'export BOLOS_SDK=$(echo ${input:sdk}) && make -j'", "group": { "kind": "build", "isDefault": true @@ -38,9 +59,10 @@ ] }, { - "label": "make load", + "label": "Build app [debug]", "type": "shell", - "command": "make load", + // Builds the app with debug mode enabled using the make command, inside the docker container. + "command": "docker exec -it ${config:container_name} bash -c 'export BOLOS_SDK=$(echo ${input:sdk}) && make -j DEBUG=1'", "group": { "kind": "build", "isDefault": true @@ -50,9 +72,10 @@ ] }, { - "label": "run unit tests", + "label": "Clean build files", "type": "shell", - "command": "cd unit-tests && rm -rf build && cmake -Bbuild -H. && make -C build && CTEST_OUTPUT_ON_FAILURE=1 make -C build test", + // Cleans all app build files (for all device models). + "command": "docker exec -it ${config:container_name} bash -c 'make clean'", "group": { "kind": "build", "isDefault": true @@ -62,50 +85,161 @@ ] }, { - "label": "run Speculos", + "label": "Test app with Speculos", + "type": "shell", + // Runs the app on the speculos emulator for the selected device model, in the docker container. + "command": "docker exec -it ${config:container_name} bash -c 'speculos --model ${input:model} build/${input:model}/bin/app.elf'", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "Kill Speculos", + "type": "shell", + // Kills speculos emulator in the docker container. + "command": "docker exec -it ${config:container_name} bash -c 'pkill -f speculos'", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "Run functional tests", "type": "shell", - "command": "python /path/to/speculos/speculos.py ${workspaceFolder}/bin/app.elf --ontop --sdk 1.6 --apdu-port 9999 --button-port 42000 --automation-port 43000", + // Runs functional tests inside the docker container (with Qt display disabled). + "command": "docker exec -it ${config:container_name} bash -c 'pytest tests/functional/ --tb=short -v --device ${input:model}'", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "Run functional tests (with display)", + "type": "shell", + // Runs functional tests inside the docker container (with Qt display enabled). + "command": "docker exec -it ${config:container_name} bash -c 'pytest tests/functional/ --tb=short -v --device ${input:model} --display'", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "Install tests requirements", + "type": "shell", + // Installs functional tests python requirements in the docker container. + "command": "docker exec -it -u 0 ${config:container_name} bash -c 'apk add gcc musl-dev python3-dev && pip install -r tests/functional/requirements.txt'", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "Load app on device (Linux)", + "type": "shell", + // Executes make load in the container to load the app on a physical device. + "command": "docker exec -it ${config:container_name} bash -c 'export BOLOS_SDK=$(echo ${input:sdk}) && make load'", "group": { "kind": "build", "isDefault": true }, "dependsOn": [ - "make debug" + "Install app loading requirements (Linux)" ], "problemMatcher": [] }, { - "label": "[debug] run Speculos", + "label": "Load app on device (macOS)", "type": "shell", - "command": "python /path/to/speculos/speculos.py -d ${workspaceFolder}/bin/app.elf --ontop --sdk 1.6 --apdu-port 9999 --button-port 42000 --automation-port 43000", + // Side loads the app APDU file using ledgerblue runScript. + "command": "source ledger/bin/activate && python3 -m ledgerblue.runScript --scp --fileName ${config:buid_dir_relative_path}/bin/app.apdu --elfFile ${config:buid_dir_relative_path}/bin/app.elf", "group": { "kind": "build", "isDefault": true }, "dependsOn": [ - "make debug" + "Install app loading requirements (macOS)" ], "problemMatcher": [] }, { - "label": "run tests", + "label": "Load app on device (Windows with PowerShell)", "type": "shell", - "command": "cd tests && pytest", + // Side loads the app APDU file using ledgerblue runScript. + "command": "cmd.exe /C '.\\ledger\\Scripts\\activate.bat && python -m ledgerblue.runScript --scp --fileName ${config:buid_dir_relative_path}/bin/app.apdu --elfFile ${config:buid_dir_relative_path}/bin/app.elf'", "group": { "kind": "build", "isDefault": true }, + "dependsOn": [ + "Install app loading requirements (Windows with PowerShell)" + ], "problemMatcher": [] }, + // ------------------------------------------------------------------------------ + // Helper tasks put in 'test' group so they are hidden from the build tasks menu. + // ------------------------------------------------------------------------------ { - "label": "kill Speculos", + "label": "Install app loading requirements (Linux)", "type": "shell", - "command": "pkill -f speculos.py", + // Copies the ledger udev rule file to the /etc/udev/rules.d/ directory if it does not exist, then reloads the rules and triggers udev. + "command": "if [ ! -f '/etc/udev/rules.d/${config:linux_udev_ledgerblue_rule_file}' ]; then sudo cp .vscode/${config:linux_udev_ledgerblue_rule_file} /etc/udev/rules.d/ && sudo udevadm control --reload-rules && sudo udevadm trigger; fi", "group": { - "kind": "build", + "kind": "test", "isDefault": true }, "problemMatcher": [] + }, + { + "label": "Install app loading requirements (macOS)", + "type": "shell", + // Checks that virtual env is installed, otherwise installs it. Then installs ledgerblue in a virtualenv. + "command": "[ -n '$VIRTUAL_ENV' ] || if ! python3 -m virtualenv --version >/dev/null 2>&1; then python3 -m pip install virtualenv; fi && [ -d 'ledger' ] || python3 -m virtualenv ledger && source ledger/bin/activate && python3 -m pip show ledgerblue >/dev/null 2>&1 || python3 -m pip install ledgerblue", + "group": { + "kind": "test", + "isDefault": true + }, + "problemMatcher": [] + }, + { + "label": "Install app loading requirements (Windows with PowerShell)", + "type": "shell", + // Checks that virtual env is installed, otherwise installs it. Then installs ledgerblue in a virtualenv. + "command": "cmd.exe /C 'if not exist ledger (python -m pip install virtualenv && python -m venv ledger && call ledger\\Scripts\\activate.bat && python -m pip install ledgerblue)'", + "group": { + "kind": "test", + "isDefault": true + }, + "problemMatcher": [] + }, + ], + "inputs": [ + { + "id": "sdk", + "type": "pickString", + "description": "Choose a SDK to build with", + "options": [ + "$NANOS_SDK", + "$NANOX_SDK", + "$NANOSP_SDK", + "$STAX_SDK", + ] + }, + { + "id": "model", + "type": "pickString", + "description": "Which model to run speculos for ?", + "options": [ + "nanos", + "nanox", + "nanosp", + "stax", + ] } ] -} \ No newline at end of file +} diff --git a/Makefile b/Makefile index 15bfee9c..6deb3250 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,6 @@ # **************************************************************************** -# This work is licensed under a Creative Commons Attribution-NoDerivatives -# 4.0 International License. -# -# This software also incorporates work covered by the following copyright -# and permission notice: -# # Ledger App Boilerplate -# (c) 2020 Ledger SAS. +# (c) Ledger SAS. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -27,115 +21,52 @@ endif include $(BOLOS_SDK)/Makefile.defines -APP_LOAD_PARAMS = --curve secp256k1 -ifeq ($(TARGET_NAME), TARGET_NANOX) -APP_LOAD_PARAMS=--appFlags 0x200 # APPLICATION_FLAG_BOLOS_SETTINGS -else -APP_LOAD_PARAMS=--appFlags 0x000 -endif -APP_LOAD_PARAMS += --path "44'/3333'" -APP_LOAD_PARAMS += --path "44'/1'" -APP_LOAD_PARAMS += $(COMMON_LOAD_PARAMS) +######################################## +# Mandatory configuration # +######################################## +# Application name +APPNAME = "Solar" -APPNAME = "Solar" +# Application version APPVERSION_M = 1 APPVERSION_N = 0 APPVERSION_P = 0 -APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" - -ifeq ($(TARGET_NAME),TARGET_NANOS) - ICONNAME=icons/nanos_app_solar.gif -else - ICONNAME=icons/nanox_app_solar.gif -endif - -all: default - -DEFINES += $(DEFINES_LIB) -DEFINES += APPNAME=\"$(APPNAME)\" -DEFINES += APPVERSION=\"$(APPVERSION)\" -DEFINES += MAJOR_VERSION=$(APPVERSION_M) MINOR_VERSION=$(APPVERSION_N) PATCH_VERSION=$(APPVERSION_P) -DEFINES += OS_IO_SEPROXYHAL -DEFINES += HAVE_BAGL HAVE_UX_FLOW HAVE_SPRINTF -DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=6 IO_HID_EP_LENGTH=64 HAVE_USB_APDU -DEFINES += USB_SEGMENT_SIZE=64 -DEFINES += BLE_SEGMENT_SIZE=32 -DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL="" -DEFINES += UNUSED\(x\)=\(void\)x -DEFINES += NANO_PXLS_PER_LINE=114 - -ifeq ($(TARGET_NAME),TARGET_NANOX) - DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 HAVE_BLE_APDU -endif - -ifeq ($(TARGET_NAME),TARGET_NANOS) - DEFINES += IS_NANOS=1 - DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128 -else - DEFINES += IS_NANOS=0 - DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300 - DEFINES += HAVE_GLO096 - DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=64 - DEFINES += HAVE_BAGL_ELLIPSIS - DEFINES += HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX - DEFINES += HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX - DEFINES += HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX -endif - -DEBUG = 0 -ifneq ($(DEBUG),0) - DEFINES += HAVE_PRINTF - ifeq ($(TARGET_NAME),TARGET_NANOS) - DEFINES += PRINTF=screen_printf - else - DEFINES += PRINTF=mcu_usb_printf - endif -else - DEFINES += PRINTF\(...\)= -endif - -ifneq ($(BOLOS_ENV),) -$(info BOLOS_ENV=$(BOLOS_ENV)) -CLANGPATH := $(BOLOS_ENV)/clang-arm-fropi/bin/ -GCCPATH := $(BOLOS_ENV)/gcc-arm-none-eabi-5_3-2016q1/bin/ -else -$(info BOLOS_ENV is not set: falling back to CLANGPATH and GCCPATH) -endif -ifeq ($(CLANGPATH),) -$(info CLANGPATH is not set: clang will be used from PATH) -endif -ifeq ($(GCCPATH),) -$(info GCCPATH is not set: arm-none-eabi-* will be used from PATH) -endif - -CC := $(CLANGPATH)clang -CFLAGS += -O3 -Os -AS := $(GCCPATH)arm-none-eabi-gcc -LD := $(GCCPATH)arm-none-eabi-gcc -LDFLAGS += -O3 -Os -LDLIBS += -lm -lgcc -lc - -include $(BOLOS_SDK)/Makefile.glyphs +APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" +# Application source files APP_SOURCE_PATH += src -SDK_SOURCE_PATH += lib_stusb lib_stusb_impl lib_ux -ifeq ($(TARGET_NAME),TARGET_NANOX) - SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl -endif +# Application icons following guidelines: +# https://developers.ledger.com/docs/embedded-app/design-requirements/#device-icon +ICON_NANOS = icons/app_solar_16px.gif +ICON_NANOX = icons/app_solar_14px.gif +ICON_NANOSP = icons/app_solar_14px.gif +# ICON_STAX = icons/app_boilerplate_32px.gif + +# Application allowed derivation curves. +CURVE_APP_LOAD_PARAMS = secp256k1 -load: all - python3 -m ledgerblue.loadApp $(APP_LOAD_PARAMS) +# Application allowed derivation paths. +PATH_APP_LOAD_PARAMS = "44'/3333'" "44'/1'" -load-offline: all - python3 -m ledgerblue.loadApp $(APP_LOAD_PARAMS) --offline +# Setting to allow building variant applications +VARIANT_PARAM = COIN +VARIANT_VALUES = SXP -delete: - python3 -m ledgerblue.deleteApp $(COMMON_DELETE_PARAMS) +# Enabling DEBUG flag will enable PRINTF and disable optimizations +#DEBUG = 1 -include $(BOLOS_SDK)/Makefile.rules +######################################## +# Application communication interfaces # +######################################## +ENABLE_BLUETOOTH = 1 +#ENABLE_NFC = 1 -dep/%.d: %.c Makefile +######################################## +# NBGL custom features # +######################################## +#ENABLE_NBGL_QRCODE = 1 +#ENABLE_NBGL_KEYBOARD = 1 +#ENABLE_NBGL_KEYPAD = 1 -listvariants: - @echo VARIANTS COIN SOL +include $(BOLOS_SDK)/Makefile.standard_app diff --git a/README.md b/README.md index 354af000..1ded7070 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,10 @@ ## Development -Visit the [Ledger Developer Portal](https://developers.ledger.com/docs/nano-app/start-here) to learn more about Nano app development and the development environment, or skip to the following links for specific instructions on building and loading a Nano app: +Visit the [Ledger Developer Portal](https://developers.ledger.com/docs/embedded-app/introduction) to learn more about embedded apps and the app development environment, or visit the following links for specific instructions on building and loading an embedded app: -- [Build the application](https://developers.ledger.com/docs/nano-app/build) -- [Load the application](https://developers.ledger.com/docs/nano-app/load) +- [Build the Application](https://developers.ledger.com/docs/embedded-app/build-app) +- Load the Application: [Linux](https://developers.ledger.com/docs/embedded-app/load-linux) | [Mac](https://developers.ledger.com/docs/embedded-app/load-mac) ## Documentation diff --git a/doc/APDU.md b/doc/APDU.md index a650b68a..959676c4 100644 --- a/doc/APDU.md +++ b/doc/APDU.md @@ -12,7 +12,7 @@ Status words tend to be similar to common [APDU responses](https://www.eftlab.co ## Command APDU | Field | Length (bytes) | Description | -| ----- | :------------: | --------------------------------------------------------------------- | +|-------|:--------------:|-----------------------------------------------------------------------| | CLA | 1 | Instruction class - indicates the type of command | | INS | 1 | Instruction code - indicates the specific command | | P1 | 1 | Instruction parameter 1 for the command | @@ -23,6 +23,6 @@ Status words tend to be similar to common [APDU responses](https://www.eftlab.co ## Response APDU | Field | Length (bytes) | Description | -| ----- | :------------: | ----------------------------------------------------------------------------- | -| RData | variable | Reponse data (can be empty) | +|-------|:--------------:|-------------------------------------------------------------------------------| +| RData | variable | Response data (can be empty) | | SW | 2 | Status word containing command processing status (e.g., `0x9000` for success) | diff --git a/doc/COMMANDS.md b/doc/COMMANDS.md index 12ff7a91..022b3abe 100644 --- a/doc/COMMANDS.md +++ b/doc/COMMANDS.md @@ -3,7 +3,7 @@ ## Overview | Command Name | INS | Description | -| ---------------- | :----: | ------------------------------------------------------------------- | +|------------------|:------:|---------------------------------------------------------------------| | `GET_APP_NAME` | `0xa1` | Get the ASCII encoded application name. | | `GET_VERSION` | `0xa2` | Get the application's version as `[MAJOR(1), MINOR(1), PATCH(1)]`. | | `GET_PUBLIC_KEY` | `0xb1` | Get the user's PublicKey given a BIP32 path. | @@ -18,7 +18,7 @@ The `GET_APP_NAME` instruction will return the app name, "`Solar`" as an ASCII-e ### Command | CLA | INS | P1 | P2 | Lc | CData | -| :----: | :----: | :----: | :----: | :----: | :--------: | +|:------:|:------:|:------:|:------:|:------:|:----------:| | `0xe0` | `0xa1` | `0x00` | `0x00` | `0x00` | _not used_ | > Note that `CData` is not used and should remain empty. @@ -28,14 +28,14 @@ The `GET_APP_NAME` instruction will return the app name, "`Solar`" as an ASCII-e For the `GET_APP_NAME` instruction, both P1 and P2 values are not used and should be set as `0x00`. | Parameter | Value | Description | -| :-------: | :----: | :---------: | +|:---------:|:------:|:-----------:| | P1 | `0x00` | _not used_ | | P2 | `0x00` | _not used_ | ### Response | Response length | SW | RData | -| :-------------: | :------: | :-----: | +|:---------------:|:--------:|:-------:| | 5 _(bytes)_ | `0x9000` | `Solar` | ### Example Session @@ -53,7 +53,7 @@ The `GET_VERSION` instruction will return the Solar App's version as a byte arra ### Command | CLA | INS | P1 | P2 | Lc | CData | -| :----: | :----: | :----: | :----: | :----: | :--------: | +|:------:|:------:|:------:|:------:|:------:|:----------:| | `0xe0` | `0xa2` | `0x00` | `0x00` | `0x00` | _not used_ | > Note that `CData` is not used and should remain empty. @@ -63,14 +63,14 @@ The `GET_VERSION` instruction will return the Solar App's version as a byte arra For the `GET_VERSION` instruction, both P1 and P2 values are not used and should be set as `0x00`. | Parameter | Value | Description | -| :-------: | :----: | :---------: | +|:---------:|:------:|:-----------:| | P1 | `0x00` | _not used_ | | P2 | `0x00` | _not used_ | ### Response | Response length | SW | RData | -| :-------------: | :------: | :------------------------------: | +|:---------------:|:--------:|:--------------------------------:| | 3 _(bytes)_ | `0x9000` | `[MAJOR(1), MINOR(1), PATCH(1)]` | ### Example Session @@ -88,7 +88,7 @@ The `GET_PUBLIC_KEY` instruction will return the user's PublicKey given a deriva ### Command | CLA | INS | P1 | P2 | Lc | CData | -| :----: | :----: | :---------------: | :---------------: | :----: | :-------------------------------------------------------------: | +|:------:|:------:|:-----------------:|:-----------------:|:------:|:---------------------------------------------------------------:| | `0xe0` | `0xb1` | `0x00`
`0x01` | `0x00`
`0x01` | 1 + 4n | `[len(bip32_path)(1), bip32_path{1}(4), ..., bip32_path{n}(4)]` | ### Parameters @@ -96,13 +96,13 @@ The `GET_PUBLIC_KEY` instruction will return the user's PublicKey given a deriva For the `GET_PUBLIC_KEY` instruction, the P1 value is used to signify whether or not to display the user's PublicKey on the Ledger device's screen and prompt the user for approval. | P1 | -| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
ValueDescription
`0x00`Don't display or ask for user confirmation.
`0x01`Display and ask for user confirmation.
| For the `GET_PUBLIC_KEY` instruction, the P2 value is used to signify whether or not the HD chain code should be included in the response. _(see ['BIP-0032: Extended Keys'](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#extended-keys) for more about the chain code)._ | P2 | -| :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
ValueDescription
`0x00`Don't request the chain code.
`0x01`Request the chain code.
| ### Response @@ -110,13 +110,13 @@ For the `GET_PUBLIC_KEY` instruction, the P2 value is used to signify whether or No Chain Code: | Response length | SW | RData | -| :-------------: | :------: | :------------------------------------: | +|:---------------:|:--------:|:--------------------------------------:| | 34 _(bytes)_ | `0x9000` | `[len(public_key)(1), public_key(33)]` | With Chain Code: | Response length | SW | RData | -| :-------------: | :------: | :------------------------------------------------------------------------: | +|:---------------:|:--------:|:--------------------------------------------------------------------------:| | 67 _(bytes)_ | `0x9000` | `[len(public_key)(1), public_key(33), len(chain_code)(1), chain_code(32)]` | ### Example Session @@ -134,7 +134,7 @@ The `GET_ADDRESS` instruction will return the user's Address given a derivation ### Command | CLA | INS | P1 | P2 | Lc | CData | -| ------ | ------ | ----------------- | ------------------------------------- | ------ | --------------------------------------------------------------- | +|--------|--------|-------------------|---------------------------------------|--------|-----------------------------------------------------------------| | `0xe0` | `0xb2` | `0x00`
`0x01` | `0x3F` (mainnet)
`0x1E` (testnet) | 1 + 4n | `[len(bip32_path)(1), bip32_path{1}(4), ..., bip32_path{n}(4)]` | ### Parameters @@ -142,19 +142,19 @@ The `GET_ADDRESS` instruction will return the user's Address given a derivation For the `GET_ADDRESS` instruction, the P1 value is used to signify whether or not to display the user's PublicKey on the Ledger device's screen and prompt the user for approval. | P1 | -| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
ValueDescription
`0x00`Don't display or ask for user confirmation.
`0x01`Display and ask for user confirmation.
| For the `GET_ADDRESS` instruction, the P2 value is used to specify which network the Address should be created for. | P2 | -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
Value Network Prefix Example Address
0x3F Mainnet S SNAgA2XCRZDKfm5Vu9h4KR1bZw5xn9EiC3
0x1E Testnet D D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib
| ### Response | Response length | SW | RData | -| :-------------: | :------: | :--------------------------------------: | +|:---------------:|:--------:|:----------------------------------------:| | 35 _(bytes)_ | `0x9000` | `[len(address)(1), base_58_address(34)]` | ### Example Session @@ -172,7 +172,7 @@ The `SIGN_MESSAGE` instruction is used to sign an ASCII text message for a given First Chunk: | CLA | INS | P1 | P2 | Lc | CData | -| :----: | :----: | :----: | :----: | :----: | :-------------------------------------------------------------: | +|:------:|:------:|:------:|:------:|:------:|:---------------------------------------------------------------:| | `0xe0` | `0xc1` | `0x00` | `0x80` | 1 + 4n | `[len(bip32_path)(1), bip32_path{1}(4), ..., bip32_path{n}(4)]` | > Note that the first chunk will only contain path information in `CData`. @@ -180,7 +180,7 @@ First Chunk: _nth_ Chunk: | CLA | INS | P1 | P2 | Lc | CData | -| :----: | :----: | :------: | :-----------------------------: | :--------------------: | :--------------------: | +|:------:|:------:|:--------:|:-------------------------------:|:----------------------:|:----------------------:| | `0xe0` | `0xc1` | _`n...`_ | `0x80` (more)
`0x00` (last) | variable (_`1...255`_) | `[payload_data_chunk]` | ### Parameters @@ -190,19 +190,19 @@ For the `SIGN_MESSAGE` instruction, the P1 value is used to represent the chunk' > There is currently a limit of 8 chunks max. | P1 | -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
ValueDescription
`0x00`The first chunk
`...`_nth_ chunk
| For the `SIGN_MESSAGE` instruction, the P2 value is used to signify whether there are more chunks to be received or if the current chunk is the final chunk of the request session. | P2 | -| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
ValueDescription
`0x80`More chunks should be expected.
`0x00`This is the final chunk that should be expected.
| ### Response | Response length | SW | RData | -| :-------------: | :------: | :-----------------------: | +|:---------------:|:--------:|:-------------------------:| | 64 _(bytes)_ | `0x9000` | `[schnorr_signature(64)]` | ### Example Session @@ -223,7 +223,7 @@ The `SIGN_TX` instruction is used to sign a Solar transaction for a given deriva First Chunk: | CLA | INS | P1 | P2 | Lc | CData | -| :----: | :----: | :----: | :----: | :----: | :-------------------------------------------------------------: | +|:------:|:------:|:------:|:------:|:------:|:---------------------------------------------------------------:| | `0xe0` | `0xc2` | `0x00` | `0x80` | 1 + 4n | `[len(bip32_path)(1), bip32_path{1}(4), ..., bip32_path{n}(4)]` | > Note that the first chunk will only contain path information in `CData`. @@ -231,7 +231,7 @@ First Chunk: _nth_ Chunk: | CLA | INS | P1 | P2 | Lc | CData | -| :----: | :----: | :------: | :-----------------------------: | :--------------------: | :--------------------: | +|:------:|:------:|:--------:|:-------------------------------:|:----------------------:|:----------------------:| | `0xe0` | `0xc2` | _`n...`_ | `0x80` (more)
`0x00` (last) | variable (_`1...255`_) | `[payload_data_chunk]` | ### Parameters @@ -241,19 +241,19 @@ For the `SIGN_TX` instruction, the P1 value is used to represent the chunk's ind > There is currently a limit of 8 chunks max. | P1 | -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
ValueDescription
`0x00`The first chunk
`...`_nth_ chunk
| For the `SIGN_TX` instruction, the P2 value is used to signify whether there are more chunks to be received or if the current chunk is the final chunk of the request session. | P2 | -| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
ValueDescription
`0x80`More chunks should be expected.
`0x00`This is the final chunk that should be expected.
| ### Response | Response length | SW | RData | -| :-------------: | :------: | :---------------: | +|:---------------:|:--------:|:-----------------:| | 64 _(bytes)_ | `0x9000` | `[signature(64)]` | ### Example Session @@ -268,17 +268,17 @@ For the `SIGN_TX` instruction, the P2 value is used to signify whether there are ## Status Words | SW | SW name | Description | -| :------: | :--------------------------- | :----------------------------------------------- | +|:--------:|:-----------------------------|:-------------------------------------------------| | `0x6985` | `SW_DENY` | Rejected by user | | `0x6A86` | `SW_WRONG_P1P2` | Either `P1` or `P2` is incorrect | -| `0x6A87` | `SW_WRONG_DATA_LENGTH` | `Lc` or minimum APDU lenght is incorrect | +| `0x6A87` | `SW_WRONG_DATA_LENGTH` | `Lc` or minimum APDU length is incorrect | | `0x6D00` | `SW_INS_NOT_SUPPORTED` | No command exists with `INS` | | `0x6E00` | `SW_CLA_NOT_SUPPORTED` | Bad `CLA` used for this application | -| `0xB000` | `SW_WRONG_RESPONSE_LENGTH` | Wrong response lenght (buffer size problem) | +| `0xB000` | `SW_WRONG_RESPONSE_LENGTH` | Wrong response length (buffer size problem) | | `0xB001` | `SW_DISPLAY_BIP32_PATH_FAIL` | BIP32 path conversion to string failed | | `0xB002` | `SW_DISPLAY_PUBLICKEY_FAIL` | PublicKey conversion to string failed | | `0xB003` | `SW_DISPLAY_AMOUNT_FAIL` | Amount conversion to string failed | -| `0xB004` | `SW_WRONG_TX_LENGTH` | Wrong raw transaction lenght | +| `0xB004` | `SW_WRONG_TX_LENGTH` | Wrong raw transaction length | | `0xB005` | `SW_TX_PARSING_FAIL` | Failed to parse raw transaction | | `0xB006` | `SW_TX_HASH_FAIL` | Failed to compute hash digest of raw transaction | | `0xB007` | `SW_BAD_STATE` | Security issue with bad state | diff --git a/doc/TRANSACTION.md b/doc/TRANSACTION.md index 28a5b051..d821e3e1 100644 --- a/doc/TRANSACTION.md +++ b/doc/TRANSACTION.md @@ -48,12 +48,8 @@ The network/version byte is used to set the leading character of the address and ## Transaction Structures - TypeGroup 1 - - [Type 4: MultiSignature Registration](./transactions/TG01_T04_MULTISIGNATURE_REG.md) - [Type 5: IPFS](./transactions/TG01_T05_IPFS.md) - [Type 6: Transfer](./transactions/TG01_T06_TRANSFER.md) - - [Type 8: HTLC Lock](./transactions/TG01_T08_HTLC_LOCK.md) - - [Type 9: HTLC Claim](./transactions/TG01_T09_HTLC_CLAIM.md) - - [Type 10: HTLC Refund](./transactions/TG01_T10_HTLC_REFUND.md) - TypeGroup 2 - [Type 0: Burn](./transactions/TG02_T00_BURN.md) - [Type 2: Vote](./transactions/TG02_T02_VOTE.md) @@ -69,7 +65,5 @@ Solar transaction fees are dynamic and can be found via the network's API: [http ## Links -- Solar API Documentation - [https://docs.solar.org/api/public-rest-api/getting-started](https://docs.solar.org/api/public-rest-api/getting-started) -- Solar Explorer - [https://explorer.solar.org](https://explorer.solar.org) -- Solar Staking - [https://solar.org/staking](https://solar.org/staking) +- Solar Documentation - [https://docs.solar.org/](https://docs.solar.org) - Solar Whitepaper - [https://docs.solar.org/assets/documents/whitepaper-february-2022.pdf](https://docs.solar.org/assets/documents/whitepaper-february-2022.pdf) diff --git a/doc/transactions/TG01_T04_MULTISIGNATURE_REG.md b/doc/transactions/TG01_T04_MULTISIGNATURE_REG.md deleted file mode 100644 index b957031b..00000000 --- a/doc/transactions/TG01_T04_MULTISIGNATURE_REG.md +++ /dev/null @@ -1,60 +0,0 @@ -# TypeGroup 1 | Type 4: MultiSignature Registration - -## JSON - -```json -{ - "version": 3, - "network": 63, - "typeGroup": 1, - "type": 4, - "nonce": "3", - "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - "fee": "2000000000", - "amount": "0", - "asset": { - "multiSignature": { - "publicKeys": [ - "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - "03df0a1eb42d99b5de395cead145ba1ec2ea837be308c7ce3a4e8018b7efc7fdb8", - "03860d76b1df09659ac282cea3da5bd84fc45729f348a4a8e5f802186be72dc17f" - ], - "min": 2 - } - } -} -``` - -## Serialised - -```shell -ff033f0100000004000300000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920094357700000000000203034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19203df0a1eb42d99b5de395cead145ba1ec2ea837be308c7ce3a4e8018b7efc7fdb803860d76b1df09659ac282cea3da5bd84fc45729f348a4a8e5f802186be72dc17f -``` - -## Deserialised - -| Key | Pos. | Size
_(bytes)_ | Value
_(hex)_ | -| :------------------- | :-------: | :---------------: | :--------------------------------------------------------------------- | -| **Header:** | **[0]** | **1** | `0xff` | -| **Version:** | **[1]** | **1** | `0x03` | -| **Network:** | **[2]** | **1** | `0x3f` | -| **Typegroup:** | **[3]** | **4** | `0x01000000` | -| **Type:** | **[7]** | **2** | `0x0400` | -| **Nonce:** | **[9]** | **8** | `0x0300000000000000` | -| **SenderPublicKey:** | **[17]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | -| **Fee:** | **[50]** | **8** | `0x0094357700000000` | -| **Memo Length:** | **[58]** | **1** | `0x00` | -| **Key Min:** | **[59]** | **1** | `0x02` | -| **Key Count:** | **[60]** | **1** | `0x03` | -| **Key 1:** | **[61]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | -| **Key 2:** | **[94]** | **33** | `0x03df0a1eb42d99b5de395cead145ba1ec2ea837be308c7ce3a4e8018b7efc7fdb8` | -| **Key 3:** | **[127]** | **33** | `0x03860d76b1df09659ac282cea3da5bd84fc45729f348a4a8e5f802186be72dc17f` | - -## APDU Session - -```shell -=> e0c2008015058000002c80000d05800000000000000000000000 -<= 9000 -=> e0c20100a0ff033f0100000004000300000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920094357700000000000203034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19203df0a1eb42d99b5de395cead145ba1ec2ea837be308c7ce3a4e8018b7efc7fdb803860d76b1df09659ac282cea3da5bd84fc45729f348a4a8e5f802186be72dc17f -<= , 0x9000 -``` diff --git a/doc/transactions/TG01_T05_IPFS.md b/doc/transactions/TG01_T05_IPFS.md index b0b5ca77..df074066 100644 --- a/doc/transactions/TG01_T05_IPFS.md +++ b/doc/transactions/TG01_T05_IPFS.md @@ -4,23 +4,23 @@ ```json { - "version": 3, - "network": 63, - "typeGroup": 1, - "type": 5, - "nonce": "4", - "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - "fee": "500000000", - "asset": { - "ipfs": "QmYSK2JyM3RyDyB52caZCTKFR3HKniEcMnNJYdk8DQ6KKB" - } + "version": 3, + "network": 63, + "typeGroup": 1, + "type": 5, + "nonce": "7", + "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + "fee": "5000000", + "asset": { + "ipfs": "QmYSK2JyM3RyDyB52caZCTKFR3HKniEcMnNJYdk8DQ6KKB" + } } ``` ## Serialised ```shell -ff033f0100000005000400000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000012209608184d6cee2b9af8e6c2a46fc9318adf73329aeb8a86cf8472829fff5bb89e +ff033f0100000005000700000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192404b4c00000000000012209608184d6cee2b9af8e6c2a46fc9318adf73329aeb8a86cf8472829fff5bb89e ``` ## Deserialised @@ -32,9 +32,9 @@ ff033f0100000005000400000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b | **Network:** | **[2]** | **1** | `0x3f` | | **TypeGroup:** | **[3]** | **4** | `0x01000000` | | **Type:** | **[7]** | **2** | `0x0500` | -| **Nonce:** | **[9]** | **8** | `0x0400000000000000` | +| **Nonce:** | **[9]** | **8** | `0x0700000000000000` | | **SenderPublicKey:** | **[17]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | -| **Fee:** | **[50]** | **8** | `0x0065cd1d00000000` | +| **Fee:** | **[50]** | **8** | `0x404b4c0000000000` | | **Memo Length:** | **[58]** | **1** | `0x00` | | **IPFS Hash:** | **[59]** | **34** | `0x12209608184d6cee2b9af8e6c2a46fc9318adf73329aeb8a86cf8472829fff5bb89e` | @@ -53,6 +53,6 @@ ff033f0100000005000400000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b ```shell => e0c2008015058000002c80000d05800000000000000000000000 <= 9000 -=> e0c201005dff033f0100000005000400000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000012209608184d6cee2b9af8e6c2a46fc9318adf73329aeb8a86cf8472829fff5bb89e +=> e0c201005dff033f0100000005000700000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192404b4c00000000000012209608184d6cee2b9af8e6c2a46fc9318adf73329aeb8a86cf8472829fff5bb89e <= , 0x9000 ``` diff --git a/doc/transactions/TG01_T06_TRANFER.md b/doc/transactions/TG01_T06_TRANFER.md index cfe2a24d..be61d2c8 100644 --- a/doc/transactions/TG01_T06_TRANFER.md +++ b/doc/transactions/TG01_T06_TRANFER.md @@ -4,64 +4,65 @@ ```json { - "version": 3, - "network": 63, - "type": 6, - "nonce": "5", - "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - "fee": "10000000", - "amount": "0", - "asset": { - "transfers": [ - { "amount": "1", "recipientId": "SNAgA2XCRZDKfm5Vu9h4KR1bZw5xn9EiC3" }, - { "amount": "1", "recipientId": "SjHT1fxVsW75eaQUPN4U2SEgFVU8ZqSVgk" }, - { "amount": "1", "recipientId": "SVzKH9r6u8UGcd2Ki7tAzQtB5Pa6FRn4GA" }, - { "amount": "1", "recipientId": "SVhLL7NR8WhkKRfYDzSmGxUH4Gg5k3uis7" }, - { "amount": "1", "recipientId": "SeznGToSzxw7maHDWXD2eRoTBSS2BmK8nU" }, - { "amount": "1", "recipientId": "SfVFPA5e2JYcgJeUmVBEsFCYCWpt5xkZ5o" }, - { "amount": "1", "recipientId": "SQEDRvC79Tqqmv85FrnqG4AxAxFoYPADCa" }, - { "amount": "1", "recipientId": "SX87pA6bJdQQf57JnUUkzVJxZ2n9jxDgeN" }, - { "amount": "1", "recipientId": "SMMJgffKfvtERv3d4MFeypAg53UcxJ9dE1" }, - { "amount": "1", "recipientId": "SefdTc8Sjx5pqSUu3TpfjFw6epyPYWoooQ" }, - { "amount": "1", "recipientId": "SSB1coESUy1GHsXjxd1Qzw5e1HqMUNQzRG" }, - { "amount": "1", "recipientId": "SNtHvv7fr23EcKHkXeSwCYz6w2ZLaT7y9y" }, - { "amount": "1", "recipientId": "SUogQH6n5EjwFnXwDapkJ1jri13Hrj1Ppz" }, - { "amount": "1", "recipientId": "SY4RAvsUTZ5q9PR9Df28vguH6LfRFrgB3a" }, - { "amount": "1", "recipientId": "SPZynxFxAtSBVKQWQW8LQPtrt87CBqpn7i" }, - { "amount": "1", "recipientId": "Sj6YjvZYDH4xh8HsRiYzWLBpeAkx65Nc1W" }, - { "amount": "1", "recipientId": "SX3XMHrMSbXLLNGcRVbMBy4WgQbS3MZzWV" }, - { "amount": "1", "recipientId": "SYqJcLu2wWYHDYvSomgsDPtnteCVhpNCTQ" }, - { "amount": "1", "recipientId": "Sa1v9xUZaniWKiCGzEV7qYXt1pW3G3XJbi" }, - { "amount": "1", "recipientId": "SQVwXdWCqouKWQhaAJMsNieZmjE3GLYYiz" }, - { "amount": "1", "recipientId": "SR1ZhBPLnSvrq3SQt8zeqBshemiudGb9fe" }, - { "amount": "1", "recipientId": "Sd1beR5X9pKKEYSxYWc7XXozC52y8QGJSt" }, - { "amount": "1", "recipientId": "SScQEYdkr5mPGD9uwFrdk15KjyKAfwHZFc" }, - { "amount": "1", "recipientId": "SRMhbyiuDa14kQKE7g8NB9jrBE8Jh9NwPv" }, - { "amount": "1", "recipientId": "SUwp9puY8x9GYbvq8X4eYE5UjQxCgmNJMJ" }, - { "amount": "1", "recipientId": "ShomZcGU7c15EUXTUAfZB2QHw17UsHxxyf" }, - { "amount": "1", "recipientId": "ScCTPEwY4Bz2cTJJxL4Fy388zRTrAKmV8m" }, - { "amount": "1", "recipientId": "ShqpcENQP4gSqRcrC1oqAzSiNscvutyQ3B" }, - { "amount": "1", "recipientId": "SjcaXuPypJxUv8qg4z7SaAry9ipqkVZsV2" }, - { "amount": "1", "recipientId": "SZk35koLSrjSetXda5toYEhNNv3GNbosDN" }, - { "amount": "1", "recipientId": "SVBBoMW8u2TiH4C59yi5wxk5mis81NJupL" }, - { "amount": "1", "recipientId": "SgZEJxkDxfDSWP38QjkDkAf9uQLwb4XL8N" }, - { "amount": "1", "recipientId": "SgE9Mqj1ZX9ziL9bJUUaRXzwNibEocJm5s" }, - { "amount": "1", "recipientId": "SYkqTvG2n54Fbg1hAiZDeK33DYwCYZWcuC" }, - { "amount": "1", "recipientId": "SjUcnukBRT6qxLRbbyrsQxVjbMdVLYRi5a" }, - { "amount": "1", "recipientId": "SNSmzTzFPmzSmaKgcDj32nz7aJp1dJqJ5a" }, - { "amount": "1", "recipientId": "SRdLAGYYk8HVeL3iJxRmYxZ9qvGUdRBiub" }, - { "amount": "1", "recipientId": "SQf1Dpta8b94FYjKDBu2dfFF4EdUfLMnoU" }, - { "amount": "1", "recipientId": "Si5KNcn97V6TZYH1ccZZpyMvCJZmKuLEzv" }, - { "amount": "1", "recipientId": "SfxX8nJVJ5rUbAXPVgFMXhpEbXXp1P3aWc" } - ] - } + "version": 3, + "network": 63, + "type": 6, + "nonce": "8", + "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + "fee": "50000000", + "amount": "0", + "asset": { + "transfers": [ + { "amount": "1", "recipientId": "SNAgA2XCRZDKfm5Vu9h4KR1bZw5xn9EiC3" }, + { "amount": "1", "recipientId": "SjHT1fxVsW75eaQUPN4U2SEgFVU8ZqSVgk" }, + { "amount": "1", "recipientId": "SVzKH9r6u8UGcd2Ki7tAzQtB5Pa6FRn4GA" }, + { "amount": "1", "recipientId": "SVhLL7NR8WhkKRfYDzSmGxUH4Gg5k3uis7" }, + { "amount": "1", "recipientId": "SeznGToSzxw7maHDWXD2eRoTBSS2BmK8nU" }, + { "amount": "1", "recipientId": "SfVFPA5e2JYcgJeUmVBEsFCYCWpt5xkZ5o" }, + { "amount": "1", "recipientId": "SQEDRvC79Tqqmv85FrnqG4AxAxFoYPADCa" }, + { "amount": "1", "recipientId": "SX87pA6bJdQQf57JnUUkzVJxZ2n9jxDgeN" }, + { "amount": "1", "recipientId": "SMMJgffKfvtERv3d4MFeypAg53UcxJ9dE1" }, + { "amount": "1", "recipientId": "SefdTc8Sjx5pqSUu3TpfjFw6epyPYWoooQ" }, + { "amount": "1", "recipientId": "SSB1coESUy1GHsXjxd1Qzw5e1HqMUNQzRG" }, + { "amount": "1", "recipientId": "SNtHvv7fr23EcKHkXeSwCYz6w2ZLaT7y9y" }, + { "amount": "1", "recipientId": "SUogQH6n5EjwFnXwDapkJ1jri13Hrj1Ppz" }, + { "amount": "1", "recipientId": "SY4RAvsUTZ5q9PR9Df28vguH6LfRFrgB3a" }, + { "amount": "1", "recipientId": "SPZynxFxAtSBVKQWQW8LQPtrt87CBqpn7i" }, + { "amount": "1", "recipientId": "Sj6YjvZYDH4xh8HsRiYzWLBpeAkx65Nc1W" }, + { "amount": "1", "recipientId": "SX3XMHrMSbXLLNGcRVbMBy4WgQbS3MZzWV" }, + { "amount": "1", "recipientId": "SYqJcLu2wWYHDYvSomgsDPtnteCVhpNCTQ" }, + { "amount": "1", "recipientId": "Sa1v9xUZaniWKiCGzEV7qYXt1pW3G3XJbi" }, + { "amount": "1", "recipientId": "SQVwXdWCqouKWQhaAJMsNieZmjE3GLYYiz" }, + { "amount": "1", "recipientId": "SR1ZhBPLnSvrq3SQt8zeqBshemiudGb9fe" }, + { "amount": "1", "recipientId": "Sd1beR5X9pKKEYSxYWc7XXozC52y8QGJSt" }, + { "amount": "1", "recipientId": "SScQEYdkr5mPGD9uwFrdk15KjyKAfwHZFc" }, + { "amount": "1", "recipientId": "SRMhbyiuDa14kQKE7g8NB9jrBE8Jh9NwPv" }, + { "amount": "1", "recipientId": "SUwp9puY8x9GYbvq8X4eYE5UjQxCgmNJMJ" }, + { "amount": "1", "recipientId": "ShomZcGU7c15EUXTUAfZB2QHw17UsHxxyf" }, + { "amount": "1", "recipientId": "ScCTPEwY4Bz2cTJJxL4Fy388zRTrAKmV8m" }, + { "amount": "1", "recipientId": "ShqpcENQP4gSqRcrC1oqAzSiNscvutyQ3B" }, + { "amount": "1", "recipientId": "SjcaXuPypJxUv8qg4z7SaAry9ipqkVZsV2" }, + { "amount": "1", "recipientId": "SZk35koLSrjSetXda5toYEhNNv3GNbosDN" }, + { "amount": "1", "recipientId": "SVBBoMW8u2TiH4C59yi5wxk5mis81NJupL" }, + { "amount": "1", "recipientId": "SgZEJxkDxfDSWP38QjkDkAf9uQLwb4XL8N" }, + { "amount": "1", "recipientId": "SgE9Mqj1ZX9ziL9bJUUaRXzwNibEocJm5s" }, + { "amount": "1", "recipientId": "SYkqTvG2n54Fbg1hAiZDeK33DYwCYZWcuC" }, + { "amount": "1", "recipientId": "SjUcnukBRT6qxLRbbyrsQxVjbMdVLYRi5a" }, + { "amount": "1", "recipientId": "SNSmzTzFPmzSmaKgcDj32nz7aJp1dJqJ5a" }, + { "amount": "1", "recipientId": "SRdLAGYYk8HVeL3iJxRmYxZ9qvGUdRBiub" }, + { "amount": "1", "recipientId": "SQf1Dpta8b94FYjKDBu2dfFF4EdUfLMnoU" }, + { "amount": "1", "recipientId": "Si5KNcn97V6TZYH1ccZZpyMvCJZmKuLEzv" }, + { "amount": "1", "recipientId": "SfxX8nJVJ5rUbAXPVgFMXhpEbXXp1P3aWc" } + ] + } } + ``` ## Serialised ```shell -ff033f0100000006000500000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192809698000000000000280001000000000000003f0995750207ecaf0ccf251c1265b92ad84f55366201000000000000003ff13809c4c5fb2b3967a9b40efc70843f7db462ad01000000000000003f5f60e0594115b71d5b136cf929c8504082ac199d01000000000000003f5c2aaead4ce542788406c54e1ae31f1afdb7f08101000000000000003fc2308975254751ead4df705fc76aa84116c5e34e01000000000000003fc792d1958bb950596d0e7cd0bef325062009684801000000000000003f2031100e628422b8409810fdb438e874765846ba01000000000000003f6bd2c24bded5fdfd7888a28b3c6990503699b5e801000000000000003f009ffbb10efc47ad00a0a29cc2ef6e6c83d8c6ec01000000000000003fbe9147febbfe462cdbfda8575c18dabe85db4f5b01000000000000003f358634b58d88abf4aef3a6fe264b4ad18b74e98b01000000000000003f11745fc47a9c58c4e6f5a74eb59411ac102c6a8801000000000000003f5265ceb5d6102474ea7d0f401d6e6b9f13864a0501000000000000003f7617b5f3b82f153e388b4b200abd8636fff73dd501000000000000003f18f5df4fe3108277bfa4e39071fead9d59b35b8f01000000000000003fef283e95c3fdf0e2df9ba8321407c5621f98687601000000000000003f6af453a17439c9c258c25c707aa9fc1f3b59d9b401000000000000003f7e94f3954665ebd80ced3d434c67cd4351966f2b01000000000000003f8b8ee88e27291e33ce5403ea9b159235887dcfa901000000000000003f232a71b6b2586d5b02b6a72db08759066ba2a92b01000000000000003f28c4b220f14f3745f3fff6d3c066ba2353393eb601000000000000003fac67d5bfbef4a7ed8149727b93a01e903d84ee0c01000000000000003f3a537bef2ed296a54adc354967efe3a5e52cdfb801000000000000003f2c939e4633bd96ccc1d1509dbe794299603aad9901000000000000003f53ef9af027797e4827d708d9ed47c511f4ea552401000000000000003fe103c02fc06140aeac275f8e579f3397d041f81701000000000000003fa37d6366d765f5e446fc18ddcc3da3fa300cf6bb01000000000000003fe1671fea563be042824751a3465a7dbbc482794201000000000000003ff4d63847bf07a9faad83bd69fed408b3b734dce801000000000000003f888e092eba4cbd5eab9e10646661f5a440915f9d01000000000000003f5677152f9d640b175894c8da0b9f30bad3801aff01000000000000003fd34bb692e52d515398d00fd57ce2c8bfd348055401000000000000003fcfafad73ebddc38d53317c80cdbf6d343c331d6201000000000000003f7dbca0c01f96de655cf41eb53e1b8d5e2ffa260701000000000000003ff354c71350a110a7b45b5095ed0a4601bf4bbf9d01000000000000003f0ca0fbbfb8e3f615ec4eedaef6281d4d60a8f2b201000000000000003f2f885faaf6a3fcc38b1f35c652bf72f0fd7ac60301000000000000003f24e14548f3874b9413a28f258c2b73d35ec2b2f901000000000000003fe3f48b5211d1f21034bc15908259901ecf972be801000000000000003fccbb32ea36fad927cb2c46cbc63930db6cda829d +ff033f0100000006000500000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280f0fa020000000000280001000000000000003f0995750207ecaf0ccf251c1265b92ad84f55366201000000000000003ff13809c4c5fb2b3967a9b40efc70843f7db462ad01000000000000003f5f60e0594115b71d5b136cf929c8504082ac199d01000000000000003f5c2aaead4ce542788406c54e1ae31f1afdb7f08101000000000000003fc2308975254751ead4df705fc76aa84116c5e34e01000000000000003fc792d1958bb950596d0e7cd0bef325062009684801000000000000003f2031100e628422b8409810fdb438e874765846ba01000000000000003f6bd2c24bded5fdfd7888a28b3c6990503699b5e801000000000000003f009ffbb10efc47ad00a0a29cc2ef6e6c83d8c6ec01000000000000003fbe9147febbfe462cdbfda8575c18dabe85db4f5b01000000000000003f358634b58d88abf4aef3a6fe264b4ad18b74e98b01000000000000003f11745fc47a9c58c4e6f5a74eb59411ac102c6a8801000000000000003f5265ceb5d6102474ea7d0f401d6e6b9f13864a0501000000000000003f7617b5f3b82f153e388b4b200abd8636fff73dd501000000000000003f18f5df4fe3108277bfa4e39071fead9d59b35b8f01000000000000003fef283e95c3fdf0e2df9ba8321407c5621f98687601000000000000003f6af453a17439c9c258c25c707aa9fc1f3b59d9b401000000000000003f7e94f3954665ebd80ced3d434c67cd4351966f2b01000000000000003f8b8ee88e27291e33ce5403ea9b159235887dcfa901000000000000003f232a71b6b2586d5b02b6a72db08759066ba2a92b01000000000000003f28c4b220f14f3745f3fff6d3c066ba2353393eb601000000000000003fac67d5bfbef4a7ed8149727b93a01e903d84ee0c01000000000000003f3a537bef2ed296a54adc354967efe3a5e52cdfb801000000000000003f2c939e4633bd96ccc1d1509dbe794299603aad9901000000000000003f53ef9af027797e4827d708d9ed47c511f4ea552401000000000000003fe103c02fc06140aeac275f8e579f3397d041f81701000000000000003fa37d6366d765f5e446fc18ddcc3da3fa300cf6bb01000000000000003fe1671fea563be042824751a3465a7dbbc482794201000000000000003ff4d63847bf07a9faad83bd69fed408b3b734dce801000000000000003f888e092eba4cbd5eab9e10646661f5a440915f9d01000000000000003f5677152f9d640b175894c8da0b9f30bad3801aff01000000000000003fd34bb692e52d515398d00fd57ce2c8bfd348055401000000000000003fcfafad73ebddc38d53317c80cdbf6d343c331d6201000000000000003f7dbca0c01f96de655cf41eb53e1b8d5e2ffa260701000000000000003ff354c71350a110a7b45b5095ed0a4601bf4bbf9d01000000000000003f0ca0fbbfb8e3f615ec4eedaef6281d4d60a8f2b201000000000000003f2f885faaf6a3fcc38b1f35c652bf72f0fd7ac60301000000000000003f24e14548f3874b9413a28f258c2b73d35ec2b2f901000000000000003fe3f48b5211d1f21034bc15908259901ecf972be801000000000000003fccbb32ea36fad927cb2c46cbc63930db6cda829d ``` ## Deserialised @@ -73,9 +74,9 @@ ff033f0100000006000500000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b | **Network:** | **[2]** | **1** | `0x3f` | | **TypeGroup:** | **[3]** | **4** | `0x01000000` | | **Type:** | **[7]** | **2** | `0x0600` | -| **Nonce:** | **[9]** | **8** | `0x0500000000000000` | +| **Nonce:** | **[9]** | **8** | `0x0800000000000000` | | **SenderPublicKey:** | **[17]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | -| **Fee:** | **[50]** | **8** | `0x8096980000000000` | +| **Fee:** | **[50]** | **8** | `0x80f0fa0200000000` | | **Memo Length:** | **[58]** | **1** | `0x00` | | **Number of Transfers:** | **[59]** | **2** | `0x2800` | | **Amount 1:** | **[61]** | **8** | `0x0100000000000000` | @@ -89,7 +90,7 @@ ff033f0100000006000500000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b ```shell => e0c2008015058000002c80000d05800000000000000000000000 <= 9000 -=> e0c20180ffff033f0100000006000500000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192809698000000000000280001000000000000003f0995750207ecaf0ccf251c1265b92ad84f55366201000000000000003ff13809c4c5fb2b3967a9b40efc70843f7db462ad01000000000000003f5f60e0594115b71d5b136cf929c8504082ac199d01000000000000003f5c2aaead4ce542788406c54e1ae31f1afdb7f08101000000000000003fc2308975254751ead4df705fc76aa84116c5e34e01000000000000003fc792d1958bb950596d0e7cd0bef325062009684801000000000000003f2031100e628422b8409810 +=> e0c20180ffff033f0100000006000500000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280f0fa020000000000280001000000000000003f0995750207ecaf0ccf251c1265b92ad84f55366201000000000000003ff13809c4c5fb2b3967a9b40efc70843f7db462ad01000000000000003f5f60e0594115b71d5b136cf929c8504082ac199d01000000000000003f5c2aaead4ce542788406c54e1ae31f1afdb7f08101000000000000003fc2308975254751ead4df705fc76aa84116c5e34e01000000000000003fc792d1958bb950596d0e7cd0bef325062009684801000000000000003f2031100e628422b8409810 <= 9000 => e0c20280fffdb438e874765846ba01000000000000003f6bd2c24bded5fdfd7888a28b3c6990503699b5e801000000000000003f009ffbb10efc47ad00a0a29cc2ef6e6c83d8c6ec01000000000000003fbe9147febbfe462cdbfda8575c18dabe85db4f5b01000000000000003f358634b58d88abf4aef3a6fe264b4ad18b74e98b01000000000000003f11745fc47a9c58c4e6f5a74eb59411ac102c6a8801000000000000003f5265ceb5d6102474ea7d0f401d6e6b9f13864a0501000000000000003f7617b5f3b82f153e388b4b200abd8636fff73dd501000000000000003f18f5df4fe3108277bfa4e39071fead9d59b35b8f01000000000000003fef283e95c3 <= 9000 diff --git a/doc/transactions/TG01_T08_HTLC_LOCK.md b/doc/transactions/TG01_T08_HTLC_LOCK.md deleted file mode 100644 index 21f2e6fa..00000000 --- a/doc/transactions/TG01_T08_HTLC_LOCK.md +++ /dev/null @@ -1,62 +0,0 @@ -# TypeGroup 1 | Type 8: HTLC Lock - -## JSON - -```json -{ - "version": 3, - "network": 63, - "typeGroup": 1, - "type": 8, - "nonce": "6", - "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - "fee": "10000000", - "amount": "1", - "recipientId": "SNAgA2XCRZDKfm5Vu9h4KR1bZw5xn9EiC3", - "asset": { - "lock": { - "secretHash": "9c1a3815d49e0c9f78b872bfb017e825ea2db708158b70815526a830c85912b4", - "expiration": { - "type": 1, - "value": 78740307 - } - } - } -} -``` - -## Serialised - -```shell -ff033f0100000008000600000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1928096980000000000000100000000000000029c1a3815d49e0c9f78b872bfb017e825ea2db708158b70815526a830c85912b401537bb1043f0995750207ecaf0ccf251c1265b92ad84f553662 -``` - -## Deserialised - -| Key | Pos. | Size
_(bytes)_ | Value
_(hex)_ | -| :---------------------- | :-------: | :---------------: | :--------------------------------------------------------------------- | -| **Header:** | **[0]** | **1** | `0xff` | -| **Version:** | **[1]** | **1** | `0x03` | -| **Network:** | **[2]** | **1** | `0x3f` | -| **Typegroup:** | **[3]** | **4** | `0x01000000` | -| **Type:** | **[7]** | **2** | `0x0800` | -| **Nonce:** | **[9]** | **8** | `0x0600000000000000` | -| **SenderPublicKey:** | **[17]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | -| **Fee:** | **[50]** | **8** | `0x8096980000000000` | -| **Memo Length:** | **[58]** | **1** | `0x00` | -| **Amount:** | **[59]** | **8** | `0x0100000000000000` | -| **Secret Hash Length:** | **[67]** | **8** | `0x20` | -| **Secret Hash:** | **[68]** | **32** | `0x9c1a3815d49e0c9f78b872bfb017e825ea2db708158b70815526a830c85912b4` | -| **Expiration Type:** | **[100]** | **1** | `0x01` | -| **Expiration Value:** | **[101]** | **4** | `0x537bb104` | -| **Recipient:** | **[105]** | **21** | `0x3f0995750207ecaf0ccf251c1265b92ad84f553662` | - -## APDU Session - -```shell -=> e0c2008015058000002c80000d05800000000000000000000000 -<= 9000 -=> -e0c201007eff033f0100000008000600000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1928096980000000000000100000000000000209c1a3815d49e0c9f78b872bfb017e825ea2db708158b70815526a830c85912b401537bb1043f0995750207ecaf0ccf251c1265b92ad84f553662 -<= , 0x9000 -``` diff --git a/doc/transactions/TG01_T09_HTLC_CLAIM.md b/doc/transactions/TG01_T09_HTLC_CLAIM.md deleted file mode 100644 index d1748e53..00000000 --- a/doc/transactions/TG01_T09_HTLC_CLAIM.md +++ /dev/null @@ -1,68 +0,0 @@ -# TypeGroup 1 | Type 9: HTLC Claim - -## JSON - -```json -{ - "version": 3, - "network": 63, - "typeGroup": 1, - "type": 9, - "nonce": "7", - "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - "fee": "0", - "asset": { - "claim": { - "lockTransactionId": "3aade2b98391ba7230252530cdd5124183a9f4e582660666ae873da48173ea5f", - "unlockSecret": "c27f1ce845d8c29eebc9006be932b604fd06755521b1a8b0be4204c65377151a" - } - } -} -``` - -## Serialised - -```shell -ff033f0100000009000700000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192000000000000000000003aade2b98391ba7230252530cdd5124183a9f4e582660666ae873da48173ea5f20c27f1ce845d8c29eebc9006be932b604fd06755521b1a8b0be4204c65377151a -``` - -## Deserialised - -| Key | Pos. | Size
_(bytes)_ | Value
_(hex)_ | -| :------------------------ | :------: | :---------------: | :--------------------------------------------------------------------- | -| **Header:** | **[0]** | **1** | `0xff` | -| **Version:** | **[1]** | **1** | `0x03` | -| **Network:** | **[2]** | **1** | `0x3f` | -| **TypeGroup:** | **[3]** | **4** | `0x01000000` | -| **Type:** | **[7]** | **2** | `0x0900` | -| **Nonce:** | **[9]** | **8** | `0x0700000000000000` | -| **SenderPublicKey:** | **[17]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | -| **Fee:** | **[50]** | **8** | `0x0000000000000000` | -| **Memo Length:** | **[58]** | **1** | `0x00` | -| **Hash Type:** | **[59]** | **1** | `0x00` | -| **Lock Id:** | **[60]** | **32** | `0x3aade2b98391ba7230252530cdd5124183a9f4e582660666ae873da48173ea5f` | -| **Unlock Secret Length:** | **[92]** | **1** | `0x20` | -| **Unlock Secret:** | **[93]** | **32** | `0xc27f1ce845d8c29eebc9006be932b604fd06755521b1a8b0be4204c65377151a` | - -### Hash Types - -| Hash Type | Value | -| --------- | :---: | -| SHA256 | 0 | -| SHA384 | 1 | -| SHA512 | 2 | -| SHA3256 | 3 | -| SHA3384 | 4 | -| SHA3512 | 5 | -| Keccak256 | 6 | -| Keccak384 | 7 | -| Keccak512 | 8 | - -## APDU Session - -```shell -=> e0c2008015058000002c80000d05800000000000000000000000 -<= 9000 -=> e0c201007dff033f0100000009000700000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192000000000000000000003aade2b98391ba7230252530cdd5124183a9f4e582660666ae873da48173ea5f20c27f1ce845d8c29eebc9006be932b604fd06755521b1a8b0be4204c65377151a -<= , 0x9000 -``` diff --git a/doc/transactions/TG01_T10_HTLC_REFUND.md b/doc/transactions/TG01_T10_HTLC_REFUND.md deleted file mode 100644 index 5d41444d..00000000 --- a/doc/transactions/TG01_T10_HTLC_REFUND.md +++ /dev/null @@ -1,51 +0,0 @@ -# TypeGroup 1 | Type 10: HTLC Refund - -## JSON - -```json -{ - "version": 3, - "network": 63, - "typeGroup": 1, - "type": 10, - "nonce": "8", - "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - "fee": "0", - "amount": "0", - "asset": { - "refund": { - "lockTransactionId": "3aade2b98391ba7230252530cdd5124183a9f4e582660666ae873da48173ea5f" - } - } -} -``` - -## Serialised - -```shell -ff033f010000000a000800000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920000000000000000003aade2b98391ba7230252530cdd5124183a9f4e582660666ae873da48173ea5f -``` - -## Deserialised - -| Key | Pos. | Size
_(bytes)_ | Value
_(hex)_ | -| :------------------- | :------: | :---------------: | :--------------------------------------------------------------------- | -| **Header:** | **[0]** | **1** | `0xff` | -| **Version:** | **[1]** | **1** | `0x03` | -| **Network:** | **[2]** | **1** | `0x3f` | -| **TypeGroup:** | **[3]** | **4** | `0x01000000` | -| **Type:** | **[7]** | **2** | `0x0a00` | -| **Nonce:** | **[9]** | **8** | `0x0800000000000000` | -| **SenderPublicKey:** | **[17]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | -| **Fee:** | **[50]** | **8** | `0x0000000000000000` | -| **Memo Length:** | **[58]** | **1** | `0x00` | -| **Lock Id:** | **[59]** | **32** | `0x3aade2b98391ba7230252530cdd5124183a9f4e582660666ae873da48173ea5f` | - -## APDU Session - -```shell -=> e0c2008015058000002c80000d05800000000000000000000000 -<= 9000 -=> e0c201005bff033f010000000a000800000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920000000000000000003aade2b98391ba7230252530cdd5124183a9f4e582660666ae873da48173ea5f -<= , 0x9000 -``` diff --git a/doc/transactions/TG02_T00_BURN.md b/doc/transactions/TG02_T00_BURN.md index 2aba9d2b..f7537448 100644 --- a/doc/transactions/TG02_T00_BURN.md +++ b/doc/transactions/TG02_T00_BURN.md @@ -4,22 +4,22 @@ ```json { - "version": 3, - "network": 63, - "typeGroup": 2, - "type": 0, - "nonce": "9", - "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - "fee": "0", - "burnedFee": "0", - "amount": "100000000" + "version": 3, + "network": 63, + "typeGroup": 2, + "type": 0, + "nonce": "12", + "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + "fee": "0", + "burnedFee": "0", + "amount": "100000000" } ``` ## Serialised ```shell -ff033f0200000000000900000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200000000000000000000e1f50500000000 +ff033f0200000000000c00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200000000000000000000e1f50500000000 ``` ## Deserialised @@ -31,7 +31,7 @@ ff033f0200000000000900000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b | **Network:** | **[2]** | **1** | `0x3f` | | **Typegroup:** | **[3]** | **4** | `0x02000000` | | **Type:** | **[7]** | **2** | `0x0000` | -| **Nonce:** | **[9]** | **8** | `0x0900000000000000` | +| **Nonce:** | **[9]** | **8** | `0x0c00000000000000` | | **SenderPublicKey:** | **[17]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | | **Fee:** | **[50]** | **8** | `0x0000000000000000` | | **Memo Length:** | **[58]** | **1** | `0x00` | @@ -42,6 +42,6 @@ ff033f0200000000000900000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b ```shell => e0c2008015058000002c80000d05800000000000000000000000 <= 9000 -=> e0c2010043ff033f0200000000000900000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200000000000000000000e1f50500000000 +=> e0c2010043ff033f0200000000000c00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200000000000000000000e1f50500000000 <= , 0x9000 ``` diff --git a/doc/transactions/TG02_T02_VOTE.md b/doc/transactions/TG02_T02_VOTE.md index f0411708..1421d931 100644 --- a/doc/transactions/TG02_T02_VOTE.md +++ b/doc/transactions/TG02_T02_VOTE.md @@ -6,27 +6,27 @@ ```json { - "version": 3, - "network": 63, - "typeGroup": 2, - "type": 2, - "nonce": "10", - "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - "fee": "100000000", - "asset": { - "votes": { - "gym": 50, - "cactus1549": 25, - "sl33p": 25 - } - } + "version": 3, + "network": 63, + "typeGroup": 2, + "type": 2, + "nonce": "13", + "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + "fee": "9000000", + "asset": { + "votes": { + "gym": 50, + "cactus1549": 25, + "sl33p": 25 + } + } } ``` ### Serialised ```shell -ff033f0200000002000a00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200e1f5050000000000030367796d88130a63616374757331353439c40905736c333370c409 +ff033f0200000002000d00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192405489000000000000030367796d88130a63616374757331353439c40905736c333370c409 ``` ### Deserialised @@ -38,9 +38,9 @@ ff033f0200000002000a00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b | **Network:** | **[2]** | **1** | `0x3f` | | **Typegroup:** | **[3]** | **4** | `0x02000000` | | **Type:** | **[7]** | **2** | `0x0200` | -| **Nonce:** | **[9]** | **8** | `0x0a00000000000000` | +| **Nonce:** | **[9]** | **8** | `0x0d00000000000000` | | **SenderPublicKey:** | **[17]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | -| **Fee:** | **[50]** | **8** | `0x00e1f50500000000` | +| **Fee:** | **[50]** | **8** | `0x4054890000000000` | | **Memo Length:** | **[58]** | **1** | `0x00` | | **Vote Count:** | **[59]** | **1** | `0x03` | | **Vote 1 Name Length:** | **[60]** | **1** | `0x03` | @@ -58,7 +58,7 @@ ff033f0200000002000a00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b ```shell => e0c2008015058000002c80000d05800000000000000000000000 <= 9000 -=> e0c2010057ff033f0200000002000a00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200e1f5050000000000030367796d88130a63616374757331353439c40905736c333370c409 +=> e0c2010057ff033f0200000002000d00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192405489000000000000030367796d88130a63616374757331353439c40905736c333370c409 <= , 0x9000 ``` @@ -72,7 +72,7 @@ ff033f0200000002000a00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b "network": 63, "typeGroup": 2, "type": 2, - "nonce": "11", + "nonce": "14", "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", "fee": "10000000", "asset": {} @@ -94,9 +94,9 @@ ff033f0200000002000b00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b | **Network:** | **[2]** | **1** | `0x3f` | | **Typegroup:** | **[3]** | **4** | `0x02000000` | | **Type:** | **[7]** | **2** | `0x0200` | -| **Nonce:** | **[9]** | **8** | `0x0b00000000000000` | +| **Nonce:** | **[9]** | **8** | `0x0e00000000000000` | | **SenderPublicKey:** | **[17]** | **33** | `0x034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192` | -| **Fee:** | **[50]** | **8** | `0x00e1f50500000000` | +| **Fee:** | **[50]** | **8** | `0x4054890000000000` | | **Memo Length:** | **[58]** | **1** | `0x00` | | **Vote Count:** | **[59]** | **1** | `0x00` | @@ -105,6 +105,6 @@ ff033f0200000002000b00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b ```shell => e0c2008015058000002c80000d05800000000000000000000000 <= 9000 -=> e0c201003cff033f0200000002000b00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200e1f505000000000000 +=> e0c201003cff033f0200000002000e00000000000000034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19240548900000000000000 <= , 0x9000 ``` diff --git a/icons/nanox_app_solar.gif b/icons/app_solar_14px.gif similarity index 100% rename from icons/nanox_app_solar.gif rename to icons/app_solar_14px.gif diff --git a/icons/nanos_app_solar.gif b/icons/app_solar_16px.gif similarity index 100% rename from icons/nanos_app_solar.gif rename to icons/app_solar_16px.gif diff --git a/src/address.c b/src/address.c index 93e1d747..b8d954f3 100644 --- a/src/address.c +++ b/src/address.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,18 +28,18 @@ * limitations under the License. *****************************************************************************/ -#include // uint*_t -#include // size_t +#include "address.h" + #include // bool +#include // size_t +#include // uint*_t #include // memmove -#include "os.h" +#include "base58.h" #include "cx.h" - -#include "address.h" +#include "os.h" #include "constants.h" -#include "common/base58.h" bool address_from_pubkey(const uint8_t public_key[static 33], uint8_t *out, @@ -63,7 +70,10 @@ void crypto_get_checksum(const uint8_t *in, size_t in_len, uint8_t out[static 4] } int base58_encode_address(const uint8_t *in, size_t in_len, char *out, size_t out_len) { - uint8_t tmp[in_len + 4 + 1]; // version + max_in_len + checksum + null-byte + if (in_len != ADDRESS_HASH_LEN) { + return -1; + } + uint8_t tmp[ADDRESS_HASH_LEN + 4 + 1]; // ... + checksum + null-byte memcpy(tmp, in, in_len); crypto_get_checksum(tmp, in_len, tmp + in_len); diff --git a/src/address.h b/src/address.h index eecb53e1..1e21f61d 100644 --- a/src/address.h +++ b/src/address.h @@ -1,31 +1,8 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once -#include // uint*_t -#include // size_t #include // bool +#include // size_t +#include // uint*_t /** * Convert public key to address. @@ -39,7 +16,7 @@ * @param[out] out * Pointer to output byte buffer for address. * @param[in] out_len - * Lenght of output byte buffer. + * Length of output byte buffer. * @param[in] network * Network byte. * @@ -59,7 +36,7 @@ bool address_from_pubkey(const uint8_t public_key[static 33], * @param[in] in * Pointer to address bytes. * @param[in] in_len - * Lenght of input byte buffer. + * Length of input byte buffer. * @param[out] out * Pointer to output checksum bytes. * @@ -73,7 +50,7 @@ void crypto_get_checksum(const uint8_t *in, size_t in_len, uint8_t out[static 4] * @param[in] in * Pointer to byte buffer with address. * @param[in] in_len - * Lenght of input address bytes. + * Length of input address bytes. * @param[out] out * Pointer to output byte buffer for address. * @param[in] out_len diff --git a/src/apdu/dispatcher.c b/src/apdu/dispatcher.c index 651fad9c..fd20df87 100644 --- a/src/apdu/dispatcher.c +++ b/src/apdu/dispatcher.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,20 +28,23 @@ * limitations under the License. *****************************************************************************/ +#include "apdu/dispatcher.h" + #include #include -#include "dispatcher.h" -#include "../constants.h" -#include "../types.h" -#include "../io.h" -#include "../sw.h" -#include "../common/buffer.h" -#include "../handler/get_version.h" -#include "../handler/get_app_name.h" -#include "../handler/get_public_key.h" -#include "../handler/get_address.h" -#include "../handler/sign_tx.h" +#include "buffer.h" +#include "io.h" + +#include "constants.h" +#include "sw.h" +#include "types.h" + +#include "handler/get_version.h" +#include "handler/get_app_name.h" +#include "handler/get_public_key.h" +#include "handler/get_address.h" +#include "handler/sign_tx.h" int apdu_dispatcher(const command_t *cmd) { if (cmd->cla != CLA) { diff --git a/src/apdu/dispatcher.h b/src/apdu/dispatcher.h index 04d08539..f53e0db6 100644 --- a/src/apdu/dispatcher.h +++ b/src/apdu/dispatcher.h @@ -1,29 +1,8 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once -#include "../types.h" +#include "parser.h" + +#include "types.h" /** * Parameter 2 for last APDU to receive. diff --git a/src/apdu/parser.c b/src/apdu/parser.c deleted file mode 100644 index 47151ad3..00000000 --- a/src/apdu/parser.c +++ /dev/null @@ -1,46 +0,0 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include // size_t -#include // uint*_t -#include // bool - -#include "parser.h" -#include "../types.h" -#include "offsets.h" - -bool apdu_parser(command_t *cmd, uint8_t *buf, size_t buf_len) { - // Check minimum length and Lc field of APDU command - if (buf_len < OFFSET_CDATA || buf_len - OFFSET_CDATA != buf[OFFSET_LC]) { - return false; - } - - cmd->cla = buf[OFFSET_CLA]; - cmd->ins = (command_e) buf[OFFSET_INS]; - cmd->p1 = buf[OFFSET_P1]; - cmd->p2 = buf[OFFSET_P2]; - cmd->lc = buf[OFFSET_LC]; - cmd->data = (buf[OFFSET_LC] > 0) ? buf + OFFSET_CDATA : NULL; - - return true; -} diff --git a/src/apdu/parser.h b/src/apdu/parser.h deleted file mode 100644 index dfba3fd6..00000000 --- a/src/apdu/parser.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include // size_t -#include // uint*_t -#include // bool - -#include "../types.h" - -/** - * Parse APDU command from byte buffer. - * - * @param[out] cmd - * Structured APDU command (CLA, INS, P1, P2, Lc, Command data). - * @param[in] buf - * Byte buffer with raw APDU command. - * @param[in] buf_len - * Length of byte buffer. - * - * @return true if success, false otherwise. - * - */ -bool apdu_parser(command_t *cmd, uint8_t *buf, size_t buf_len); diff --git a/src/main.c b/src/app_main.c similarity index 61% rename from src/main.c rename to src/app_main.c index c3cd365b..705e7027 100644 --- a/src/main.c +++ b/src/app_main.c @@ -1,12 +1,6 @@ /***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,22 +18,18 @@ #include // uint*_t #include // memset, explicit_bzero +#include "io.h" #include "os.h" +#include "sw.h" #include "ux.h" -#include "types.h" -#include "globals.h" -#include "io.h" -#include "sw.h" #include "context.h" -#include "ui/menu.h" -#include "apdu/parser.h" +#include "globals.h" +#include "types.h" + #include "apdu/dispatcher.h" +#include "ui/menu.h" -uint8_t G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; -io_state_e G_io_state; -ux_state_t G_ux; -bolos_ux_params_t G_ux_params; global_ctx_t G_context; /** @@ -51,9 +41,9 @@ void app_main() { // Structured APDU command command_t cmd; - // Reset length of APDU response - G_output_len = 0; - G_io_state = READY; + io_init(); + + ui_menu_main(); // Reset context reset_app_context(); @@ -105,67 +95,3 @@ void app_main() { } } } - -/** - * Exit the application and go back to the dashboard. - */ -void app_exit() { - BEGIN_TRY_L(exit) { - TRY_L(exit) { - os_sched_exit(-1); - } - FINALLY_L(exit) { - } - } - END_TRY_L(exit); -} - -/** - * Main loop to setup USB, Bluetooth, UI and launch app_main(). - */ -__attribute__((section(".boot"))) int main() { - __asm volatile("cpsie i"); - - os_boot(); - - for (;;) { - // Reset UI - memset(&G_ux, 0, sizeof(G_ux)); - - BEGIN_TRY { - TRY { - io_seproxyhal_init(); - -#ifdef TARGET_NANOX - G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); -#endif // TARGET_NANOX - - USB_power(0); - USB_power(1); - - ui_menu_main(); - -#ifdef HAVE_BLE - BLE_power(0, NULL); - BLE_power(1, "Nano X"); -#endif // HAVE_BLE - app_main(); - } - CATCH(EXCEPTION_IO_RESET) { - CLOSE_TRY; - continue; - } - CATCH_ALL { - CLOSE_TRY; - break; - } - FINALLY { - } - } - END_TRY; - } - - app_exit(); - - return 0; -} diff --git a/src/common/base58.c b/src/common/base58.c deleted file mode 100644 index 62d6d730..00000000 --- a/src/common/base58.c +++ /dev/null @@ -1,161 +0,0 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include // size_t -#include // uint*_t -#include // memmove, memset -#include // bool - -#include "base58.h" - -uint8_t const BASE58_TABLE[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // - 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0xFF, 0xFF, // - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // - 0x10, 0xFF, 0x11, 0x12, 0x13, 0x14, 0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, // - 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // - 0xFF, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, // - 0xFF, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, // - 0x37, 0x38, 0x39, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // -}; - -char const BASE58_ALPHABET[] = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', // - 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', // - 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', // - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' // -}; - -int base58_decode(const char *in, size_t in_len, uint8_t *out, size_t out_len) { - uint8_t tmp[MAX_DEC_INPUT_SIZE] = {0}; - uint8_t buffer[MAX_DEC_INPUT_SIZE] = {0}; - uint8_t j; - uint8_t start_at; - uint8_t zero_count = 0; - - if (in_len > MAX_DEC_INPUT_SIZE || in_len < 2) { - return -1; - } - - memmove(tmp, in, in_len); - - for (uint8_t i = 0; i < in_len; i++) { - if (in[i] >= sizeof(BASE58_TABLE)) { - return -1; - } - - tmp[i] = BASE58_TABLE[(int) in[i]]; - - if (tmp[i] == 0xFF) { - return -1; - } - } - - while ((zero_count < in_len) && (tmp[zero_count] == 0)) { - ++zero_count; - } - - j = in_len; - start_at = zero_count; - while (start_at < in_len) { - uint16_t remainder = 0; - for (uint8_t div_loop = start_at; div_loop < in_len; div_loop++) { - uint16_t digit256 = (uint16_t)(tmp[div_loop] & 0xFF); - uint16_t tmp_div = remainder * 58 + digit256; - tmp[div_loop] = (uint8_t)(tmp_div / 256); - remainder = tmp_div % 256; - } - - if (tmp[start_at] == 0) { - ++start_at; - } - - buffer[--j] = (uint8_t) remainder; - } - - while ((j < in_len) && (buffer[j] == 0)) { - ++j; - } - - int length = in_len - (j - zero_count); - - if ((int) out_len < length) { - return -1; - } - - memmove(out, buffer + j - zero_count, length); - - return length; -} - -int base58_encode(const uint8_t *in, size_t in_len, char *out, size_t out_len) { - uint8_t buffer[MAX_ENC_INPUT_SIZE * 138 / 100 + 1] = {0}; - size_t i, j; - size_t stop_at; - size_t zero_count = 0; - size_t output_size; - - if (in_len > MAX_ENC_INPUT_SIZE) { - return -1; - } - - while ((zero_count < in_len) && (in[zero_count] == 0)) { - ++zero_count; - } - - output_size = (in_len - zero_count) * 138 / 100 + 1; - stop_at = output_size - 1; - for (size_t start_at = zero_count; start_at < in_len; start_at++) { - int carry = in[start_at]; - for (j = output_size - 1; (int) j >= 0; j--) { - carry += 256 * buffer[j]; - buffer[j] = carry % 58; - carry /= 58; - - if (j <= stop_at - 1 && carry == 0) { - break; - } - } - stop_at = j; - } - - j = 0; - while (j < output_size && buffer[j] == 0) { - j += 1; - } - - if (out_len < zero_count + output_size - j) { - return -1; - } - - memset(out, BASE58_ALPHABET[0], zero_count); - - i = zero_count; - while (j < output_size) { - out[i++] = BASE58_ALPHABET[buffer[j++]]; - } - - return i; -} diff --git a/src/common/base58.h b/src/common/base58.h deleted file mode 100644 index f214afd8..00000000 --- a/src/common/base58.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include // size_t -#include // uint*_t -#include // bool - -/** - * Maximum length of input when decoding in base 58. - */ -#define MAX_DEC_INPUT_SIZE 164 -/** - * Maximum length of input when encoding in base 58. - */ -#define MAX_ENC_INPUT_SIZE 120 - -/** - * Decode input string in base 58. - * - * @see https://tools.ietf.org/html/draft-msporny-base58-02 - * - * @param[in] in - * Pointer to input string buffer. - * @param[in] in_len - * Length of the input string buffer. - * @param[out] out - * Pointer to output byte buffer. - * @param[in] out_len - * Maximum length to write in output byte buffer. - * - * @return number of bytes decoded, -1 otherwise. - * - */ -int base58_decode(const char *in, size_t in_len, uint8_t *out, size_t out_len); - -/** - * Encode input bytes in base 58. - * - * @see https://tools.ietf.org/html/draft-msporny-base58-02 - * - * @param[in] in - * Pointer to input byte buffer. - * @param[in] in_len - * Length of the input byte buffer. - * @param[out] out - * Pointer to output string buffer. - * @param[in] out_len - * Maximum length to write in output byte buffer. - * - * @return number of bytes encoded, -1 otherwise. - * - */ -int base58_encode(const uint8_t *in, size_t in_len, char *out, size_t out_len); diff --git a/src/common/bip32.c b/src/common/bip32.c deleted file mode 100644 index a6ac6e59..00000000 --- a/src/common/bip32.c +++ /dev/null @@ -1,87 +0,0 @@ -/***************************************************************************** - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include // snprintf -#include // memset, strlen -#include // size_t -#include // uint*_t -#include // bool - -#include "bip32.h" -#include "read.h" - -bool bip32_path_read(const uint8_t *in, size_t in_len, uint32_t *out, size_t out_len) { - if (out_len == 0 || out_len > MAX_BIP32_PATH) { - return false; - } - - size_t offset = 0; - - for (size_t i = 0; i < out_len; i++) { - if (offset > in_len) { - return false; - } - out[i] = read_u32_be(in, offset); - offset += 4; - } - - return true; -} - -bool bip32_path_format(const uint32_t *bip32_path, - size_t bip32_path_len, - char *out, - size_t out_len) { - if (bip32_path_len == 0 || bip32_path_len > MAX_BIP32_PATH) { - return false; - } - - size_t offset = 0; - - for (uint16_t i = 0; i < bip32_path_len; i++) { - size_t written; - - snprintf(out + offset, out_len - offset, "%d", bip32_path[i] & 0x7FFFFFFFu); - written = strlen(out + offset); - if (written == 0 || written >= out_len - offset) { - memset(out, 0, out_len); - return false; - } - offset += written; - - if ((bip32_path[i] & 0x80000000u) != 0) { - snprintf(out + offset, out_len - offset, "'"); - written = strlen(out + offset); - if (written == 0 || written >= out_len - offset) { - memset(out, 0, out_len); - return false; - } - offset += written; - } - - if (i != bip32_path_len - 1) { - snprintf(out + offset, out_len - offset, "/"); - written = strlen(out + offset); - if (written == 0 || written >= out_len - offset) { - memset(out, 0, out_len); - return false; - } - offset += written; - } - } - - return true; -} diff --git a/src/common/bip32.h b/src/common/bip32.h deleted file mode 100644 index 3e2491e1..00000000 --- a/src/common/bip32.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include // size_t -#include // uint*_t -#include // bool - -/** - * Maximum length of BIP32 path allowed. - */ -#define MAX_BIP32_PATH 10 - -/** - * Read BIP32 path from byte buffer. - * - * @param[in] in - * Pointer to input byte buffer. - * @param[in] in_len - * Length of input byte buffer. - * @param[out] out - * Pointer to output 32-bit integer buffer. - * @param[in] out_len - * Number of BIP32 paths read in the output buffer. - * - * @return true if success, false otherwise. - * - */ -bool bip32_path_read(const uint8_t *in, size_t in_len, uint32_t *out, size_t out_len); - -/** - * Format BIP32 path as string. - * - * @param[in] bip32_path - * Pointer to 32-bit integer input buffer. - * @param[in] bip32_path_len - * Maximum number of BIP32 paths in the input buffer. - * @param[out] out string - * Pointer to output string. - * @param[in] out_len - * Length of the output string. - * - * @return true if success, false otherwise. - * - */ -bool bip32_path_format(const uint32_t *bip32_path, - size_t bip32_path_len, - char *out, - size_t out_len); diff --git a/src/common/buffer.c b/src/common/buffer.c deleted file mode 100644 index 3bd617bd..00000000 --- a/src/common/buffer.c +++ /dev/null @@ -1,165 +0,0 @@ -/***************************************************************************** - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include // uint*_t -#include // size_t -#include // bool -#include // memmove - -#include "buffer.h" -#include "read.h" -#include "varint.h" -#include "bip32.h" - -bool buffer_can_read(const buffer_t *buffer, size_t n) { - return buffer->size - buffer->offset >= n; -} - -bool buffer_seek_set(buffer_t *buffer, size_t offset) { - if (offset > buffer->size) { - return false; - } - - buffer->offset = offset; - - return true; -} - -bool buffer_seek_cur(buffer_t *buffer, size_t offset) { - if (buffer->offset + offset < buffer->offset || // overflow - buffer->offset + offset > buffer->size) { // exceed buffer size - return false; - } - - buffer->offset += offset; - - return true; -} - -bool buffer_seek_end(buffer_t *buffer, size_t offset) { - if (offset > buffer->size) { - return false; - } - - buffer->offset = buffer->size - offset; - - return true; -} - -bool buffer_read_u8(buffer_t *buffer, uint8_t *value) { - if (!buffer_can_read(buffer, 1)) { - *value = 0; - - return false; - } - - *value = buffer->ptr[buffer->offset]; - buffer_seek_cur(buffer, 1); - - return true; -} - -bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness) { - if (!buffer_can_read(buffer, 2)) { - *value = 0; - - return false; - } - - *value = ((endianness == BE) ? read_u16_be(buffer->ptr, buffer->offset) - : read_u16_le(buffer->ptr, buffer->offset)); - - buffer_seek_cur(buffer, 2); - - return true; -} - -bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness) { - if (!buffer_can_read(buffer, 4)) { - *value = 0; - - return false; - } - - *value = ((endianness == BE) ? read_u32_be(buffer->ptr, buffer->offset) - : read_u32_le(buffer->ptr, buffer->offset)); - - buffer_seek_cur(buffer, 4); - - return true; -} - -bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness) { - if (!buffer_can_read(buffer, 8)) { - *value = 0; - - return false; - } - - *value = ((endianness == BE) ? read_u64_be(buffer->ptr, buffer->offset) - : read_u64_le(buffer->ptr, buffer->offset)); - - buffer_seek_cur(buffer, 8); - - return true; -} - -bool buffer_read_varint(buffer_t *buffer, uint64_t *value) { - int length = varint_read(buffer->ptr + buffer->offset, buffer->size - buffer->offset, value); - - if (length < 0) { - *value = 0; - - return false; - } - - buffer_seek_cur(buffer, (size_t) length); - - return true; -} - -bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len) { - if (!bip32_path_read(buffer->ptr + buffer->offset, - buffer->size - buffer->offset, - out, - out_len)) { - return false; - } - - buffer_seek_cur(buffer, sizeof(*out) * out_len); - - return true; -} - -bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len) { - if (buffer->size - buffer->offset > out_len) { - return false; - } - - memmove(out, buffer->ptr + buffer->offset, buffer->size - buffer->offset); - - return true; -} - -bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len) { - if (!buffer_copy(buffer, out, out_len)) { - return false; - } - - buffer_seek_cur(buffer, out_len); - - return true; -} diff --git a/src/common/buffer.h b/src/common/buffer.h deleted file mode 100644 index ae3e8293..00000000 --- a/src/common/buffer.h +++ /dev/null @@ -1,192 +0,0 @@ -#pragma once - -#include // uint*_t -#include // size_t -#include // bool - -/** - * Enumeration for endianness. - */ -typedef enum { - BE, /// Big Endian - LE /// Little Endian -} endianness_t; - -/** - * Struct for buffer with size and offset. - */ -typedef struct { - const uint8_t *ptr; /// Pointer to byte buffer - size_t size; /// Size of byte buffer - size_t offset; /// Offset in byte buffer -} buffer_t; - -/** - * Tell whether buffer can read bytes or not. - * - * @param[in] buffer - * Pointer to input buffer struct. - * @param[in] n - * Number of bytes to read in buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_can_read(const buffer_t *buffer, size_t n); - -/** - * Seek the buffer to specific offset. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[in] offset - * Specific offset to seek. - * - * @return true if success, false otherwise. - * - */ -bool buffer_seek_set(buffer_t *buffer, size_t offset); - -/** - * Seek buffer relatively to current offset. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[in] offset - * Offset to seek relatively to `buffer->offset`. - * - * @return true if success, false otherwise. - * - */ -bool buffer_seek_cur(buffer_t *buffer, size_t offset); - -/** - * Seek the buffer relatively to the end. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[in] offset - * Offset to seek relatively to `buffer->size`. - * - * @return true if success, false otherwise. - * - */ -bool buffer_seek_end(buffer_t *buffer, size_t offset); - -/** - * Read 1 byte from buffer into uint8_t. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] value - * Pointer to 8-bit unsigned integer read from buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_u8(buffer_t *buffer, uint8_t *value); - -/** - * Read 2 bytes from buffer into uint16_t. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] value - * Pointer to 16-bit unsigned integer read from buffer. - * @param[in] endianness - * Either BE (Big Endian) or LE (Little Endian). - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_u16(buffer_t *buffer, uint16_t *value, endianness_t endianness); - -/** - * Read 4 bytes from buffer into uint32_t. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] value - * Pointer to 32-bit unsigned integer read from buffer. - * @param[in] endianness - * Either BE (Big Endian) or LE (Little Endian). - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_u32(buffer_t *buffer, uint32_t *value, endianness_t endianness); - -/** - * Read 8 bytes from buffer into uint64_t. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] value - * Pointer to 64-bit unsigned integer read from buffer. - * @param[in] endianness - * Either BE (Big Endian) or LE (Little Endian). - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_u64(buffer_t *buffer, uint64_t *value, endianness_t endianness); - -/** - * Read Bitcoin-like varint from buffer into uint64_t. - * - * @see https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] value - * Pointer to 64-bit unsigned integer read from buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_varint(buffer_t *buffer, uint64_t *value); - -/** - * Read BIP32 path from buffer. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] out - * Pointer to output 32-bit integer buffer. - * @param[in] out_len - * Number of BIP32 paths read in the output buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_read_bip32_path(buffer_t *buffer, uint32_t *out, size_t out_len); - -/** - * Copy bytes from buffer without moving offset. - * - * @param[in] buffer - * Pointer to input buffer struct. - * @param[out] out - * Pointer to output byte buffer. - * @param[in] out_len - * Length of output byte buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_copy(const buffer_t *buffer, uint8_t *out, size_t out_len); - -/** - * Move bytes from buffer. - * - * @param[in,out] buffer - * Pointer to input buffer struct. - * @param[out] out - * Pointer to output byte buffer. - * @param[in] out_len - * Length of output byte buffer. - * - * @return true if success, false otherwise. - * - */ -bool buffer_move(buffer_t *buffer, uint8_t *out, size_t out_len); diff --git a/src/common/format.c b/src/common/format.c deleted file mode 100644 index e76a39fb..00000000 --- a/src/common/format.c +++ /dev/null @@ -1,241 +0,0 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include // size_t -#include // int*_t, uint*_t -#include // strncpy, memmove -#include // bool -#include // snprintf - -#include "format.h" - -bool format_i64(char *dst, size_t dst_len, const int64_t value) { - char temp[] = "-9223372036854775808"; - - char *ptr = temp; - int64_t num = value; - int sign = 1; - - if (value < 0) { - sign = -1; - } - - while (num != 0) { - *ptr++ = '0' + (num % 10) * sign; - num /= 10; - } - - if (value < 0) { - *ptr++ = '-'; - } else if (value == 0) { - *ptr++ = '0'; - } - - int distance = (ptr - temp) + 1; - - if ((int) dst_len < distance) { - return false; - } - - size_t index = 0; - - while (--ptr >= temp) { - dst[index++] = *ptr; - } - - dst[index] = '\0'; - - return true; -} - -bool format_u64(char *out, size_t outLen, uint64_t in) { - uint8_t i = 0; - - if (outLen == 0) { - return false; - } - outLen--; - - while (in > 9) { - out[i] = in % 10 + '0'; - in /= 10; - i++; - if (i + 1 > outLen) { - return false; - } - } - out[i] = in + '0'; - out[i + 1] = '\0'; - - uint8_t j = 0; - char tmp; - - // revert the string - while (j < i) { - // swap out[j] and out[i] - tmp = out[j]; - out[j] = out[i]; - out[i] = tmp; - - i--; - j++; - } - return true; -} - -bool format_fpu64(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals) { - char buffer[21] = {0}; - - if (!format_u64(buffer, sizeof(buffer), value)) { - return false; - } - - size_t digits = strlen(buffer); - - if (digits <= decimals) { - if (dst_len <= 2 + decimals + 1) { - return false; - } - *dst++ = '0'; - *dst++ = '.'; - for (uint16_t i = 0; i < decimals - digits; i++, dst++) { - *dst = '0'; - } - dst_len -= 2 + decimals - digits; - strncpy(dst, buffer, dst_len); - } else { - if (dst_len <= digits + 1) { - return false; - } - - const size_t shift = digits - decimals; - memmove(dst, buffer, shift); - dst[shift] = '.'; - strncpy(dst + shift + 1, buffer + shift, decimals); - } - - return true; -} - -/** - * Remove trailing zeros up to the decimal + padding. - * - */ -static void unpad_amount(char *amount, size_t len, size_t padding) { - char *ptr = amount + len - 1; - while (*ptr == '0' && *(ptr - padding) != '.') { - *ptr-- = 0; - } -} - -#if (IS_NANOS) // Estimate amount/fee line pixel count for the Nano S. - -// extern from: -// https://github.com/LedgerHQ/nanos-secure-sdk/blob/master/lib_ux/src/ux_layout_paging_compute.c#L20-#L117 -extern const char nanos_characters_width[96]; - -// adapted from: -// https://github.com/LedgerHQ/nanos-secure-sdk/blob/master/lib_ux/src/ux_layout_paging_compute.c#L147-#L175 -static uint32_t get_pixels(const char *text, uint8_t text_length) { - char current_char; - uint32_t line_width = 0; - - while (text_length--) { - current_char = *text; - line_width += (nanos_characters_width[current_char - 0x20] >> 0x04) & 0x0F; - text++; - } - - return line_width; -} - -#define PXLS(num_str) (get_pixels((num_str), strlen((num_str)))) -#else // if NOT NANOS -#define PXLS(num_str) (0) -#endif - -/** - * Determine if a new page should be used for ticker display on the Nano S. - * - * (e.g., avoid `123456789012345678 / 9.00 SXP` being misread as `9.00 SXP`) - * - */ -#define TICKER_SPACING(num_str) (IS_NANOS && PXLS((num_str)) >= NANO_PXLS_PER_LINE - 1 ? '\n' : ' ') - -bool format_amount(char *dst, - size_t dst_len, - const uint64_t value, - uint8_t decimals, - const char *ticker, - size_t ticker_len) { - char amount[22] = {0}; - if (dst_len < 22 + 5 || ticker_len > 5) { - return false; - } - if (!format_fpu64(amount, 22, value, decimals)) { - return false; - } - - unpad_amount(amount, strlen(amount), 2); - - snprintf(dst, dst_len, "%s%c%s", amount, TICKER_SPACING(amount), ticker); - return true; -} - -bool format_percentage(char *dst, size_t dst_len, const uint16_t value, uint8_t decimals) { - char amount[22] = {0}; - if (dst_len < 9) { - return false; - } - if (!format_fpu64(amount, 22, (const uint64_t) value, decimals)) { - return false; - } - snprintf(dst, dst_len, "%s%%", amount); - return true; -} - -int format_hex(const uint8_t *in, size_t in_len, char *out, size_t out_len) { - if (out_len < 2 * in_len + 1) { - return -1; - } - - const char hex[] = "0123456789abcdef"; - size_t i = 0; - int written = 0; - - while (i < in_len && (i * 2 + (2 + 1)) <= out_len) { - uint8_t high_nibble = (in[i] & 0xF0) >> 4; - *out = hex[high_nibble]; - out++; - - uint8_t low_nibble = in[i] & 0x0F; - *out = hex[low_nibble]; - out++; - - i++; - written += 2; - } - - *out = '\0'; - - return written + 1; -} diff --git a/src/common/format.h b/src/common/format.h deleted file mode 100644 index d553ac51..00000000 --- a/src/common/format.h +++ /dev/null @@ -1,134 +0,0 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#pragma once - -#include // size_t -#include // int*_t, uint*_t -#include // bool - -/** - * Format 64-bit signed integer as string. - * - * @param[out] dst - * Pointer to output string. - * @param[in] dst_len - * Length of output string. - * @param[in] value - * 64-bit signed integer to format. - * - * @return true if success, false otherwise. - * - */ -bool format_i64(char *dst, size_t dst_len, const int64_t value); - -/** - * Format 64-bit unsigned integer as string. - * - * @param[out] dst - * Pointer to output string. - * @param[in] dst_len - * Length of output string. - * @param[in] value - * 64-bit unsigned integer to format. - * - * @return true if success, false otherwise. - * - */ -bool format_u64(char *dst, size_t dst_len, uint64_t value); - -/** - * Format 64-bit unsigned integer as string with decimals. - * - * @param[out] dst - * Pointer to output string. - * @param[in] dst_len - * Length of output string. - * @param[in] value - * 64-bit unsigned integer to format. - * @param[in] decimals - * Number of digits after decimal separator. - * - * @return true if success, false otherwise. - * - */ -bool format_fpu64(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals); - -/** - * Format 64-bit unsigned integer as string with decimals and ticker. - * - * @param[out] dst - * Pointer to output string. - * @param[in] dst_len - * Length of output string. - * @param[in] value - * 64-bit unsigned integer to format. - * @param[in] decimals - * Number of digits after decimal separator. - * @param[in] ticker - * The token's ticker name to be displayed. - * @param[in] ticker_len - * The length of the ticker name (not including the null-terminator). - * - * @return true if success, false otherwise. - * - */ -bool format_amount(char *dst, - size_t dst_len, - const uint64_t value, - uint8_t decimals, - const char *ticker, - size_t ticker_len); - -/** - * Format 16-bit unsigned integer as string with decimals and percentage sign. - * - * @param[out] dst - * Pointer to output string. - * @param[in] dst_len - * Length of output string. - * @param[in] value - * 16-bit unsigned integer to format. - * @param[in] decimals - * Number of digits after decimal separator. - * - * @return true if success, false otherwise. - * - */ -bool format_percentage(char *dst, size_t dst_len, const uint16_t value, uint8_t decimals); - -/** - * Format byte buffer to uppercase hexadecimal string. - * - * @param[in] in - * Pointer to input byte buffer. - * @param[in] in_len - * Length of input byte buffer. - * @param[out] out - * Pointer to output string. - * @param[in] out_len - * Length of output string. - * - * @return number of bytes written if success, -1 otherwise. - * - */ -int format_hex(const uint8_t *in, size_t in_len, char *out, size_t out_len); diff --git a/src/common/macros.h b/src/common/macros.h deleted file mode 100644 index 13f75a3c..00000000 --- a/src/common/macros.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -/** - * Macro for the size of a specific structure field. - */ -#define MEMBER_SIZE(type, member) (sizeof(((type *) 0)->member)) diff --git a/src/common/read.c b/src/common/read.c deleted file mode 100644 index c8ee851f..00000000 --- a/src/common/read.c +++ /dev/null @@ -1,64 +0,0 @@ -/***************************************************************************** - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include // uint*_t -#include // size_t - -uint16_t read_u16_be(const uint8_t *ptr, size_t offset) { - return (uint16_t) ptr[offset + 0] << 8 | // - (uint16_t) ptr[offset + 1] << 0; -} - -uint32_t read_u32_be(const uint8_t *ptr, size_t offset) { - return (uint32_t) ptr[offset + 0] << 24 | // - (uint32_t) ptr[offset + 1] << 16 | // - (uint32_t) ptr[offset + 2] << 8 | // - (uint32_t) ptr[offset + 3] << 0; -} - -uint64_t read_u64_be(const uint8_t *ptr, size_t offset) { - return (uint64_t) ptr[offset + 0] << 56 | // - (uint64_t) ptr[offset + 1] << 48 | // - (uint64_t) ptr[offset + 2] << 40 | // - (uint64_t) ptr[offset + 3] << 32 | // - (uint64_t) ptr[offset + 4] << 24 | // - (uint64_t) ptr[offset + 5] << 16 | // - (uint64_t) ptr[offset + 6] << 8 | // - (uint64_t) ptr[offset + 7] << 0; -} - -uint16_t read_u16_le(const uint8_t *ptr, size_t offset) { - return (uint16_t) ptr[offset + 0] << 0 | // - (uint16_t) ptr[offset + 1] << 8; -} - -uint32_t read_u32_le(const uint8_t *ptr, size_t offset) { - return (uint32_t) ptr[offset + 0] << 0 | // - (uint32_t) ptr[offset + 1] << 8 | // - (uint32_t) ptr[offset + 2] << 16 | // - (uint32_t) ptr[offset + 3] << 24; -} - -uint64_t read_u64_le(const uint8_t *ptr, size_t offset) { - return (uint64_t) ptr[offset + 0] << 0 | // - (uint64_t) ptr[offset + 1] << 8 | // - (uint64_t) ptr[offset + 2] << 16 | // - (uint64_t) ptr[offset + 3] << 24 | // - (uint64_t) ptr[offset + 4] << 32 | // - (uint64_t) ptr[offset + 5] << 40 | // - (uint64_t) ptr[offset + 6] << 48 | // - (uint64_t) ptr[offset + 7] << 56; -} diff --git a/src/common/read.h b/src/common/read.h deleted file mode 100644 index 61cfa8c0..00000000 --- a/src/common/read.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include // uint*_t -#include // size_t - -/** - * Read 2 bytes as Big Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 2 bytes value read from buffer. - * - */ -uint16_t read_u16_be(const uint8_t *ptr, size_t offset); - -/** - * Read 4 bytes as Big Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 4 bytes value read from buffer. - * - */ -uint32_t read_u32_be(const uint8_t *ptr, size_t offset); - -/** - * Read 8 bytes as Big Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 8 bytes value read from buffer. - * - */ -uint64_t read_u64_be(const uint8_t *ptr, size_t offset); - -/** - * Read 2 bytes as Little Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 2 bytes value read from buffer. - * - */ -uint16_t read_u16_le(const uint8_t *ptr, size_t offset); - -/** - * Read 4 bytes as Little Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 4 bytes value read from buffer. - * - */ -uint32_t read_u32_le(const uint8_t *ptr, size_t offset); - -/** - * Read 8 bytes as Little Endian from byte buffer. - * - * @param[in] ptr - * Pointer to byte buffer. - * @param[in] offset - * Offset in the byte buffer. - * - * @return 8 bytes value read from buffer. - * - */ -uint64_t read_u64_le(const uint8_t *ptr, size_t offset); diff --git a/src/common/varint.c b/src/common/varint.c deleted file mode 100644 index d04fbb27..00000000 --- a/src/common/varint.c +++ /dev/null @@ -1,101 +0,0 @@ -/***************************************************************************** - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include // uint*_t -#include // size_t -#include // bool - -#include "varint.h" -#include "write.h" -#include "read.h" - -uint8_t varint_size(uint64_t value) { - if (value <= 0xFC) { - return 1; - } - - if (value <= UINT16_MAX) { - return 3; - } - - if (value <= UINT32_MAX) { - return 5; - } - - return 9; // <= UINT64_MAX -} - -int varint_read(const uint8_t *in, size_t in_len, uint64_t *value) { - if (in_len < 1) { - return -1; - } - - uint8_t prefix = in[0]; - - if (prefix == 0xFD) { - if (in_len < 3) { - return -1; - } - *value = (uint64_t) read_u16_le(in, 1); - return 3; - } - - if (prefix == 0xFE) { - if (in_len < 5) { - return -1; - } - *value = (uint64_t) read_u32_le(in, 1); - return 5; - } - - if (prefix == 0xFF) { - if (in_len < 9) { - return -1; - } - *value = (uint64_t) read_u64_le(in, 1); - return 9; - } - - *value = (uint64_t) prefix; // prefix <= 0xFC - - return 1; -} - -int varint_write(uint8_t *out, size_t offset, uint64_t value) { - uint8_t varint_len = varint_size(value); - - switch (varint_len) { - case 1: - out[offset] = (uint8_t) value; - break; - case 3: - out[offset++] = 0xFD; - write_u16_le(out, offset, (uint16_t) value); - break; - case 5: - out[offset++] = 0xFE; - write_u32_le(out, offset, (uint32_t) value); - break; - case 9: - out[offset++] = 0xFF; - write_u64_le(out, offset, (uint64_t) value); - break; - default: - return -1; - } - - return varint_len; -} diff --git a/src/common/varint.h b/src/common/varint.h deleted file mode 100644 index 80aeb430..00000000 --- a/src/common/varint.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include // uint*_t -#include // size_t -#include // bool - -/** - * Size of value represented as Bitcoin-like varint. - * - * @see https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer - * - * @param[in] value - * 64-bit unsigned integer to compute varint size. - * - * @return number of bytes to write value as varint (1, 3, 5 or 9 bytes). - * - */ -uint8_t varint_size(uint64_t value); - -/** - * Read Bitcoin-like varint from byte buffer. - * - * @see https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer - * - * @param[in] in - * Pointer to input byte buffer. - * @param[in] in_len - * Length of the input byte buffer. - * @param[out] value - * Pointer to 64-bit unsigned integer to output varint. - * - * @return number of bytes read (1, 3, 5 or 9 bytes), -1 otherwise. - * - */ -int varint_read(const uint8_t *in, size_t in_len, uint64_t *value); - -/** - * Write Bitcoin-like varint to byte buffer. - * - * @see https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer - * - * @param[out] out - * Pointer to output byte buffer. - * @param[in] offset - * Offset in the output byte buffer. - * @param[in] value - * 64-bit unsigned integer to write as varint. - * - * @return number of bytes written (1, 3, 5 or 9 bytes), -1 otherwise. - * - */ -int varint_write(uint8_t *out, size_t offset, uint64_t value); diff --git a/src/common/write.c b/src/common/write.c deleted file mode 100644 index 43cc5519..00000000 --- a/src/common/write.c +++ /dev/null @@ -1,70 +0,0 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include // uint*_t -#include // size_t - -void write_u16_be(uint8_t *ptr, size_t offset, uint16_t value) { - ptr[offset + 0] = (uint8_t)(value >> 8); - ptr[offset + 1] = (uint8_t)(value >> 0); -} - -void write_u32_be(uint8_t *ptr, size_t offset, uint32_t value) { - ptr[offset + 0] = (uint8_t)(value >> 24); - ptr[offset + 1] = (uint8_t)(value >> 16); - ptr[offset + 2] = (uint8_t)(value >> 8); - ptr[offset + 3] = (uint8_t)(value >> 0); -} - -void write_u64_be(uint8_t *ptr, size_t offset, uint64_t value) { - ptr[offset + 0] = (uint8_t)(value >> 56); - ptr[offset + 1] = (uint8_t)(value >> 48); - ptr[offset + 2] = (uint8_t)(value >> 40); - ptr[offset + 3] = (uint8_t)(value >> 32); - ptr[offset + 4] = (uint8_t)(value >> 24); - ptr[offset + 5] = (uint8_t)(value >> 16); - ptr[offset + 6] = (uint8_t)(value >> 8); - ptr[offset + 7] = (uint8_t)(value >> 0); -} - -void write_u16_le(uint8_t *ptr, size_t offset, uint16_t value) { - ptr[offset + 0] = (uint8_t)(value >> 0); - ptr[offset + 1] = (uint8_t)(value >> 8); -} - -void write_u32_le(uint8_t *ptr, size_t offset, uint32_t value) { - ptr[offset + 0] = (uint8_t)(value >> 0); - ptr[offset + 1] = (uint8_t)(value >> 8); - ptr[offset + 2] = (uint8_t)(value >> 16); - ptr[offset + 3] = (uint8_t)(value >> 24); -} - -void write_u64_le(uint8_t *ptr, size_t offset, uint64_t value) { - ptr[offset + 0] = (uint8_t)(value >> 0); - ptr[offset + 1] = (uint8_t)(value >> 8); - ptr[offset + 2] = (uint8_t)(value >> 16); - ptr[offset + 3] = (uint8_t)(value >> 24); - ptr[offset + 4] = (uint8_t)(value >> 32); - ptr[offset + 5] = (uint8_t)(value >> 40); - ptr[offset + 6] = (uint8_t)(value >> 48); - ptr[offset + 7] = (uint8_t)(value >> 56); -} diff --git a/src/common/write.h b/src/common/write.h deleted file mode 100644 index 0418f5c6..00000000 --- a/src/common/write.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include // uint*_t -#include // size_t - -/** - * Write 16-bit unsigned integer value as Big Endian. - * - * @param[out] ptr - * Pointer to output byte buffer. - * @param[in] offset - * Offset in the output byte buffer. - * @param[in] value - * 16-bit unsigned integer to write in output byte buffer as Big Endian. - * - */ -void write_u16_be(const uint8_t *ptr, size_t offset, uint16_t value); - -/** - * Write 32-bit unsigned integer value as Big Endian. - * - * @param[out] ptr - * Pointer to output byte buffer. - * @param[in] offset - * Offset in the output byte buffer. - * @param[in] value - * 32-bit unsigned integer to write in output byte buffer as Big Endian. - * - */ -void write_u32_be(uint8_t *ptr, size_t offset, uint32_t value); - -/** - * Write 64-bit unsigned integer value as Big Endian. - * - * @param[out] ptr - * Pointer to output byte buffer. - * @param[in] offset - * Offset in the output byte buffer. - * @param[in] value - * 64-bit unsigned integer to write in output byte buffer as Big Endian. - * - */ -void write_u64_be(uint8_t *ptr, size_t offset, uint64_t value); - -/** - * Write 16-bit unsigned integer value as Little Endian. - * - * @param[out] ptr - * Pointer to output byte buffer. - * @param[in] offset - * Offset in the output byte buffer. - * @param[in] value - * 16-bit unsigned integer to write in output byte buffer as Little Endian. - * - */ -void write_u16_le(uint8_t *ptr, size_t offset, uint16_t value); - -/** - * Write 32-bit unsigned integer value as Little Endian. - * - * @param[out] ptr - * Pointer to output byte buffer. - * @param[in] offset - * Offset in the output byte buffer. - * @param[in] value - * 32-bit unsigned integer to write in output byte buffer as Little Endian. - * - */ -void write_u32_le(uint8_t *ptr, size_t offset, uint32_t value); - -/** - * Write 64-bit unsigned integer value as Little Endian. - * - * @param[out] ptr - * Pointer to output byte buffer. - * @param[in] offset - * Offset in the output byte buffer. - * @param[in] value - * 64-bit unsigned integer to write in output byte buffer as Little Endian. - * - */ -void write_u64_le(uint8_t *ptr, size_t offset, uint64_t value); diff --git a/src/constants.h b/src/constants.h index 716ad324..db22ce7c 100644 --- a/src/constants.h +++ b/src/constants.h @@ -1,32 +1,14 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once /** - * Instruction class of the Solar application. + * String length of a Solar address. */ -#define CLA 0xE0 +#define ADDRESS_LEN 34 + +/** + * Length of the address hash ([network/version(1), pubKeyHash(20)]). + */ +#define ADDRESS_HASH_LEN 21 /** * Length of APPNAME variable in the Makefile. @@ -34,19 +16,19 @@ #define APPNAME_LEN (sizeof(APPNAME) - 1) /** - * Maximum length of MAJOR_VERSION || MINOR_VERSION || PATCH_VERSION. + * Maximum length of application name. */ -#define APPVERSION_LEN 3 +#define APPNAME_MAX_LEN 64 /** - * Maximum length of application name. + * Maximum length of MAJOR_VERSION || MINOR_VERSION || PATCH_VERSION. */ -#define MAX_APPNAME_LEN 64 +#define APPVERSION_LEN 3 /** - * Maximum transaction length (bytes). + * Instruction class of the Solar application. */ -#define MAX_TRANSACTION_LEN 1600 +#define CLA 0xE0 /** * Exponent used to convert SXP unit (N SXP = N * 10^8). @@ -63,16 +45,6 @@ */ #define HASH_64_LEN 64 -/** - * Length of the address hash ([network/version(1), pubKeyHash(20)]). - */ -#define ADDRESS_HASH_LEN 21 - -/** - * String length of a Solar address. - */ -#define ADDRESS_LEN 34 - /** * Solar Mainnet Network Byte */ @@ -94,16 +66,11 @@ #define SIG_SCHNORR_LEN 64 /** - * Max length for memo. - */ -#define MAX_MEMO_LEN 255 - -/** - * Max length for the hash on HTLC transactions. + * The default ticker name used for displaying amounts. */ -#define MAX_HTLC_HASH_LEN 192 +#define TICKER_DEFAULT "SXP" /** - * The default ticker name used for displaying amounts. + * Maximum transaction length (bytes). */ -#define TICKER_DEFAULT "SXP" +#define TRANSACTION_MAX_LEN 1600 diff --git a/src/context.c b/src/context.c index 5c66a47f..497f7c68 100644 --- a/src/context.c +++ b/src/context.c @@ -5,9 +5,10 @@ * 4.0 International License. *****************************************************************************/ +#include "context.h" + #include // explicit_bzero -#include "context.h" #include "globals.h" void reset_app_context() { diff --git a/src/context.h b/src/context.h index 5cab5887..61256aa1 100644 --- a/src/context.h +++ b/src/context.h @@ -1,10 +1,3 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once /** diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c index 24218ee3..bbdca36a 100644 --- a/src/crypto/crypto.c +++ b/src/crypto/crypto.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index affa1632..0dd9eda9 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -1,32 +1,9 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once #include // uint*_t -#include "os.h" #include "cx.h" +#include "os.h" /** * Derive private key given BIP32 path. diff --git a/src/globals.h b/src/globals.h index 175ebf7c..049e8120 100644 --- a/src/globals.h +++ b/src/globals.h @@ -2,11 +2,11 @@ #include +#include "io.h" #include "ux.h" -#include "io.h" -#include "types.h" #include "constants.h" +#include "types.h" /** * Global buffer for interactions between SE and MCU. @@ -14,7 +14,7 @@ extern uint8_t G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; /** - * Global variable with the lenght of APDU response to send back. + * Global variable with the length of APDU response to send back. */ extern uint32_t G_output_len; diff --git a/src/handler/get_address.c b/src/handler/get_address.c index b622fd8a..0a43394e 100644 --- a/src/handler/get_address.c +++ b/src/handler/get_address.c @@ -3,30 +3,52 @@ * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. + * + ***************************************************************************** + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + * This software also incorporates work covered by the following copyright + * and permission notice: + * + * Ledger App Boilerplate. + * (c) Ledger SAS. + * + * 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. *****************************************************************************/ -#include "get_public_key.h" +#include "get_address.h" #include // uint*_t #include // bool #include // size_t #include // memset, explicit_bzero -#include "os.h" #include "cx.h" +#include "io.h" +#include "os.h" -#include "../io.h" -#include "../sw.h" -#include "../context.h" - -#include "../globals.h" -#include "../types.h" +#include "buffer.h" -#include "../common/buffer.h" -#include "../crypto/crypto.h" +#include "context.h" +#include "globals.h" +#include "sw.h" +#include "types.h" -#include "../ui/display.h" -#include "../helper/send_response.h" +#include "crypto/crypto.h" +#include "helper/send_response.h" +#include "ui/display.h" int handler_get_address(buffer_t *cdata, bool user_approval, uint8_t network) { reset_app_context(); diff --git a/src/handler/get_address.h b/src/handler/get_address.h index ca8ac2ef..b89f9b45 100644 --- a/src/handler/get_address.h +++ b/src/handler/get_address.h @@ -1,17 +1,9 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include // size_t #include // bool #include // uint*_t -#include "../common/buffer.h" +#include "buffer.h" /** * Handler for GET_ADDRESS command. diff --git a/src/handler/get_app_name.c b/src/handler/get_app_name.c index ea440ae8..8ba27938 100644 --- a/src/handler/get_app_name.c +++ b/src/handler/get_app_name.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,19 +28,18 @@ * limitations under the License. *****************************************************************************/ -#include // uint*_t - #include "get_app_name.h" -#include "../constants.h" -#include "../io.h" -#include "../sw.h" -#include "../types.h" -#include "common/buffer.h" -int handler_get_app_name() { - _Static_assert(APPNAME_LEN < MAX_APPNAME_LEN, "APPNAME must be at most 64 characters!"); +#include "buffer.h" +#include "io.h" +#include "os.h" - buffer_t rdata = {.ptr = (uint8_t *) PIC(APPNAME), .size = APPNAME_LEN, .offset = 0}; +#include "constants.h" +#include "sw.h" +#include "types.h" + +int handler_get_app_name() { + _Static_assert(APPNAME_LEN < APPNAME_MAX_LEN, "APPNAME must be at most 64 characters!"); - return io_send_response(&rdata, SW_OK); + return io_send_response_pointer(PIC(APPNAME), APPNAME_LEN, SW_OK); } diff --git a/src/handler/get_app_name.h b/src/handler/get_app_name.h index b568b1f3..45653e8f 100644 --- a/src/handler/get_app_name.h +++ b/src/handler/get_app_name.h @@ -1,7 +1,5 @@ #pragma once -#include "os.h" - /** * Handler for GET_APP_NAME command. Send APDU response with ASCII * encoded name of the application. diff --git a/src/handler/get_public_key.c b/src/handler/get_public_key.c index 71cef894..4b2bd7c3 100644 --- a/src/handler/get_public_key.c +++ b/src/handler/get_public_key.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,18 +35,19 @@ #include // size_t #include // memset, explicit_bzero -#include "os.h" +#include "buffer.h" #include "cx.h" +#include "io.h" +#include "os.h" + +#include "context.h" +#include "globals.h" +#include "types.h" +#include "sw.h" -#include "../globals.h" -#include "../types.h" -#include "../context.h" -#include "../io.h" -#include "../sw.h" -#include "../crypto/crypto.h" -#include "../common/buffer.h" -#include "../ui/display.h" -#include "../helper/send_response.h" +#include "crypto/crypto.h" +#include "helper/send_response.h" +#include "ui/display.h" int handler_get_public_key(buffer_t *cdata, bool user_approval, bool use_chain_code) { reset_app_context(); diff --git a/src/handler/get_public_key.h b/src/handler/get_public_key.h index b743f8e0..3de5222b 100644 --- a/src/handler/get_public_key.h +++ b/src/handler/get_public_key.h @@ -1,33 +1,8 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once -#include // size_t #include // bool -#include // uint*_t -#include "../common/buffer.h" +#include "buffer.h" /** * Handler for GET_PUBLIC_KEY command. If it successfully parses BIP32 path, diff --git a/src/handler/get_version.c b/src/handler/get_version.c index d9c96a4c..b3052296 100644 --- a/src/handler/get_version.c +++ b/src/handler/get_version.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,16 +28,18 @@ * limitations under the License. *****************************************************************************/ +#include "get_version.h" + #include // uint*_t #include // UINT8_MAX #include // _Static_assert -#include "get_version.h" -#include "../constants.h" -#include "../io.h" -#include "../sw.h" -#include "../types.h" -#include "common/buffer.h" +#include "io.h" +#include "buffer.h" + +#include "constants.h" +#include "sw.h" +#include "types.h" int handler_get_version() { _Static_assert(APPVERSION_LEN == 3, "Length of (MAJOR || MINOR || PATCH) must be 3!"); @@ -41,11 +50,10 @@ int handler_get_version() { _Static_assert(PATCH_VERSION >= 0 && PATCH_VERSION <= UINT8_MAX, "PATCH version must be between 0 and 255!"); - return io_send_response( - &(const buffer_t){.ptr = (uint8_t[APPVERSION_LEN]){(uint8_t) MAJOR_VERSION, - (uint8_t) MINOR_VERSION, - (uint8_t) PATCH_VERSION}, - .size = APPVERSION_LEN, - .offset = 0}, + return io_send_response_pointer( + (const uint8_t *) &(uint8_t[APPVERSION_LEN]){(uint8_t) MAJOR_VERSION, + (uint8_t) MINOR_VERSION, + (uint8_t) PATCH_VERSION}, + APPVERSION_LEN, SW_OK); } diff --git a/src/handler/sign_tx.c b/src/handler/sign_tx.c index e37cdd25..31a44618 100644 --- a/src/handler/sign_tx.c +++ b/src/handler/sign_tx.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,23 +28,26 @@ * limitations under the License. *****************************************************************************/ +#include "sign_tx.h" + #include // uint*_t #include // bool #include // size_t #include // memset, explicit_bzero -#include "os.h" #include "cx.h" +#include "os.h" +#include "sw.h" -#include "sign_tx.h" -#include "../sw.h" -#include "../globals.h" -#include "../context.h" -#include "../crypto/crypto.h" -#include "../ui/display.h" -#include "../common/buffer.h" -#include "../transaction/types.h" -#include "../transaction/deserialise.h" +#include "buffer.h" + +#include "context.h" +#include "crypto.h" +#include "globals.h" + +#include "transaction/deserialise.h" +#include "transaction/types.h" +#include "ui/display.h" int handler_sign_tx(buffer_t *cdata, uint8_t chunk, bool more, bool is_message) { if (chunk == 0) { // first APDU, parse BIP32 path @@ -71,7 +81,7 @@ int handler_sign_tx(buffer_t *cdata, uint8_t chunk, bool more, bool is_message) G_context.req_num++; if (more) { // more APDUs with transaction part - if (G_context.tx_info.raw_tx_len + cdata->size > MAX_TRANSACTION_LEN || // + if (G_context.tx_info.raw_tx_len + cdata->size > TRANSACTION_MAX_LEN || // cdata->size < UINT8_MAX || // !buffer_move(cdata, G_context.tx_info.raw_tx + G_context.tx_info.raw_tx_len, @@ -83,7 +93,7 @@ int handler_sign_tx(buffer_t *cdata, uint8_t chunk, bool more, bool is_message) return io_send_sw(SW_OK); } else { // last APDU, let's parse and sign - if (G_context.tx_info.raw_tx_len + cdata->size > MAX_TRANSACTION_LEN || // + if (G_context.tx_info.raw_tx_len + cdata->size > TRANSACTION_MAX_LEN || // !buffer_move(cdata, G_context.tx_info.raw_tx + G_context.tx_info.raw_tx_len, cdata->size)) { diff --git a/src/handler/sign_tx.h b/src/handler/sign_tx.h index 472f319a..493360b0 100644 --- a/src/handler/sign_tx.h +++ b/src/handler/sign_tx.h @@ -1,32 +1,9 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once #include // uint*_t #include // bool -#include "../common/buffer.h" +#include "buffer.h" /** * Handler for SIGN_TX command. If successfully parse BIP32 path diff --git a/src/helper/send_reponse.c b/src/helper/send_response.c similarity index 81% rename from src/helper/send_reponse.c rename to src/helper/send_response.c index bc4b68d7..9c9e6533 100644 --- a/src/helper/send_reponse.c +++ b/src/helper/send_response.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,17 +28,19 @@ * limitations under the License. *****************************************************************************/ +#include "send_response.h" + #include // size_t #include // uint*_t #include // memmove -#include "send_response.h" -#include "../constants.h" -#include "../globals.h" -#include "../context.h" -#include "../sw.h" -#include "common/buffer.h" -#include "../address.h" +#include "buffer.h" + +#include "address.h" +#include "constants.h" +#include "context.h" +#include "globals.h" +#include "sw.h" int helper_send_response_pubkey() { uint8_t resp[1 + PUBLIC_KEY_LEN + 1 + CHAINCODE_LEN] = {0}; @@ -49,7 +58,7 @@ int helper_send_response_pubkey() { reset_app_context(); - return io_send_response(&(const buffer_t){.ptr = resp, .size = offset, .offset = 0}, SW_OK); + return io_send_response_pointer(resp, offset, SW_OK); } int helper_send_response_address() { @@ -76,7 +85,7 @@ int helper_send_response_address() { reset_app_context(); - return io_send_response(&(const buffer_t){.ptr = resp, .size = offset, .offset = 0}, SW_OK); + return io_send_response_pointer(resp, offset, SW_OK); } int helper_send_response_sig() { @@ -84,6 +93,5 @@ int helper_send_response_sig() { memmove(resp, G_context.tx_info.signature, SIG_SCHNORR_LEN); - return io_send_response(&(const buffer_t){.ptr = resp, .size = SIG_SCHNORR_LEN, .offset = 0}, - SW_OK); + return io_send_response_pointer(resp, SIG_SCHNORR_LEN, SW_OK); } diff --git a/src/helper/send_response.h b/src/helper/send_response.h index 6ba72603..5340d948 100644 --- a/src/helper/send_response.h +++ b/src/helper/send_response.h @@ -1,31 +1,8 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once #include "os.h" -#include "../common/macros.h" +#include "macros.h" /** * Length of chain code. diff --git a/src/io.c b/src/io.c deleted file mode 100644 index fa66dbc0..00000000 --- a/src/io.c +++ /dev/null @@ -1,159 +0,0 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include - -#include "os.h" -#include "ux.h" - -#include "io.h" -#include "globals.h" -#include "context.h" -#include "sw.h" -#include "common/buffer.h" -#include "common/write.h" - -uint32_t G_output_len = 0; - -void io_seproxyhal_display(const bagl_element_t *element) { - io_seproxyhal_display_default((bagl_element_t *) element); -} - -uint8_t io_event(uint8_t channel __attribute__((unused))) { - switch (G_io_seproxyhal_spi_buffer[0]) { - case SEPROXYHAL_TAG_BUTTON_PUSH_EVENT: - UX_BUTTON_PUSH_EVENT(G_io_seproxyhal_spi_buffer); - break; - case SEPROXYHAL_TAG_STATUS_EVENT: - if (G_io_apdu_media == IO_APDU_MEDIA_USB_HID && // - !(U4BE(G_io_seproxyhal_spi_buffer, 3) & // - SEPROXYHAL_TAG_STATUS_EVENT_FLAG_USB_POWERED)) { - THROW(EXCEPTION_IO_RESET); - } - /* fallthrough */ - case SEPROXYHAL_TAG_DISPLAY_PROCESSED_EVENT: - UX_DISPLAYED_EVENT({}); - break; - case SEPROXYHAL_TAG_TICKER_EVENT: - UX_TICKER_EVENT(G_io_seproxyhal_spi_buffer, {}); - break; - default: - UX_DEFAULT_EVENT(); - break; - } - - if (!io_seproxyhal_spi_is_status_sent()) { - io_seproxyhal_general_status(); - } - - return 1; -} - -uint16_t io_exchange_al(uint8_t channel, uint16_t tx_len) { - switch (channel & ~(IO_FLAGS)) { - case CHANNEL_KEYBOARD: - break; - case CHANNEL_SPI: - if (tx_len) { - io_seproxyhal_spi_send(G_io_apdu_buffer, tx_len); - - if (channel & IO_RESET_AFTER_REPLIED) { - halt(); - } - - return 0; - } else { - return io_seproxyhal_spi_recv(G_io_apdu_buffer, sizeof(G_io_apdu_buffer), 0); - } - default: - THROW(INVALID_PARAMETER); - } - - return 0; -} - -int io_recv_command() { - int ret; - - switch (G_io_state) { - case READY: - G_io_state = RECEIVED; - ret = io_exchange(CHANNEL_APDU, G_output_len); - break; - case RECEIVED: - G_io_state = WAITING; - ret = io_exchange(CHANNEL_APDU | IO_ASYNCH_REPLY, G_output_len); - G_io_state = RECEIVED; - break; - case WAITING: - G_io_state = READY; - ret = -1; - break; - } - - return ret; -} - -int io_send_response(const buffer_t *rdata, uint16_t sw) { - int ret; - - if (rdata != NULL) { - if (rdata->size - rdata->offset > IO_APDU_BUFFER_SIZE - 2 || // - !buffer_copy(rdata, G_io_apdu_buffer, sizeof(G_io_apdu_buffer))) { - return io_send_sw(SW_WRONG_RESPONSE_LENGTH); - } - G_output_len = rdata->size - rdata->offset; - PRINTF("<= SW=%04X | RData=%.*H\n", sw, rdata->size, rdata->ptr); - } else { - G_output_len = 0; - PRINTF("<= SW=%04X | RData=\n", sw); - } - - write_u16_be(G_io_apdu_buffer, G_output_len, sw); - G_output_len += 2; - - switch (G_io_state) { - case READY: - ret = -1; - break; - case RECEIVED: - G_io_state = READY; - ret = 0; - break; - case WAITING: - ret = io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, G_output_len); - G_output_len = 0; - G_io_state = READY; - break; - } - - if (sw != 0x9000) { - reset_app_context(); - } - - return ret; -} - -int io_send_sw(uint16_t sw) { - return io_send_response(NULL, sw); -} diff --git a/src/io.h b/src/io.h deleted file mode 100644 index d6a31a83..00000000 --- a/src/io.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include - -#include "ux.h" -#include "os_io_seproxyhal.h" - -#include "types.h" -#include "common/buffer.h" - -void io_seproxyhal_display(const bagl_element_t *element); - -/** - * IO callback called when an interrupt based channel has received - * data to be processed. - * - * @return 1 if success, 0 otherwise. - * - */ -uint8_t io_event(uint8_t channel __attribute__((unused))); - -uint16_t io_exchange_al(uint8_t channel, uint16_t tx_len); - -/** - * Receive APDU command in G_io_apdu_buffer and update G_output_len. - * - * @return zero or positive integer if success, -1 otherwise. - * - */ -int io_recv_command(void); - -/** - * Send APDU response (response data + status word) by filling - * G_io_apdu_buffer. - * - * @param[in] rdata - * Buffer with APDU response data. - * @param[in] sw - * Status word of APDU response. - * - * @return zero or positive integer if success, -1 otherwise. - * - */ -int io_send_response(const buffer_t *rdata, uint16_t sw); - -/** - * Send APDU response (only status word) by filling - * G_io_apdu_buffer. - * - * @param[in] sw - * Status word of APDU response. - * - * @return zero or positive integer if success, -1 otherwise. - * - */ -int io_send_sw(uint16_t sw); diff --git a/src/sw.h b/src/sw.h index 09ca355c..a2fc8678 100644 --- a/src/sw.h +++ b/src/sw.h @@ -1,26 +1,3 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once /** @@ -36,7 +13,7 @@ */ #define SW_WRONG_P1P2 0x6A86 /** - * Status word for either wrong Lc or lenght of APDU command less than 5. + * Status word for either wrong Lc or length of APDU command less than 5. */ #define SW_WRONG_DATA_LENGTH 0x6A87 /** @@ -48,7 +25,7 @@ */ #define SW_CLA_NOT_SUPPORTED 0x6E00 /** - * Status word for wrong reponse length (buffer too small or too big). + * Status word for wrong response length (buffer too small or too big). */ #define SW_WRONG_RESPONSE_LENGTH 0xB000 /** diff --git a/src/transaction/deserialise.c b/src/transaction/deserialise.c index 67c8ac75..1320a91a 100644 --- a/src/transaction/deserialise.c +++ b/src/transaction/deserialise.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) 2023 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +29,16 @@ *****************************************************************************/ #include "deserialise.h" -#include "utils.h" -#include "types.h" -#include "../constants.h" -#include "../common/buffer.h" + +#include // uint*_t + +#include "buffer.h" + +#include "constants.h" + +#include "transaction/errors.h" +#include "transaction/transaction_utils.h" +#include "transaction/types.h" parser_status_e transaction_deserialise(buffer_t *buf, transaction_t *tx) { parser_status_e parse_common = transaction_deserialise_common(buf, tx); @@ -79,7 +92,7 @@ parser_status_e transaction_deserialise_common(buffer_t *buf, transaction_t *tx) } // nonce - if (!buffer_seek_cur(buf, NONCE_LENGTH)) { + if (!buffer_seek_cur(buf, sizeof(uint64_t))) { return WRONG_LENGTH_ERROR; } @@ -129,18 +142,10 @@ parser_status_e transaction_deserialise_core_asset(buffer_t *buf, } } else if (typeGroup == TYPEGROUP_CORE) { switch (type) { - case MULTISIGNATURE_REGISTRATION: - return multisignature_type_deserialise(buf, &tx->Multisignature); case IPFS: return ipfs_type_deserialise(buf, &tx->Ipfs); case TRANSFER: return transfer_type_deserialise(buf, &tx->Transfer); - case HTLC_LOCK: - return htlc_lock_type_deserialise(buf, &tx->Htlc_lock); - case HTLC_CLAIM: - return htlc_claim_type_deserialise(buf, &tx->Htlc_claim); - case HTLC_REFUND: - return htlc_refund_type_deserialise(buf, &tx->Htlc_refund); default: return TYPE_PARSING_ERROR; } @@ -152,7 +157,7 @@ parser_status_e transaction_deserialise_core_asset(buffer_t *buf, parser_status_e message_deserialise(buffer_t *buf, transaction_t *tx) { // message length if (!buffer_read_u16(buf, &tx->message_length, LE) || tx->message_length < 1 || - tx->message_length > MAX_TRANSACTION_LEN - 3) { + tx->message_length > TRANSACTION_MAX_LEN - 3) { return WRONG_LENGTH_ERROR; } diff --git a/src/transaction/deserialise.h b/src/transaction/deserialise.h index b8ce5df9..6b87bdf4 100644 --- a/src/transaction/deserialise.h +++ b/src/transaction/deserialise.h @@ -1,30 +1,10 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once -#include "types.h" -#include "../common/buffer.h" +#include // uint*_t + +#include "buffer.h" + +#include "transaction/types.h" /** * Deserialise raw transaction in structure. diff --git a/src/transaction/errors.h b/src/transaction/errors.h index c660c3df..484a5563 100644 --- a/src/transaction/errors.h +++ b/src/transaction/errors.h @@ -1,10 +1,3 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once typedef enum { diff --git a/src/transaction/transaction_utils.c b/src/transaction/transaction_utils.c new file mode 100644 index 00000000..03446ab2 --- /dev/null +++ b/src/transaction/transaction_utils.c @@ -0,0 +1,118 @@ +/***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + * This software also incorporates work covered by the following copyright + * and permission notice: + * + * Ledger App Boilerplate. + * (c) 2023 Ledger SAS. + * + * 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. + *****************************************************************************/ + +#include "transaction/transaction_utils.h" + +#include // size_t +#include // uint*_t +#include // bool +#include // strlen +#include // snprintf + +#include "format.h" + +#include "ui/ui_utils.h" + +static bool _format_fpu64(char *dst, size_t dst_len, const uint64_t value, uint8_t decimals) { + char buffer[21] = {0}; + + if (!format_u64(buffer, sizeof(buffer), value)) { + return false; + } + + size_t digits = strlen(buffer); + + if (digits <= decimals) { + if (dst_len <= 2 + decimals + 1) { + return false; + } + *dst++ = '0'; + *dst++ = '.'; + for (uint16_t i = 0; i < decimals - digits; i++, dst++) { + *dst = '0'; + } + dst_len -= 2 + decimals - digits; + strncpy(dst, buffer, dst_len); + } else { + if (dst_len <= digits + 1) { + return false; + } + + const size_t shift = digits - decimals; + memmove(dst, buffer, shift); + dst[shift] = '.'; + strncpy(dst + shift + 1, buffer + shift, decimals); + } + + return true; +} + +bool format_amount(char *dst, + size_t dst_len, + const uint64_t value, + uint8_t decimals, + const char *ticker, + size_t ticker_len) { + char amount[22] = {0}; + if (dst_len < sizeof(amount) + 5 || ticker_len > 5) { + return false; + } + if (!_format_fpu64(amount, sizeof(amount), value, decimals)) { + return false; + } + + unpad_amount(amount, strlen(amount), 2); + + snprintf(dst, dst_len, "%s%c%s", amount, get_ticker_line_break(amount), ticker); + return true; +} + +bool format_percentage(char *dst, size_t dst_len, const uint16_t value, uint8_t decimals) { + char amount[22] = {0}; + if (dst_len < 9) { + return false; + } + if (!_format_fpu64(amount, sizeof(amount), (const uint64_t) value, decimals)) { + return false; + } + snprintf(dst, dst_len, "%s%%", amount); + return true; +} + +bool transaction_utils_check_ascii(const uint8_t *text, uint64_t text_len, bool allow_new_lines) { + for (uint64_t i = 0; i < text_len; i++) { + bool lf = text[i] == 0x0A; + bool crlf = text[i] == 0x0D && i + 1 < text_len && text[i + 1] == 0x0A; + if (!((allow_new_lines && (lf || crlf)) || (text[i] >= 0x20 && text[i] <= 0x7E))) { + return false; + } + } + return true; +} diff --git a/src/transaction/transaction_utils.h b/src/transaction/transaction_utils.h new file mode 100644 index 00000000..b8828fbb --- /dev/null +++ b/src/transaction/transaction_utils.h @@ -0,0 +1,63 @@ +#pragma once + +#include // size_t +#include // uint*_t +#include // bool + +/** + * Format 64-bit unsigned integer as string with decimals and ticker. + * + * @param[out] dst + * Pointer to output string. + * @param[in] dst_len + * Length of output string. + * @param[in] value + * 64-bit unsigned integer to format. + * @param[in] decimals + * Number of digits after decimal separator. + * @param[in] ticker + * The token's ticker name to be displayed. + * @param[in] ticker_len + * The length of the ticker name (not including the null-terminator). + * + * @return true if success, false otherwise. + * + */ +bool format_amount(char *dst, + size_t dst_len, + const uint64_t value, + uint8_t decimals, + const char *ticker, + size_t ticker_len); + +/** + * Format 16-bit unsigned integer as string with decimals and percentage sign. + * + * @param[out] dst + * Pointer to output string. + * @param[in] dst_len + * Length of output string. + * @param[in] value + * 16-bit unsigned integer to format. + * @param[in] decimals + * Number of digits after decimal separator. + * + * @return true if success, false otherwise. + * + */ +bool format_percentage(char *dst, size_t dst_len, const uint16_t value, uint8_t decimals); + +/** + * Check if input is encoded using ASCII characters. + * + * @param[in] text + * Pointer to input byte buffer. + * @param[in] text_len + * Length of input byte buffer. + * @param[in] allow_new_lines + * Allow ASCII text to contain new lines. + * + * @return true if success, false otherwise. + * + */ +bool transaction_utils_check_ascii(const uint8_t *text, uint64_t text_len, bool allow_new_lines); diff --git a/src/transaction/types.h b/src/transaction/types.h index 6720c7d4..85a8ec7b 100644 --- a/src/transaction/types.h +++ b/src/transaction/types.h @@ -1,48 +1,15 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once -//#include // size_t #include // uint*_t -#include "types/types.h" + +#include "transaction/types/types.h" #define STARTING_BYTE 0xFF #define TRANSACTION_VERSION_3 0x03 -#define NONCE_LENGTH 0x08 -#define MAX_MEMO_LEN 255 typedef enum { TYPEGROUP_CORE = 1, TYPEGROUP_SOLAR = 2 } transaction_typegroup; -typedef enum { - MULTISIGNATURE_REGISTRATION = 4, - IPFS = 5, - TRANSFER = 6, - HTLC_LOCK = 8, - HTLC_CLAIM = 9, - HTLC_REFUND = 10 -} transaction_type_core; - +typedef enum { IPFS = 5, TRANSFER = 6 } transaction_type_core; typedef enum { BURN = 0, VOTE = 2 } transaction_type_solar; typedef struct { @@ -52,10 +19,10 @@ typedef struct { // Transaction uint32_t typeGroup; /// typeGroup (4 bytes) uint16_t type; /// type (2 bytes) - uint8_t *sender_publickey; /// sender publick key (33 bytes) + uint8_t *sender_publickey; /// sender public key (33 bytes) uint64_t fee; /// fee (8 bytes) uint8_t memo_len; /// length of memo (1 byte) - uint8_t *memo; /// memo (MAX lenth 255) + uint8_t *memo; /// memo (MAX length 255) transaction_asset_t core_asset; /// transaction specific assets (variable length and structure) } transaction_t; diff --git a/src/transaction/types/burn.c b/src/transaction/types/burn.c index 1ee89f56..ca3effa5 100644 --- a/src/transaction/types/burn.c +++ b/src/transaction/types/burn.c @@ -6,8 +6,12 @@ *****************************************************************************/ #include "burn.h" + +#include "buffer.h" + #include "constants.h" -#include "../../common/buffer.h" + +#include "transaction/errors.h" parser_status_e burn_type_deserialise(buffer_t *buf, burn_transaction_asset_t *tx) { // amount diff --git a/src/transaction/types/burn.h b/src/transaction/types/burn.h index 6cb44974..8705020b 100644 --- a/src/transaction/types/burn.h +++ b/src/transaction/types/burn.h @@ -1,14 +1,8 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include "../errors.h" -#include "../../common/buffer.h" +#include "buffer.h" + +#include "transaction/errors.h" typedef struct { uint64_t amount; /// amount (8 bytes) diff --git a/src/transaction/types/htlc_claim.c b/src/transaction/types/htlc_claim.c deleted file mode 100644 index 955ebfff..00000000 --- a/src/transaction/types/htlc_claim.c +++ /dev/null @@ -1,42 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#include "htlc_claim.h" -#include "constants.h" -#include "../../common/buffer.h" - -parser_status_e htlc_claim_type_deserialise(buffer_t *buf, htlc_claim_transaction_asset_t *tx) { - // hash type - if (!buffer_read_u8(buf, &tx->hash_type)) { - return WRONG_LENGTH_ERROR; - } - - // lock transaction id - tx->lockId = (uint8_t *) (buf->ptr + buf->offset); - - if (!buffer_seek_cur(buf, HASH_32_LEN)) { - return WRONG_LENGTH_ERROR; - } - - // unlock secret length - if (!buffer_read_u8(buf, &tx->unlock_secret_length)) { - return WRONG_LENGTH_ERROR; - } - - if (tx->unlock_secret_length < 1 || tx->unlock_secret_length > MAX_HTLC_HASH_LEN) { - return CORE_ASSET_PARSING_ERROR; - } - - // unlock secret - tx->unlock_secret = (uint8_t *) (buf->ptr + buf->offset); - - if (!buffer_seek_cur(buf, tx->unlock_secret_length)) { - return WRONG_LENGTH_ERROR; - } - - return (buf->offset == buf->size) ? PARSING_OK : WRONG_LENGTH_ERROR; -} diff --git a/src/transaction/types/htlc_claim.h b/src/transaction/types/htlc_claim.h deleted file mode 100644 index f60ea87c..00000000 --- a/src/transaction/types/htlc_claim.h +++ /dev/null @@ -1,31 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#pragma once - -#include "../errors.h" -#include "../../common/buffer.h" - -typedef struct { - uint8_t hash_type; /// hashing algorithm (1 byte) - uint8_t *lockId; /// lock transaction id (32 bytes) - uint8_t unlock_secret_length; /// lock secret length (1 byte) - uint8_t *unlock_secret; /// unlock secret (1-255 bytes) -} htlc_claim_transaction_asset_t; - -/** - * Deserialise asset of transaction in structure. - * - * @param[in, out] buf - * Pointer to buffer with serialised transaction. - * @param[out] tx - * Pointer to transaction asset structure. - * - * @return PARSING_OK if success, error status otherwise. - * - */ -parser_status_e htlc_claim_type_deserialise(buffer_t *buf, htlc_claim_transaction_asset_t *tx); diff --git a/src/transaction/types/htlc_lock.c b/src/transaction/types/htlc_lock.c deleted file mode 100644 index 6bf82941..00000000 --- a/src/transaction/types/htlc_lock.c +++ /dev/null @@ -1,52 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#include "htlc_lock.h" -#include "constants.h" -#include "../../common/buffer.h" - -parser_status_e htlc_lock_type_deserialise(buffer_t *buf, htlc_lock_transaction_asset_t *tx) { - // amount - if (!buffer_read_u64(buf, &tx->amount, LE)) { - return WRONG_LENGTH_ERROR; - } - - // secret hash length - if (!buffer_read_u8(buf, &tx->secret_hash_length)) { - return WRONG_LENGTH_ERROR; - } - - if (tx->secret_hash_length < 1 || tx->secret_hash_length > MAX_HTLC_HASH_LEN) { - return CORE_ASSET_PARSING_ERROR; - } - - // secret hash - tx->secret_hash = (uint8_t *) (buf->ptr + buf->offset); - - if (!buffer_seek_cur(buf, tx->secret_hash_length)) { - return WRONG_LENGTH_ERROR; - } - - // expiration type - if (!buffer_read_u8(buf, &tx->expiration_type)) { - return WRONG_LENGTH_ERROR; - } - - // expiration value - if (!buffer_read_u32(buf, &tx->expiration_value, LE)) { - return WRONG_LENGTH_ERROR; - } - - // recipientId - tx->recipientId = (uint8_t *) (buf->ptr + buf->offset); - - if (!buffer_seek_cur(buf, ADDRESS_HASH_LEN)) { - return WRONG_LENGTH_ERROR; - } - - return (buf->offset == buf->size) ? PARSING_OK : WRONG_LENGTH_ERROR; -} diff --git a/src/transaction/types/htlc_lock.h b/src/transaction/types/htlc_lock.h deleted file mode 100644 index 2f2f8747..00000000 --- a/src/transaction/types/htlc_lock.h +++ /dev/null @@ -1,33 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#pragma once - -#include "../errors.h" -#include "../../common/buffer.h" - -typedef struct { - uint64_t amount; /// Amount (8 bytes) - uint8_t secret_hash_length; /// Secret hash length (1 byte) - uint8_t *secret_hash; /// secret hash (1-255 bytes) - uint8_t expiration_type; /// expiration type (1 byte) - uint32_t expiration_value; /// expiration value (4 bytes) - uint8_t *recipientId; /// recipientId (MAX 21 bytes) -} htlc_lock_transaction_asset_t; - -/** - * Deserialise asset of transaction in structure. - * - * @param[in, out] buf - * Pointer to buffer with serialised transaction. - * @param[out] tx - * Pointer to transaction asset structure. - * - * @return PARSING_OK if success, error status otherwise. - * - */ -parser_status_e htlc_lock_type_deserialise(buffer_t *buf, htlc_lock_transaction_asset_t *tx); diff --git a/src/transaction/types/htlc_refund.c b/src/transaction/types/htlc_refund.c deleted file mode 100644 index d9eebc63..00000000 --- a/src/transaction/types/htlc_refund.c +++ /dev/null @@ -1,21 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#include "htlc_refund.h" -#include "constants.h" -#include "../../common/buffer.h" - -parser_status_e htlc_refund_type_deserialise(buffer_t *buf, htlc_refund_transaction_asset_t *tx) { - // lock transaction id - tx->lockId = (uint8_t *) (buf->ptr + buf->offset); - - if (!buffer_seek_cur(buf, HASH_32_LEN)) { - return WRONG_LENGTH_ERROR; - } - - return (buf->offset == buf->size) ? PARSING_OK : WRONG_LENGTH_ERROR; -} diff --git a/src/transaction/types/htlc_refund.h b/src/transaction/types/htlc_refund.h deleted file mode 100644 index 29346802..00000000 --- a/src/transaction/types/htlc_refund.h +++ /dev/null @@ -1,28 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#pragma once - -#include "../errors.h" -#include "../../common/buffer.h" - -typedef struct { - uint8_t *lockId; /// lock transaction id (32 bytes) -} htlc_refund_transaction_asset_t; - -/** - * Deserialise asset of transaction in structure. - * - * @param[in, out] buf - * Pointer to buffer with serialised transaction. - * @param[out] tx - * Pointer to transaction asset structure. - * - * @return PARSING_OK if success, error status otherwise. - * - */ -parser_status_e htlc_refund_type_deserialise(buffer_t *buf, htlc_refund_transaction_asset_t *tx); diff --git a/src/transaction/types/ipfs.c b/src/transaction/types/ipfs.c index af4266ca..711fb73f 100644 --- a/src/transaction/types/ipfs.c +++ b/src/transaction/types/ipfs.c @@ -6,8 +6,12 @@ *****************************************************************************/ #include "ipfs.h" + +#include "buffer.h" + #include "constants.h" -#include "../../common/buffer.h" + +#include "transaction/errors.h" parser_status_e ipfs_type_deserialise(buffer_t *buf, ipfs_transaction_asset_t *tx) { // ipfs diff --git a/src/transaction/types/ipfs.h b/src/transaction/types/ipfs.h index 5f8ce097..2ea08f7a 100644 --- a/src/transaction/types/ipfs.h +++ b/src/transaction/types/ipfs.h @@ -1,14 +1,8 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include "../errors.h" -#include "../../common/buffer.h" +#include "buffer.h" + +#include "transaction/errors.h" typedef struct { uint8_t ipfs_length; /// ipfs length (1 byte) diff --git a/src/transaction/types/multi_signature_registration.c b/src/transaction/types/multi_signature_registration.c deleted file mode 100644 index 897c8c60..00000000 --- a/src/transaction/types/multi_signature_registration.c +++ /dev/null @@ -1,36 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#include "multi_signature_registration.h" -#include "constants.h" -#include "../../common/buffer.h" - -parser_status_e multisignature_type_deserialise(buffer_t *buf, - multisignature_transaction_asset_t *tx) { - // min - if (!buffer_read_u8(buf, &tx->min)) { - return WRONG_LENGTH_ERROR; - } - - // count - if (!buffer_read_u8(buf, &tx->pkey_length)) { - return WRONG_LENGTH_ERROR; - } - - if (tx->pkey_length < MIN_NUM_SIGNATURES || tx->pkey_length > MAX_NUM_SIGNATURES) { - return CORE_ASSET_PARSING_ERROR; - } - - // public keys - tx->pkeys = (uint8_t *) (buf->ptr + buf->offset); - - if (!buffer_seek_cur(buf, PUBLIC_KEY_LEN * tx->pkey_length)) { - return WRONG_LENGTH_ERROR; - } - - return (buf->offset == buf->size) ? PARSING_OK : WRONG_LENGTH_ERROR; -} diff --git a/src/transaction/types/multi_signature_registration.h b/src/transaction/types/multi_signature_registration.h deleted file mode 100644 index fd47bfa3..00000000 --- a/src/transaction/types/multi_signature_registration.h +++ /dev/null @@ -1,34 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#pragma once - -#include "../errors.h" -#include "../../common/buffer.h" - -#define MIN_NUM_SIGNATURES 2 -#define MAX_NUM_SIGNATURES 16 - -typedef struct { - uint8_t min; /// multisignatures minimum (1 byte) - uint8_t pkey_length; /// number of public keys (1 byte) - uint8_t *pkeys; /// publickeys (MAX 33 * 16 bytes) -} multisignature_transaction_asset_t; - -/** - * Deserialise asset of transaction in structure. - * - * @param[in, out] buf - * Pointer to buffer with serialised transaction. - * @param[out] tx - * Pointer to transaction asset structure. - * - * @return PARSING_OK if success, error status otherwise. - * - */ -parser_status_e multisignature_type_deserialise(buffer_t *buf, - multisignature_transaction_asset_t *tx); diff --git a/src/transaction/types/transfer.c b/src/transaction/types/transfer.c index 4b7c5270..fa6ca786 100644 --- a/src/transaction/types/transfer.c +++ b/src/transaction/types/transfer.c @@ -6,8 +6,12 @@ *****************************************************************************/ #include "transfer.h" + +#include "buffer.h" + #include "constants.h" -#include "../../common/buffer.h" + +#include "transaction/errors.h" parser_status_e transfer_type_deserialise(buffer_t *buf, transfer_transaction_asset_t *tx) { // length diff --git a/src/transaction/types/transfer.h b/src/transaction/types/transfer.h index 57ee96be..6a2d90a4 100644 --- a/src/transaction/types/transfer.h +++ b/src/transaction/types/transfer.h @@ -1,14 +1,8 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include "../errors.h" -#include "../../common/buffer.h" +#include "buffer.h" + +#include "transaction/errors.h" #define MIN_NUM_TRANSFERS 1 #define MAX_NUM_TRANSFERS 40 // Limited respect to protocol maximum due to SRAM limitations diff --git a/src/transaction/types/types.h b/src/transaction/types/types.h index 06b9bd4b..28fa4c42 100644 --- a/src/transaction/types/types.h +++ b/src/transaction/types/types.h @@ -1,28 +1,13 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include -#include -#include -#include -#include -#include -#include -#include +#include "transaction/types/ipfs.h" +#include "transaction/types/transfer.h" +#include "transaction/types/burn.h" +#include "transaction/types/vote.h" typedef union transaction_asset_t { - multisignature_transaction_asset_t Multisignature; ipfs_transaction_asset_t Ipfs; transfer_transaction_asset_t Transfer; - htlc_lock_transaction_asset_t Htlc_lock; - htlc_claim_transaction_asset_t Htlc_claim; - htlc_refund_transaction_asset_t Htlc_refund; burn_transaction_asset_t Burn; vote_transaction_asset_t Vote; } transaction_asset_t; diff --git a/src/transaction/types/vote.c b/src/transaction/types/vote.c index 6d78fb65..fab411e5 100644 --- a/src/transaction/types/vote.c +++ b/src/transaction/types/vote.c @@ -6,9 +6,15 @@ *****************************************************************************/ #include "vote.h" + +#include // uint*_t + +#include "buffer.h" + #include "constants.h" -#include "../utils.h" -#include "../../common/buffer.h" + +#include "transaction/errors.h" +#include "transaction/transaction_utils.h" parser_status_e vote_type_deserialise(buffer_t *buf, vote_transaction_asset_t *tx) { // length diff --git a/src/transaction/types/vote.h b/src/transaction/types/vote.h index 96308db1..ef51891c 100644 --- a/src/transaction/types/vote.h +++ b/src/transaction/types/vote.h @@ -1,14 +1,10 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include "../errors.h" -#include "../../common/buffer.h" +#include // uint*_t + +#include "buffer.h" + +#include "transaction/errors.h" #define MIN_NUM_VOTES 0 #define MAX_NUM_VOTES 53 diff --git a/src/transaction/utils.c b/src/transaction/utils.c deleted file mode 100644 index f4950b8a..00000000 --- a/src/transaction/utils.c +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#include // uint*_t -#include // bool -#include // memmove - -#include "types.h" - -bool transaction_utils_check_ascii(const uint8_t *text, uint64_t text_len, bool allow_new_lines) { - for (uint64_t i = 0; i < text_len; i++) { - bool lf = text[i] == 0x0A; - bool crlf = text[i] == 0x0D && i + 1 < text_len && text[i + 1] == 0x0A; - if (!((allow_new_lines && (lf || crlf)) || (text[i] >= 0x20 && text[i] <= 0x7E))) { - return false; - } - } - return true; -} diff --git a/src/transaction/utils.h b/src/transaction/utils.h deleted file mode 100644 index a928e838..00000000 --- a/src/transaction/utils.h +++ /dev/null @@ -1,44 +0,0 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - -#pragma once - -#include // uint*_t -#include // bool - -#include "types.h" - -/** - * Check if input is encoded using ASCII characters. - * - * @param[in] text - * Pointer to input byte buffer. - * @param[in] text_len - * Lenght of input byte buffer. - * @param[in] allow_new_lines - * Allow ASCII text to contain new lines. - * - * @return true if success, false otherwise. - * - */ -bool transaction_utils_check_ascii(const uint8_t *text, uint64_t text_len, bool allow_new_lines); diff --git a/src/types.h b/src/types.h index c09f4695..128dc4f1 100644 --- a/src/types.h +++ b/src/types.h @@ -1,44 +1,14 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once #include // bool #include // size_t #include // uint*_t +#include "bip32.h" + #include "constants.h" -#include "transaction/types.h" -#include "common/bip32.h" -/** - * Enumeration for the status of IO. - */ -typedef enum { - READY, /// ready for new event - RECEIVED, /// data received - WAITING /// waiting -} io_state_e; +#include "transaction/types.h" /** * Enumeration with expected INS of APDU commands. @@ -52,18 +22,6 @@ typedef enum { SIGN_TX = 0xc2 /// sign transaction with BIP32 path } command_e; -/** - * Structure with fields of APDU command. - */ -typedef struct { - uint8_t cla; /// Instruction class - command_e ins; /// Instruction code - uint8_t p1; /// Instruction parameter 1 - uint8_t p2; /// Instruction parameter 2 - uint8_t lc; /// Lenght of command data - uint8_t *data; /// Command data -} command_t; - /** * Enumeration with parsing state. */ @@ -96,7 +54,7 @@ typedef struct { * Structure for transaction information context. */ typedef struct { - uint8_t raw_tx[MAX_TRANSACTION_LEN]; /// raw transaction serialised + uint8_t raw_tx[TRANSACTION_MAX_LEN]; /// raw transaction serialised size_t raw_tx_len; /// length of raw transaction transaction_t transaction; /// structured transaction uint8_t m_hash[32]; /// message hash digest @@ -115,6 +73,6 @@ typedef struct { }; request_type_e req_type; /// user request uint32_t bip32_path[MAX_BIP32_PATH]; /// BIP32 path - uint8_t bip32_path_len; /// lenght of BIP32 path + uint8_t bip32_path_len; /// length of BIP32 path uint8_t network; /// network byte } global_ctx_t; diff --git a/src/ui/action/validate.c b/src/ui/action/validate.c index 32bf8264..9b5443ac 100644 --- a/src/ui/action/validate.c +++ b/src/ui/action/validate.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,16 +28,19 @@ * limitations under the License. *****************************************************************************/ +#include "ui/action/validate.h" + #include // bool -#include "validate.h" -#include "../menu.h" -#include "../../sw.h" -#include "../../io.h" -#include "../../crypto/crypto.h" -#include "../../globals.h" -#include "../../context.h" -#include "../../helper/send_response.h" +#include "io.h" + +#include "context.h" +#include "globals.h" +#include "sw.h" + +#include "crypto/crypto.h" +#include "helper/send_response.h" +#include "ui/menu.h" void ui_action_validate_pubkey(bool choice) { if (choice) { diff --git a/src/ui/action/validate.h b/src/ui/action/validate.h index 0b904cf2..5fd1bdff 100644 --- a/src/ui/action/validate.h +++ b/src/ui/action/validate.h @@ -1,26 +1,3 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once #include // bool diff --git a/src/ui/ctx.c b/src/ui/ctx.c index 201068e4..b79b20ae 100644 --- a/src/ui/ctx.c +++ b/src/ui/ctx.c @@ -5,8 +5,9 @@ * 4.0 International License. *****************************************************************************/ -#include -#include "../transaction/types.h" +#include "ui/ctx.h" + +#include "transaction/types.h" bool context_get_next(ctx_t *ctx, transaction_t *tx, char title[], char text[]) { bool result = ctx->f(tx, title, text, ctx->offset); diff --git a/src/ui/ctx.h b/src/ui/ctx.h index 373c5504..7447e50c 100644 --- a/src/ui/ctx.h +++ b/src/ui/ctx.h @@ -1,16 +1,9 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include -#include +#include // bool +#include // uint*_t -#include "../transaction/types.h" +#include "transaction/types.h" #define MAX_TITLE_LEN 16 #define MAX_TEXT_LEN 385 @@ -24,7 +17,7 @@ typedef struct { * Get next content to display. * * @param[in, out] ctx - * Pointer to the contect structure. + * Pointer to the context structure. * @param[in] tx * Pointer to transaction structure. * @param[out] title @@ -41,7 +34,7 @@ bool context_get_next(ctx_t *ctx, transaction_t *tx, char title[], char text[]); * Get previous content to display. * * @param[in, out] ctx - * Pointer to the contect structure. + * Pointer to the context structure. * @param[in] tx * Pointer to transaction structure. * @param[out] title diff --git a/src/ui/display.c b/src/ui/display.c index 2baf8bf4..cc26b31c 100644 --- a/src/ui/display.c +++ b/src/ui/display.c @@ -1,4 +1,11 @@ /***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * * This work is licensed under a Creative Commons Attribution-NoDerivatives * 4.0 International License. * @@ -6,7 +13,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) 2023 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,34 +28,32 @@ * limitations under the License. *****************************************************************************/ -#include "display.h" +#include "ui/display.h" #include // bool #include // memset +#include "glyphs.h" + +#include "bip32.h" +#include "buffer.h" +#include "format.h" +#include "io.h" #include "os.h" #include "ux.h" -#include "glyphs.h" +#include "address.h" #include "constants.h" -#include "ctx.h" -#include "../globals.h" -#include "../io.h" -#include "../sw.h" +#include "globals.h" +#include "sw.h" + #include "action/validate.h" -#include "../transaction/types.h" -#include "../common/bip32.h" -#include "../common/buffer.h" -#include "../common/format.h" -#include "../address.h" -#include "transactions/multi_signature_registration_display.h" -#include "transactions/ipfs_display.h" -#include "transactions/transfer_display.h" -#include "transactions/htlc_lock_display.h" -#include "transactions/htlc_claim_display.h" -#include "transactions/htlc_refund_display.h" -#include "transactions/burn_display.h" -#include "transactions/vote_display.h" +#include "transaction/types.h" +#include "ui/ctx.h" +#include "ui/transactions/ipfs_display.h" +#include "ui/transactions/transfer_display.h" +#include "ui/transactions/burn_display.h" +#include "ui/transactions/vote_display.h" ctx_t display_context = {0}; @@ -266,7 +271,7 @@ void display_next_state(bool is_upper_delimiter) { } } -// Upper delimeter step +// Upper delimiter step UX_STEP_INIT(step_upper_delimiter, NULL, NULL, { display_next_state(true); }); // general dynamic step @@ -277,7 +282,7 @@ UX_STEP_NOCB(ux_display_general, .text = g_current_text, }); -// Lower delimeter step +// Lower delimiter step UX_STEP_INIT(step_lower_delimiter, NULL, NULL, { display_next_state(false); }); // FLOW to display transaction: @@ -326,12 +331,6 @@ int ui_display_transaction() { } } else { switch (G_context.tx_info.transaction.type) { - case MULTISIGNATURE_REGISTRATION: { - snprintf(g_transaction_name, sizeof(g_transaction_name), "%s", "Multisignature"); - - display_context.f = &multisignature_type_display; - break; - } case IPFS: { // First screen snprintf(g_transaction_name, sizeof(g_transaction_name), "%s", "IPFS"); @@ -345,27 +344,6 @@ int ui_display_transaction() { display_context.f = &transfer_type_display; break; } - case HTLC_LOCK: { - // First screen - snprintf(g_transaction_name, sizeof(g_transaction_name), "%s", "HTLC Lock"); - - display_context.f = &htlc_lock_type_display; - break; - } - case HTLC_CLAIM: { - // First screen - snprintf(g_transaction_name, sizeof(g_transaction_name), "%s", "HTLC Claim"); - - display_context.f = &htlc_claim_type_display; - break; - } - case HTLC_REFUND: { - // First screen - snprintf(g_transaction_name, sizeof(g_transaction_name), "%s", "HTLC Refund"); - - display_context.f = &htlc_refund_type_display; - break; - } default: return io_send_sw(SW_TX_PARSING_FAIL); } diff --git a/src/ui/display.h b/src/ui/display.h index 50ae8ff8..51423004 100644 --- a/src/ui/display.h +++ b/src/ui/display.h @@ -1,26 +1,3 @@ -/***************************************************************************** - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - * - * This software also incorporates work covered by the following copyright - * and permission notice: - * - * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. - * - * 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. - *****************************************************************************/ - #pragma once #include // bool diff --git a/src/ui/menu.c b/src/ui/menu.c index 91eee668..c8d8cc9e 100644 --- a/src/ui/menu.c +++ b/src/ui/menu.c @@ -6,7 +6,7 @@ * and permission notice: * * Ledger App Boilerplate. - * (c) 2020 Ledger SAS. + * (c) 2023 Ledger SAS. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,14 @@ * limitations under the License. *****************************************************************************/ +#include "ui/menu.h" + +#include "glyphs.h" + #include "os.h" #include "ux.h" -#include "glyphs.h" -#include "../globals.h" -#include "menu.h" +#include "globals.h" UX_STEP_NOCB(ux_menu_ready_step, pnn, {&C_solar_logo, "Solar", "is ready"}); UX_STEP_NOCB(ux_menu_version_step, bn, {"Version", APPVERSION}); @@ -53,7 +55,7 @@ void ui_menu_main() { ux_flow_init(0, ux_menu_main_flow, NULL); } -UX_STEP_NOCB(ux_menu_info_step, bn, {"Solar App", "(c) 2022 Solar"}); +UX_STEP_NOCB(ux_menu_info_step, bn, {"Solar App", "(c) Solar Network"}); UX_STEP_CB(ux_menu_back_step, pb, ui_menu_main(), {&C_icon_back, "Back"}); // FLOW for the about submenu: diff --git a/src/ui/transactions/burn_display.c b/src/ui/transactions/burn_display.c index 828f8e60..b0c092e9 100644 --- a/src/ui/transactions/burn_display.c +++ b/src/ui/transactions/burn_display.c @@ -5,13 +5,19 @@ * 4.0 International License. *****************************************************************************/ -#include -#include "burn_display.h" -#include "types.h" +#include "ui/transactions/burn_display.h" + +#include // snprintf +#include // uint*_t + +#include "base58.h" +#include "buffer.h" + #include "constants.h" -#include "../../common/buffer.h" -#include "../../common/format.h" -#include "../../common/base58.h" + +#include "transaction/transaction_utils.h" +#include "transaction/types.h" +#include "ui/ctx.h" bool burn_type_display(transaction_t *tx, char title[], char text[], uint16_t step) { switch (step) { diff --git a/src/ui/transactions/burn_display.h b/src/ui/transactions/burn_display.h index c139c40b..98570a40 100644 --- a/src/ui/transactions/burn_display.h +++ b/src/ui/transactions/burn_display.h @@ -1,15 +1,9 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include -#include "../../transaction/types.h" -#include "../ctx.h" +#include // bool +#include // uint*_t + +#include "transaction/types.h" /** * Produce content for specific transaction. diff --git a/src/ui/transactions/htlc_claim_display.c b/src/ui/transactions/htlc_claim_display.c deleted file mode 100644 index 3b2f56b5..00000000 --- a/src/ui/transactions/htlc_claim_display.c +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#include -#include "htlc_claim_display.h" -#include "types.h" -#include "constants.h" -#include "../../common/buffer.h" -#include "../../common/format.h" -#include "../../common/base58.h" - -bool htlc_claim_type_display(transaction_t *tx, char title[], char text[], uint16_t step) { - switch (step) { - case 0: { - // Lock Transaction Id - snprintf(title, MAX_TITLE_LEN, "%s", "Lock ID"); - format_hex(tx->core_asset.Htlc_claim.lockId, HASH_32_LEN, text, MAX_TEXT_LEN); - break; - } - case 1: { - // Unlock secret - snprintf(title, MAX_TITLE_LEN, "%s", "Unlock secret"); - format_hex(tx->core_asset.Htlc_claim.unlock_secret, - tx->core_asset.Htlc_claim.unlock_secret_length, - text, - MAX_TEXT_LEN); - break; - } - case 2: { - // Fee - snprintf(title, MAX_TITLE_LEN, "%s", "Fee"); - format_amount(text, - MAX_TEXT_LEN, - tx->fee, - EXPONENT_SMALLEST_UNIT, - TICKER_DEFAULT, - sizeof(TICKER_DEFAULT)); - break; - } - default: { - return false; - } - } - return true; -} diff --git a/src/ui/transactions/htlc_claim_display.h b/src/ui/transactions/htlc_claim_display.h deleted file mode 100644 index 5277b0b4..00000000 --- a/src/ui/transactions/htlc_claim_display.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#pragma once - -#include -#include "../../transaction/types.h" -#include "../ctx.h" - -/** - * Produce content for specific transaction. - * - * @param[in] tx - * Pointer to transaction structure. - * @param[out] title - * Title output. - * @param[out] text - * Text output. - * @param[in] step - * current step to display. - * - * @return true if there is content, false otherwise. - * - */ -bool htlc_claim_type_display(transaction_t *tx, char title[], char text[], uint16_t step); diff --git a/src/ui/transactions/htlc_lock_display.c b/src/ui/transactions/htlc_lock_display.c deleted file mode 100644 index b2ebedd9..00000000 --- a/src/ui/transactions/htlc_lock_display.c +++ /dev/null @@ -1,71 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#include -#include "htlc_lock_display.h" -#include "types.h" -#include "constants.h" -#include "address.h" -#include "../../common/buffer.h" -#include "../../common/format.h" - -bool htlc_lock_type_display(transaction_t *tx, char title[], char text[], uint16_t step) { - switch (step) { - case 0: { - // RecipientId - snprintf(title, MAX_TITLE_LEN, "%s", "Recipient"); - base58_encode_address(tx->core_asset.Htlc_lock.recipientId, - ADDRESS_HASH_LEN, - text, - MAX_TEXT_LEN); - break; - } - case 1: { - // Amount - snprintf(title, MAX_TITLE_LEN, "%s", "Amount"); - format_amount(text, - MAX_TEXT_LEN, - tx->core_asset.Htlc_lock.amount, - EXPONENT_SMALLEST_UNIT, - TICKER_DEFAULT, - sizeof(TICKER_DEFAULT)); - break; - } - case 2: { - // Secret hash - snprintf(title, MAX_TITLE_LEN, "%s", "Secret Hash"); - format_hex(tx->core_asset.Htlc_lock.secret_hash, - tx->core_asset.Htlc_lock.secret_hash_length, - text, - MAX_TEXT_LEN); - break; - } - case 3: { - // Expiration - bool isTime = tx->core_asset.Htlc_lock.expiration_type == 1; - snprintf(title, MAX_TITLE_LEN, "%s", isTime ? "Expire Time" : "Expire Height"); - snprintf(text, MAX_TEXT_LEN, "%d", tx->core_asset.Htlc_lock.expiration_value); - break; - } - case 4: { - // Fee - snprintf(title, MAX_TITLE_LEN, "%s", "Fee"); - format_amount(text, - MAX_TEXT_LEN, - tx->fee, - EXPONENT_SMALLEST_UNIT, - TICKER_DEFAULT, - sizeof(TICKER_DEFAULT)); - break; - } - default: { - return false; - } - } - - return true; -} diff --git a/src/ui/transactions/htlc_lock_display.h b/src/ui/transactions/htlc_lock_display.h deleted file mode 100644 index f572b215..00000000 --- a/src/ui/transactions/htlc_lock_display.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#pragma once - -#include -#include "../../transaction/types.h" -#include "../ctx.h" - -/** - * Produce content for specific transaction. - * - * @param[in] tx - * Pointer to transaction structure. - * @param[out] title - * Title output. - * @param[out] text - * Text output. - * @param[in] step - * current step to display. - * - * @return true if there is content, false otherwise. - * - */ -bool htlc_lock_type_display(transaction_t *tx, char title[], char text[], uint16_t step); diff --git a/src/ui/transactions/htlc_refund_display.c b/src/ui/transactions/htlc_refund_display.c deleted file mode 100644 index 02986d93..00000000 --- a/src/ui/transactions/htlc_refund_display.c +++ /dev/null @@ -1,41 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#include -#include "htlc_refund_display.h" -#include "types.h" -#include "constants.h" -#include "../../common/buffer.h" -#include "../../common/format.h" -#include "../../common/base58.h" - -bool htlc_refund_type_display(transaction_t *tx, char title[], char text[], uint16_t step) { - switch (step) { - case 0: { - // Lock Transaction Id - snprintf(title, MAX_TITLE_LEN, "%s", "Lock ID"); - format_hex(tx->core_asset.Htlc_refund.lockId, HASH_32_LEN, text, MAX_TEXT_LEN); - break; - } - case 1: { - // Fee - snprintf(title, MAX_TITLE_LEN, "%s", "Fee"); - format_amount(text, - MAX_TEXT_LEN, - tx->fee, - EXPONENT_SMALLEST_UNIT, - TICKER_DEFAULT, - sizeof(TICKER_DEFAULT)); - break; - } - default: { - return false; - } - } - - return true; -} diff --git a/src/ui/transactions/htlc_refund_display.h b/src/ui/transactions/htlc_refund_display.h deleted file mode 100644 index 8ad15fb8..00000000 --- a/src/ui/transactions/htlc_refund_display.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#pragma once - -#include -#include "../../transaction/types.h" -#include "../ctx.h" - -/** - * Produce content for specific transaction. - * - * @param[in] tx - * Pointer to transaction structure. - * @param[out] title - * Title output. - * @param[out] text - * Text output. - * @param[in] step - * current step to display. - * - * @return true if there is content, false otherwise. - * - */ -bool htlc_refund_type_display(transaction_t *tx, char title[], char text[], uint16_t step); diff --git a/src/ui/transactions/ipfs_display.c b/src/ui/transactions/ipfs_display.c index 9ca4619f..111f04a9 100644 --- a/src/ui/transactions/ipfs_display.c +++ b/src/ui/transactions/ipfs_display.c @@ -5,13 +5,21 @@ * 4.0 International License. *****************************************************************************/ -#include -#include "ipfs_display.h" -#include "types.h" +#include "ui/transactions/ipfs_display.h" + +#include // bool +#include // uint*_t +#include // snprintf + +#include "base58.h" +#include "buffer.h" +#include "format.h" + #include "constants.h" -#include "../../common/buffer.h" -#include "../../common/format.h" -#include "../../common/base58.h" + +#include "transaction/transaction_utils.h" +#include "transaction/types.h" +#include "ui/ctx.h" bool ipfs_type_display(transaction_t *tx, char title[], char text[], uint16_t step) { switch (step) { diff --git a/src/ui/transactions/ipfs_display.h b/src/ui/transactions/ipfs_display.h index cf2d6aab..c510dec1 100644 --- a/src/ui/transactions/ipfs_display.h +++ b/src/ui/transactions/ipfs_display.h @@ -1,15 +1,9 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include -#include "../../transaction/types.h" -#include "../ctx.h" +#include // bool +#include // uint*_t + +#include "transaction/types.h" /** * Produce content for specific transaction. diff --git a/src/ui/transactions/multi_signature_registration_display.c b/src/ui/transactions/multi_signature_registration_display.c deleted file mode 100644 index 7188dd84..00000000 --- a/src/ui/transactions/multi_signature_registration_display.c +++ /dev/null @@ -1,55 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#include -#include "multi_signature_registration_display.h" -#include "types.h" -#include "constants.h" -#include "../../common/buffer.h" -#include "../../common/format.h" - -bool multisignature_type_display(transaction_t *tx, char title[], char text[], uint16_t step) { - // Public keys - if (step < tx->core_asset.Multisignature.pkey_length) { - snprintf(title, - MAX_TITLE_LEN, - "%s %d/%d", - "PublicKey", - step + 1, - tx->core_asset.Multisignature.pkey_length); - format_hex(&tx->core_asset.Multisignature.pkeys[PUBLIC_KEY_LEN * step], - PUBLIC_KEY_LEN, - text, - MAX_TEXT_LEN); - return true; - } - - switch (step - tx->core_asset.Multisignature.pkey_length) { - case 0: { - // Minimum - snprintf(title, MAX_TITLE_LEN, "%s", "Minimum"); - snprintf(text, MAX_TEXT_LEN, "%d", tx->core_asset.Multisignature.min); - break; - } - case 1: { - // Fee - snprintf(title, MAX_TITLE_LEN, "%s", "Fee"); - format_amount(text, - MAX_TEXT_LEN, - tx->fee, - EXPONENT_SMALLEST_UNIT, - TICKER_DEFAULT, - sizeof(TICKER_DEFAULT)); - break; - } - default: { - return false; - } - } - - return true; -} diff --git a/src/ui/transactions/multi_signature_registration_display.h b/src/ui/transactions/multi_signature_registration_display.h deleted file mode 100644 index 259fb4b0..00000000 --- a/src/ui/transactions/multi_signature_registration_display.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - -#pragma once - -#include -#include "../../transaction/types.h" -#include "../ctx.h" - -/** - * Produce content for specific transaction. - * - * @param[in] tx - * Pointer to transaction structure. - * @param[out] title - * Title output. - * @param[out] text - * Text output. - * @param[in] step - * current step to display. - * - * @return true if there is content, false otherwise. - * - */ -bool multisignature_type_display(transaction_t *tx, char title[], char text[], uint16_t step); diff --git a/src/ui/transactions/transfer_display.c b/src/ui/transactions/transfer_display.c index 2a197548..eb5c035b 100644 --- a/src/ui/transactions/transfer_display.c +++ b/src/ui/transactions/transfer_display.c @@ -5,14 +5,21 @@ * 4.0 International License. *****************************************************************************/ -#include -#include "transfer_display.h" -#include "types.h" -#include "constants.h" +#include "ui/transactions/transfer_display.h" + +#include // snprintf +#include // uint*_t + +#include "buffer.h" +#include "format.h" +#include "read.h" + #include "address.h" -#include "../../common/buffer.h" -#include "../../common/format.h" -#include "../../common/read.h" +#include "constants.h" + +#include "transaction/transaction_utils.h" +#include "transaction/types.h" +#include "ui/ctx.h" bool transfer_type_display(transaction_t *tx, char title[], char text[], uint16_t step) { // transfers (amount + recipient) diff --git a/src/ui/transactions/transfer_display.h b/src/ui/transactions/transfer_display.h index eb397c2d..bd063056 100644 --- a/src/ui/transactions/transfer_display.h +++ b/src/ui/transactions/transfer_display.h @@ -1,15 +1,9 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include -#include "../../transaction/types.h" -#include "../ctx.h" +#include // bool +#include // uint*_t + +#include "transaction/types.h" /** * Produce content for specific transaction. diff --git a/src/ui/transactions/vote_display.c b/src/ui/transactions/vote_display.c index a149aedf..216acc68 100644 --- a/src/ui/transactions/vote_display.c +++ b/src/ui/transactions/vote_display.c @@ -5,87 +5,82 @@ * 4.0 International License. *****************************************************************************/ -#include +#include "ui/transactions/vote_display.h" + +#include // uint*_t +#include // snprintf #include -#include "vote_display.h" -#include "types.h" + +#include "base58.h" +#include "buffer.h" +#include "format.h" +#include "read.h" + #include "constants.h" -#include "../../transaction/types/vote.h" -#include "../../common/buffer.h" -#include "../../common/format.h" -#include "../../common/read.h" -#include "../../common/base58.h" +#include "types.h" + +#include "transaction/transaction_utils.h" +#include "transaction/types/vote.h" +#include "ui/ctx.h" bool vote_type_display(transaction_t *tx, char title[], char text[], uint16_t step) { - // Votes - uint16_t vote_number = step / 2; - if (vote_number < tx->core_asset.Vote.vote_length) { + uint16_t vote_count = step / 2; + + // Check if we are still in the voting phase + if (vote_count < tx->core_asset.Vote.vote_length) { vote_deserialised_t asset = {0}; - vote_search(tx->core_asset.Vote.votes, - vote_number, - tx->core_asset.Vote.vote_length, - &asset); + vote_search(tx->core_asset.Vote.votes, vote_count, tx->core_asset.Vote.vote_length, &asset); + if (step % 2 == 0) { - char title_text[] = "Delegate (%d/%d)"; - if (vote_number >= 9) { - strcpy(title_text, "Delegate(%d/%d)"); - } + // Prepare the vote screen snprintf(title, MAX_TITLE_LEN, - title_text, - vote_number + 1, + "Vote (%d/%d)", + vote_count + 1, tx->core_asset.Vote.vote_length); - snprintf(text, MAX_TEXT_LEN, "%.*s", asset.username_length, asset.username); - return true; } else { - char title_text[] = "Vote %% (%d/%d)"; - if (vote_number >= 9) { - strcpy(title_text, "Vote %%(%d/%d)"); - } + // Prepare the vote percentage screen snprintf(title, MAX_TITLE_LEN, - title_text, - vote_number + 1, + "Vote %% (%d/%d)", + vote_count + 1, tx->core_asset.Vote.vote_length); format_percentage(text, MAX_TEXT_LEN, asset.percentage, 2); - return true; } + + return true; } - switch (step - (tx->core_asset.Vote.vote_length * 2)) { - case 0: { - // Fee - snprintf(title, MAX_TITLE_LEN, "%s", "Fee"); - format_amount(text, - MAX_TEXT_LEN, - tx->fee, - EXPONENT_SMALLEST_UNIT, - TICKER_DEFAULT, - sizeof(TICKER_DEFAULT)); - break; - } - default: { - return false; - } + // Prepare the fee screen + if (step - (tx->core_asset.Vote.vote_length * 2) == 0) { + snprintf(title, MAX_TITLE_LEN, "Fee"); + format_amount(text, + MAX_TEXT_LEN, + tx->fee, + EXPONENT_SMALLEST_UNIT, + TICKER_DEFAULT, + sizeof(TICKER_DEFAULT)); + return true; } - return true; + return false; } bool vote_search(uint8_t *tx, uint8_t vote_number, uint8_t max_votes, vote_deserialised_t *asset) { if (vote_number >= max_votes) { return false; } - uint16_t offset = 0; + + uint8_t *ptr = tx; for (uint8_t i = 0; i < vote_number; i++) { - uint8_t username_length = *(tx + offset); - offset += username_length + 3; + uint8_t username_length = *ptr; + ptr += username_length + 3; } - asset->username_length = *(tx + offset); - offset += 1; - asset->username = tx + offset; - offset += asset->username_length; - asset->percentage = read_u16_le(tx, offset); + asset->username_length = *ptr++; + asset->username = ptr; + ptr += asset->username_length; + asset->percentage = read_u16_le(tx, ptr - tx); + return true; } diff --git a/src/ui/transactions/vote_display.h b/src/ui/transactions/vote_display.h index c3368c88..f66968f1 100644 --- a/src/ui/transactions/vote_display.h +++ b/src/ui/transactions/vote_display.h @@ -1,15 +1,9 @@ -/***************************************************************************** - * Copyright (c) Solar Network - * - * This work is licensed under a Creative Commons Attribution-NoDerivatives - * 4.0 International License. - *****************************************************************************/ - #pragma once -#include -#include "../../transaction/types.h" -#include "../ctx.h" +#include // bool +#include // uint*_t + +#include "transaction/types.h" /** * Produce content for specific transaction. diff --git a/src/ui/ui_utils.c b/src/ui/ui_utils.c new file mode 100644 index 00000000..235921c8 --- /dev/null +++ b/src/ui/ui_utils.c @@ -0,0 +1,83 @@ +/***************************************************************************** + * Copyright (c) Solar Network + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + ***************************************************************************** + * + * This work is licensed under a Creative Commons Attribution-NoDerivatives + * 4.0 International License. + * + * This software also incorporates work covered by the following copyright + * and permission notice: + * + * Ledger App Boilerplate. + * (c) 2023 Ledger SAS. + * + * 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. + *****************************************************************************/ + +#include "ui/ui_utils.h" + +#include // size_t +#include // uint*_t +#include // bool +#include // strlen + +#include "bolos_target.h" + +#if defined(TARGET_NANOS) // Estimate amount/fee line pixel count for the Nano S. + +// copied from: +// https://github.com/LedgerHQ/nanos-secure-sdk/blob/master/lib_ux/include/ux_layout_paging_compute.h#L8 +#define PIXEL_PER_LINE 114 + +// extern from: +// https://github.com/LedgerHQ/nanos-secure-sdk/blob/master/lib_ux/src/ux_layout_paging_compute.c#L20-#L117 +extern const char nanos_characters_width[96]; + +// adapted from: +// https://github.com/LedgerHQ/nanos-secure-sdk/blob/master/lib_ux/src/ux_layout_paging_compute.c#L147-#L175 +static uint32_t calculate_pixels(char *text, size_t text_length) { + char current_char; + uint32_t line_width = 0; + + while (text_length--) { + current_char = *text; + line_width += (nanos_characters_width[current_char - 0x20] >> 0x04) & 0x0F; + text++; + } + + return line_width; +} + +#define GET_TICKER_LINE_BREAK(num_str) \ + (((calculate_pixels((num_str), strlen(num_str))) >= ((PIXEL_PER_LINE) - (1))) ? ('\n') : (' ')) + +#else // if NOT Nano S, Only return the space character. + +#define GET_TICKER_LINE_BREAK(num_str) ((void) (num_str), (' ')) + +#endif + +void unpad_amount(char *amount, size_t len, size_t padding) { + char *ptr = amount + len - 1; + while (*ptr == '0' && *(ptr - padding) != '.') { + *ptr-- = 0; + } +} + +char get_ticker_line_break(char *num_str) { + return GET_TICKER_LINE_BREAK(num_str); +} diff --git a/src/ui/ui_utils.h b/src/ui/ui_utils.h new file mode 100644 index 00000000..da689673 --- /dev/null +++ b/src/ui/ui_utils.h @@ -0,0 +1,29 @@ +#pragma once + +#include // size_t + +/** + * Remove trailing zeros up to the decimal + padding. + * + * @param[in] amount + * Pointer to amount string. + * @param[in] len + * Length of amount string. + * @param[in] padding + * Length of zero padding to keep. + * + */ +void unpad_amount(char *amount, size_t len, size_t padding); + +/** + * Determine if a new page should be used for ticker display. + * + * (e.g., avoid `123456789012345678 / 9.00 SXP` being misread as `9.00 SXP`) + * + * @param[in] num_str + * Pointer to formatted number string. + * + * @return new line character if needed for Nano S, otherwise a space character. + * + */ +char get_ticker_line_break(char *num_str); diff --git a/tests/functional/README.md b/tests/functional/README.md index 44b9edb6..ace569a3 100644 --- a/tests/functional/README.md +++ b/tests/functional/README.md @@ -1,42 +1,73 @@ -# Functional Tests +# How to use the Ragger test framework -> :point_right: Every path on this document assumes you are at the root of the repository. +This framework allows testing the application on the Speculos emulator or on a real device using LedgerComm or LedgerWallet -These tests are implemented in Python and can be executed either using the -[Speculos](https://github.com/LedgerHQ/speculos) emulator or a Ledger Nano S/X. -Python dependencies are listed in [requirements.txt](requirements.txt), install -them using [pip](https://pypi.org/project/pip/) +## Quickly get started with Ragger and Speculos -```shell -pip install --extra-index-url https://test.pypi.org/simple/ -r tests/functional/requirements.txt +### Install ragger and dependencies + +``` +pip install --extra-index-url https://test.pypi.org/simple/ -r requirements.txt +sudo apt-get update && sudo apt-get install qemu-user-static ``` -> The `--extra-index-url` parameter helps fetch the latest version of Speculos. +### Compile the application -## Manual (Speculos GUI) +The application to test must be compiled for all required devices. +You can use for this the container `ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite`: +``` +docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest +cd # replace with the name of your app, (eg boilerplate) +docker run --user "$(id -u)":"$(id -g)" --rm -ti -v "$(realpath .):/app" --privileged -v "/dev/bus/usb:/dev/bus/usb" ledger-app-builder-lite:latest +make clean && make BOLOS_SDK=$_SDK # replace with one of [NANOS, NANOX, NANOSP, STAX] +exit +``` -The `--manual` parameter is used to launch the Speculos GUI via command line and is offered as a convenient alternative to opening Speculos separately. +### Run a simple test using the Speculos emulator -```shell -pytest tests/functional/ --manual +You can use the following command to get your first experience with Ragger and Speculos ``` +pytest -v --tb=short --device nanox --display +``` +Or you can refer to the section `Available pytest options` to configure the options you want to use -## Headless (Speculos Backend) -The `--headless` parameter is used to run functional tests using the Speculos backend where button presses will be handled automatically. +### Run a simple test using a real device -```shell -pytest tests/functional/ --headless +The application to test must be loaded and started on a Ledger device plugged in USB. +You can use for this the container `ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite`: +``` +docker pull ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest +cd app-/ # replace with the name of your app, (eg boilerplate) +docker run --user "$(id -u)":"$(id -g)" --rm -ti -v "$(realpath .):/app" --privileged -v "/dev/bus/usb:/dev/bus/usb" ledger-app-builder-lite:latest +make clean && make BOLOS_SDK=$_SDK load # replace with one of [NANOS, NANOX, NANOSP, STAX] +exit ``` -## Launch with your Nano S/X/SPlus +You can use the following command to get your first experience with Ragger and Ledgerwallet on a NANOX. +Make sure that the device is plugged, unlocked, and that the tested application is open. +``` +pytest -v --tb=short --device nanox --backend ledgerwallet +``` +Or you can refer to the section `Available pytest options` to configure the options you want to use + + +## Available pytest options -To run the tests on your Ledger Nano S/X/SPlus, make sure you have the Solar application installed (see -[this page](https://developers.ledger.com/docs/nano-app/load/) for installing an -application on a Nano S) and opened on the device, and the device connected -through USB, without any other software interacting with it. Then run: +Standard useful pytest options +``` + -v formats the test summary in a readable way + -s enable logs for successful tests, on Speculos it will enable app logs if compiled with DEBUG=1 + -k only run the tests that contain in their names + --tb=short in case of errors, formats the test traceback in a readable way +``` -```shell -pytest tests/functional/ --hid +Custom pytest options +``` + --device run the test on the specified device [nanos,nanox,nanosp,stax,all]. This parameter is mandatory + --backend run the tests against the backend [speculos, ledgercomm, ledgerwallet]. Speculos is the default + --display on Speculos, enables the display of the app screen using QT + --golden_run on Speculos, screen comparison functions will save the current screen instead of comparing + --log_apdu_file log all apdu exchanges to the file in parameter. The previous file content is erased ``` diff --git a/tests/functional/client/__init__.py b/tests/functional/application_client/__init__.py similarity index 100% rename from tests/functional/client/__init__.py rename to tests/functional/application_client/__init__.py diff --git a/tests/functional/application_client/py.typed b/tests/functional/application_client/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/tests/functional/application_client/solar_command_sender.py b/tests/functional/application_client/solar_command_sender.py new file mode 100644 index 00000000..95b05001 --- /dev/null +++ b/tests/functional/application_client/solar_command_sender.py @@ -0,0 +1,202 @@ +from enum import IntEnum +from typing import Generator, List, Optional, Union +from contextlib import contextmanager + +from application_client.solar_transaction import Transaction + +# from application_client.solar_utils import bip32_path_from_string + +from ragger.backend.interface import BackendInterface, RAPDU +from ragger.bip import pack_derivation_path + + +MAX_APDU_LEN: int = 255 + +CLA: int = 0xE0 + + +class P1(IntEnum): + # Parameter 1 for first APDU number. + P1_START = 0x00 + # Parameter 1 for maximum APDU number. + P1_MAX = 0x03 + # Parameter 1 for screen confirmation for GET_PUBLIC_KEY. + P1_CONFIRM = 0x01 + + +class P2(IntEnum): + # Parameter 2 for last APDU to receive. + P2_LAST = 0x00 + # Parameter 2 for more APDU to receive. + P2_MORE = 0x80 + + +class InsType(IntEnum): + GET_APP_NAME = 0xA1 + GET_VERSION = 0xA2 + GET_PUBLIC_KEY = 0xB1 + GET_ADDRESS = 0xB2 + SIGN_MESSAGE = 0xC1 + SIGN_TX = 0xC2 + + +class Errors(IntEnum): + SW_DENY = 0x6985 + SW_WRONG_P1P2 = 0x6A86 + SW_WRONG_DATA_LENGTH = 0x6A87 + SW_INS_NOT_SUPPORTED = 0x6D00 + SW_CLA_NOT_SUPPORTED = 0x6E00 + SW_WRONG_RESPONSE_LENGTH = 0xB000 + SW_DISPLAY_BIP32_PATH_FAIL = 0xB001 + SW_DISPLAY_ADDRESS_FAIL = 0xB002 + SW_DISPLAY_AMOUNT_FAIL = 0xB003 + SW_WRONG_TX_LENGTH = 0xB004 + SW_TX_PARSING_FAIL = 0xB005 + SW_TX_HASH_FAIL = 0xB006 + SW_BAD_STATE = 0xB007 + SW_SIGNATURE_FAIL = 0xB008 + + +def split_message(message: bytes, max_size: int) -> List[bytes]: + return [message[x : x + max_size] for x in range(0, len(message), max_size)] + + +class SolarCommandSender: + def __init__(self, backend: BackendInterface) -> None: + self.backend = backend + + def serialise( + self, + cla: int, + ins: Union[int, IntEnum], + p1: int = 0, + p2: int = 0, + data: bytes = b"", + ) -> bytes: + + ins = cast(int, ins.value) if isinstance(ins, IntEnum) else cast(int, ins) + + header: bytes = struct.pack( + "BBBBB", cla, ins, p1, p2, len(data) + ) # add Lc to APDU header + + if self.debug: + logging.info("header: %s", header.hex()) + logging.info("data: %s", data.hex()) + + return header + data + + def get_app_and_version(self) -> RAPDU: + return self.backend.exchange( + cla=0xB0, # specific CLA for BOLOS + ins=0x01, # specific INS for get_app_and_version + p1=P1.P1_START, + p2=P2.P2_LAST, + data=b"", + ) + + def get_version(self) -> RAPDU: + return self.backend.exchange( + cla=CLA, ins=InsType.GET_VERSION, p1=P1.P1_START, p2=P2.P2_LAST, data=b"" + ) + + def get_app_name(self) -> RAPDU: + return self.backend.exchange( + cla=CLA, ins=InsType.GET_APP_NAME, p1=P1.P1_START, p2=P2.P2_LAST, data=b"" + ) + + # def get_public_key(self, path: str) -> RAPDU: + def get_public_key(self, path: str, display: int = 0, chaincode: int = 0) -> RAPDU: + return self.backend.exchange( + cla=CLA, + ins=InsType.GET_PUBLIC_KEY, + p1=display, + p2=chaincode, + data=pack_derivation_path(path), + ) + + @contextmanager + def get_public_key_with_confirmation(self, path: str, chaincode: int = 0) -> RAPDU: + with self.backend.exchange_async( + cla=CLA, + ins=InsType.GET_PUBLIC_KEY, + p1=P1.P1_CONFIRM, + p2=chaincode, + data=pack_derivation_path(path), + ) as response: + yield response + + def get_address(self, path: str, display: int = 0, network: int = 0) -> RAPDU: + return self.backend.exchange( + cla=CLA, + ins=InsType.GET_ADDRESS, + p1=display, + p2=network, + data=pack_derivation_path(path), + ) + + @contextmanager + def get_address_with_confirmation(self, path: str, network: int = 0) -> RAPDU: + with self.backend.exchange_async( + cla=CLA, + ins=InsType.GET_ADDRESS, + p1=P1.P1_CONFIRM, + p2=network, + data=pack_derivation_path(path), + ) as response: + yield response + + @contextmanager + def sign_message(self, path: str, message: str) -> RAPDU: + msg: bytes = b"".join( + [len(message).to_bytes(2, byteorder="little"), bytes(message, "ascii")] + ) + + self.backend.exchange( + cla=CLA, + ins=InsType.SIGN_MESSAGE, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=pack_derivation_path(path), + ) + chunks = split_message(msg, MAX_APDU_LEN) + idx: int = P1.P1_START + 1 + + for chunk in chunks[:-1]: + self.backend.exchange( + cla=CLA, ins=InsType.SIGN_MESSAGE, p1=idx, p2=P2.P2_MORE, data=chunk + ) + idx += 1 + + with self.backend.exchange_async( + cla=CLA, ins=InsType.SIGN_MESSAGE, p1=idx, p2=P2.P2_LAST, data=chunks[-1] + ) as response: + yield response + + @contextmanager + def sign_transaction(self, path: str, transaction: Transaction) -> RAPDU: + tx: bytes = transaction.serialise() + + self.backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=pack_derivation_path(path), + ) + chunks = split_message(tx, MAX_APDU_LEN) + idx: int = P1.P1_START + 1 + + for chunk in chunks[:-1]: + self.backend.exchange( + cla=CLA, ins=InsType.SIGN_TX, p1=idx, p2=P2.P2_MORE, data=chunk + ) + idx += 1 + + with self.backend.exchange_async( + cla=CLA, ins=InsType.SIGN_TX, p1=idx, p2=P2.P2_LAST, data=chunks[-1] + ) as response: + yield response + + def get_async_response(self) -> Optional[RAPDU]: + return self.backend.last_async_response diff --git a/tests/functional/application_client/solar_response_unpacker.py b/tests/functional/application_client/solar_response_unpacker.py new file mode 100644 index 00000000..74c7739d --- /dev/null +++ b/tests/functional/application_client/solar_response_unpacker.py @@ -0,0 +1,91 @@ +from typing import Tuple +from struct import unpack + +# remainder, data_len, data +def pop_sized_buf_from_buffer(buffer:bytes, size:int) -> Tuple[bytes, bytes]: + return buffer[size:], buffer[0:size] + +# remainder, data_len, data +def pop_size_prefixed_buf_from_buf(buffer:bytes) -> Tuple[bytes, int, bytes]: + data_len = buffer[0] + return buffer[1+data_len:], data_len, buffer[1:data_len+1] + +# Unpack from response: +# response = app_name (var) +def unpack_get_app_name_response(response: bytes) -> str: + return response.decode("ascii") + +# Unpack from response: +# response = MAJOR (1) +# MINOR (1) +# PATCH (1) +def unpack_get_version_response(response: bytes) -> Tuple[int, int, int]: + assert len(response) == 3 + major, minor, patch = unpack("BBB", response) + return (major, minor, patch) + +# Unpack from response: +# response = format_id (1) +# app_name_raw_len (1) +# app_name_raw (var) +# version_raw_len (1) +# version_raw (var) +# unused_len (1) +# unused (var) +def unpack_get_app_and_version_response(response: bytes) -> Tuple[str, str]: + response, _ = pop_sized_buf_from_buffer(response, 1) + response, _, app_name_raw = pop_size_prefixed_buf_from_buf(response) + response, _, version_raw = pop_size_prefixed_buf_from_buf(response) + response, _, _ = pop_size_prefixed_buf_from_buf(response) + + assert len(response) == 0 + + return app_name_raw.decode("ascii"), version_raw.decode("ascii") + +# Unpack from response: +# response = pub_key_len (1) +# pub_key (var) +def unpack_get_public_key_response(response: bytes) -> Tuple[int, bytes]: + response, pub_key_len, pub_key = pop_size_prefixed_buf_from_buf(response) + + assert pub_key_len == 33 + assert len(response) == 0 + + return pub_key_len, pub_key + +# Unpack from response: +# response = pub_key_len (1) +# pub_key (var) +# chain_code_len (1) +# chain_code (var) +def unpack_get_public_key_chaincode_response(response: bytes) -> Tuple[int, bytes, int, bytes]: + response, pub_key_len, pub_key = pop_size_prefixed_buf_from_buf(response) + response, chain_code_len, chain_code = pop_size_prefixed_buf_from_buf(response) + + assert pub_key_len == 33 + assert chain_code_len == 32 + assert len(response) == 0 + + return pub_key_len, pub_key, chain_code_len, chain_code + +# Unpack from response: +# response = address_len (1) +# address (var) +def unpack_get_address_response(response: bytes) -> Tuple[int, str]: + response, address_len, address = pop_size_prefixed_buf_from_buf(response) + + assert address_len == 34 + + return address_len, address + +# Unpack from response: +# response = der_sig_len (1) +# der_sig (var) +# v (1) +def unpack_sign_tx_response(response: bytes) -> Tuple[int, bytes, int]: + response, der_sig_len, der_sig = pop_size_prefixed_buf_from_buf(response) + response, v = pop_sized_buf_from_buffer(response, 1) + + assert len(response) == 0 + + return der_sig_len, der_sig, int.from_bytes(v, byteorder='big') diff --git a/tests/functional/client/transaction.py b/tests/functional/application_client/solar_transaction.py similarity index 93% rename from tests/functional/client/transaction.py rename to tests/functional/application_client/solar_transaction.py index 99147bb5..4ef2ae11 100644 --- a/tests/functional/client/transaction.py +++ b/tests/functional/application_client/solar_transaction.py @@ -1,6 +1,6 @@ from typing import Union -from client.utils import write_varint, UINT64_MAX, UINT32_MAX, UINT16_MAX, UINT8_MAX +from application_client.solar_utils import write_varint, UINT64_MAX, UINT32_MAX, UINT16_MAX, UINT8_MAX class TransactionError(Exception): @@ -33,7 +33,7 @@ def __init__( self.startingByte: int = startingByte if not (0 <= self.network <= UINT8_MAX): - raise TransactionError(f"Bad netowrk: '{self.network}'!") + raise TransactionError(f"Bad network: '{self.network}'!") if not (0 <= self.version <= UINT8_MAX): raise TransactionError(f"Bad version: '{self.version}'!") diff --git a/tests/functional/client/utils.py b/tests/functional/application_client/solar_utils.py similarity index 77% rename from tests/functional/client/utils.py rename to tests/functional/application_client/solar_utils.py index 01a5e76a..efd1312b 100644 --- a/tests/functional/client/utils.py +++ b/tests/functional/application_client/solar_utils.py @@ -17,9 +17,12 @@ def bip32_path_from_string(path: str) -> List[bytes]: if "m" in splitted_path and splitted_path[0] == "m": splitted_path = splitted_path[1:] - return [int(p).to_bytes(4, byteorder="big") if "'" not in p - else (0x80000000 | int(p[:-1])).to_bytes(4, byteorder="big") - for p in splitted_path] + return [ + int(p).to_bytes(4, byteorder="big") + if "'" not in p + else (0x80000000 | int(p[:-1])).to_bytes(4, byteorder="big") + for p in splitted_path + ] def write_varint(n: int) -> bytes: @@ -38,8 +41,7 @@ def write_varint(n: int) -> bytes: raise ValueError(f"Can't write to varint: '{n}'!") -def read_varint(buf: BytesIO, - prefix: Optional[bytes] = None) -> int: +def read_varint(buf: BytesIO, prefix: Optional[bytes] = None) -> int: b: bytes = prefix if prefix else buf.read(1) if not b: @@ -59,14 +61,14 @@ def read(buf: BytesIO, size: int) -> bytes: b: bytes = buf.read(size) if len(b) < size: - raise ValueError(f"Cant read {size} bytes in buffer!") + raise ValueError(f"Can't read {size} bytes in buffer!") return b -def read_uint(buf: BytesIO, - bit_len: int, - byteorder: Literal['big', 'little'] = 'little') -> int: +def read_uint( + buf: BytesIO, bit_len: int, byteorder: Literal["big", "little"] = "little" +) -> int: size: int = bit_len // 8 b: bytes = buf.read(size) diff --git a/tests/functional/client/client_interface.py b/tests/functional/client/client_interface.py deleted file mode 100644 index 4ea91a10..00000000 --- a/tests/functional/client/client_interface.py +++ /dev/null @@ -1,106 +0,0 @@ -from abc import ABCMeta, abstractmethod - -from speculos.client import SpeculosClient, ApduException -from ledgercomm import Transport - - -class ClientInterface(metaclass=ABCMeta): - @abstractmethod - def apdu_exchange_with_buttons(self, cla, ins, p1, p2, cdata, n_screens): - ... - - @abstractmethod - def apdu_exchange_raw_with_buttons(self, raw, n_screens): - ... - - @abstractmethod - def apdu_exchange_raw(self, raw): - ... - - @abstractmethod - def apdu_exchange(self, cla, ins, p1, p2, cdata): - ... - - @abstractmethod - def start(self): - ... - - @abstractmethod - def close(self): - ... - - -class Speculos(ClientInterface): - def __init__(self, file_path: str, args, automatic) -> None: - self.client = SpeculosClient(app=file_path, args=args) - self.automatic = automatic - - def apdu_exchange_with_buttons(self, cla, ins, p1, p2, cdata, n_screens): - with self.client.apdu_exchange_nowait( - cla=cla, ins=ins, p1=p1, p2=p2, data=cdata - ) as exchange: - if self.automatic: - for _ in range(n_screens): - self.client.press_and_release("right") - # Approve - self.client.press_and_release("both") - return exchange.receive() - - def apdu_exchange_raw_with_buttons(self, raw, n_screens): - return self.apdu_exchange_with_buttons( - cla=raw[0] if len(raw) > 0 else b"", - ins=raw[1] if len(raw) > 1 else b"", - p1=raw[2] if len(raw) > 2 else b"", - p2=raw[3] if len(raw) > 3 else b"", - cdata=raw[5:] if len(raw) > 5 else b"", - n_screens=n_screens, - ) - - def apdu_exchange_raw(self, raw): - return self.client._apdu_exchange( - bytes.fromhex(raw) if isinstance(raw, str) else raw - ) - - def apdu_exchange(self, cla, ins, p1, p2, cdata): - return self.client.apdu_exchange(cla=cla, ins=ins, p1=p1, p2=p2, data=cdata) - - def start(self): - self.client.start() - - def close(self): - self.client.stop() - - -class Ledgercomm(ClientInterface): - def __init__(self) -> None: - self.transport = Transport(interface="hid", debug=True) - - def apdu_exchange_with_buttons(self, cla, ins, p1, p2, cdata, n_screens): - return self.apdu_exchange(cla, ins, p1, p2, cdata) - - def apdu_exchange_raw_with_buttons(self, raw, n_screens): - return self.apdu_exchange_raw(raw) - - def apdu_exchange_raw(self, raw): - sw, response = self.transport.exchange_raw(raw) - - if sw != 0x9000: - raise ApduException(sw=sw, data=response) - - return response - - def apdu_exchange(self, cla, ins, p1, p2, cdata): - sw, response = self.transport.exchange( - cla=cla, ins=ins, p1=p1, p2=p2, cdata=cdata - ) - - if sw != 0x9000: - raise ApduException(sw=sw, data=response) - - return response - - def start(self): - pass - - def close(self): - pass diff --git a/tests/functional/client/cmd.py b/tests/functional/client/cmd.py deleted file mode 100644 index e289b99c..00000000 --- a/tests/functional/client/cmd.py +++ /dev/null @@ -1,196 +0,0 @@ -import struct -from typing import Tuple - -from client.client_interface import ClientInterface -from speculos.client import ApduException - -from client.cmd_builder import CommandBuilder, InsType -from client.exception import DeviceException -from client.transaction import Transaction - - -class Command: - def __init__(self, transport: ClientInterface, debug: bool = False) -> None: - self.transport = transport - self.builder = CommandBuilder(debug=debug) - self.debug = debug - - def get_app_and_version(self) -> Tuple[str, str]: - try: - response = self.transport.apdu_exchange_raw( - self.builder.get_app_and_version() - ) # type: int, bytes - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=0x01) - - # response = format_id (1) || - # app_name_len (1) || - # app_name (var) || - # version_len (1) || - # version (var) || - offset: int = 0 - - format_id: int = response[offset] - offset += 1 - app_name_len: int = response[offset] - offset += 1 - app_name: str = response[offset : offset + app_name_len].decode("ascii") - offset += app_name_len - version_len: int = response[offset] - offset += 1 - version: str = response[offset : offset + version_len].decode("ascii") - offset += version_len - - return app_name, version - - def get_version(self) -> Tuple[int, int, int]: - try: - response = self.transport.apdu_exchange_raw( - self.builder.get_version() - ) # type: int, bytes - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_GET_VERSION) - - # response = MAJOR (1) || MINOR (1) || PATCH (1) - assert len(response) == 3 - - major, minor, patch = struct.unpack("BBB", response) # type: int, int, int - - return major, minor, patch - - def get_app_name(self) -> str: - try: - response = self.transport.apdu_exchange_raw( - self.builder.get_app_name() - ) # type: int, bytes - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_GET_APP_NAME) - - return response.decode("ascii") - - def get_public_key( - self, - bip32_path: str, - display: int = False, - chaincode: int = False, - n_screens: int = 0, - ) -> Tuple[bytes, bytes]: - try: - response = self.transport.apdu_exchange_raw_with_buttons( - self.builder.get_public_key( - bip32_path=bip32_path, display=display, chaincode=chaincode - ), - n_screens, - ) # type: int, bytes - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_GET_PUBLIC_KEY) - - # response = pub_key_len (1) || - # pub_key (var) || - # chain_code_len (1) || - # chain_code (var) - offset: int = 0 - - pub_key_len: int = response[offset] - offset += 1 - pub_key: bytes = response[offset : offset + pub_key_len] - offset += pub_key_len - - chain_code_len: int = 0 - chain_code: bytes = {} - - if chaincode: - chain_code_len = response[offset] - offset += 1 - chain_code = response[offset : offset + chain_code_len] - offset += chain_code_len - - assert len(response) == 1 + pub_key_len + ( - (1 + chain_code_len) if chaincode else 0 - ) - - return pub_key, chain_code - - def get_address( - self, - bip32_path: str, - display: int = False, - network: int = 0, - n_screens: int = 0, - ) -> Tuple[bytes, bytes]: - try: - response = self.transport.apdu_exchange_raw_with_buttons( - self.builder.get_address( - bip32_path=bip32_path, display=display, network=network - ), - n_screens, - ) # type: int, bytes - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_GET_ADDRESS) - - # response = address_len(1), address_string(34) - offset: int = 0 - - address_len: int = response[offset] - offset += 1 - address: bytes = response[offset : offset + address_len] - offset += address_len - - assert len(response) == 1 + address_len - - return address - - def sign_tx( - self, - bip32_path: str, - transaction: Transaction, - n_screens: int = 0, - ) -> Tuple[int, bytes]: - response: bytes = b"" - - for is_last, chunk in self.builder.sign_tx( - bip32_path=bip32_path, transaction=transaction - ): - try: - response = self.transport.apdu_exchange_raw_with_buttons( - chunk, - n_screens if is_last else 0, - ) # type: int, bytes - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - # response = schnorr_sig_len (1) || - # schnorr_sig (var) || - # v (1) - - schnorr_sig: bytes = response - - assert len(response) == 64 - - return schnorr_sig - - def sign_message( - self, bip32_path: str, message: str, n_screens: int = 0 - ) -> Tuple[int, bytes]: - response: bytes = b"" - - for is_last, chunk in self.builder.sign_message( - bip32_path=bip32_path, message=message - ): - try: - response = self.transport.apdu_exchange_raw_with_buttons( - chunk, - n_screens if is_last else 0, - ) # type: int, bytes - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_MESSAGE) - - # response = schnorr_sig_len (1) || - # schnorr_sig (var) || - # v (1) - - schnorr_sig: bytes = response - - assert len(response) == 64 - - return schnorr_sig diff --git a/tests/functional/client/cmd_builder.py b/tests/functional/client/cmd_builder.py deleted file mode 100644 index 40ba3c11..00000000 --- a/tests/functional/client/cmd_builder.py +++ /dev/null @@ -1,304 +0,0 @@ -import enum -import logging -import struct -from typing import List, Tuple, Union, Iterator, cast - -from client.transaction import Transaction -from client.utils import bip32_path_from_string - -MAX_APDU_LEN: int = 255 - - -def chunkify(data: bytes, chunk_len: int) -> Iterator[Tuple[bool, bytes]]: - size: int = len(data) - - if size <= chunk_len: - yield True, data - return - - remainder: int = size % chunk_len - chunk: int = size // chunk_len if remainder == 0 else (size // chunk_len) + 1 - offset: int = 0 - - for i in range(chunk - 1): - yield False, data[offset : offset + chunk_len] - offset += chunk_len - - yield True, data[offset:] - - -class InsType(enum.IntEnum): - INS_GET_APP_NAME = 0xA1 - INS_GET_VERSION = 0xA2 - INS_GET_PUBLIC_KEY = 0xB1 - INS_GET_ADDRESS = 0xB2 - INS_SIGN_MESSAGE = 0xC1 - INS_SIGN_TX = 0xC2 - - -class CommandBuilder: - """APDU command builder for the Solar application. - - Parameters - ---------- - debug: bool - Whether you want to see logging or not. - - Attributes - ---------- - debug: bool - Whether you want to see logging or not. - - """ - - CLA: int = 0xE0 - - def __init__(self, debug: bool = False): - """Init constructor.""" - self.debug = debug - - def serialise( - self, - cla: int, - ins: Union[int, enum.IntEnum], - p1: int = 0, - p2: int = 0, - cdata: bytes = b"", - ) -> bytes: - """Serialise the whole APDU command (header + data). - - Parameters - ---------- - cla : int - Instruction class: CLA (1 byte) - ins : Union[int, IntEnum] - Instruction code: INS (1 byte) - p1 : int - Instruction parameter 1: P1 (1 byte). - p2 : int - Instruction parameter 2: P2 (1 byte). - cdata : bytes - Bytes of command data. - - Returns - ------- - bytes - Bytes of a complete APDU command. - - """ - ins = cast(int, ins.value) if isinstance(ins, enum.IntEnum) else cast(int, ins) - - header: bytes = struct.pack( - "BBBBB", cla, ins, p1, p2, len(cdata) - ) # add Lc to APDU header - - if self.debug: - logging.info("header: %s", header.hex()) - logging.info("cdata: %s", cdata.hex()) - - return header + cdata - - def get_app_and_version(self) -> bytes: - """Command builder for GET_APP_AND_VERSION (builtin in BOLOS SDK). - - Returns - ------- - bytes - APDU command for GET_APP_AND_VERSION. - - """ - return self.serialise( - cla=0xB0, ins=0x01, p1=0x00, p2=0x00, cdata=b"" # specific CLA for BOLOS - ) - - def get_app_name(self) -> bytes: - """Command builder for GET_APP_NAME. - - Returns - ------- - bytes - APDU command for GET_APP_NAME. - - """ - return self.serialise( - cla=self.CLA, ins=InsType.INS_GET_APP_NAME, p1=0x00, p2=0x00, cdata=b"" - ) - - def get_version(self) -> bytes: - """Command builder for GET_VERSION. - - Returns - ------- - bytes - APDU command for GET_VERSION. - - """ - return self.serialise( - cla=self.CLA, ins=InsType.INS_GET_VERSION, p1=0x00, p2=0x00, cdata=b"" - ) - - def get_public_key( - self, bip32_path: str, display: int = 0, chaincode: int = 0 - ) -> bytes: - """Command builder for GET_PUBLIC_KEY. - - Parameters - ---------- - bip32_path: str - String representation of BIP32 path. - display : bool - Whether you want to display the public key on the device. - chaincode : bool - Whether you want to include the chain code in the response. - - Returns - ------- - bytes - APDU command for GET_PUBLIC_KEY. - - """ - bip32_paths: List[bytes] = bip32_path_from_string(bip32_path) - - cdata: bytes = b"".join( - [len(bip32_paths).to_bytes(1, byteorder="big"), *bip32_paths] - ) - - return self.serialise( - cla=self.CLA, - ins=InsType.INS_GET_PUBLIC_KEY, - p1=display, - p2=chaincode, - cdata=cdata, - ) - - def get_address(self, bip32_path: str, display: int = 0, network: int = 0) -> bytes: - """Command builder for GET_ADDRESS. - - Parameters - ---------- - bip32_path: str - String representation of BIP32 path. - display : bool - Whether you want to display the public key on the device. - network : bool - Which network the publicKey should be encoded for. - - Returns - ------- - bytes - APDU command for GET_ADDRESS. - - """ - bip32_paths: List[bytes] = bip32_path_from_string(bip32_path) - - cdata: bytes = b"".join( - [len(bip32_paths).to_bytes(1, byteorder="big"), *bip32_paths] - ) - - return self.serialise( - cla=self.CLA, - ins=InsType.INS_GET_ADDRESS, - p1=display, - p2=network, - cdata=cdata, - ) - - def sign_message( - self, bip32_path: str, message: str - ) -> Iterator[Tuple[bool, bytes]]: - """Command builder for INS_SIGN_TX. - - Parameters - ---------- - bip32_path : str - String representation of BIP32 path. - message : str - Message to be signed. - - Yields - ------- - bytes - APDU command chunk for INS_SIGN_MESSAGE. - - """ - bip32_paths: List[bytes] = bip32_path_from_string(bip32_path) - - cdata: bytes = b"".join( - [len(bip32_paths).to_bytes(1, byteorder="big"), *bip32_paths] - ) - - yield False, self.serialise( - cla=self.CLA, ins=InsType.INS_SIGN_MESSAGE, p1=0x00, p2=0x80, cdata=cdata - ) - - tx: bytes = b"".join( - [len(message).to_bytes(2, byteorder="little"), bytes(message, "ascii")] - ) - - for i, (is_last, chunk) in enumerate(chunkify(tx, MAX_APDU_LEN)): - if is_last: - yield True, self.serialise( - cla=self.CLA, - ins=InsType.INS_SIGN_MESSAGE, - p1=i + 1, - p2=0x00, - cdata=chunk, - ) - return - else: - yield False, self.serialise( - cla=self.CLA, - ins=InsType.INS_SIGN_MESSAGE, - p1=i + 1, - p2=0x80, - cdata=chunk, - ) - - def sign_tx( - self, bip32_path: str, transaction: Transaction - ) -> Iterator[Tuple[bool, bytes]]: - """Command builder for INS_SIGN_TX. - - Parameters - ---------- - bip32_path : str - String representation of BIP32 path. - transaction : Transaction - Representation of the transaction to be signed. - - Yields - ------- - bytes - APDU command chunk for INS_SIGN_TX. - - """ - bip32_paths: List[bytes] = bip32_path_from_string(bip32_path) - - cdata: bytes = b"".join( - [len(bip32_paths).to_bytes(1, byteorder="big"), *bip32_paths] - ) - - yield False, self.serialise( - cla=self.CLA, ins=InsType.INS_SIGN_TX, p1=0x00, p2=0x80, cdata=cdata - ) - - tx: bytes = transaction.serialise() - - for i, (is_last, chunk) in enumerate(chunkify(tx, MAX_APDU_LEN)): - if is_last: - yield True, self.serialise( - cla=self.CLA, - ins=InsType.INS_SIGN_TX, - p1=i + 1, - p2=0x00, - cdata=chunk, - ) - return - else: - yield False, self.serialise( - cla=self.CLA, - ins=InsType.INS_SIGN_TX, - p1=i + 1, - p2=0x80, - cdata=chunk, - ) diff --git a/tests/functional/client/exception/__init__.py b/tests/functional/client/exception/__init__.py deleted file mode 100644 index 4f791324..00000000 --- a/tests/functional/client/exception/__init__.py +++ /dev/null @@ -1,39 +0,0 @@ -from .device_exception import DeviceException -from .errors import (UnknownDeviceError, - DenyError, - WrongP1P2Error, - WrongDataLengthError, - InsNotSupportedError, - ClaNotSupportedError, - WrongResponseLengthError, - DisplayBip32PathFailError, - DisplayPublicKeyFailError, - DisplayAmountFailError, - WrongTxLengthError, - TxParsingFailError, - TxHashFail, - BadStateError, - SignatureFailError, - OutOfOrderReqError, - DisplayAddressFailError) - -__all__ = [ - "DeviceException", - "DenyError", - "UnknownDeviceError", - "WrongP1P2Error", - "WrongDataLengthError", - "InsNotSupportedError", - "ClaNotSupportedError", - "WrongResponseLengthError", - "DisplayBip32PathFailError", - "DisplayPublicKeyFailError", - "DisplayAmountFailError", - "WrongTxLengthError", - "TxParsingFailError", - "TxHashFail", - "BadStateError", - "SignatureFailError", - "OutOfOrderReqError", - "DisplayAddressFailError" -] diff --git a/tests/functional/client/exception/device_exception.py b/tests/functional/client/exception/device_exception.py deleted file mode 100644 index 160ae049..00000000 --- a/tests/functional/client/exception/device_exception.py +++ /dev/null @@ -1,41 +0,0 @@ -import enum -from typing import Dict, Any, Union - -from .errors import * - - -class DeviceException(Exception): # pylint: disable=too-few-public-methods - exc: Dict[int, Any] = { - 0x6985: DenyError, - 0x6A86: WrongP1P2Error, - 0x6A87: WrongDataLengthError, - 0x6D00: InsNotSupportedError, - 0x6E00: ClaNotSupportedError, - 0xB000: WrongResponseLengthError, - 0xB001: DisplayBip32PathFailError, - 0xB002: DisplayPublicKeyFailError, - 0xB003: DisplayAmountFailError, - 0xB004: WrongTxLengthError, - 0xB005: TxParsingFailError, - 0xB006: TxHashFail, - 0xB007: BadStateError, - 0xB008: SignatureFailError, - 0xB009: OutOfOrderReqError, - 0xB010: EncodeAddressFailError, - 0xB011: DisplayAddressFailError, - } - - def __new__(cls, - error_code: int, - ins: Union[int, enum.IntEnum, None] = None, - message: str = "" - ) -> Any: - error_message: str = (f"Error in {ins!r} command" - if ins else "Error in command") - - if error_code in DeviceException.exc: - return DeviceException.exc[error_code](hex(error_code), - error_message, - message) - - return UnknownDeviceError(hex(error_code), error_message, message) diff --git a/tests/functional/client/exception/errors.py b/tests/functional/client/exception/errors.py deleted file mode 100644 index a16c778c..00000000 --- a/tests/functional/client/exception/errors.py +++ /dev/null @@ -1,67 +0,0 @@ -class UnknownDeviceError(Exception): - pass - - -class DenyError(Exception): - pass - - -class WrongP1P2Error(Exception): - pass - - -class WrongDataLengthError(Exception): - pass - - -class InsNotSupportedError(Exception): - pass - - -class ClaNotSupportedError(Exception): - pass - - -class WrongResponseLengthError(Exception): - pass - - -class DisplayBip32PathFailError(Exception): - pass - - -class DisplayPublicKeyFailError(Exception): - pass - - -class DisplayAmountFailError(Exception): - pass - - -class WrongTxLengthError(Exception): - pass - - -class TxParsingFailError(Exception): - pass - - -class TxHashFail(Exception): - pass - - -class BadStateError(Exception): - pass - - -class SignatureFailError(Exception): - pass - -class OutOfOrderReqError(Exception): - pass - -class DisplayAddressFailError(Exception): - pass - -class EncodeAddressFailError(Exception): - pass diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py index 8442c9c4..909ec8bf 100644 --- a/tests/functional/conftest.py +++ b/tests/functional/conftest.py @@ -1,63 +1,15 @@ -from pathlib import Path +from ragger.conftest import configuration -import pytest +########################### +### CONFIGURATION START ### +########################### -from client.client_interface import Speculos, Ledgercomm -from client.cmd import Command +# You can configure optional parameters by overriding the value of ragger.configuration.OPTIONAL_CONFIGURATION +# Please refer to ragger/conftest/configuration.py for their descriptions and accepted values -SCRIPT_DIR = Path(__file__).absolute().parent +######################### +### CONFIGURATION END ### +######################### - -def pytest_addoption(parser): - parser.addoption("--hid", action="store_true") - parser.addoption("--headless", action="store_true") - parser.addoption("--manual", action="store_true") - - -@pytest.fixture(scope="module") -def sw_h_path(): - # path with tests - conftest_folder_path: Path = Path(__file__).parent - # sw.h should be in ../../src/sw.h - sw_h_path = conftest_folder_path.parent.parent / "src" / "sw.h" - - if not sw_h_path.is_file(): - raise FileNotFoundError(f"Can't find sw.h: '{sw_h_path}'") - - return sw_h_path - - -@pytest.fixture(scope="session") -def hid(pytestconfig): - return pytestconfig.getoption("hid") - - -@pytest.fixture(scope="session") -def headless(pytestconfig): - return pytestconfig.getoption("headless") - - -@pytest.fixture(scope="session") -def manual(pytestconfig): - return pytestconfig.getoption("manual") - - -@pytest.fixture(scope="session") -def cmd(hid, headless, manual): - file_path = SCRIPT_DIR.parent.parent / "bin" / "app.elf" - args = ["--model", "nanos", "--sdk", "2.1"] - if headless: - manual = False - else: - args.append("--display") - args.append("qt") - - transport = ( - Ledgercomm() - if hid - else Speculos(file_path=str(file_path), args=args, automatic=not manual) - ) - command = Command(transport=transport, debug=True) - command.transport.start() - yield command - command.transport.close() +# Pull all features from the base ragger conftest using the overridden configuration +pytest_plugins = ("ragger.conftest.base_conftest", ) diff --git a/tests/functional/constants.py b/tests/functional/constants.py new file mode 100644 index 00000000..4348e562 --- /dev/null +++ b/tests/functional/constants.py @@ -0,0 +1,7 @@ + +NETWORK_MAINNET: int = 0x3F +NETWORK_TESTNET: int = 0x1E +NETWORKS: [int] = [NETWORK_MAINNET, NETWORK_TESTNET] + +PATH_MAINNET: str = "m/44'/3333'/0'/0/0" +PATH_TESTNET: str = "m/44'/1'/0'/0/0" diff --git a/tests/functional/requirements.txt b/tests/functional/requirements.txt index 2b2c5e78..085b7583 100644 --- a/tests/functional/requirements.txt +++ b/tests/functional/requirements.txt @@ -1,4 +1,8 @@ -speculos -pytest>=6.1.1,<7.0.0 +pytest btclib -ledgercomm[hid] +ragger[speculos]>=1.6.0 +ragger[ledgerwallet]>=1.6.0 +Jinja2==3.1.2 +Flask==2.1.2 +ecdsa>=0.16.1,<0.17.0 +pysha3>=1.0.0,<2.0.0 diff --git a/tests/functional/setup.cfg b/tests/functional/setup.cfg index c79fd882..7d0d7e30 100644 --- a/tests/functional/setup.cfg +++ b/tests/functional/setup.cfg @@ -8,10 +8,11 @@ disable = C0114, # missing-module-docstring C0103, # invalid-name R0801, # duplicate-code R0913 # too-many-arguments +max-line-length=100 extension-pkg-whitelist=hid [pycodestyle] -max-line-length = 90 +max-line-length = 100 [mypy-hid.*] ignore_missing_imports = True diff --git a/tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00000.png b/tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..0e647232672da686d01091e623185997888ca452 GIT binary patch literal 359 zcmV-t0hs=YP)$-~WL<*h4xt4L>Si!`l6(heAsxZXgg0fe=E-zcP6{P|Lb}zE88CAFTie zKufQ|3}Hz_Tv^4(e{qo@#os`*_LplFK>eKNkk- z&QoI#c3yJ-x76)?_0Vw&Hd>+I(? zq$+x>0CB=>N)=mWBW5y+0}_l_qg~-*|Hs{g2_b}F@&Y&g#@?_l)gu4^002ovPDHLk FV1l=KnBo8c literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00001.png b/tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..94281378b25ef6dca3e418d4c918f36fa5054ec7 GIT binary patch literal 495 zcmV}+)_AVo7ZVZClmLpND2gJNed}vdo}V0j-x%eG~wR<78E!iw1>2vr^OhEPoGWx3V@%q%5w_J*=tjH zlH?UY7x*DzePlZB{DA)@+y*txqup;(`jK2Ta;`ONDN?Ih z+mTcaloLEQC>_}!A$4i1W86h7q|T!VyK-F7z|yXG<_(Trc2bTz^4%8z)(&M6}0M4n0YF=P@Hv3L5ZShfKDP;^3Uq^Q_j_SI-;yB}db~OZ6 z@!Vm%?~7Ol8SBgw74{Y4!w~?_DM+%?6gG>^`Y6g!<(-TqCg-rRdk(VAImCb^g-!Hb l^^y-Vg-ivYD2n3$@&(P6V9l1tqRhr8;4fN%h%xSEWSUR^o9xgXz&<+$QNrw-NioJEvmdWe=>P!h zve)A@cW|Z}Ad8A(5_$%JY3^gEnM;nKj{cytrJOt^$3S9AjTz~Hir)e7UsiE$qncGp zc(CXLz!WQ2VM(bjoV7okhkWz>#_d%1XjB9~GWsx50yLRVjsAcz zq0Z=EOy=ND@)Ww0Ztr3CQcC-d^r9~fQUloDWL2-^j^2~d8+KJ#y+?obj-&^BAoM|H z87r`30@wsgi>p*yRUB$7Lb_fKcA0dtU9yb5qYd`f22BB}^@8Y~P`XUo{V{?hBdZj> zXZvyXm8?m}^lZ;(@)6mL(+fxH7PKSPspW$uojzk|3D!1Ba{`pK(;Xui;c?hiZXb2< zeNu-u3RU9U(ba;|PZ)~?he?X|Yq{?y$s^;u-f6PgZy(qGX!8_;Le?gBj2#e-`)!f@ g0C^TAN%FJ20WNfxhxR08t^fc407*qoM6N<$f`Am_h5!Hn literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00003.png b/tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..a16583ff484fa169783c06315f311dd13dba2b0e GIT binary patch literal 336 zcmV-W0k8gvP)@XwH{jw9p_Ps7;gz0002c_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00005.png b/tests/functional/snapshots/nanos/test_get_address_confirm_accepted/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3$-~WL<*h4xt4L>Si!`l6(heAsxZXgg0fe=E-zcP6{P|Lb}zE88CAFTie zKufQ|3}Hz_Tv^4(e{qo@#os`*_LplFK>eKNkk- z&QoI#c3yJ-x76)?_0Vw&Hd>+I(? zq$+x>0CB=>N)=mWBW5y+0}_l_qg~-*|Hs{g2_b}F@&Y&g#@?_l)gu4^002ovPDHLk FV1l=KnBo8c literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_address_confirm_refused/00001.png b/tests/functional/snapshots/nanos/test_get_address_confirm_refused/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..94281378b25ef6dca3e418d4c918f36fa5054ec7 GIT binary patch literal 495 zcmV}+)_AVo7ZVZClmLpND2gJNed}vdo}V0j-x%eG~wR<78E!iw1>2vr^OhEPoGWx3V@%q%5w_J*=tjH zlH?UY7x*DzePlZB{DA)@+y*txqup;(`jK2Ta;`ONDN?Ih z+mTcaloLEQC>_}!A$4i1W86h7q|T!VyK-F7z|yXG<_(Trc2bTz^4%8z)(&M6}0M4n0YF=P@Hv3L5ZShfKDP;^3Uq^Q_j_SI-;yB}db~OZ6 z@!Vm%?~7Ol8SBgw74{Y4!w~?_DM+%?6gG>^`Y6g!<(-TqCg-rRdk(VAImCb^g-!Hb l^^y-Vg-ivYD2n3$@&(P6V9l1tqRhr8;4fN%h%xSEWSUR^o9xgXz&<+$QNrw-NioJEvmdWe=>P!h zve)A@cW|Z}Ad8A(5_$%JY3^gEnM;nKj{cytrJOt^$3S9AjTz~Hir)e7UsiE$qncGp zc(CXLz!WQ2VM(bjoV7okhkWz>#_d%1XjB9~GWsx50yLRVjsAcz zq0Z=EOy=ND@)Ww0Ztr3CQcC-d^r9~fQUloDWL2-^j^2~d8+KJ#y+?obj-&^BAoM|H z87r`30@wsgi>p*yRUB$7Lb_fKcA0dtU9yb5qYd`f22BB}^@8Y~P`XUo{V{?hBdZj> zXZvyXm8?m}^lZ;(@)6mL(+fxH7PKSPspW$uojzk|3D!1Ba{`pK(;Xui;c?hiZXb2< zeNu-u3RU9U(ba;|PZ)~?he?X|Yq{?y$s^;u-f6PgZy(qGX!8_;Le?gBj2#e-`)!f@ g0C^TAN%FJ20WNfxhxR08t^fc407*qoM6N<$f`Am_h5!Hn literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_address_confirm_refused/00003.png b/tests/functional/snapshots/nanos/test_get_address_confirm_refused/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..a16583ff484fa169783c06315f311dd13dba2b0e GIT binary patch literal 336 zcmV-W0k8gvP)@XwH{jw9p_Ps7;gz0002c_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_address_confirm_refused/00005.png b/tests/functional/snapshots/nanos/test_get_address_confirm_refused/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..9c7e7049cb3e9bcfb1601ec510ee465d38229d4d GIT binary patch literal 340 zcmV-a0jvIrP)b=%MgRq*37h4eRxPbkJCLY|1VIo49_}P}TKpH4$L<8?X{t;p zy+UQc_4@p%0?~E_&igM#?#L~IOHR(-<@sYotiy&C*Y&GII0yeh-p3zW9cv$Q0k>6Y_)5~SfP=m zSMUtz)%Ex|-o}7!H9hbQ(8{%C?kQVa?C`*Uj-J(h>P7(Y#?ZWvi?6}@n{fGLp>YTp myqR(V_$?>^<%seR_VWh!s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3U%=<@d-KSaORm-+!GG{X4Eq0P8-y6 zlQTOr{sTMEuS?qj{SBR?{?lBem_+0&@_C{ZO2RRgq_;x3s%Tp4Pjeh~UVF*FWBJ4C z?un_^W;7M!r4~f(hZ_}#8_f$h1H3rs2i{Y`J_7E;WgB66jEh<58psZ~az!Qg!9lIt zm!tjv1e{Rcr{Z1v>~9~daFr%SX zf>+)%s&R=@^kBU{en(tfudL+#<`CvJ)QfQu7eptZrgd<@v%-tjVJgC6ODlp*{*I@4 z5NfR7STt)9E*hpDv*4IM1K*tdg=l$F-0FQ~wkp@7P>enA(Fqv&sMa|Mw=Sw#hulOb zU@+=)Ag(S460_gf=gAn70Q{x}ceU@PaFj*sg(C&hMn<_~nd;VWodbA{_fYHKc#)Ss zqu=^i&==D8o&9O=NO5dhU%!>i!I}I@6`GURAg{{h@*WmVwA$pEGJAX5V!Zc$s94ABuSDaN%GtL Y1E0=xOGvy%y8r+H07*qoM6N<$g4YS&P5=M^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00002.png b/tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..ac25c21ea9367495296913fdaaee2b90767ac257 GIT binary patch literal 481 zcmV<70UrK|P)71`u-2xi|uB$4)FIEH8maI*~N}QAP@f8IEo1>!%Vqcqjj*3hl|?ARoqM-Jku+s`s;aX^Sqfw!K^zi&`64Vf27o z&^;^TL#p33X`-Xe85|JSh9@;it&JQRF}ujUO+zClEWFduxecpU8VaBhFMdL-JW<_RePxcjTme2)rMc$k-uLJPoLQJ@FdkLwGEHUXqFUf3-O#8$%&cCR?;F5}~LwBvbR2h5`YA8J+n9rU+zN*J2r-jhKk-3#p$zcKB5!tDrC;%)+WbL&F#^l)8J6O jO(~H`Boc{4;tF^G9;}cA;}g)@00000NkvXXu0mjfpYPn3 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00004.png b/tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..ec00557e127218f10d70b2be2e0eb80cee26619a GIT binary patch literal 475 zcmV<10VMv3P)J?9MA0UQH|b&#(}zguJ`2o1o_koy3P zHZd^$5U0u_GeLd; zA%FJnANg^JwH#dpKxk)pM%1}GFEaQqroDIl4tCpdh39<~8|E{r@p{h~*AVpCWMNt%m#uIFSW@uwa Rgf{>H002ovPDHLkV1oR+)ocI& literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00005.png b/tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00006.png b/tests/functional/snapshots/nanos/test_get_public_key_chaincode_confirm_accepted/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3U%=<@d-KSaORm-+!GG{X4Eq0P8-y6 zlQTOr{sTMEuS?qj{SBR?{?lBem_+0&@_C{ZO2RRgq_;x3s%Tp4Pjeh~UVF*FWBJ4C z?un_^W;7M!r4~f(hZ_}#8_f$h1H3rs2i{Y`J_7E;WgB66jEh<58psZ~az!Qg!9lIt zm!tjv1e{Rcr{Z1v>~9~daFr%SX zf>+)%s&R=@^kBU{en(tfudL+#<`CvJ)QfQu7eptZrgd<@v%-tjVJgC6ODlp*{*I@4 z5NfR7STt)9E*hpDv*4IM1K*tdg=l$F-0FQ~wkp@7P>enA(Fqv&sMa|Mw=Sw#hulOb zU@+=)Ag(S460_gf=gAn70Q{x}ceU@PaFj*sg(C&hMn<_~nd;VWodbA{_fYHKc#)Ss zqu=^i&==D8o&9O=NO5dhU%!>i!I}I@6`GURAg{{h@*WmVwA$pEGJAX5V!Zc$s94ABuSDaN%GtL Y1E0=xOGvy%y8r+H07*qoM6N<$g4YS&P5=M^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00002.png b/tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..ac25c21ea9367495296913fdaaee2b90767ac257 GIT binary patch literal 481 zcmV<70UrK|P)71`u-2xi|uB$4)FIEH8maI*~N}QAP@f8IEo1>!%Vqcqjj*3hl|?ARoqM-Jku+s`s;aX^Sqfw!K^zi&`64Vf27o z&^;^TL#p33X`-Xe85|JSh9@;it&JQRF}ujUO+zClEWFduxecpU8VaBhFMdL-JW<_RePxcjTme2)rMc$k-uLJPoLQJ@FdkLwGEHUXqFUf3-O#8$%&cCR?;F5}~LwBvbR2h5`YA8J+n9rU+zN*J2r-jhKk-3#p$zcKB5!tDrC;%)+WbL&F#^l)8J6O jO(~H`Boc{4;tF^G9;}cA;}g)@00000NkvXXu0mjfpYPn3 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00004.png b/tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..ec00557e127218f10d70b2be2e0eb80cee26619a GIT binary patch literal 475 zcmV<10VMv3P)J?9MA0UQH|b&#(}zguJ`2o1o_koy3P zHZd^$5U0u_GeLd; zA%FJnANg^JwH#dpKxk)pM%1}GFEaQqroDIl4tCpdh39<~8|E{r@p{h~*AVpCWMNt%m#uIFSW@uwa Rgf{>H002ovPDHLkV1oR+)ocI& literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00005.png b/tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00006.png b/tests/functional/snapshots/nanos/test_get_public_key_confirm_refused/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..9c7e7049cb3e9bcfb1601ec510ee465d38229d4d GIT binary patch literal 340 zcmV-a0jvIrP)b=%MgRq*37h4eRxPbkJCLY|1VIo49_}P}TKpH4$L<8?X{t;p zy+UQc_4@p%0?~E_&igM#?#L~IOHR(-<@sYotiy&C*Y&GII0yeh-p3zW9cv$Q0k>6Y_)5~SfP=m zSMUtz)%Ex|-o}7!H9hbQ(8{%C?kQVa?C`*Uj-J(h>P7(Y#?ZWvi?6}@n{fGLp>YTp myqR(V_$?>^<%seR_VWh!s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3U%=<@d-KSaORm-+!GG{X4Eq0P8-y6 zlQTOr{sTMEuS?qj{SBR?{?lBem_+0&@_C{ZO2RRgq_;x3s%Tp4Pjeh~UVF*FWBJ4C z?un_^W;7M!r4~f(hZ_}#8_f$h1H3rs2i{Y`J_7E;WgB66jEh<58psZ~az!Qg!9lIt zm!tjv1e{Rcr{Z1v>~9~daFr%SX zf>+)%s&R=@^kBU{en(tfudL+#<`CvJ)QfQu7eptZrgd<@v%-tjVJgC6ODlp*{*I@4 z5NfR7STt)9E*hpDv*4IM1K*tdg=l$F-0FQ~wkp@7P>enA(Fqv&sMa|Mw=Sw#hulOb zU@+=)Ag(S460_gf=gAn70Q{x}ceU@PaFj*sg(C&hMn<_~nd;VWodbA{_fYHKc#)Ss zqu=^i&==D8o&9O=NO5dhU%!>i!I}I@6`GURAg{{h@*WmVwA$pEGJAX5V!Zc$s94ABuSDaN%GtL Y1E0=xOGvy%y8r+H07*qoM6N<$g4YS&P5=M^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00002.png b/tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..ac25c21ea9367495296913fdaaee2b90767ac257 GIT binary patch literal 481 zcmV<70UrK|P)71`u-2xi|uB$4)FIEH8maI*~N}QAP@f8IEo1>!%Vqcqjj*3hl|?ARoqM-Jku+s`s;aX^Sqfw!K^zi&`64Vf27o z&^;^TL#p33X`-Xe85|JSh9@;it&JQRF}ujUO+zClEWFduxecpU8VaBhFMdL-JW<_RePxcjTme2)rMc$k-uLJPoLQJ@FdkLwGEHUXqFUf3-O#8$%&cCR?;F5}~LwBvbR2h5`YA8J+n9rU+zN*J2r-jhKk-3#p$zcKB5!tDrC;%)+WbL&F#^l)8J6O jO(~H`Boc{4;tF^G9;}cA;}g)@00000NkvXXu0mjfpYPn3 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00004.png b/tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..ec00557e127218f10d70b2be2e0eb80cee26619a GIT binary patch literal 475 zcmV<10VMv3P)J?9MA0UQH|b&#(}zguJ`2o1o_koy3P zHZd^$5U0u_GeLd; zA%FJnANg^JwH#dpKxk)pM%1}GFEaQqroDIl4tCpdh39<~8|E{r@p{h~*AVpCWMNt%m#uIFSW@uwa Rgf{>H002ovPDHLkV1oR+)ocI& literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00005.png b/tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00006.png b/tests/functional/snapshots/nanos/test_get_public_key_no_chaincode_confirm_accepted/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3&HnKs<1FD8!#&=}Xx$G!PoP zUqaXGeRw#IxPU|Sv6_gDO@(!!O><2D6soNNu}A>o{O-dA)lg0D+@hwFj#8uU=j;?z zkO%M#c2w0W!Xzp#MLaEfkXt0WVvBaw)CAQ^(G?BR1{ygWBMf3)`4hfRXiK?nTQ36Ogyjgi{)5vI|T7cXWVs4$fA8Zuby^A4|!srA!s04 i|1aoikS78FfX)u7xAbN92cC!k0000iro2@o?E^o6kPsXWhr{8}#C3-2EJ&U-Mm8f!ie?X( z!miF}7uOlKgB8Yy?fBV`OfmqUanushl+xsDhNOi17X~MPA>vxVqlAa#13AR<9xCAn zHIY->8)ka|l)w`Thm~`_u{4<$7>me<0T{UfDSBe-Gf6g2JZ&6#F!P!b#!?c_(w&_B zVtQO3GeQtt*_tFA#894`hD^dyPHt5u$Nq{XBV!RT%Q#xIqT-DDsSv}SzkY>Z+l3TY z?VtUGcsra}U3Y>od(oM!3*Up8ctaFg7llPG*6y`LcQNh|SU6tIHe_v_F0K}hHrWP1 zsSuM(C$63*WV4V|#&se&TKG#Lvh~p7 zSM|#z>%HBVoe#2$sor0F^4_VTdg=$6ze?;3wnw#*w|KL(##K8U4o5e>@v>+|zgX?_= zMxOv^fjbwz8s}_xgOTa8^3Z^m3$VO@MWNXv3z{dLHtjq#vZY2XOIgP{Isw43VC*Y( zE-mGJ)lXwu5Ui}_M>q*B3;NKQa4Z@J*%NnOsinsf&i|)w>93;WjLwH55mx;1e24T_ zXnl45y?=1rX)lyBgh~6NGr2CY1|zvc7rHK)BKuxDsdJsam{k-UX}Swf1wSLqvXZYo zNY4f6i}@l31vN!|td=B|%NGizNOg+Hqe!YWzNErRX;}OnP((!O0r_P0(K;hL3K~KW zm32@~TdDs)-crQ0Z9!^c)mznRrrrxM^F>)q2n600000NkvXXu0mjfP`AnH literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00003.png b/tests/functional/snapshots/nanos/test_sign_message_long/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..15e5b124305ae9293c01c2993501860b00dac096 GIT binary patch literal 462 zcmV;<0WtoGP)`g3aQ5v#+Hr4g(L@@_`EWe466vkK=9&w%aqK%w+GquvG#iL08eIAmI7 z0(UNaG>+M#mSP3{V1=w&YkDrg`S?r<^&UykIO(uy=AoAN%sjW*4gk`Ev5!=F&lyL| zNI`IBEg#`SNLf&a+Jt>cy--c~I+gUyMPJrG>UzJ54M$XOideYe=AVe`b4|ez0%dPhiuj$Y=RE6X1f<<%j)KO30_gwE$BAw=}Uh->w{$m1d1Y{ zUab}O?uOkloipI61+7_h-^oPt}a+bfU9GQb42!b7W19g{i=apz@-v9sr07*qoM6N<$ Ef+p(R9{>OV literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00004.png b/tests/functional/snapshots/nanos/test_sign_message_long/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..28e37418bb9982a01640a1570cb5145a61146406 GIT binary patch literal 472 zcmV;}0Vn>6P)Nkl{AQb0h(s2ScVAucT9mXv}Z2!gu--pjzlY=X7Y`)y<~gWciEKs&{B2j&W!$GcthX z3>b8};G+iLl`?ELmj?i@ftE!$6{aj$hPDa&5`2xm(yXPD;lW#chfup7x|`G4AgTVq zpO?wadm?Ru7a#kXb6+^|blnf5`M$<%O2l9$+s{Hzyo$K~Sl2VRR85k8c8$CZO_#@@voH3CPpOQPU4wr~-u3sB zpIsgqz-m)kzS!HxWE;Gt9}H@1#*UB`Y%O6Y5=`Kh`MnL{{U8W}pocF_jA%K6%C>v} O00008YRQe=OkErcL&OZBluiDK-UB1@ySl zw_1Ad04RYg7dDMC7uBdi)XQoqXnUWbQty!j#Yw}anTJ}QGxNN9I{?TN#x|+)oFk6t zk%HjJT3*6QNLf&a+Jt>cy--c~IF+=_MPGWI*6mz_DW-xRU%!nc>$*W;q))$!MU zM*60m1;*`3Bbk?&gPyFAh32I&$X;_G)duQ%RF0t)xWrgzg2PRUQ2)qx;1n`ebCFLdXLiAICWKV;Axcg&gLTaTFF|{{Mk)aJZo`D(l_I` z16)uHF8YypyB4JE?rLk&txIzt6=DZtq-tmpy*^5nhadgqumdiweYh&wf`0KOT;Uik zmp1A#IBEP7(U+-G(28um9caT4XY(Kkg3z?ORQdh%`z8k1*yj5K4u!bVwZt%n0Rase*)x2aNlR>JI*X3NMUCFhJh*U<_P)&)~vW#gPP z&KMDb=*%LAa5F*{Z6jsUu~-{5utq?Jko}RHm9Baujeh1Xb$eqz|nJwY}5WF9b)I zjoA-T8#EA!3P780WbcEP)#K zic3&3%Y|yzOaLi?(bpf?@n^14MfT))SDca(?yg63#-f-w`kBQ|w1!D4Pyd9f;j(b8 zi(qyIKna|=@Kot@LuiVplI5z6wvygy0vdbLy!7ZAq}tc@)mWy zF4DTX{@l-Sd)m7|n0-@E?n~rgCOfP`_vIqURXOlZn3I0Lt@UV~dnaHBb{jFFg^7h+ zo3l`bA3^Sk&SRlziodPNOV~WYPSU~Av^CSo&ZR6YB=}dhiW^{JXJ0)zR6yq#TLY@L zmNS+ny997$UfZzjw}D$pl(*~Qdc8F`x1&9D!mhO@xXNK|#&lzp0J0gWY*-4aYT^2H znwPNBJf;50IRA||A3FzE`a|ZC9A1jKZ~Sf8-oYRU9>5RQu4Wlt-MDrD0000=Y4!AE+z@$8j9TvE;Lb&sLCJ>5S|~loZ|W z6+$&*b^u<;PvsYlc$-^P5hGdFid$Bad+X8cZ9xW(eq`ka+JQk@oQQIQlJzaqVk+APUw+> z(w5aM!XcBgQXRCJev9a^i3R5?N?PWkKjUw8Yga|Xh|Ze=3orWk7V~;sq`W%**pKYH z!;Xi$lQ3>i8p*tPAN1r7S!iAgjeOar!sLA0Zp1WNV8AAv1AG@0TJ8qH?4g60d{D}j zFi}%!P|z2QuyvkzopUeRAxAc1S@1S@Bs4?*gF;zzXN9tw?0_J|->Odt%KBjQ7?mPU zrppH}{&uw>_OFtvcOS_})lhS=5;tB?+sy#Y*k>ytxM~#((HbL-xa>oY<2a7vIJf2t XBXm|0d#$~!00000NkvXXu0mjfsma2# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00009.png b/tests/functional/snapshots/nanos/test_sign_message_long/00009.png new file mode 100644 index 0000000000000000000000000000000000000000..2022ea73fb7384d13621bc3ce3b462af0b03c57d GIT binary patch literal 421 zcmV;W0b2fvP)}R&JwR*rfbs$IoKm)((Qv5dbA{ z=fYQ|&6;L-HQ^{Rl5!6XXz74${~3&DpGXorvDrBDV9nwhm3p)buhA0#M2C^DxbYIX zenbj_E35et4w;k%+hCn=tlTKLCG3tREpyQyOW{dV`m0#cqWh|lhFAJ|iMX~4msjoY z{mA+6aNyzYCd9NSwPar02P0V_3(bqL$ZPn(tQBS_R)Jc!^dNgA__@K``Z{Z)zH#rt0dDd4!BUc)HEY6XJ(^|17^*h zJ?Iz#L8@FPh|O~8o2+s2W99T*>u!j~_jwCo=|bj_^gRbm8O4s{ILq<{^NKi3d}s#e P00000NkvXXu0mjfyY#{k literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00010.png b/tests/functional/snapshots/nanos/test_sign_message_long/00010.png new file mode 100644 index 0000000000000000000000000000000000000000..c4e69dcc08a06469678eb2a077ef532209c4ff75 GIT binary patch literal 441 zcmV;q0Y?6bP)jv zfKpPvp=DP%LlsAW|IM*gYv^IH0Neg^3bqwUz^w2japu9A7tb)S*#;B~Mt1Sw#XSxf zn1V{rN;cudrt%y#-OExoZo^I4|iG+_OCvr<%l(y$--Ia0W_Sv=o+Y-ZRCeV-AiNY^iiJL^i@h~mblUh zp2bfwr)6;L;tzDS?`&Rw%|ee{EnZ$Ny9<>xg^Xsoh24xQMf8_8on%jKGi(;%cFmF> zMqbMdW`S~a@|+*tVHp9bRkH*%ht-OsWG$2buT&{~)owDbDxZeUy`2d@Y;$lSGX*zw jU*mItk4XkW5CkM&-d|86?1YJm00000NkvXXu0mjf)p){` literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00011.png b/tests/functional/snapshots/nanos/test_sign_message_long/00011.png new file mode 100644 index 0000000000000000000000000000000000000000..d8bac7bb62701ae354eea9026bd8b25ab641543f GIT binary patch literal 433 zcmV;i0Z#sjP)c(+69n3!V#hmG=1@eT#gu{|2!g|r9dC1u9L0cQs-{UwTK~ded8_C0Lx8m_+TarN1+EGEV8)|dOKCGUrZhY_TPjp?!*CNp-HdG z6d%=4QrN1AR;u&^;W7r6lb>~B!PPaFYMFeQlNXYbR=Je#EY8G^+11c{eFoEWN@E>B z-a{q#)y=rb2izFDE00000NkvXXu0mjf^vS;O literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00012.png b/tests/functional/snapshots/nanos/test_sign_message_long/00012.png new file mode 100644 index 0000000000000000000000000000000000000000..6098daa454ba81807e0850b09f73460947ad113b GIT binary patch literal 450 zcmV;z0X_bSP)h z+;2ED)(^LCL8)aWhj3uG@)$JeA$-aiE2nQ|Enx&h$v_tx{lXQW*zyKF^c*}_Uio7) zvH4864c6@1kHj0SeN}l7{a2sTa<~s>vhXhS018HK^Fhoy@Y^(h-S45ZtD?4Aj9TKg zsakbCR&fA8=^|EjUDm6Q3xJs6FfE;ss^aUFZppu$Y1FAim%MvC~;Xrcr9Go#f s5p^-}L*~EPW-Bll(;w`P<2aM~0w!W(?~7b%AOHXW literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00013.png b/tests/functional/snapshots/nanos/test_sign_message_long/00013.png new file mode 100644 index 0000000000000000000000000000000000000000..a7cedc93b8f98733b377f755ff51045e95d097e0 GIT binary patch literal 491 zcmVrkC41X5FB4G2KBx1}WARz?DaU93#z~>!4Z$)yYF`OA^6Ag)3#CK8%=F`d|a3|NA zU28#Ie$q!2e$|*327Lg%YeD463Br|2QP^GwF08qh_m>e|qnK0;wH7ty5^047RiU+i z+SB5iaRjL8wVtBj*H^d*lefs?sI0J}Mk{0Oe>J_P*9HGvt6W>)K<2+WCcKmTg|{kM haEy0x&2b#(D!#Vwo!>tLH#h(Q002ovPDHLkV1o1U;Mf2F literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00014.png b/tests/functional/snapshots/nanos/test_sign_message_long/00014.png new file mode 100644 index 0000000000000000000000000000000000000000..3e3b15e656635139993a17b9a936c6ae450e323a GIT binary patch literal 501 zcmVc(+14Klsw&6Rqj8YJP=~4=UAP9m{&Lf>iLo(ADjT=;6B+YP~ zLVLSd*_ZQ3uW$9InsUB)egE=-Bu;#M%}Es3OOTpdR#JP4BDDSmt+|vO4D2%Wmc3wa zseHs#O+k22GoyOsZ^a0J64*oGtui*pE{xs|=OXsP3GW1yaZSBM5)=;&kIp>QvY{>L z&~$CkUM7wJmYguy=t7IQv{Y@(En-#z;EJbNgp)XxmqEiW!g3Z_kUky9RB~1F_S_is zu6`4uu)Tsj^~OK19+D47+WYR=_X~L!xbSrC2ou5sqPiE6gO%KM7J3GaM!q5kdYjw! z0Js8;I5{ssr(N0>G>c0E)DL2)9tn>;Yz+q~6bne7s+C)f8&pnf7`3Vn(q}{KMd_Xe z_Tz)CBw5qZC^YS`_1CUitl?Ov@kC?UxfEe208B%Em-`7+9hzSPY}H!!W6Ko?UR_aV zR-3YZlFU;lb$a1vCb-xb>T!!a_ZtDVawc14Og(*{TJBvrWqn~ir;lr1I=HZFnbTkP r+?e|D^nXQck7){`b4w5eL2yHUc@u&>weEP&00000NkvXXu0mjf&w$=7 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00015.png b/tests/functional/snapshots/nanos/test_sign_message_long/00015.png new file mode 100644 index 0000000000000000000000000000000000000000..b52c205cda7571fac7e3899b8a88cec9b2157d76 GIT binary patch literal 466 zcmV;@0WJQCP)Yzh)m7AI-J zLr*{~iFat+RL;<_5NIN?dp}#;MLRkK;5h#iLthg~GAo=UW**eMc!qgB?LZVTvWcA+ zU-5*2DJWi9%}Y3lsr-Iu$d~XX=R$>cacry*B^`1RI5!)m@4&7TF)N3Guk`j_5BPLQ z33l4Of5V+%mxJ(s^(iff$KXj8&O#fIS!Ch%gyHE>9n)I0b<2DOh1Cw0Yk3<8hZP4g zxv+&t9`0LKu5QXhI4hdd7Mc^z-umez3ejjAF(QeI>?YpzJGva>o8rc#70 z&W2Gn8*0E?p@j)+Er|R>(tK29inlpgs=tm##WMjFZofU8|-YGLSo(Prc- zoqD=vA#_hJq<5#!AG^mG<$s?aGG0|3$_C}hn9Zi+IF7^f1Dd&c#trUS0RR9107*qo IM6N<$f>*H2-v9sr literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00016.png b/tests/functional/snapshots/nanos/test_sign_message_long/00016.png new file mode 100644 index 0000000000000000000000000000000000000000..825f1b402c7aa07477c6d62a60f732f7d757aa96 GIT binary patch literal 434 zcmV;j0ZsmiP)U7qBqN<++_)uJ$m^5F zCt}V8xEsak1Ny?oV_vNciHLr0#}8dnl6wo2lP?I^Yh;&fkXd9Y>U8D`gZAXzZ7i8}lsy zuFVDQmFSsyG>UO%GU*6L9l|_Jg+#LVb2U-Y8dl)9h1|FS)N{JJ1Ip-*|F36%ffAms0rDwR<}Z$B3;+NC07*qoM6N<$f>QapQ~&?~ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00017.png b/tests/functional/snapshots/nanos/test_sign_message_long/00017.png new file mode 100644 index 0000000000000000000000000000000000000000..07d12d32d40bf8c55c0b9147cf5497ea252c0428 GIT binary patch literal 450 zcmV;z0X_bSP)lg9&fZQECZ7z=Wn01VIo41NeT@_fwF}G=?+dn3C3# z>q!kB@fm<)K$=1Nv}(}Jdz2y-r`_9LF(oD3uP~hahJbsGoRR}_ise13iV~q@agq^S zlmWRUzeDq>a)(140j_)I7B?7&K>)V>?-Xn+kbqs`P2$RfHMe=hz?E&ht~MYG7&*m@ zeK>9u6H8F;S^(`$&#NbL6u0l7U;AB@ZD3*KjIaNL6Y)+HANw02Zk_R;O_>vG0cFWw)wF_6#~Q0B1Vao8+inKjEncm?T(O sYy4nVdY*NSgFj@RO#~nag5bIQ038Qw)-l}sqW}N^07*qoM6N<$g1_U$vH$=8 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00018.png b/tests/functional/snapshots/nanos/test_sign_message_long/00018.png new file mode 100644 index 0000000000000000000000000000000000000000..8eb48bd42a00de1f718d5820d30a3b8e79675370 GIT binary patch literal 477 zcmV<30V4j1P)OvBxe^JP6;2W}4_e+l!#rmbC>D(EqVnb* zC%7;Lm7cX6!bwf#IcV5J_>e2dav4cP6C)TUC*-0(Ec%6OKC$fzBj`2`FFxtxdj$qoLPmd_m;i-h|`uf<9OXv;aQCUeJmr- zCT=OEb0a`fu-x^U>ZTnunly1Nzx{qrH8jZ-^(qZ9f;OePX)BE;P2}uXFPKpc)$5)1 z7rX6@5ABD62&kT)-Ds_wvY{XyOQi+rPp5v!qr#P2VMYAw$xlakKM)860-NFsG5?Ri T-i@#300000NkvXXu0mjfQp3}H literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00019.png b/tests/functional/snapshots/nanos/test_sign_message_long/00019.png new file mode 100644 index 0000000000000000000000000000000000000000..2afb34ebdb464fab5e2469fbb5075d7022f98490 GIT binary patch literal 432 zcmV;h0Z;ykP)!2te&*djA7=(OEb#L=f?ZpYT>nTZ$-HsdI*57>3b-_i^u&k!Tvjm_ZsAB-#6C z4JyN$6W|-9`*@+G(ag7(A`!vv>n`Y$lGIa}l>9)VwMKTy2HC~(7FF^HaI#SD6al}f-3EvxHE7j=7fC;$n|M0M_kt7-w9wg2@SaXF(O6PbapV48zYw5D61rV$-%=BUlS#-3YBE5tvews#5-yxn1fhpS-(X|Z`328QBU16Y%ySP zn$oHTk$+U`G_;gItKU0}1*)M%@U_wn(TV_x*LdfqYNftF&1{wY)zq&G$+L!G7=~dO aMlC;{13)yFZ>rt^0000zh>Wy;+o+1NV`@CuB506^nir9vXc`G z@&MXHZ!T?uE5yYN7b)h=zNJ0*alrvB>t|EAtwm3h|!d1KW$o)(=sF8Q_a!D8FRDA;kX7d;i45G(6$~J`4Lj8 ztQIB>J>YZ)=B20DTGMT$Z#DEVUJ=9Pwz`I|n;d|bcf06u4K))~LnnmR@`}2iHzPbi uD`9E^hJ01kd1IR7qnH*1K@bE%fbj-IKVUz+$ZeSb0000wm1-s23+;%JU=hL+kNAUmZUAi0*gOyx(7y1DzgKUoh-I3cO=XaOrvZm;swK?@} zws5&j`?Pxi0PlyGJ)=qAN+_0~GwgmWzS@-hsF>}^Gyo(e;oR#wr~QD9_v*0IT1GM>G+pg-VP?LZmvaS#MS b5cu&109AqKtmhVd00000NkvXXu0mjff{NXv literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00022.png b/tests/functional/snapshots/nanos/test_sign_message_long/00022.png new file mode 100644 index 0000000000000000000000000000000000000000..6a27c7086913458988eee45b4fea4bd6720cfe19 GIT binary patch literal 463 zcmV;=0WkiFP)Asp0Q`$`(|5I*Hxk0>GW;2F#%9YbjJ3l~1I@eX&WR?c30(Vxxa z<}=YYShH*Y;<~}wH&sWlfAuLXhsR(h3-3Y?AmijFF=!jeG0OruV89B8KFSD|&ZMpZ zU{qbiQnwiKD>hrL0%f zfecYmb4{6%Dz%1m{A>hO<=&Cy++)>M^K3i-j^j9!_yPyXiOj$sM&SSe002ovPDHLk FV1fs?%R~SG literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00023.png b/tests/functional/snapshots/nanos/test_sign_message_long/00023.png new file mode 100644 index 0000000000000000000000000000000000000000..eb1f6ada77dfbe970af7708c80d9bf1bf234d5c9 GIT binary patch literal 459 zcmV;+0W|)JP)Wi*_+HIUES&Cnk!OZ>30pkegyDNs=ThTO723gr(m>B zPFev}LT4_$1$&6AQAc(4u#2X!sWyoP1F${+k|JYe64oo(NxAb#%Sc8RByJXuvjZRl z*1VO<-c$z8emQgtqM1bw;i7C=R7cvRzN8(^uWU;VO3A`O4f=))pV+v<9)^vJh7bNY z@M`@AtPM8o+^^Ix*!ZE^G~&N{mo7(+!I@lm7y1G^N!~vO0~IT;Q+gN-R2`OLyE`Hh zqzqX^j;1&o)0v3h-8SezD_9m$Ini{eu&E>6$zU{P#5Mkzrp16{V={IHv3t>Ni#PWM z1L|n{_Oc$>b^q~~B98o6i||sgI0okcEUU^|?#^X#3`5mWyI`4kaIS#v31&BBI@)i8 zY7jJz)3wPI4E+`1xyf~~n*cv#?oAFrk|fD}`2fq}ea+|7oHhUe002ovPDHLkV1kJ? B%j*CD literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00024.png b/tests/functional/snapshots/nanos/test_sign_message_long/00024.png new file mode 100644 index 0000000000000000000000000000000000000000..c2be7c6af42022c327113a8637056f8467045f9e GIT binary patch literal 480 zcmV<60U!Q}P)os`2oym@t>vA{6i`Hi5FE#G9H*7@2MT&@M@wO{olP$SXDr2^NyVrSe4#}6p{rj%D_aiZ>X0?UTMH`^X!sg$U&ci?4Oj5BQY3H1d>-eNu*DTnn-(;hMl#iueu<)JA}|iusf{ zNV4sA8^|~UnEGXexnp}7aIGMth5srvZ|EibCupm%dh9P@hh>{>!1B-x!*LwvE&Kp_ WJc+S1g|gZJ0000;afv=x zxALG(aMBK-C3NM|S8#;5Sk}zDDEiHNOM4i{1P3hZcVOJsqNErVA0&@FTr)Bw6DDpH zkFyOR4ijIwaO+e$p8a%a2%a~qx*XwyGr4dSx&f6*Zt}qm!m)^P{Ov0QYuoTJ z^^9RRj9S(>EfZusp6Nn~ob-|Fp2E78)T)rN+oU8QBN4m!%WCLpy3P|TLs46u#C zRe{zbX8bZI6)_|-bSM!ok{&{(&a_+*lE_3fbo8iYVO@ISz-(woBD1d-mlLfqZ3k2n znKs5pRa9%sBQDwFIqzPd^E2-rIQSv+-}K%CS~=mE90WlSRCohEAa}rKVS~5;0000< KMNUMnLSTY7Nzn5E literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00026.png b/tests/functional/snapshots/nanos/test_sign_message_long/00026.png new file mode 100644 index 0000000000000000000000000000000000000000..fcd321461fc3f249db31925df4afe791e5634c48 GIT binary patch literal 456 zcmV;(0XP1MP)5(`~DByL-(*d8HOJej8Sa)P6i1gDp6BPk|arz4B-7L?^i=I(;4c6=okuV zE$X9YEMg7-N<^2i)>634&nQDCPQQ<*<584oZ+$g?v0&50K996%)iEWTa~x9;D>s+& zphd7~1yBi{x%AQ4L%SMnh^-#h?pdo9#&N>{9MAubp|4EBdWD_D%!8IK5xF67qj;=# zfDD-Uh|1nj29AE2nu2I#Eg#{cq%5j~HfdXEhrJ~x7F@w7xp7c~?r_atY`el0x{bq& z4_+O3wSEG%1RHklpNQMX9TEKBy-VAXW3ZBqv(N|72=c<+Ma+H6So@7#P*Dz+n+AO# z^~)tY5Z=SrHlA8hO}xt#k4qNImcyEOjYF}!EgGyl=C$8L<<_uS(1c#gE`<(%yq>#! z)7Q$ltB75a$z)n#88-mYj?mhT>||OF%>5rQljWheVIF|`gwj5<*DYIGsVC@)x>d41fUlZ%l600004%P)=13_#JT_dl?UcF_)#=4U{Vpm{3|7(+gwNht_|AP5@p-qU+OkX&gDv;mrtCDd9t z0SzGy9`P9fqXc^2esP*tD@7)<-OE;R%SxoD9?jPmC{65nB&AhFO0uf-IdqRgqeg2B z8B_sK0y7uh8dqqarj!VJZ>}xrq8%Lquxvl4P+O4%t%@#^?mSep#Us>l9b8$*I@$mb zF!q*CE_Iw6U$b1e1wqeR4&fwhS#S>33ExHau#rF!q7_Uf9fRuh3)g&N+b5i%S~+=e z#lw!P^$utotlQkrNPn=?!Pr0hlBOeKFp`OPp&M}EWVbOm^WlL`j)7}*>)vD9efhca z!nM61NNFpSKA7YmvC_9I!rP+v;*}xegK&=C__V9)z_s zowjm{-s6*O=#PVL=(F)r0qj{?m-}q%zuJZ%2!bF8f}jr{$Z0etW;MAO00000NkvXX Hu0mjf6{WSP literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00028.png b/tests/functional/snapshots/nanos/test_sign_message_long/00028.png new file mode 100644 index 0000000000000000000000000000000000000000..506c2d4d6296ec8115a4778842035f1d899fe640 GIT binary patch literal 427 zcmV;c0aX5pP)Qs)f~okSun^;$2YDEM=ob zaM22&5*oSmRyjg_Gum@rJ?uh$%B;0u!USyl&najtldw_YATje`&l-fZ{d8&yqMp@k!l{z7XdCR4z6<+dTE)bID;OmcC)Mc}u6oDTHyGh?=b-rD zj~%bpJ0K-kx3QneXIlTJ$`tHheMrj@b8saKXQ3O=aPpnz;P6>`o)a2hK`BaFlL7ad z9>ls1R>HYV^Ry_zx72K_H51yS&{rW=E-q?>O_kpE%Ic|{f+qhJIJX))!r*94()xtG zVVwy`mESU5x+Vsg;-DJ(-`K4Hwr$qxlp|=148=}+{{wen7j~RXegq5>HE*R69{EB^OGzXWiA2Hy>$j}misVdXpbi$r&=h6- zETbxj82~Dw5BgVq;xW9vh)me^UOo-4tVEjiXl%YfX=2YKDXltElBF_MK(UpwQxQz6 z04RZ(3tx>E+J~Wqq_6w4^5BO70a!kN^Qf*!f~=xO(w&DgTRegs*BaxIc+FM-1dM&9 zgIjZOK-xOu#4QMV)^Z3JVatMJC?{Nt@<{8_xsZ@b1_m`iRq|*(1BV*YO-?4h@aMqQ zdIxA5Y}nl2vEOOqtEz+1|LP`P4jF@)xbQA?15})xF_7TmnV{~~TQ^>W2YJT$ZgJp{ z?y=H62uWzyQ|FZWHY{NgZcpq)x-_dp5pHnPe#9HQ>XMMYDib>hVN+IW&{l=j!M*h{ zuNUNA(LuM@3MK_$>!~@q%$@KoOznocyNo4-#|An=yjDEGIldd(bSxt?r2iGFT~cLk xRX3J7TV!!@tcU~rA(KdS;s$-$L?ZEQ`~X|ibL+EYI0OIy002ovPDHLkV1j6x$SME; literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00030.png b/tests/functional/snapshots/nanos/test_sign_message_long/00030.png new file mode 100644 index 0000000000000000000000000000000000000000..577a9b1155511e09df06911ceb130cf6b1f838e5 GIT binary patch literal 457 zcmV;)0XF`LP)Wi_T(ZJPudL^)G6|w@Qp6f?%Z~IF92uP6s~k@OdA!oT*Hz1EZK2 zV)UQ2r~}q?0Jh+R{nZ}W##b*v6jATTtKc=;qK&#WKeiCtgx^QnwyM~YWCGE$3KPnm zf?!evq%G;rO<&0sGTmaVXi*~O75(v{9|Iilc>Nj$brmgQRk%pZJSchd%=4VBK;p3M zD|X)8;(`-XP->#J&$(SP?PZHN0{CL3p=3vgiM#eI-f&(L|b<*cSpA0|4WSw4Lc z!`fufODM6Makt8rJeh)MX|X7)|KUVhBgzzaI-`FRd^OSdaIq=B4ua!x1hy3%viVnK-{>Fn7zW)Qe(1lKh;U_@T#02GAH5>}$0k`6o{+w);az8MUS!4nvJ zMbV!%DT6gP0447S47K6mGWTAFT$H%?jN95QivlHl-IF9C}i@ zQxZ(d04ky9kq(_R^r)3wshxf1m+9j}KL%{TetZ@MV`UOHE1V=&9<&_1p4?^!KsHPq zqH^#RXMC{)(UtXF!ds>W6CBF)C(#T)|g52 zezRvSnD%Sw($Px~tPRlnmoE~Cz`sUdc$%NLIi1KfZ4xP6bg6+ z)moTL-x(O<>6q#r@8)as%DY2|a0chHz&~XEo7{jTNs|BN1sJ4z{qb^9UH||907*qo IM6N<$g7g2@XaE2J literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00032.png b/tests/functional/snapshots/nanos/test_sign_message_long/00032.png new file mode 100644 index 0000000000000000000000000000000000000000..7f305393361e75565f52c29a150ae9e67168eb93 GIT binary patch literal 452 zcmV;#0XzPQP)c5knSS5;z-x;6j4V9NwwN7l0HSd!pIv`!UdD^J=4 z2kihVp(~fZf?tSq+xLnymwa{}=CL3E+w1ETX)BYkuaX}rPadhc&m#+5*~jB(14zKs zSJ`>oabdh)etHB^&mxy_F^(+SN9v?=Ikz+wvUtcHEF}v=81xq|d}HGsM(9>920nOm zn7w&TyaP7u+TYnT*!ZUUDE6QIlTJs*;7Cq<3SEGTlQRZON%ux$t9NnoBQ;}ElcNqL zjsaGas#7iUNK>Vfs^-?YI&m@}wHVo2ylho6(J*!RBKr-nQp9+IHgfhw$Y}@dx4j1h zU`i$SsIj>I6*bpV_a0mg^^24jV@l1HDKxwX>;SL;2~OXt#OcYJtezcZyQ;PLToW$g uThUr`9VWmZGWQ0^1MY^EjwDHvT#i4^L4qb}n-(nq00000%t?=sD@iG{9UDw&Xr{s_9mb$_w_3OzI%Ck=1-@n+k`ar(Qp9E% zjbK)1=hHU;!+n*?sFTpEvrAa}KfokHAp{ok&bBJ2yU;NJQYF%<#-=ZiL8||*Q7diP z3XJ(_Ey9X)c6>AD{P0^!lg|Nu$b2__=YX*&yZ+!T-a8~ok__SnvGH;itU0YG00000 LNkvXXu0mjf(>~BB literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00034.png b/tests/functional/snapshots/nanos/test_sign_message_long/00034.png new file mode 100644 index 0000000000000000000000000000000000000000..266fca810cf9c800107db4d8efebfdf86f471702 GIT binary patch literal 464 zcmV;>0WbcEP)59@sX6XN_+t#8p&}4K@bE%FQ51Ec~?qiDnoTBsUgc* zM^;5kR+(00PY2)en zuF?Q9C(2(jwrr>rjnCUoGlK@aH@!!_NidRdKoA7M|MCTGcYnh2Ly2Ml0000CDL1e%{~^zGO@2CX<1b)$ zzZKx&&=PFewSOR;V3&jOfAuacN6x`a7S2LHz{wzw`MT(5fd$y2@0ho;kB5;YE@rXXJeS9!PD4seY4nog1=N#G59;DfO_ SK%YGT00007P^!*>Wi+0gdhv8R(Rs~bOMJF*7@B-da3W6XAf&n}q>G?P*S?LV*q39SE z(yu6wlD_cS0a#LW3BPI{zUFU~A{E*1wK{F4{7m(1o_TK8 z4v-EjzM}BvEzVe&f@sTXCgD^`SyTpfQd>2(EJj&k!3f5Z3AyNl(-p3I#?}jbL$`AH zwI+yH{yDq7N+DI162XlSYm{m`XISH;&Z?@kCSDjunq+ z5-gYHbJNKK)7o3Xc-0BT8ZQ-7S3mKoR8vdsH lfW-kWnD#e02SE@l;03Z~Ogb&<2#x>%002ovPDHLkV1l)9#+d*B literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00037.png b/tests/functional/snapshots/nanos/test_sign_message_long/00037.png new file mode 100644 index 0000000000000000000000000000000000000000..2e14ae41ea3daf6df40eaaf6bd45820992e8bb61 GIT binary patch literal 433 zcmV;i0Z#sjP)6lDP^M~ zXjB1ogk~ma23>!puX~FB0h^TpkuKWiStfDDl)p-d1EQdk5FE#G9H#;25zZqa8L3RHgGMn>MJPXO zPzh{K0G8kf`Kw&9j%TZeR9t#*d&Vm%;cERgZ(D$6qF+bcvMN}TNk=3l#pNrQiH zUb*qBa)g>ZEKr7%$XZqZAsCwtO_G%^)l@H5gL9YG z7@L6HbSc+DjmfyAY#$6{Lz85sOFMPijcN}_Zj1sTmzkR`C0#-Je?};#Ot^9tr)|RH n@iX;I6S(z5a4R^D7P^!*>Wi=IW=j3e-iH`J7Gm3TpjKq3jjaU92SI`Dpl_bbz4sZ6YcMzLfH z7(dIX3~O!xZJ`&q7f)>Cua_Vdm)^&-;FfKXX8knhvq;=T??;kbRk)-wfk;_J6Uv=} zU{VCcEwSguw@M2&!>(A7geP6eczV%~0UK~UKju+gla|CPY9!4(RC2`=Dc$3dJZ38p zZ5Vq?2j45#8>XQ6$!cE0K}cEg7%DSfD=U^wEHr{?%Ya<;Wr3*VDSZbHHKbZNnfOS% z?-k(7ffDSpzJGC@Y1da3!|1=eN!#IjFq4h5&<)5uOrteS~`1v#B0@~FC}6Z04H1A3(A(&bJ>YYG8ajr`Sk;1XCTSmEjZ}iQQf7f_XbWfBZLgr<66{EH5g-*ES*6*Z0l+-H zWV}Qjn(`_xkF)x3L%ZLt{8g%8^Axl{w*Q3t(lHS^j^q3!|4!C(;qowuJOBUy07*qo IM6N<$f+f4rkN^Mx literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00040.png b/tests/functional/snapshots/nanos/test_sign_message_long/00040.png new file mode 100644 index 0000000000000000000000000000000000000000..57a1b8644df251428b2991a353823eb7a0c53ff2 GIT binary patch literal 467 zcmV;^0WAKBP)r0+**nYkFXkz8JGQN>v$ z8q4Me;M6BKT7LBLav8-$Uh(5y@kq9CZwXUB-uwBiFPC_QgV;TY(@ujka*y^1NVb6X zu;_{ifGyB-;iFMDN2e}k&k@G`aKhUFInwbeijX1$ygQ z{=Hw2-U{h7yr=JHu2bN`%bg>H2se=GEW!pWIW-I214YTccT3?YIS9B_G|x3|k@H+! zt?f*h_k@6Ux`>gtDy}9`ypqIgT4JtdRmWvGIGz{ZmSN>bUPkRohM-m%$>k{4TtJ`}e{lFtNrnP}Y1+>3Ehv0_?%&;mU(Gi@v~# zI9c)Om;odyV5QR;A3gA0EyJdvR{+X2P_qbcY{||^LoUL66iGmToX1$wDx9Of+b5_7)$ne-JnaCdD8VZs7d`66O460cQg4Fo6m`F@x`(v4;~ z-f;67IQP`vXP7VKc_gz16Sr(YVeN2~KU)R6Wm3Kl`~jp!sL>#ft{=BCqtAjgh{ven zt?`w&iiZI3$EbI2O@`ZFlFXjI!H>gsjLraN<*aq6E!w;)O-NitE(n4k2!g;hAJz6Q UpDq!0J^%m!07*qoM6N<$f_9q0ng9R* literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00042.png b/tests/functional/snapshots/nanos/test_sign_message_long/00042.png new file mode 100644 index 0000000000000000000000000000000000000000..77c86de8b5bba2b5c379932633e54fa42d70a25c GIT binary patch literal 445 zcmV;u0Yd(XP)WFWB&{TE;5;h^-Dl5ClOGSowY7_pMk~IwKn&-)OUB zsfM#Fv?9(EP;!RVwCTde-;iEZB#*DV;g+?Oo)U(>Zhv!jEKhjZ1kul+k~$rev2?4i z0MHfmh>Y&20BpfC7vCylGfI$+NUw#9L5xm7s&wjQX365A;n9_c_FUD179y+oJ{DF0 z%abrHx}ZykUP6UAP#@MM0KWq@FJUMwS-1`D6OW}V4z@k5V``a|LZ6=st#7{tQS=Q# zp8DiJ`zXxUB7F_}ocoEicXjTk1}20TM0FOCgPokZ3cZ7h$j9Ztz8PN0aq;ia&vs-C^zev&0^g4hP7XW4Q4LXbPx^gkEnsk+^08AbNIBLu;sX7^c8D;=TE z+g*-WzCQIP-ni}tL7&F+7WyVvXWH(VE6FOgEfn>z=;?dK0h~R z0LeLFFzAgK8Dhs}*fiWV0k8&Yitxg0S+EV(3C9x4ay2^E0M%m2Rns}=QK7f`-Qb07 z2-NFS|9QS7eHE?K@SJPEQ0}gi+o^$Y;RRkji=2azJard(2SSh=PXfK~P~78}VVXTF zgEU)jMr_qFs}BVr_sF{iPnvBxN9W4=p>ilRhmZx*b|+aoGmQmY83D;}Yq9GQ mwhxPJLHi;c5C{YU|BDae4u&|AN&NZ%00007P^!*>Wi=IVhG7LW=8oZ@^tA-#7Dn^=85ClOG+~xa8-%mj@axl8^9Gf_1 zs=!_`3m*KrSlIxK*YOr~PNC(869XsU3c=-x=?&f!;Bq3C3NM|N271eA;6AU@4Kd;Yp3HVnS}X+?qTLZ%f(pWMsy9| zeP$oR=Y-LqD=}(_U2cah!>9?MXQ1T}PMMTNb?Q3|=wSSSjyY7hK!UMe8is1oV%%=9s#Bwn zHFPUQcvWuQvr3i0{yDAN1mvorwJy1D?J9%)6U*#s=sGBcbQk>$eI`JxQ?j+6t7Yms z#eWv{pjbL>Qw}EJaYDd7AP6?#8AaJ32!5V_hI&|QHQ%^800000NkvXXu0mjfwE@)e literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00046.png b/tests/functional/snapshots/nanos/test_sign_message_long/00046.png new file mode 100644 index 0000000000000000000000000000000000000000..926e232abf5e44be99f20ed8b2d5b4ac70420f01 GIT binary patch literal 458 zcmV;*0X6=KP)-Cz&{thD%aLy0u)1N^j%X>j&wRp)PmMSmq#-X)m*g&4MbP- z^)q`Dz8waQUa*nDc2a~b!zc&9Jy5d=Cn04)8LAVGRkk&XR3uO1n6`Y&oogNyT6ezz ztFR40dOh&x^@8*$N~hs9|NRVmaNHDT2?wldFTw{i*) zo-;S=GWghQ==HelUD-OxM=^KvLWeMPo_pn^8~2TZtfm#dQc;-#i< zldy82o@uuZDl@wliyNF3e-$u@Iz({Cy-QGz*jAvH$=807*qoM6N<$f-%U= A#{d8T literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00047.png b/tests/functional/snapshots/nanos/test_sign_message_long/00047.png new file mode 100644 index 0000000000000000000000000000000000000000..7f998d7ee0e522ee98224e120259df636b822a14 GIT binary patch literal 445 zcmV;u0Yd(XP)fIrwhyz^kq*|orlh*xta|hF2j~#Q~=U5P;&?eam$WLLmt9%6iGmToX1$wE1YY7DwLjn1H7k$UCk8(-*m#$UWGG+k~aI2}<Rt8RmR)?@L$ZZfrLk9mxeUE%b3R2bd;F0f*5 z2>8`c``KTTJ__zM>~roH@+t6Oac4-!ga=r4FCqpfx$7$Q3;!tiy?Y8VEV8=SETxU6C}Vm^Q1OZ?QOz_a;Hx|MTSi7W)Y#;HAGOtYVgW2cR(RV> zycQ69mY_X1w@diZ3hI#mUjtAvny2gxjAM(0H`a(lIH2^H^7T` zCeW|;^7DK}x)inD@SM4yxp#q%hdVz`RXjR2ErhBjRBm;`x$E2Y<=TK zXm((jZ9_x-`|N!ZPSV9^ag;5DWJ~d)6n-M_qt@Jx>rYQFF7B~@lk3%GD*ztryDkP~ zBG0tfa0)@ zHryj_17LY1g_euUd}>co+h)rRI`J_F(qX3*$u zA)PXSO6bX@x5gD7s#y%Od1G#A7xlOy0MqhYs`Qmf*sA0rW#y5U2d_MHZwE-glDATM z@EvC~EJ1WUa(Et-)D+VK^he#ReIaV zrX2u#;PVKZ$_T5&GzQUq^WKs!#xY?5j`JHT^%eD?sA!Nh^H9sq^T}hk17N|}CLQd2 z#t{os5S&@fA)JJi1;q`_!G~4Itb7JI#td>I4udA(PPSe#; z_C>bvkww3RC9RGRw+_l?v$s;YWi#v)(48)IvIEL0N+}XmOST1FR@BSdYG^CvIG5$R znK!b%0Obw7a{IG?ghnu-8fxJX&afqMRPo+gfEm35KJh4PmKsx%7L~GPmQj-{od@O) h;UEZtAP52s%}N57{>$yT<)K#N?lnEo0XiTj670u+lowB$~LaM6(9!7 z7G>l9g>$p|X=wJ7 z-R#ZZL<_KPegBJcp*)L>{-;mrIKl=yIXDXa0LCJ(u|al}sTUi)uac`6d+>O1ac>4F zHN#WTt-5tT#E{37{(eEy#qw!ZdQ~C9I}@mKMl|iX^d67+i(aX_Se1M**{O`Ehag;R z4QsQZ4IppBQPDX&(B$-kZv%iy;FDkP4zi&pdVX}^C_Cue0W29=%1!F&<*Gy2)WH<4 pD487vzp!mMgo7Xmf*=S^002ovPDHLkV1h=^%g+D+ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00053.png b/tests/functional/snapshots/nanos/test_sign_message_long/00053.png new file mode 100644 index 0000000000000000000000000000000000000000..8be05f7504a215b1eade56858d6ee0ad158979a7 GIT binary patch literal 482 zcmV<80UiE{P)E8(k(81oNs=T3INs%W8#QMd18snoprX_S zy@EAY4a#8I1u$h;dCx>TpTq+BD{{n^k}7 zw6>9pb^xq_o(qf45t?GG!n%9V16#?84PwFqJYGLTrM99PG%7ks8hNPZ%_GnAY6HN6 zu|+Dp`HUk@3_);aJ%?}+LKc*vI$>X?S~jrI9ZYK`#G+po{layh*nWWs-O5SBCw_ge z4Za*&fL+%2E9?j5jxhG`KBVo)HMo+EqtFd7CON(atOhg9fQoCn!lcQWg_*xa$)d8- z0yMdiUjxB$5o7Zt^;t@=z{!n&+IH9gi%<`eMD?(_ZoGcK8$0|z>ZseI?pZI6?|?oV zBmvV-eFu1&4BG)ZkvkzwCq&#tnym9LmF=C5$OW-~OFRq=^ip!^%r)rh)Rzr~PTJ?N zto$dn=~UHWgPvHOL}RBTc7W1fJ%tYW#|tYEv_U$AS)`Pza)h!?q?-8Xk|arzBuQ?^ YH!XpozzrQBc>n+a07*qoM6N<$f@#&;-T(jq literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00054.png b/tests/functional/snapshots/nanos/test_sign_message_long/00054.png new file mode 100644 index 0000000000000000000000000000000000000000..9fb37c5d79d4a3ee8cc0fcadb042bef34f33918d GIT binary patch literal 445 zcmV;u0Yd(XP)8|#y}UQuj~W+O6Av@ zVndL=BKoS-xrYc3fD*WJ;j7ZN(_;DtQSVO;LDjFRmPmr^q2|%ZLtDNu7SuIO2eg;y zO?aO$IOvTLF&Qbz=YsH>0J!66HsKF*wo%UHUCcMC^XOVLd$y1}yJ2)BSY0nQKI+&{(Z#%k(#;Rde z>;};{;fjvy_nXo%+?P$%fLsIyx@JVQBe)--jbu&x<4@ nS)vsir6sd@lGuqV&)*rfD5P2V>gv*I?+8iFmx#X?|&$yB-5whh%m0{=xpqZ8A zgk-i-&Nd7A&axqVwJTpku18~MSTr?Y#BqMx3Yzh#3UP)k|arzBmumh<@IbxMg~*I0Fg+E z>;g^DeMY8T0ISK@XC4mo6J>~Ei~IKIcvU4JGP{nZJJ35x`074 z+D~E zeU-|K&p0qJ1=Tale1waUvT7Y^v-V|~g)<6?MV??OIUyJQGwB~L{l(@LjC=zkd$M$iC%3zr%K3jH5}yU2y>f zp%*c~ehD=n5UQHZdZ*gdtg8BIR!EM5?v|G8cO0SgLZAU4Ns=UaDvPJGZ3O^W-kM|@+xp+` zZo`fwVXG(|DJ5gEtzUg(B{Pjd4@w!fyyf9Ee_o1A6uXfp>aVOss`Y60u|RHO_an)z zI$RRDcKIpI(JJVx(b`5XS^>3$jlyhUqfUfHA!@g*E$P9J0TZyi#l06vP_JkwY2=}r z`$iR@frmp2uwi|_ARQ=g2V?);yL3Bp4zA?JQRoLa8049A;L?`gfn)}; zT>M&VVvL2~AF-yi`=Jt61DiNf^8U0f_K+?84>zg}cW`Gjl)6xnNY(X(s3n8nQPFO& znK3Kiq@LD<=zM}+$gtNYeHxU6Xe&}`_9W*G1Ay800Y+%JN1vc&K*Po8FI*?U;tqPY z*^&_LwyJw3SPfyrV<22E5eE-+fD4&t6LJsmg5I?yNs=TLAL8>)S)SG@#sB~S07*qo IM6N<$f?d|oasU7T literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00058.png b/tests/functional/snapshots/nanos/test_sign_message_long/00058.png new file mode 100644 index 0000000000000000000000000000000000000000..1dc61fb996ef8562c28e30ca665ef1288074730d GIT binary patch literal 437 zcmV;m0ZRUfP)=E`X(oW?B-(ylNRTaqHfWghw_J{m`;R-*>*UT7j-iqzJi!2)c@cc@e=%0Z)|gQT8^T3+1q?4t#M1!Es+<;7@ac#- z*lG9v4f{g5B8>jkhqN5N1|wP63q1g3l2g~9zeisB4ydfW|3r*^`)t6L-!u}fw0u}e z-%zY&wa37HQL`F?5cz@Wh;ml;u!w9tph(kdX54s!{r?}_MO{=o96)&`+}z^1YJMQ7pi(JGk|aqI!1Ga_52IvHWvC8J6IC(R zg;lZcGcxT0AXTyu`SCONC_xaL-pktYsg~4w{Wb5oVA}-WN40I`*pf2ZP+x3&z}AHc z1hwttAP=A=bm!7f&_c7BDp1ZQZMOMV?MEB~7GPOF=1E;y3A0KXDI<@R?3j_>H6F?B zXa&fEsh_g(wPO8_A&AZ_atN17$f9keOgfe+Rt+rDgJsEpSoCEAuhi*11BV*o7A`v8 zc=fd$d^%bIcG|tap}uL)h@$`5O*$R921jz@D0BggNp4q%uTb1|0%|rOo7RVM3o6>f zavrw`)a0nko*379h|z=^@?5GVGF7p)LRAQ&2~OjgCN;z@H6MK*8Y#nCOR$;R#UZxg z8T96ACPYmoL6z`PVp0)Nkzq`}muFkmal!5BP|4~NlnYY-F!2cq7mEyvuR*U$me>ih zp)=4BGJ#q*oQ9hIjZ%Y<-6siiM+rEByIc3w$`F1Uqc(NAQ7i zQV9KLH)%TD2R)fM3q63$B;Vr$p+KhWU)HAu!b5Q2))tcK}pzdGb*2d`;?pcMYPN3e2^-!-wRgGSmrUVJxugaDh z$qc5&I4&ESq?e|b#D1p_>tY-zmYuIA=2^)RUD$zhj z1r=e=36KVwx|;D&%%_$i6T$EOOlYzaNy~!0=VG9h#WvXown^oArb7PFU#BOisCq7g zb^w&X^$45B2rb>%4J5e{o|T7sG?;+>d_twZA_d|aT56gI!$TVI^4>Y00000NkvXXu0mjf0-DJ^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00062.png b/tests/functional/snapshots/nanos/test_sign_message_long/00062.png new file mode 100644 index 0000000000000000000000000000000000000000..09b221dd68b995146714ecb3faf7446e99c48109 GIT binary patch literal 457 zcmV;)0XF`LP)U7qdhRp^nUQ)>lMX2^ zWY(eztQi2o0M@6bi)KE(6sbsdZ-=4D_T)zWHPIJno9OpZZd+AsNjCooIfosBB$d`0 znREhR58S!1sa&B(j6FbTE_y9o^kYB(w&S-{YAfnNtD=jfj-#6EJTkzQb?mbZ00Cp0 zRJh%7%XmNBnu4HbH4ovCNm)>a>V$J48IUg));8=GJ9)Kuw}I)CN)*)25#|X z18`dzxk`Db4>4NOiO`o?*+EENE{L)-vdZCS6l7P^!*>Wi=IV0j)fn@cu)8inS>xB-XaOXaU92S8t{IF_bVeA=?rlrO2{KG zl5NPWMrByD0~7~fOp9)+`Dco(Q>kk*|MaWyD zw}nia0jVS%x#^>^g%&ksN|75VgldiG&;iHu+f?o=k&ssLM)JUM%bTw}kJ%0+9R?q{ z^5zjI3|xZJ$XYhxAS_v_4!4=sMRd4XxUg`2Xrb3QSo90mykpxHYB+726@1Xw*P7tV zp)Ih>j{OMypxhDQ|L#rN4)24RY`h9xfZre=;5FZeVG?El4eRakeIdn4spyOw6Q{)n z8Q>5?m7f&{F+E#JGCV{mX&UQ=d7Eer8t0mlKd=5C{YUy|~VFofXMQX9_n+Pp~jc zs^K_=_UB?{U0i26zU(Wmv*y7G11BH{oFmaRNeQRbhz z4T!=v1k(DHuVn> zTY*<>V{>%aRWV_SU*TI7M|NtogdqfH62s&`VOA{ckn~h15$g}(%33r@8nVhw%JzkB zavvop+Ui>)I;aSFY|L~jZ5p)tVYq=h`PRn;aZE2qZ7QubY4yX#GdubAsdq8M_RDG3 zkE%)I_EiAqv68klYbgyXedacQk{`XFNpg4oZoDj(B}e}Yp3Y8({f>LU7Fg)C9tZ>i a%i#w^0diUh+mnz00000TpkzS-jDVq2e#s;_E%3xU*lYn1Jk|arz?7-_;Ue89&k-@MqYE3Q5 zXsH2v#T?GaoC6>OP(zaT$U`?jdpUxrao-*rifWDZ)xYN57i^l~^T?W3fhnoxA3p`j zPnbh6+KrsF0%#4LxwHtj5HYjX3LO$!S?#Td{TMI+x5r<@WUQ=)wMsTpW*+Hz@yv5S zI{-3ZYEc?5-s6k|QxNT0WD_n%%Az*XC;b<*k#5z*BJEWVqvpY+CtP^P#tnK1I~O0` z`Ri*f@agap?6h;gV%=buLy3R&CM`#f!I>ka>WMK5Ah9*)>45mtSr77r$flY&%1k?Ek8tF5AD&x7BJ zO_pjsuGD@rOo{;SbWMFU@ZUjaW?yg18CpN19t5a7l5sAuEirsvx24 z6a<4Jpe!jpw|oUHM5+h_%f2@_v= z<;6#wuz3nALp4br?YIeRGPyEIiW^Nsq`uh1jY&_q@Q#gF=;5$%*6>C@|5kuchqb^? z>-!n;__!j1{;Qj`95DwYS$Gxt0lo*B9YYW7!{X@>5!=+4mW%)y%d?qb}ws1mmQH-y_&-p=$P2gk#wvYjwG9Z^vBU9Xx3D>>77y5o0fqWJYc)jeZOWz_R|gN^M0WXjgQT)NxdEn@0w?vW?Hx27rLE zT`KIualM$Bf}m$DFX1GlEGR>D!e=2FDRSsGP-Owtqz}s5!PtNIE!~cY!Ij)N3q62>lOqNP#Wzixqr$x=EN*gI3u22Zxvdm9 z(dRFfEKbp%b&4gdJbj9;$|APg)inTQP; z)hK~E2Y~NrMyUDI&Bw}-iZkwIt9T?OC97BS>kE)3`aCM7RYOXW>kq#KiEowBRx)S? z#$!!AKmhLJvUbb5WnKqTfXAp*V;oXgDzdK@bG* Zw&d(CGv~ z3Ea8x))=8hjUFJHO*rqNFJ08bVF9M)7asK$Nl;WYNGWm9&V`JeU1Lw?-VT5TV{fVQ zvub_A5(G1Ac?c(=WI-Kj6V8Qns9CnKP<_^d*FG5FRPvmC2D%1v**FF9tj5?CO^2u#+wSczW zP{at&{N6rvU4Rh|a&I37=!U)<&l4d1E3hLqGE2zXL<)+&hkHQ~1VIo4!JjYbBvtKK S2PJ6$0000q@x7(j$Xv*MkK6cI#|l!71#g1~`&OZ!%lj5G$?fGlARLtW4( z)O|+g3;>nT2l=bqv5l{nA{E*0Wi`CAl2Wf%bNB)+6a6|WEvpktQds__Uh)RTN<6qI z1E2)1T==S-p^GEXxH-2<4}NqAz_R|GLTyD7G%Gquy7N%Y8jo~voEM*~4FCaSUuol6 zU3rdyTM+cD<`7QeR-TiFJ%kT=DO4y&QA?V^RMIh}CjG-zpV;~aEu2Ga^qd-0aTovou%clxunyEa z03H+fzKGGg6?=Js)fLnpzG{Xml}_1af~h4Xa)}UK=uE~pp)W2%L#_2uVNmPP8vB)M zt4b`H(U1Wy0q?zinXZ;s{DU+Ez$MXoXRBNkV%w*ok?3Cyg)XqV!_k0QaXo}fwaIhs v<&#r6gcTI3YVh(QY@K@$1VIo4!MphZ^EPkHtBT(+00000NkvXXu0mjf+V;p7 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00071.png b/tests/functional/snapshots/nanos/test_sign_message_long/00071.png new file mode 100644 index 0000000000000000000000000000000000000000..2948a655a76992b85a7f594a5b154d553c34e1ca GIT binary patch literal 461 zcmV;;0W$uHP)ih(Ae z2sF2d%>}@cCxKP1NHp`&>PSS;dp`@Zq$Jf!g1qKpfSpBV$po3j@|Lc$68?fBB^pdR z0kI_Bk8xHwLlr}Sal_e4CG_a90Q>nf3f2`!z^w2j@y&yKmRO{N;j}nrD-bOhnZ=c@ znzD|8S5RzO$s@e67k4-`$+yv}Mf>SvmfQQsb8751|$41@iq z*bm}sGIH!8>$OkD~+L9F{x@E@_mdY3#4b_5~B;!jK znP$*cK5+q35mO1NR@tC2`D3SO2uW!P^P-{s;+lLs)ff#YAoUWqH|GyWDgui8Wa6*n zSRu^}L3X>;l9$IdUyXquGXG7jAJE9?uV%+_9Eacw-*s>H{3Rm)00000NkvXXu0mjf DFdo%W literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00072.png b/tests/functional/snapshots/nanos/test_sign_message_long/00072.png new file mode 100644 index 0000000000000000000000000000000000000000..a6547499f07b7afb58da8ff8456ca80dac6bd0b0 GIT binary patch literal 474 zcmV<00VV#4P)%whPBE9w3e0>px2_8pMSSdmh3I8ChfPgLK zMvGw33ZN1ix%3tsq1q9VE`FW4XotZBY_FeFxUG>S8WkTT-+6e?h)1~N3|y(>G1>q! zVaZ$GxZZKoct3RAf~aSaLpWr&@?+5?58>u!)c2N@cuRf&Z@HrUC!n@E7C^)&@`L679=`Fr!{FtE?>o9p? zXDmWcW>YE)EGMD`lamIP=tgalX%|n;km9J6QF9eY!Bxugz^-gjSI_e$btKzTD^eI% zEYM0X!c>$ZI&T+E)G0bKPEIQ(pjc^XZZ}dKMS4(ZG@ApPVqCX+Mju7R(q0AH3Al7X zNnDNJVsSK2-sYrXQhU6s-q`%N8>z^c34X}@Hx+q+M7J;E-k;u%<2ZNY159vx;6$va QWB>pF07*qoM6N<$f+ZWz+W-In literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00073.png b/tests/functional/snapshots/nanos/test_sign_message_long/00073.png new file mode 100644 index 0000000000000000000000000000000000000000..02697b37acbbc56af16a365dce624074d694f59c GIT binary patch literal 427 zcmV;c0aX5pP)X3R$&AbeMo;`vryiiX>=MbdYrCp_Vlf=@7V9tg{^e6UH{F zvei(QF>nilk<}c+A-R>uq+t)?Q!Y&veJrZk|8ii4$4A9rs)78o{9Z5f3J`3L@H#~khO^v68b&da~#KU9LI6~d;tRl VP5J$$@vwpjiDE7HDTxp?G%2MZ2!bFOJ zA2HQZU>=mLs220*kpWNw-(1)f#%A~mSH0hL2`YJwy{sfvJUBeO@?gu7vB1-u{w9Ix zfNJsHg!6>KL1#w9WTaX-=ftWBfIFUK6He?>UXq5~g!x${sq}FkW67+^+w;RfyZbGO z;#wEzsaJj5J0%|u_wBpqyI+Ii9bT<<&Vtz{><+6*j9_7_qplq@v?Wj6Bz5FM zMveD`cT#IabO=qt(fostFHpl7B3yYd5&|t6r`Aw z0ZiGl(Ar~FUF1=g?4P7s>(_%*`3vKDt73C5XSaWzgFo)_q5d=XHP<#Pw4ulH_ S^)Q710000W{2M>h;wmU!ZMb-$&B6 za%@Ru`@{daM5mKBK;4bjHZti1loB=yvyF{oR-r18-h8&CALBS-0k*ez_aX_J6`drF zJalA>M;5&^0RUdJ4Ja0jeWZ<7b)}CBLs02i%OwnID9?w6y@ZooS}LlS_ALjbk`s^A zthdH0t#{z56LAktI==AV&pP1Cp#|7w_kM zjis?pEyHn4P!*Cy?6S9@Rz-_Az0*IWdwU{g&z{({MX#&q^|&${V)HMlGAd=-G+#@P zs6nZktya-w{zTXcA{$SPLcN);w>pl`043?uBd4XoC*7rprS9#4#1V}WYubW#MT?$+zFgXlW}Y%x;59*v{1NS_%LV|+-HVvDBW-1|YnJl{nK i3g+^F+G-F4ftOzZns71a5|>{90000q@x91uc9#p0a`6;aR*LWTY{v4ZspC!A(FB zXl@ak4#1MENw`$<(9Bm$k%(ybwimo+B~+_dbIk<^6L}m_VO0^5O!x&WIw`}oN^Udqo5{U!C2C9Ng4ga6@Rhi6NJrnT>PU`#xPE}0$lR3&|mE%J=rRw&~XaXj=NY%_%tINpqs*3F7yHmXtn4Jxs zrKGVJJsZY4AP`q87%HDi3Dx0y(X(N=1BBSxTRWod048$N3PL?t6_x(vi%RX}RTXu# u9(`{9%wpg|=H2L>0~DeD%^k;a994cN`d$9?+}hv(0000>KiE;X^csd%cjE5JiQdD$aYtrC_j=C?yFmq#-ef)y&rLIb;2dB z?hhy$nxX6z1d}45l#r`1Sy`#`oMCu<7YcrKn1JoY?!A?y>J{!JUU{%)&4}QETV@x1 z%r>ByF!B*sUSr_A7`OzLBdghjL0q_V(2$#Ok}IdGs)-{QOF9P7tW#qX>mJy(Bd3+4 z4wN1H&y$gP@di!2kdN07*qoM6N<$g8$9RbpQYW literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00078.png b/tests/functional/snapshots/nanos/test_sign_message_long/00078.png new file mode 100644 index 0000000000000000000000000000000000000000..cea20b0d25b74640e12dcc27d63061aae6d40cbd GIT binary patch literal 461 zcmV;;0W$uHP)X0#gw;7{18CVhyXzl1VJ!>&l^7PO36%RavhK+tYWAO zszTj8;&T9K34M@j<&J$kM+s7q^gdn}UfGgTufOK>1)3)Mc~qKK4O3E>{^?cdq6y_e zL9i$S@{)Y!=C4W%8yu0oLLcN>r0oa{2H<%8oI-U)CCDmjBwcx^WQ|7*95;%`Y6Y?Z zV_#`wudZxk;u4g5Rz3Sei5{?Jk%@C9nB?SLV~%_SNoHnR@w3In@Zz z*mx0}T+j`E)%EmQYLg3cc$_XJXgldnQ#;6p&cQT|Dray-Ebjw=y8y_mN-gDdbepNl z-STRnEZ&5-z~(A(6o0b>dF5EGz!cDpTMz_60001A_uzB8J}84V00000NkvXXu0mjf D6E4es literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00079.png b/tests/functional/snapshots/nanos/test_sign_message_long/00079.png new file mode 100644 index 0000000000000000000000000000000000000000..d06d03f64996c9a3003b9014bd5c96351ebeebcd GIT binary patch literal 446 zcmV;v0YUzWP)xS^ zn6v|+1!gY1Eu3N7LeSNO7dem2BL9?Qhq?L#ET(Tl);c8>tljm#) zK)~2r`tn}2eqafLD_e31C$*I4O~W3-Kf4qvIxcMsJEWElwTL+9joLG?>qMG6Ck>zY z@m?F;9a@2PoBJ8|n|4JQ|5u;VazqSfvTzmJfRjb`69X$x;K^~NPZNLqEbmpyXL3cu z=`TTBe~7W7O1`FFypj+EZzWk2ejK%FqPqTSHOgq9-$)Qe@30rjJEumyAFH9+Caug? zL+8>*VXk6q0Fv-)WfqcNJJ7vuax@gnl!~cn*Y{xf4lqov963o7We24iXDZNNcg_zd o$N&HU07*qoM6N<$f)~ZNE*1hdFUeOZjufOK%iz-ayaYThxM@R}65NcJCOl74>Flh#q zC1vE6uR;%-X1UI)ElLKom(a)S}ND+fQm>d()b;O^iSShumC zxz2(UFLzoX`d4>pIbsZEvhXVO02-Y93YI4YzAX(U z+5^C(LUmh7CL_Unq2Z&0Y^WJmaOBjtkGzZ35>#%U=q}f!%3m5lX_kBqf*=TjAP87K X=yhZ1QpL+-00000NkvXXu0mjf_B*_V literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00081.png b/tests/functional/snapshots/nanos/test_sign_message_long/00081.png new file mode 100644 index 0000000000000000000000000000000000000000..c067cdb8ed98417ec98909ee62e7233f5b28bbcb GIT binary patch literal 437 zcmV;m0ZRUfP)?mXmwtY#p_Km`Nes$Oj(@u`{w$Lf`zq* z{LG7(+|FbzASSG7;uQ4GMTJeX0yv{S76XE~S5CHION f1VIo4L2x6!h$dsq+10pF00000NkvXXu0mjf_DRiF literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00082.png b/tests/functional/snapshots/nanos/test_sign_message_long/00082.png new file mode 100644 index 0000000000000000000000000000000000000000..81d1a9cb846ea46236513c395c2572013db63180 GIT binary patch literal 472 zcmV;}0Vn>6P)NklO@veO2M89;0-P#%Ok3+c=S>PA^UxM9_Us_T3`J&zOg8l3BHb6%gV4M!Hw9eD#%vu zvDR*%ogLjeZ!AfZOvI6z*#=Qp}1^l2;zC*%pxjp|s(?+5wWV zYL^T91Gi1|)6^0~Ba0lusZp}14A)6*6*5Kr;gW@)bR!lc15>!^4HrJKaRCp^%Grna z^5<>#<~1P|*lpK-Mt;HW@2ZT7|7V}l=@28J_v`tnnyGLnJS)rgGG)iei6;0enw^E|Y^Y3jI@S8aXLHYC-M0hO zwQ{Xl(We~nZtk5NJ@a@@D)50^y?_tal=&IMW~`gO!DtA-_6-H1g?vwsJR zb^x@%l?yMGBdoe*O(>2m=)K%s6zvEM5^#HdCWXd|ENE21G-asr=9TBZIslNc;w5$7 ze8v$IOAwq{&6jXuN*45?n($r7hsqWU3-vE5Sgix6zi`#x*m{Q^n#IY3cYOO=8{8dI zfpxp~Gx-GTKUA4Q{JRfnJ0b@w*|-W_fXXCy<^YyypXpp1mF?So&N#wZkW&s~a$ghm zf{>B(Y*rS+D=Ki^Dvw=Q{ozP%#8-_&l&i8+{unUZ0r2c@x9dkKTXbP{m?eO=*pf{q z`js_ZSnjEA9CSmSAT$ZiTQ+@~p*uhrgJy+ttxcI1AL2!bF8f*|Q9zR}&TT;TkWpd{6+HVwJp$5|p5d8=m&Jxq6G$S3~ zY6{vTe-RY`C2-`zTV-rRwPv$xOVA|W(%UiOoq$%?*vn4R#e>7cGY_^r(HFQhT|3mu z!U`a%34@(3^oUDOaWxmjssz9lPqPRYX3By(*d}bN)6vgA_Mdl!qyUs#qFz95b#r-E}mI3mStj`&Q z&3S!y9Wuln6Ts;RyAZ2OBD#$jKAVI>xbY!1J7w!Fc1Ezwxh(`@MKB_qZe0Q&$V>}K zxoMvzHz9k%Ni^eK86y`IL(o}}>10$;BTbpw71~-tPy(zcqZP8JtbIrR-ihNmR#`^3 zO<(rM%6Irzx7Agpt^j#q)cDk{Cr(B=H@E}Q!sl-|`*E*Fo|0`-u=l{yT{}%d|B~oG iVuzvm`I96`vJGD^9iyHxx>M5t0000L=n`mMBu@|O@j?Lh^S3c-E1F^b0yjx357j(*H%!(6g3@@FtWjC_{C^wU7)|%N7TfS`VeNsSuzi;3-} zATenYU1fO{hI;hADb;3_M@uAawpx!?F9`NYdKM1#%at+}wN??1$}6TKvkS^*+iqw; z>40V{d`aGJTW+0f9ssuGSsnxSk4>R`Qc29UKh_Nm-l^WANa}$01$N?4gRh29((eGN z0h#*$q{Moqv1-I3Z#Px)NgamG%_SJ%hm0e#K;O}E9LJIQ0&Q!N&h%XyQ2+n{07*qo IM6N<$f(I(cf&c&j literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00086.png b/tests/functional/snapshots/nanos/test_sign_message_long/00086.png new file mode 100644 index 0000000000000000000000000000000000000000..5b67acdeb0c9580ddb406f75f8c07a0c5a6a1237 GIT binary patch literal 464 zcmV;>0WbcEP)Zq9}?0KJWH<8zpBtqqwn_&_dmw z6`zPX2SB;#wbvDP@r)93vH88cI&Rq#>8-zJ?F%$b{PRefRy(Goxq#3m$g^a5yzS(o z2!JJU=E7TN3r(|46N;ngLG>bgRw0N324H#p8b*CZC8$+qH*MEYC;7_rxY_|QVC*e5 zPTu2)B~lEAYU5^f;3h0-QfC?$H|>D3{&FWE)O-gq z<)q4{ZX_GlvI(geXh~0Mv^wQzrZ|Hflb*82J-tw`s~aV8C|Q~@$Xf18c{-&euk=UZ z6#?RsaYrmTX7=C5)jwej^qgQE6J$esIjd{Vp(g^&sFd~tl)iU< zpFvCM@1w4-2MUcO$v0NhEKEQqUymZ;5_B(W0E(h0{+BOYHH)B((jBV+0000FT= zmo#{ej%&paw;|na#Hbzf49$nfnMd!s=TE z#o%)TB!i>+dO>}(42h_IPs@QvR6@=AYxcG1(nOv|R9c-#NwyGC$!Yxy7*#+kX*0Kd z6h_FZRhyE5Tuq4^HegzQivoS^BwbW6NOWzY37Uc8nwNY&%*Js&$&^Fun<(CMB<9uf-9z0=gz>+hbu%AzNNg<2C(D>`OQa gfaB9YNs`2zFVmqzt!huZOaK4?07*qoM6N<$f`!1QlmGw# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00089.png b/tests/functional/snapshots/nanos/test_sign_message_long/00089.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_long/00090.png b/tests/functional/snapshots/nanos/test_sign_message_long/00090.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3&HnKs<1FD8!#&=}Xx$G!PoP zUqaXGeRw#IxPU|Sv6_gDO@(!!O><2D6soNNu}A>o{O-dA)lg0D+@hwFj#8uU=j;?z zkO%M#c2w0W!Xzp#MLaEfkXt0WVvBaw)CAQ^(G?BR1{ygWBMf3)`4hfRXiK?nTQ36Ogyjgi{)5vI|T7cXWVs4$fA8Zuby^A4|!srA!s04 i|1aoikS78FfX)u7xAbN92cC!k0000q6S(-AJ8I{k2J+p=pD}( z&xn9pQqR!3DAfOknb1Ya3wsBYScXboBxMcB50_%XRvy^$pebRP8vABy1fXPx)kbHm zpl%&1{>+%?fO?mcY{H3M%1h9on=s==p_ToXsa3ZA-W_sKFDi~ylr zUcu;Fv^BFi?vf4VUs1*y(OJ=6aOF{D_?Ki?@^W3wevlbQ0F|E1Fe*ttWOCHEx5s9} jRi&382!bF8g4go{yplF@{xIY;00000NkvXXu0mjfkjBYE literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_refused/00002.png b/tests/functional/snapshots/nanos/test_sign_message_refused/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..5cd876e891d02f69b8e2c05c403a6d45ca324101 GIT binary patch literal 405 zcmV;G0c!qn0YMg)IKg^ll|l!matssN7TIF9o?=K<$YkjzvD>p<0zCBxMI z4w_dl+kQ39Bj1jaDJ*qBTx3{$Wj8C~Ms+K;?aPAoF~S0H?9*y}_#HYY{uZ4__HOc_NomST>2Ix&H`n!)S;#z}^zpiK z^a`YZw^n}pk+`R|sCk9R8HxK~CI6F!EK)GCEg#s@77Qv}!2Wua?Szvf&*Fh79+=%{ z0oitChdUQFr;_xMJZj3lN;k?PK!!V2Zn{fRw%Ii00AO-aV$l<#w6s2}358dpCJtVSTi=Ye>@?i11jXG-+PsXG z(f3`U-&xQfO@5RK0yTA9c@^FN2(yj=uJ!K_YF+l^a#7XrsM0F$0ssI2002dN0XXd}kG#W= Qp8x;=07*qoM6N<$f?(-M0030x*xj)UlAepv2=kIQi(gv| zIsvS&mrc-Vz^}s`Ji$C~wzA7gQcq>3UN*tM8XeR4r3VApF56(cRDOFXjauod9$+8? zVoChw#$Bc5w;e?HpI$T$K*(Zh-bE7j5Z}0T9k=t)kwqucM5K>sbm}oK16X{(Vy9>9 zzu}iuhL!5nV^9F%^G$OIyTq0i>(DXdxiWrKdb!g!HO0AKdNx)us?8wl_2)rn(O1a* zwVmSK5BPiaz}xi`m^II6#?&ANBYDX#G%13U$Hw6GZ-8|Jt*@^>Hg3Y=C99}7D&F$I zA7U9YRh!i78%``686fh!ENu0TIY|Ig#Z+Y^Xl>ODU-~3z@(Y)N3=sXomN|=DNzdd| g0{{R3004C11OS-&y&;;^GXMYp07*qoM6N<$f(eGKO8@`> literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_refused/00005.png b/tests/functional/snapshots/nanos/test_sign_message_refused/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_refused/00006.png b/tests/functional/snapshots/nanos/test_sign_message_refused/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..9c7e7049cb3e9bcfb1601ec510ee465d38229d4d GIT binary patch literal 340 zcmV-a0jvIrP)b=%MgRq*37h4eRxPbkJCLY|1VIo49_}P}TKpH4$L<8?X{t;p zy+UQc_4@p%0?~E_&igM#?#L~IOHR(-<@sYotiy&C*Y&GII0yeh-p3zW9cv$Q0k>6Y_)5~SfP=m zSMUtz)%Ex|-o}7!H9hbQ(8{%C?kQVa?C`*Uj-J(h>P7(Y#?ZWvi?6}@n{fGLp>YTp myqR(V_$?>^<%seR_VWh!s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3&HnKs<1FD8!#&=}Xx$G!PoP zUqaXGeRw#IxPU|Sv6_gDO@(!!O><2D6soNNu}A>o{O-dA)lg0D+@hwFj#8uU=j;?z zkO%M#c2w0W!Xzp#MLaEfkXt0WVvBaw)CAQ^(G?BR1{ygWBMf3)`4hfRXiK?nTQ36Ogyjgi{)5vI|T7cXWVs4$fA8Zuby^A4|!srA!s04 i|1aoikS78FfX)u7xAbN92cC!k0000q6S(-AJ8I{k2J+p=pD}( z&xn9pQqR!3DAfOknb1Ya3wsBYScXboBxMcB50_%XRvy^$pebRP8vABy1fXPx)kbHm zpl%&1{>+%?fO?mcY{H3M%1h9on=s==p_ToXsa3ZA-W_sKFDi~ylr zUcu;Fv^BFi?vf4VUs1*y(OJ=6aOF{D_?Ki?@^W3wevlbQ0F|E1Fe*ttWOCHEx5s9} jRi&382!bF8g4go{yplF@{xIY;00000NkvXXu0mjfkjBYE literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_short/00002.png b/tests/functional/snapshots/nanos/test_sign_message_short/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..5cd876e891d02f69b8e2c05c403a6d45ca324101 GIT binary patch literal 405 zcmV;G0c!qn0YMg)IKg^ll|l!matssN7TIF9o?=K<$YkjzvD>p<0zCBxMI z4w_dl+kQ39Bj1jaDJ*qBTx3{$Wj8C~Ms+K;?aPAoF~S0H?9*y}_#HYY{uZ4__HOc_NomST>2Ix&H`n!)S;#z}^zpiK z^a`YZw^n}pk+`R|sCk9R8HxK~CI6F!EK)GCEg#s@77Qv}!2Wua?Szvf&*Fh79+=%{ z0oitChdUQFr;_xMJZj3lN;k?PK!!V2Zn{fRw%Ii00AO-aV$l<#w6s2}358dpCJtVSTi=Ye>@?i11jXG-+PsXG z(f3`U-&xQfO@5RK0yTA9c@^FN2(yj=uJ!K_YF+l^a#7XrsM0F$0ssI2002dN0XXd}kG#W= Qp8x;=07*qoM6N<$f?(-M0030x*xj)UlAepv2=kIQi(gv| zIsvS&mrc-Vz^}s`Ji$C~wzA7gQcq>3UN*tM8XeR4r3VApF56(cRDOFXjauod9$+8? zVoChw#$Bc5w;e?HpI$T$K*(Zh-bE7j5Z}0T9k=t)kwqucM5K>sbm}oK16X{(Vy9>9 zzu}iuhL!5nV^9F%^G$OIyTq0i>(DXdxiWrKdb!g!HO0AKdNx)us?8wl_2)rn(O1a* zwVmSK5BPiaz}xi`m^II6#?&ANBYDX#G%13U$Hw6GZ-8|Jt*@^>Hg3Y=C99}7D&F$I zA7U9YRh!i78%``686fh!ENu0TIY|Ig#Z+Y^Xl>ODU-~3z@(Y)N3=sXomN|=DNzdd| g0{{R3004C11OS-&y&;;^GXMYp07*qoM6N<$f(eGKO8@`> literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_short/00005.png b/tests/functional/snapshots/nanos/test_sign_message_short/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_message_short/00006.png b/tests/functional/snapshots/nanos/test_sign_message_short/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3(};6-Gx=-K^W=) zYEQ$f_X9-O*3agcWBAF~;OV_vKv1J52H%_H-TMKEIy9$ONoH8zECw8K=zbBgYJr`4 zH9qsNEDX~rh~KDuaL~4gVg~RRJI?6i(J$e=q#tY#X&sPG+z%AuPq6Yu_ZfN-8oFnp z^HmN{$B9G0A^KP?#KxwOV07*qoM6N<$g8mJS(*OVf literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_burn/00001.png b/tests/functional/snapshots/nanos/test_sign_transaction_burn/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..2135fb13eeee24153e3ebeb06e20f9abeeb813be GIT binary patch literal 344 zcmV-e0jK_nP)cw>vrwQ!gb+dq!Lx7Z9n8#A{V*G(G4>t3 zfjU~FW&M0z)^dU#vDd}_$l2J({MoTjfO~B(ejkK#LvKJtl(%Y6pMx|ZXfoXo(ip%- z_Blvk0G&DI9fi8N(M`+pjs21);mI5@nvT3wKY*&pR6h(yYN{U$ZGePP2+3LG#rb(q zW!7ls*g;!ay1TkQ*>;wSRmDsAI1%uLZ=)g8==uC>@|ET8{4peW5kqmfJk%x8&A5Gg zePZsFkMJiz2f@hxk3I=#xV+om7)h)F;3-IFT76<;eIkm$5Cm60C8i7=N9|}(dUa$m qQk*+>m%Debm7#PILI@#*kPsd%Y{3_XEc<)_0000LkR?}4hi9&l|`ydc$yFZ0AN*7y8)*i`_Ip~DYau+MF)8C z)^5N()GIV0cnLg%&j2bBF3g*12IOH)16=48c-Wa(PZ<4|b^}&7)iIRss}48e31{(4 zI^jk12WSQv(I2J~YD9l9^noU3!^hryHNVxWoXY7g{}-<_n9(6FyOrf9 zS0AOvd@ktb_f*`zQMUSB<}MXsU{GITeg<5Ur$~h%Zz)~js{;~Rc0!gx%2P=O;!fNx tLGY*ITv$Cpwkj9p-D4;K0001J`v5cmMzZ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_burn/00003.png b/tests/functional/snapshots/nanos/test_sign_transaction_burn/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_burn/00004.png b/tests/functional/snapshots/nanos/test_sign_transaction_burn/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3Svz3v(>$p)K|}2LJ$IRs6%(-?!h`hq^yj%?EMl z0?_d?yq>;+1pD?q99tNEGBtVm)fEucNM*o3P4a&F28cSerdLU3Sl=QB7U0nRCSuhF zyYy~+*59@;%$Fd3A^GI!*d84jz#r^5(;tsM#OqT3WP7ys0r|o`pb&q8wJ&|Ip*NwS zdl8zi?eKD(`3g8hAFGYn+$iKhD$Ei764WvvY7&4v*L}Fd4Nb}2W@<)lQQn<3yQfCb zH*vKZF=3N6U6OTM5hI47B?f#8nkxwmm~kgXThxckhJoZ$K<=r@e;SGbOVC_cDnSxv h348zm004l+`2g4>x~SxR<{JP2002ovPDHLkV1fZCj+g)d literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00001.png b/tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..2ef344121d1e67737c1ceafb3b898c8f5556946f GIT binary patch literal 507 zcmV=R5oMG<13y`U{=mis8$pN#x&Xy54QGiZ z*X-*-kH;oNkaN*wF`xPaoYiQuPa!)45|NkYliFcgjGW8Pl{Y?s4|y#Z_)eC$H*7D6 z)C}kq8~S*%Wt@cZMfG#(A7P~|?kc3J0j{4~hTbZKr#HKb@mAh%I}SkOy_@$pf^l_u z|76q|>_okVcH+O2$uyKLu*|WdsR?zGp%QaiuPI!bGMUCGGgP!fE81}VYR*jjj3Jui z>6mCIB7@^5IwN8!1srR{P*9kmr<{K%*rh?KCw@K6)QPtmhdW`qA9Viy4LAp0Qc~;5 zr2CyN`kP+ZQKJhS2UZT_pkF*4zXJcfVM4fRCsmY}7VD>>QbbS(DK5~%$`jGkc2Y%@ zZ1BbpCVLv{1nZzagIgp#5y6*?4o3!1eG_G<@|50F(lM%Jk2E(8O=Pds{VcL|&28UX xAb&3_yz`Lm=u literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00002.png b/tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..3b1606f858a1aad64116431d9d05df56d8f30ed0 GIT binary patch literal 504 zcmV;DqgC)&cs=o)t>P{sm54?uvrG|2_e^t(yO*L5*mJ?2AS6;K<&!;?8j-6* zK9A5jK}zCKWH>quh@KVTg4-zwyd%I7eqnB~*vs-Y=Db7gz#FhQs|4Mvf6n^WA6pm1 zy=q(|puE`7<;gzddZ;(5UP``%g=cXwLEi<4j)p4bR~vTHBRq%c$^J_4QmYRU8z9ME zZS@1eEOoB_V&on~BC}8=%=d74SqhCdml|ED`>hJ8!z`s|UG~l7kEZ=MqebA^(=SBp zHLXYRiVkV4%x!?KH*7D&XpzG9*`aZi@(cBmV7Kxkaebj@GBi{u^p5B>JJ4-FJHxh6 ztY50J_9u0&CCaW-I&7DNRgQcfR3ydnsF%Mc=4meMVn%$!0>|HLa_nUSDdm>xnPO)wycRXEbC6Z&G(3h uV2P9e^bR-=rs@E&l*_9t>d+(R9{p)Pp?n8dG zbS7#3w33xf7HE5m;=Opk>MA^-RZZ-SqiUmNryUqTEC{xYZKN+sU zm2eljlBhha-qhRr0T#=r*u^+djmVZFfFFd7O#2oHDB##DIm50Me}FSX-GEYP3b}}- zPE{Rd2&1u%|Z;xZT5h$YzZ z-!*q+ItPGFc}~&zPr#vMFqE9ayBgX%||rb`z%$9}Tnn%Nk@SHMqU02f)|B;2;wB=B9nebbX&#+fHuFrhhh z2F4Rw;S|@A$r6yd<20)|Yg(5&rj`foU)BU^XmHOlSpp*b56fA&X(yE{ZD>npv?_Ba zKyO7z2C!X;Oob)D6)rJ@N%;?^Xw1o`c}OCJ5JCv4#~%rL_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00006.png b/tests/functional/snapshots/nanos/test_sign_transaction_ipfs/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3A`Y{6#2iH1r4bCON%Wb0001(m8J9ZKij{(ta$^o`U9TW z0C9U7UcFyH;IsXXKnz1KN}Z>-t^rn~CJp-Ql6UVHh}4N=dX{94^}WP_0e0OJ5wjN9 zsaNA8{+3NcJp|DQ**mjse^ht?{bT!;`uVu5d|ayU?2pnsKo8sl3UL!8eX08lO@xN- zm&E>B4h_f3DWF99cumBfO#?rWra7j+g=QYW772jPc^$5(hDvhh7B!27 zJ-oV6Ji)yIf>17%`bakL8fu=Eh_y-dZ)F4zuxP3;s)JWd0RR910G`Je#r@QkcjRcO P00000NkvXXu0mjfP#K}T literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00001.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..705cfb351d4b620a30154294884ddb01e72fd3c9 GIT binary patch literal 535 zcmV+y0_gpTP)C*2xKp}|Np`Ju=mi!Sj2Hay4_rur&cZCpi)PqP$(1%g&^K9Ul$l34q&v|TFhP$ zN#6)8A6;tj4QSDTUZycOfS!F21`ZEfo{jh8H})9<$$M*gJl(Gi>Q!OZ`+mvexu6VN z&O>$rj=8mG&?s_hR78uD>sW+**AhoY{h$8?{Ye+@ay60G@O~#4K4%c(Dw4Sx$s;Iy2&4;!A?SoPo`mg^@4Dnm1JDfpIO?;&4(Nx`;71QWb~N z-Ih_dF{5DD8}F}vrcgs(0Li%|-?>Dn1i1Vu^+pEb_Csfkm}6pekI$)CsiAF&jVqem zq07*lsnnG<^~H=CHI-Qf!g?@K5ji=US2-qBM`q>Q)`M3GAdA@SL-RbH*)dDSIBn%LELP9Ffd4v>TC4{b3WY+UP$(46 Z_ybGu)5OTs$k+e?002ovPDHLkV1lqb`rZHl literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00002.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..9e1e987aa53cb172d7ef18c431d877be38b1cf0c GIT binary patch literal 544 zcmV+*0^j|KP)EQ-?^d(3M*Og{xSc z?>NR#F<^2k=mImfZgK$-HCI;A8G zL?NEXnasVs@N$dA5_RUdOlcn16^zA`hUIBOu~(qB7Ej{ZDIr8@GESKYI0u05Yk}#& zwUC)hJR+8ij^sLNs>6B1>r)XJ@oo%%cIUGQM2nJY75y9YnwX{)n_(?0BvKKk%GE5X zC{y{6U`i{=Tg=uIUpk?^C>nr-%HNKBN^*DPk4LN#=9`Z~`T2h&@jU>Fz66{B_wRo2 zn7y2m>jqwT2Jnm~hd0pAhFN=D$bCVQ{+$ZbJQniKvN iaW|A}cGEP?|Kfm+{a7(DWKsCFGXrEUMcZac3)CGwf+Nmo4uWW;|p-)f)ml5=mFMr3I!*Q-PQ#9`@EmOnHRAY zMAF{`mbu^Dd1=w20j-*wS&eb zfb0aEb8G*>O`^-qfoNhBWHHhQqiE#4X0l>3GZcCAk&EBV3FdPfSxnsylJ@uG+w|E zT21QMe}5Ce9ncqL{$Q{QL0C|ulqGXJl;0Jc2@rjVG_Bm&T!5;@mo}HAWffCd1$%FNj+Kk6n?vu@->l!4e3O*E-Edz2F~viT7zf078T6n&xrTJ)?Ms(My<% z7X2b-z%y$NV?y#jz739H+I;80PPZ@jKJ5Y3iZ3=LPO_b*1q;3V=CI*G`87*J7G z9eV+ZSgA@&JzP|44Xs9NQ9OSnFc+w$-8hA)!}J{ zqX|1XZ{Yza0RtJN5%>bYOF>IlO ziT<^*nUR8kB9*vtMlI0Mr(iKoQD}x!WM_FI;0{2s`P^A4QDXpTvMw}%c)5XbM^N_? z-mwtB*oh^_iZa%nZ*?I1b08QyJ|gc|`faobS0WR$-Ou|4@pj$VS&2j<@x}N6a}%rj T1yYvn00000NkvXXu0mjfjqvLh literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00006.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..cd2eb67bd77e12908ee342938f0e071b15ac2ecc GIT binary patch literal 436 zcmV;l0ZaagP)guuE)fk$2><{92;}{mKY{#{<lf0Q~Vlg8=WBz^@<*FDpvINKE>y%p~O8QI6vs~|NFUMrCf zU{iMnXmwjoJ^oWSVcO?1@ke8ki1Dv9}kHE3Yd|m4ILnge8JK4U2G7Nj4)GV8h9Lc3Tb9-RCy6z9dzWSHxXh(! zfY|}q*H)iFV=1S`#?eK%0C*GhVhj1ME_+1%(_cY--NKJli!T2eqC94uYV_!JsPQ&66vQXl+_>uUDGYr52Xe8swaVAUBIN zk5D>L3j%CLnI4RvtDTWtjg-~~;u@uQ6DGHeEJ=>s^5yhnj>0$6u5f8&BV7LG#aias zLSO)nc^PN??sc3mC3%69r>qa%>JHysOe)PP<$QJ7ZXg!nJ zTuttQxn8knU<&e{EAT(93UP9ECG=)Ww~;Z7R79E=Sk6;mUfWx^<`|mLh@0?p7`z)N cNs|0N|Mc0p)))Z_2><{907*qoM6N<$f(6q2761SM literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00008.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00008.png new file mode 100644 index 0000000000000000000000000000000000000000..1f6e99c9ae450b4370678e615443025d1af5fb55 GIT binary patch literal 538 zcmV+#0_FXQP)R( zJ0NivtLuIAF=b4c-3oZXm0B}v4p0x4MA*KLZu7%{oe!`+#T~#j=%!JRqti2LY~Z?t zWwS;1sMnS1_*~J-xZg>5`o@kY&A#0FbiD&m%d-A$D5fs!-%R=7N$M1Ol1uL4o*f(m zT3LcS%0gD6YUolJ=h|dRm#Yd5XmZsO2gyj>%ViPpV8^cN%)Tj0;h#_-#w57{5Ej40 zf|nk+sX>#}aO^l!sSh~jO1+srKha27hJR|X%Hl&~xHyY@Eh^1kfoL_*m4(vl87yQ& z87&XNk_zqByEj|M5z8R>reO&sGOq@vST+l}AhId6o~#CcFr=qTZzs9~9dNuMIRD^AN94?QQ6mw*CCM?OcGi$nQ)~xtj8jchMy4L|+&I#xZnzhZ@;3 zSXbxIU-c9>rX&6GORz1hN)rw$-oDhAPZ%3HS*TzzVnD?)L~dx zPYFm{n5+WH;f9RVFUwQ%RiLSGl-MU=qkdvn9D7={YLeDstg3THW7Ko0BDfZGa5Jjr zzcN>?=YtM8+{J|0001x Z$Q!|wAlIBUZ+rj%002ovPDHLkV1fnh#4-Q? literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00010.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00010.png new file mode 100644 index 0000000000000000000000000000000000000000..3b505a589e02d8c5a9b96d6a65bc163e08431010 GIT binary patch literal 562 zcmV-20?qx2P)o1?ab1GDhAnRj+BJ z$lFKy6d}G9!wxX(8QfwCkvw}J7=w)zd2yuU_)YL2IQ>3Gjx+qqMIEQQc#*~A!o1%C zo*?3LV$e)FEYSZ7GQ%SZRGu3@QHFm_JwePoa!Lz%&}rLt5Xr~6zWjwPXyb-X{55u- z5#uJgm6V{Vl^un>S@_eDo*Pp+YbytdD<`TdyVx(ulRa7XkJu^v5V-O3@1ZHt13 zS(D7I+7r&ZFSFl=vH=|ZN88(QQRbvo)8cT+UJXS#l*Ta)!00*XF`3FxtFlFj6@YtM)J_CwIsBd@)hjv zhR)y>!=J}UlaiN!kI(grGiysxieHGN`bGMgE1-;b#KayM$sKOdh{9T?z6E*q%{0hqL7XUB+zC9LQ9uJ4w+@4a^y0s$t57Hu3Wb~T2Wra8hdQj`-v9sr07*qoM6N<$g7<<4 A?*IS* literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00011.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00011.png new file mode 100644 index 0000000000000000000000000000000000000000..179d37aebf2ecfa42f49bcd0fb63eca34dc49e50 GIT binary patch literal 552 zcmV+@0@wYCP)x#&_3^j;8s++?6zjcmjIvgUC1|bdrxUu%+bJpu?dZ(s8OUaaYGV96YHq)p`eb za*_WHjic#2@?omNuaBuMW{h%I2mELi{w>wX6*7;eBT<=XzJ<{D26{eD|L`4KP~iFn z@oGCy%Wy z_*eUf9LOEn3TXLUUmLj@l}qAs9#C&B5@80s7JbNSLD(3c7q~h^DhdG=Q2ggxuvSBD zl}Lk?Y3CyW&y%3Hi_3GkTJD%_(VrxF(2S!9wKs7CxPUUnp^X_cd%j6h`52 q+jk62-0aE|aw;c?)7VX1C7n)+45+Q^T;>GhZ+XDeQbM!nPRaci< zLLa;9VGGbFLW!mNwc$!&uHeV-)@9^kw)^YncFzrD54N-Wq<0YydpWP1E(7f?qdoxK zS;aOs&Ud04Xkh&58GxJLtzWx!%}pd9ta&)6pcQn_oJj$FbmD(UF5BB z`ONuDDaHIvSg-li+`zIA4p(gOIIFmqN+)Kl2n|c*d;GQ3K9z#7?5UNHYCU+#(y&aS zSD#LEX)WlI*e>!HY2Whx&V-kvCB+m`%SbzV29v{&q+wKWQs83)fb|LNM3k3-o{RAQ z`uBil!1VXl5P<<`3VpHwITpyw0B6shs;h|#fUy$SW&aiUe-CIL94(d0%+iwI(MFjO mzlCLU{g2&12qApK`6|EY35+uU0000bqO_Kc?>r&)%*2lwIpuFqcKx$OnlMR(BFFu7~4Cg*7S`_7u!9zPHDsvJ6U zg{`$Wpm0NH*ZZ7fsF*O?*;fWE%JfFQ^V5KXKM;M$CjfacLc?xHo)a&3 z2vf1e^hhJH`%j^1X57ytJ$0Fd>SIK;}ppt?!OZun`Y3U0H^_Eq2TonBvGcx2^%chv3 zn8WlcJ?uUe%u|`O5^%#e1G<^8Nm|K)zF$cWNb>6zFTsCTxd(JAvepy#%W5jFq0Iv1 wn{Wc>wtneViW-9R6>e@}h1uSwX_|k{3$G*FLPjyZ(EtDd07*qoM6N<$f@)R;vj6}9 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00015.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00015.png new file mode 100644 index 0000000000000000000000000000000000000000..fc85ed1106c0c7c23ef37ba4af46752118b64d3a GIT binary patch literal 527 zcmV+q0`UEbP)MDAW23hpI|{8b zy2qMr4QOrdysR{Dlv+#Sqyti+;+~WkDdNN0=)8Vo-88%t+jjS(5vlR zaL%p$trP-W3Q?eegind4-azrtUNz**sK5J9a6IVTO<7IKInF+wZ2RAjdX)lNI>>Uy zSaUldaTl}ez0WaZOc=ctbb~XsX66#W9xREVeI4EA7lVxlL?7Y_KpwQvu*cExjOrV> zUc$85WO~@w6`T0np&7g1NqG9kj)P`j9(`D!0Ig+3|6?$ruIPW5%E6t~DRd{-Aa6|d z{O1%(B>J$EzUopgS>V?sSRur2$3^Z%T^z$wo~z{sEO>>_HH0o=l0u^ET+r@h6Z0rpi- zGe>1nu${22qoie`5(!<(m84nL?P5Uel+S)QEPe+(6U*0d@lZ;wDT?AB@dh}mmP2^W R^N;`l002ovPDHLkV1gc;{&fHV literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00016.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00016.png new file mode 100644 index 0000000000000000000000000000000000000000..1b12c2f0e3430be231cfaaf94fb92b9c10f20732 GIT binary patch literal 437 zcmV;m0ZRUfP)ErwqDv_O0001vyq@PzpnOPsEzs(FZSn%b zmLU$LH!3q!95ac#t9F@sN!#P|xIL&q-NL^UJ!x;sBHyJYnFsno2PDa|bv%l8x9G|C z61#Ax>U4*m#LZWIS%!ZoX=LBj292_B7ylh_#Y2po3ZCBbcL2}q>l3(FJRLx$t|aIh z@mNkH{^N%*QMgS0k+@KtUXhM@Vf_G_Muzpn5KIm02Lm6R39`_c?2Wt$KYw#YBUeDB z0HD_fNI{~|(yYkv`=~ORBwd$zQRuLVd~d*dSyAsrTIxnopsUUD#WIB0YhJ3DS__)u z+eO}za>)Bn=A>$9MobaLT4w8QxjdGnu~_+&5aNK=+Khz( z2&snJV=(P=?$A1qIg$wQ(aElwjk5!WjJRaI-kZSx14uyGw=r>oxU!LD;hA$2nPeG2|;+Z!eHB4J!)PEetl*LGVhnvA-}>;mMqUB3fiN`+7)I;j+ZY+?lvAwN{}d+Fzj_LuFa*Pw_X`)fW;5*~j2sK55uc`{&tD>kEK1Bl};&NOffY%R~)! z5~t8k$|N7gu((c%_JFA%E}Hs6*3|&ecRuac(NPf1gPKC7)*8VQJU@u7VFM&&JFu&3 z4SLINUyLm?L}r6#K{xb{8Ls=INqlx`7y8Sb+$A^|N2qj*kShQg0a(?dw+r8A72MA> zF-dc!=4Y^wq;~2vL;>z6-M#&(8#O|$Hd|9?5zU9dT!Jo%j@(q{o?5ycP3CK9T0y(1 zNj7A{o6@kO;~e;ZfRB+R&LzjNv?od|lQ@FRDa?Cezk9=0mq(w}xcQ1*kk?RP2qazZ x{u+)gwS5 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00018.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00018.png new file mode 100644 index 0000000000000000000000000000000000000000..ea15b9960033c2b9295c18def6ee31de3077353b GIT binary patch literal 532 zcmV+v0_**WP)XpHC3D=1sDS{k)-4v}%P<&bT- zEKAoD5uFanT~Y@Wg;*~(DRH>MlG<`L*nW{(WnCrA)_W|G-B?*J4%2g0d!Q+O+4D*x ziB8n$cC@}U?_C(+P81ph)u78<2-)NDQI) zVBp9A_PDq9q&y96(?ftgf1Gbhb{#~y>%?1AvOSNklgx=7I|)}F@60BVg&c(ugT6mMFs^ZMGlX^c)RY{QqG)SQ1ig>BKAE%8o3 zoLl;@G!kWvh0w(0Q`FQQln8ZG99h3_vc`-Ktq&q1`iyqSB8c~MSxw45E?y?WR;o6x zf;O_ajJVaxTm?8*vAEukIVKNri&McdTUO>0AZ{#<6m@Ma^K8Jx4b&%l0(d>f7O^Uu zrFwK2I)qb4ml8Q9mR*N+HPpWt#vWPKAAb|k66aWAKAduH{cMnQ=J>Nf4*uT{p z-kUmrv|)&f>_Vf5hGQ1-9V%U>AJXyoeLNntLSMrF6FKE<%2t1fRa9u;D%b)jNu zE@+8wFLFz&Q$D^k`_j=`&eEC7)Nae|k=%Ygz1rdU6bJB}1TQo&HUm2raYb7FUYgOX z*_^h6lx(Pf4wiGwof_xV#{;bb*G^W|YJwdwWyDM7>!V5h9zcSI|Faiw;)(CPjuAk} mn&5lM|CkK`00000Y5V|7&ks{cL9nx-l8eB_!y|C)6AQKiVH zxO(c?`9=!eyRImt4QP$L+@%To8>nYF29LG;VMz(_T^oi7+MV9q?&-%MR_Etq-0qIa zQi3i+h6#wo)Jr$?Kx^<3#6)naVXr;RS7FSLycs5LGzDi%+0oT%J96e7ver`2#)QsR zLYaqrJd6dWtiZPHiUl`$dd&f(!AYOixwl9Pd#p`Je1P>w-2qGkGL4#!B44~MAK`WP zSTm^khiSOSCD)v1KZf%1C_W|2L@!=7wRXOh_jCXqB`bRlI{RNZ6vDg1LkApVcIBRZUWHP^JZBL}9XKYWIG~IzE|7v2ZI`vax>U*)wSZOYRP&9B zTXqIxlO&6ATgsEiQSJ=8>X&7J(Dmx9bq a|Bn}Ue68yibtV1)0000kei#>{YQX`x6hB}tMbNu0c%V^vCfpLF`LQu-=T zJ$6`X(AUP!3x%{%YLUVyO`2y#J;^bW#m!ppy#9RMG)5 zn6eUw3Z;;us4@DgFLt(YbbkQc9ew`g9ZM`^H7RkNeKoZTp&qRtIYQQ42nyWA%}glr zkdKQn;UOzDTUPHoQwuZafO>VT;MiLvrFr!YNPK|xi{Al_24osG9GNkyZZLBQ&%39I zIc#}fJ1?3U_cw7*A3vg&i2oW^J3woh*53wW>a_l5(g$afQRqwp&S51-D7CLIx@KNM z%5f^1I8p-a-PP~ z11$JMW*vuh6kp=mIwc0~^}(ea09uyyK}fQUHW@oqEgD`5m;>0O5|p7R-6ugCaZnigo`*p`o+DIZ*h5&Bnj~b$Wh$rY&F+T P00000NkvXXu0mjfg-Yo- literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00023.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00023.png new file mode 100644 index 0000000000000000000000000000000000000000..d67b574a3796928155d1dd7750e8204726c4c4fe GIT binary patch literal 423 zcmV;Y0a*TtP)F?gQb)ls7x8u-Jx{u%W!)c_l{QFA_RuyJv zQv2v^fS2p&ySL8fO6iswihl^2MDJA^C%e|uTK)#$k$rwrbvy4BPXmyt$0(#OCi_|r zHTF|q!qdc`95?dQJEEu;+V4P7$XsuKIRaYpJgRh_ z^WozNZTMMM6+x!KlR~FeS~+~V9dT%wSN{J?*mBCP!-Lu9;@OzZzG82*I`7~pScA90001hH$SX4BE{Fe R?fn1%002ovPDHLkV1gMwxBmbD literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00024.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00024.png new file mode 100644 index 0000000000000000000000000000000000000000..caeac4c8df45878f9d89ea9776264642cfc43c01 GIT binary patch literal 554 zcmV+_0@eMAP)jLs&0#YZnsJ(zm z-v~6nx|r|*5F60zXiW}D=_BQ-fNi*SCdoQlplKzJpp2s4yifA)>;Zm zOz3PTlzAw|En~uL%dRL)iu76lh{2}+0I#J@R@i4uA>j?Y-{Jva49GQVI`W)&u|t>! zrfd-qU^V|RhB+ZQ^MCej5T3qs;6Uu3d%x`u0Fo^4Uk1h1<^79MF*u3JLMJhC4pYq! zRHi(QW2-X&mCj*_4U=J-Ep2|Dt3^{!@y{}_TqJSPa|Xa7X32n-FgF7k)lmNhwHKq` z@{%>YlnrgM$%C>e5a=1oD|Bx{UL=9h38-OIm%O?&n2e`!s7kh5pQ=T?FY#EwYRK6J ztcFr)fkj)Dl#7l$GP__GlW(tw)l0%-x51HuQmV~ZfBQS(*;kjo9F&5qyx*4I0~i+L zlpf|>CsHQx>r6O=XFZ}GO;!<6w#et5m2$Dv4A@G6MGh==f5ro+6Z`TZ*1X5=hDZ5N sMEWV>#_f8Oah%%G=fYDc6bf7M15}jgzt6Is?*IS*07*qoM6N<$f^nw(b^rhX literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00025.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00025.png new file mode 100644 index 0000000000000000000000000000000000000000..3fe5d4cafa636fc0cfa3d93096ecf3f6ab5ca5b8 GIT binary patch literal 513 zcmV+c0{;DpP)B&O4Hc2PtGW9n^dMNt$*5#;ssbpiWu0NN+DbbCQ0 zV&KTL?oD5p35o{vS{fGv5N<`|C=6qGILqAtJp9FmA-oH_J=~8*M#isayFD)2v$^Ok z26m#WQDg@nbl7A85~=iW)Y7uhr|bDzr_n6BB0cCkE7`s#SL5^VH%k7 ziiiU9NxSEdh%l!l-|*XDf$;K;11Dxbp8a-y0gz>7e;b`tSN1nkHMo*Gg{~y?J3Lhc zNj21#QweXXL~4hk9cyPUi2{2TZn1EZ1{Q+Ata>2taw$vG7Q5mU^KTzAz^n!7U4So& z04!2|4qFan^G(>UI>hqm8nvNRVhYQ)I00000NkvXXu0mjf D!v^ND literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00026.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00026.png new file mode 100644 index 0000000000000000000000000000000000000000..58c2b843de67a4ed2933b22e913696b585687454 GIT binary patch literal 438 zcmV;n0ZIOeP)$zG3qSsSVqn4<(tj$#^ z1DG}pRZweatI+x|S@U~p?>g;}w#Vmnd+-KriF{`L(B71_eHW``5%h;Ez?p{K+Czm* z4OSI=O?JR7wfE0#T|1SE8m$iPl3GfB2)g1DW~(;STlo%T|>&jSJ1wE7CD9tUm$M$guu26jQ_clYtLbf+)0-y^%MidgO@4 zj)0Lok0o8EdZZvCGcP2SQA<==%m^|m^tFj{Pr!a!F;ZfsjJn^-s>nk`JwNp{%ujPc zgG=XBm!mS}^R-%+j*eXSop@#4mg_6K{YJD}F$1PJK;|T5p~O!j$|+l gr2qf`003Z^H+efI%h1?{^8f$<07*qoM6N<$f}pO(HUIzs literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00027.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00027.png new file mode 100644 index 0000000000000000000000000000000000000000..6122e47548ecf22ad25d136461fbb29d56f968c9 GIT binary patch literal 554 zcmV+_0@eMAP)cNB91Cd zTA`x340V%lKxLzhB0?ttVvcKnjA-ce#Ao$LoA7IUOatimDml*OzaU1F-!D4OiOZG@ zIS?IyvbOqL5fWX5oui4lAj%^x8GJ~b+_EYWT_^do`oM)ju{YgKpf)|^!goBuP|9RO`+djD$>T%F$kGBO5tBCF7y zxH|a|hQ;$1u@fPw?E!Gwn3-@k73V1CMw1Z&e6gYsIkSR8b58hBHwv~45nCg*O0y5q zk0`+#pDTqV=pu&f_qGk->2Zo!)gTf!(@-*XrV|LjG;2o9&JNu@Q|y2u@P`c~teE3M zrAejooCTou(dxB(>M1?tN9N*h|0+at+^&@jR)X61A#Q29!MUEeg?$x{PL$(&00>Xh z9A8q%0otj=w9;7yh#I@vvShecGx3x;wIxz2s-~>Ewl<vLd8e@P0Pj;g0Q@{2E#j%X zJgR2_*Grg-O@>E&UGczkd(r~-jND)u;pMyT!2Id|4WAAGk}U7vhT!V*{>@YjR#Lan zN_r=6LboNI0yP8sSe%Aq{X8!WWPw_Zg!=TCC!pbsbA7g&ldknLF=KEYTay9x?GT0! zF;EW?W!j_hlmx^yNp7k(Dy1Mge5svhiIs0JrlEe*X~nY38vVQfHzTZ{i)p{XECb@G zK^|L<^)sTS20000S|Nn#gusxUxF~>xCB~7ANqKUXSpgc}wrLXDh2>5CILT=6XHR(x`erHK1t@E) zzXfAT2O~*z>e8o5{iH(KRm2E`TW_hTUgS$V;h>|*wNZ)=>mzKU=jO zpgM&6VT_DyP*d7uXdAW6!W>rvF* z(ofdQF1^B8{j_-bcE3);e<`&+A^9gn-zNS$;0lKrPi{KoRPcXr11XhP+TefU3w)KMX-?s2>bsFcM^;k!(etgxg16 z(a0;HrOs0uotJu)#}#A#KFWvYvB8OU;B8B4FE9_G|q z(7~;9sgI+){jtg5C1Mg zs-e2OXO$lJMU)tDH^{C!8|MHRt8ZQQ&m!>u0FphLLUT)=)|G&X#x!CwFX literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00031.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00031.png new file mode 100644 index 0000000000000000000000000000000000000000..df3dd877bf017376b55de68a0491e4fbaa05f40d GIT binary patch literal 522 zcmV+l0`>igP)!Wg5*;`n|SnZ}ZPe^K;5*{IQqq zJ#m>;mytyQINzi`lg3iM8XHHKu&?z<^YmR)&WNg~|Ctq3>C?5Nl*V_rTSdf)R>=Wf zt{t#2p~LkqV_dFrWs}(>Dq`lj0ss@sLYiG{+|*hXmFK))%mHZhRoB3Dq&eSwhcFSf zWYdt4!~7$SjE3ZnYwRx&IeYwK)BBZ+0>B2O_iqEZI=z208G|RuEc7JbPToNG=$cjN zO{)nW|5k)D;aqvS?0>?R5v1T@wUC>{Z7^R_NkMJeSi6+f-R2oS^tB4*#tm8sg@kj4 zw-~4YM1mE^>#8(R1z&e=3uQf{uMYH|nNE1UjMu?o?{ou^#n{(yrdr7EFtO761SM M07*qoM6N<$f-4{X!vFvP literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00032.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00032.png new file mode 100644 index 0000000000000000000000000000000000000000..e969f2d1039cad7d6340f20a95d6a4e5c0d77e33 GIT binary patch literal 526 zcmV+p0`dKcP)qUOK*&iln30HUwDhTV?TJ*pkxdIZ=!p+YRo<_D(xLwF%WP5E|2<$ssd5juTs7|s zn>i@%c5~VsNc+Hrt~J)W%6XT2MyEFX1(wI>=kkySyhUG&e&}1c)m~gjsM(jHrw;&G z%JSJ~>K^H*sIyh>AbC9#5z#HB*VXB?iE|ps`Zh^h0Tw zIkgsaaOqs?o2X3re6RXeLknhRsAZ&rpTW$>#Yb<%s}VDxO8|6nLN{uh%^;Eic*VO} znBv_!Uill?F7gA=6#8JrF>W6TgLZ@WKSwc+6D-4Rvi~i*tbl^Z9!;UOWhAZZ|AHbX nV6i5|tpC4h0RR910FccalSmac8W_LI00000NkvXXu0mjf`{T(D literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00034.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00034.png new file mode 100644 index 0000000000000000000000000000000000000000..27cdb1ecdcb537348b2210b2e696c6bd87432995 GIT binary patch literal 519 zcmV+i0{H!jP)nj|Q8e2f&Qps92t%VjV^89zSGqW|Y4C$8A8go6ioZ4X^HD6Ei{dYM!t) zv;qPPdiQy+b6nPhQdRaD6LanjC7@ea0#U2jxu{ta!hO*%?gS`%5}Ix~V)nPOP1x(F z7m)I9{gJEYO>cRP{RU?Co^iDqePK}o(1eWsHaels=x-)-a3@)X?!>nbOSg|{z2Ux~ z*9f|t5#0>*|uh{rk%b;ccrWqAZ>=> zwH(qk-KG{>TmV;s7XK(Q$o?EGU}z8UvMy4powvG&s))ELYY)IZPX6{l4z7l3p;?_7 zPrPq*7*(0g4f$_Y5g%VsaGXwVDM86KasP@~%71+JlO#!Q=MA0Lqj)}J@Ol6M002ov JPDHLkV1nPB?*jk; literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00035.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00035.png new file mode 100644 index 0000000000000000000000000000000000000000..ef3d6badf4d887f06c002dbed52ee5c3dea30bbf GIT binary patch literal 541 zcmV+&0^g>7nx<)*#>e~Rt5Tj18$kNxC3sx1 zRD%C6?Ov3m(r? z*6fs`030(Jzm-COe}%-+VDNPn*gSjHk|Uz#=0ENMM(-tSM@;3)UsunC!6S=_^qd$g zv;zwFthnBBjG@|<2jo=Hhse~f2n9e)EQOF=?A+AWAqLlZAKU>T;|1dgw@B^+x z*lVX35^`*Yn18U5*^pfNO7KNw&YpO;?ft=~0B8@i_fJD`b$kD0ItEwLS?Ed%&f%r( zGc-bbL=~w^*SWYD=@mW$>^q|4{bnRt(TTh_mj)S?C)em=uoJ%)#K*Q=J@f@Gs+-CT zy&G#pR8g&GA-8Phz>fbTt%lCLZ@dr&?u}fffcaHfyu0E;-2kKLlF(-Az6W5ikWj1Z zl9HJptF$9Avtcoq%jr%+DF|BwY=aMsd1=;M#G--MDtCv{Mf&I2hCgN_w*!)kZrNPX z_>$jJmbpuBJH|@0Cj~9vQ|;(WUi2f^P>sH}yk3i9@T~1F?r~rHj#=c+fF_OqgUk&` fzMeHr)7*s*dvvw3pyTKv00000NkvXXu0mjfnvn$& literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00036.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00036.png new file mode 100644 index 0000000000000000000000000000000000000000..884bc5bc041bcc6c925d99bd941df03c72ea491c GIT binary patch literal 448 zcmV;x0YCnUP)T`9^j5DeeciBzd$RZ;0S2F74blJjbMzOxDlsy3#*FA~Z6$+wN768obcSOrw z^Q;sEz&M&r(C)S@TjGbCaHh+t`N!kd3-G*uqZOs?}j5a)$a^ra3;(`XEGOg zaBlB7nVBPCrp~i8DVBP$dtkFPzIdlwG{%Azz6!XrCn-7j#zn+T3l=QnE_e$sGB!!~ zf?kJnMvGd|k&s^TRcOw*6{RV@jybLm;%QV+^wC>qosi+Y(PycZnAnoejF>1rv?J~hazA1RU<_TM& z3|Lsu#r@vKxR{scVu4lmnP|;LIuro0uq*`2VoOqcS!ji?W52iq!0Zt=(hR(CAw)hTRbTabHr6IbrONf>tH4=xsE{#6-Km8M`5f zxmJXl6Z61ZW|R}Xhiw+p2Vk24B3zk7Q#_w$h5+Ko1tX@?s4`t2lq!UR@Adp9SMV}s!ISC6JNl^q7sydA_I^}BohA@Pp!;= U)3G-(A^-pY07*qoM6N<$f-9ZpYXATM literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00038.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00038.png new file mode 100644 index 0000000000000000000000000000000000000000..d06df4eb064dc6bad9080bf4cb17aefda6203360 GIT binary patch literal 544 zcmV+*0^j|KP)JV@B~GP4Ea*ClPiyNu)IZdS175SsjT((!s^&#G7y zfU=VMZFCZSbTUWNw6Afr^zfk}N<`u5KW+n6`;xuWX8^kia-%sXdNohj3Y~z3XI9+r zZHx(Cp34jDRa=AJ?E*AZ2cwpB82^5PaLRC?^oOu081df{}=>Ur}rO5#$YEh3+=?zJzR@_Msd-Y z#d<`wJqM)dHdBx6&DlN3(_M4anl0|C7HIW2+pS1(v6YDyBV`APE;CHnGA1SSA;xBk z?~9f(dwFT^k=Q#0A*0FnFTN@Ra@I`TS1aU}@FwfjQkJog+KHmV_QP&!bG1&K$xsGM z)Icf16=%_2UvoyVyHfwgbqY0x-X}dM-Nd-LtY?ZE*omesc)}J+POJKC*Zj> z2SD6(uA-@^Dz?V?k{=O4m#}z!iIQTfshed!kO-6I2=o7j{J9LSAK!n48}5LF2ghy# iFv5T9i9{liQ1AzT3+mO=hP_z;0000HmLl7wy7x90LR)ib*@~uB;(S9*PMi0ssI2=JR@9?E%s2xpSlZl#bON z^(wRZ42rwUoK`0?d|*-W*ylXUZ^ocH?E`F&zn|NK8?-&L&Bmd+mI7OYP+)naFCL*Grlu@hGX$xnFP_UCp+W|M!y%18IoeBxjN(+F@>~|ol zU~8PSR}uoi9CapW^;o7z{Ny2QnE4%B&8-&f_tB9T>M!6>WT?LkMQW(O7{uU8kcF;f zFY=~bj((@u#T?diG?%RK$lDDY`Q~~wqtjScuH-j?>W|IL7hh+s(dbc2l17ibD=&sPIbWK0?T7P=2{$S4}M+J2qf=$WZT`38P#JKE&2CLw!K4{ z*On8D0+4o+e}h4h!(c_UOmLl)xa4tQ#*iXPFaL2H$lAN_4yg^FZr;SUA6%Lt5kqU9 zur+i77AAD_eJ^7y=TKQ?_8Aj%?hOUNOe_mgonq&qW=&+=$G*4&P}$4WnCXc5e;fM~ zHXW-L&hP?4ZswnbrY|XDpMYT=@WPJTU_axe03d;2|1ua<2m2QzVsIxS3*Ct$$(u3V z?H`C$7n*$qQN<`zqJgU>({Iqlt9D5Xx2DYE64#p8e@BrDT4_KSuObf_XljyfFeChw zt3l#PB%X^{d3~S13|Gg3zjKuuR$XXK-^lJBbH3ZY^#Xuf0F4lb!y9HHJdLUo`x-b5c zZ!%c9ZoUenTgzxCnW>iAu7(6}<^5mas$Ul>4}5T53?cwGBLWZz1fGUJ{p^IT94D0b P00000NkvXXu0mjf7jEVG literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00041.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00041.png new file mode 100644 index 0000000000000000000000000000000000000000..4c1f8737750caba87f67ed6abd586370e1a8dccb GIT binary patch literal 532 zcmV+v0_**WP)xQyA=>^f%_X3##SbCnR&T-BfQHvPIs|EibJ&ipLaRVTlTC< zkOS&U+J8`4%B7MRx-8hb3UT$vj+vu+)I9vpJwcNmvUhj{z(v4uUQ}8!B8O}yB6(r1 zsS^-*X2t#9`?y4#vO;bJJjF`uh$#n%fh7=fik*krIz{6->le2J$b8K-VmKPcsJ?^i z5*8IB16S-qT;2;8<4@q!&wdj85Yu+R0|#Q$`i)HvKpoQhw;`B1t$#D=gD1%-^dw97 za7+I2+!M&n@lkeN`NNp!DJ^0_T2x$)IF@(tKI2&pdk5f02k(Htd3QWw?X!mnv~QZ0 z+5=j#CioEJ?;ue>@xd}wRQqp#d}-SD!za!henTNAwdPli1og_9IBzNCny)tCaYB}0XYKTeVa&^Y;*q9_qk|as;fA|7d W%g2(u4(JO200005LGPpG4Jw@=v1bDfo1*uTvlpOxA1GyPud5r*pq7uNA`K>#|x08 z$kww@jJu_u935l0xlT=cuaF*IA-xu-!zNBYMX*e8e4B)=fV;)L53(x+s1+sv&+Jd6 z4tLC22@rrdYE01LwwyfrS&};$;_Cb(@#qPAe;VOM^e1o_WJG@&LZ}h_$v}fEK^D4_ zeUKO7cJpLL4t$oX&e0IOu)`l$Z1{myZ|N}RB`p4NAbKb=;NWX4F)A%$B~oeOxB4zz z{a8E{pK@jqe=X>YfOq`x@sp?gpmzzb1zA4jjTx+dysY{;az@UZaRTrP1aIUhn}ME- zc>h5sh}s$DUG#15m_Y(G1AVfr*eB#b#0oZ9lwFJvz*uW@+5ZjWRzQYi595ipwzTAT uZe!_(|4n2Wlq@N}6=5;~00000`1t~E{4pb%hy3^e0000z^o literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00043.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00043.png new file mode 100644 index 0000000000000000000000000000000000000000..4834cdef47488dd7ac9190f430ef7f1e5e0a49d8 GIT binary patch literal 530 zcmV+t0`2{YP)t417j&KMib~l#~P1;2Y5*h)+x05HKUyS7u$y!*6FGtTf_VMVi&Qj1X|wq za6t4OF!4Zl*ZVQYg$trNqsh3(yk?^(z&%(dV)ieyosXq_9AjRyQ4-MayJ~TFA9J(C zF5%c{RY2m6y&vbLuGfCU{wl(uP~S-ty8M%@NB}C$=--AD>Wu!)WDed*o1|lUHms7`6=1C?O zqzLfVP~T9omy0Tv#axQ_W&~cY+Bo()OF-}JzW4g^tq?Me=qN!7O2wOkE8I>3Cg9jB zn1HJeNt#Sw*2~xP8*9v`kMBQ_IY^QuNs>~^6UM`) U68O8-kpKVy07*qoM6N<$f(0!4JOBUy literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00044.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00044.png new file mode 100644 index 0000000000000000000000000000000000000000..596c402ccbbc2fea074970403ecffa6e8e3bb283 GIT binary patch literal 520 zcmV+j0{8uiP)H1UgsGwsDag-b2-ez6h2h?`iy42U53h6vK#b4W+#?b1Lu{C(cg#hdjOw_o;k}(h7ZQZ2*B@2 z{SxLays%o>87S6qK_m5-vA?nH9+u+8Eob5gN<<(DNF)-8|BE*PmZ|_^M1|7;0000< KMNUMnLSTX{JMY^7 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00045.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00045.png new file mode 100644 index 0000000000000000000000000000000000000000..278c328125fd8f1fa25fc9cf76ad7f030d64bf10 GIT binary patch literal 366 zcmV-!0g?WRP)<2FcPV({*rqiaPXc(~oik$hRa-J&;Ch7Hy!DbN zo;ya8NBrzEz0>!B$ux(;`#WiX$y+ib0h$!izYHPNi2lVO2P?rXw36Q-M?t*k8?hTw zE?c<0QF!azqF5h^ZpM!iKH7IepyG7)6^l>djSI;!eH$GIRp6ob(e;y|tP)qnVv6HTkUB;7Z z;z{iQ!KbC`J^)_};e$!tQs)uviLPIpX< zC1}sMlYI%s-KRAgV*+?(-+?-CcpQCNqk$8^Hyz@%_*zbu{PCACuGkY(5@BL-DbM>d}@i? zrua97%%Y4T_LKVH$`pK<^MtB&e#BM@(rYvw(X2KdEgfBgTr};dbw%w3;kg3Wsfigj z7X$cdZ$*fE(^`?Zf4rphN55H4tp>UMjM95=VQq2%X;I3};^crW_+?5gUfW;PkHj(OFlFAJt<=*}R2!bF8f*|;} Zd;s$oq375Z0FD3v002ovPDHLkV1ma);fMeL literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00047.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00047.png new file mode 100644 index 0000000000000000000000000000000000000000..59fb927ee1e037643d44b6d6e6764eaacc21789b GIT binary patch literal 384 zcmV-`0e}99P)8iKy0DCYnG001q=K6?hv9eZ{fsXbVVyi&(p z&uMK(iNcU$5Om2^5qm76-YYk{tTGu($6Mc&Cmzgi|3|;k2C*eAlYZP;ve2HC$xPx2 z5bC_lk>(LwW^J>DxGM)jvfj7Q(e&p)S$d@7K|oYc?o(12*704*#pAGDmDNB e0001h_4xozFbG8=3{?LB0000vxXe`Xm+J$V=Jo*Xh@fytqty)EZgV!>UQoq}GBl z1kI^CIhRV^>#TZX+yEZgXCM_$uVbB6Z`2#W51nSx*=spi_K#n}dczh?(*=?xke=nQ z3^P-?_E@T=(0@C08}gA{u>n#o)W404)KLFsum>YS6dH-wdpIT?vuQPwn4EbPUeRP9 zZ^{Yxq&XWpkocE3=qI)dmSo&;oH(@!KPMo~3J5Nr&3u5K2%+EM5pflQo`|0i#J@XZ kkWr>)0RR910KhbS0H;+O@&@H)PXGV_07*qoM6N<$g6VjtCjbBd literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00049.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00049.png new file mode 100644 index 0000000000000000000000000000000000000000..10ddd46776322067bb166e8e5b35cccf2f7c833a GIT binary patch literal 362 zcmV-w0hRuVP)k z+A3R6vV?wYad@_KK*@%Ft*x(>!UMNYzf|1N;hy8!*U|2W=`P%LlF~@)`{EvL%CjB7 zQ<3FpeH+SiO=*u-5=Uv%*F#0tnjQc=N*cQ23;+NC001!I58C|8Jp=*|8vpLr(it`kpD2k#eJlHqbH=)FEE`F9)(y9)P z9eH_97Q?>5vJMNE_51PF9eIb$Is{c{>hz-Y8lj-)k~2)zbl|RMF3B(YTJrL01IOKv zbq72>%VArPY08C&1;Au-zUL4X;?##J9>P4K>O-y+L_TKkwQp7AAY}gO2MJ!1pnqfb z+`f@V6%Yph8}%XU0&wI1llsXaq%QTHsWphCvQQ)j&tY^BdmoYPD2|q7$xXsgN@s@X zt|Z4i;9CQlzKD@-<-yk+nJ`QPgtSPNVUUBMBhtToX}W8|cpPR2@XjUKOP{QG+ma8% zu#j)2#?gupU-3sLCpj?+%*%`uPo0lm!(O?u_DM++AnFg1ZWMq*t wg?-5-M|QH`$`2$~YWf42Xlen9qA2F&0~wkKf_ZbgsQ>@~07*qoM6N<$f_YfDV*mgE literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00051.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00051.png new file mode 100644 index 0000000000000000000000000000000000000000..9881e9bed92a45208ab94f3b4fde065ec9cd7ae2 GIT binary patch literal 306 zcmV-20nPr2P)iX)bPeczb$8s1}pKPTd_L&_UA5H9A&E}tc66KJ{{sk{&cq2;{ zXiUD1`eZc#wfT2a-#CoaP+u6tKoevkO%8g84FY+s;j|aP@oNzjMbpW27D4|nni{}T zDWV^HIu3Ks0Bn>=4ycCO=7u+5O3_ri3Jm}N003|}FTiZG05Rc&4*&oF07*qoM6N<$ Ef_SohYXATM literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00052.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00052.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00053.png b/tests/functional/snapshots/nanos/test_sign_transaction_transfer/00053.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3~xI zpyOqD%zl6f=kfkHwlI7$X1x6B79eUgWWc{w@|^tuL>-#bt0YsbZx#g$;B^l~tSYce zSK}-Hwz*+C1@Rk|8;fIobVLAuF+bDqkJ~QirG8_5w4MXfiTe+Q_z~>*(zgu_gof@} zXuP(=({bV_;1GSZ9>i=jAP!<~4)-r%SOkbo0+8mr4tI1zV{(_5V&2g--{Tzrf_EIm zvX+MEZbjVWu)&dn_SAybh3$yBoosiZeDXh;y$!uKWVOlB%63aZH?$2anP+wcEYIve s?W!c#Y1poj50Dz@<0a+==nQruP)&Kwi07*qoM6N<$g6-p-j{pDw literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_vote/00001.png b/tests/functional/snapshots/nanos/test_sign_transaction_vote/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..ff2eef9dc5f714d9bf5463ef07642dd3206314a4 GIT binary patch literal 322 zcmV-I0lof-P)cWbP|V%>F;QByL$RyIX<_#<)X-3_b9?ZQ-E}9B zYxNfo6VQs~U42Isq^9~0!#P00EQDn8bJ#eP*BSvmfC2QXk)?=K5+@VDLlwqgh1o4Ugu!@w511(X6G8}_9cE^} UU3@Hua{vGU07*qoM6N<$f{~|-ZvX%Q literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_vote/00002.png b/tests/functional/snapshots/nanos/test_sign_transaction_vote/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..ee9668f421e10174bd812ecd5d3bb529e419481e GIT binary patch literal 355 zcmV-p0i6DcP)cS3Y3?Y~*`Rad*PJ;<1AczbDA%qZeF5gdG(x5X{qAJ`>C~af8 zRMmEE{Ks=1UTkM95xF|ecr2nE@Q%5Sg&cL9*5UG-N@Uo^KWlG-8Uby>R3fP(&oI@z zXD6tTAb17b2RsK@n(t?QSQJy!`oYi#Jz*B=3G{nd ztvKy3VS6%4aS5{lFL}Z4>0Fln*d5cZ@JqNek8yysjKJam(g6*vO^>!?)gA<%1CBM5 zG@0>CzX0X{U`ss%DMOv5q^D-Bc1#H&gb+eVI5V`n&2S zX*WTmfyz!TJhgMc*Gh4TU=Fw4P5&SFgeDk7T%Kc{yjggWNC;3yo8V)j^}=oU>h4<0 zVtg0H!mx=7x82%JnKA@bY4KLCQ;jg)0q?Ph^@+$?Pe3vjKV!vXnb=kcL&dShhniSY z9Df#vO%N8x8J@h_S637*ZGBq70VQ3lTYn)0Q^Weozz3Ef3R&|1=P)lh z7c+0~bmOvJb%b0+TGvMErHD8QO46l7AZ{kf6i>K(vpt#eBTTR!bsfMfVxeCYXh~43 z0#oO`w#B$d7GT+$xsCPSd^)kNhVs(Q*y~-vhon8%<*MhfcEBU>a$8wAFhMNRbwGUX uiEBS6klQHLyUF&;OI&jT00000C~^X97WRm^+)xex0000O|jLPr2XP?MUnx%554oprnmjw@g-km`pJ zqW2565PFX-Zp)#x6b>Op*U4j)kXB4yvp9w|4!hX@@9=ac>Cou*V(JGx2UtB{PkmSl zQd50r=!2Co3a#Wf_F0ZWvDbKh`bGIlJz7nYd3b%bRBpnVbmk*B)}XnRei}C zA*};22TbB@($oWNKlK=n! literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_vote/00005.png b/tests/functional/snapshots/nanos/test_sign_transaction_vote/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1b6f032112a3c5dfddb530d225ae4d05748b9d GIT binary patch literal 328 zcmV-O0k{5%P)aUh zq+NnWfn=i!t?LZ%UNx~qlEe95@w(?VsR%k@w`X4^TNFCTtp}0s?!4yqyVR~xLD|VD z2m>lzP?e25&ujGpPRFfY08tG09bLv)HY`(d6w**-|GXzVzLryEIu>;=e%f1CCNix) zSulV!mv!|G!AK4DCj%R-1YT$*hU2i1?EIJh)Q0{QO0;CKt-Yb{RK!TuGq;46KUwB@ zn$D~y^}sW#->n+Iu_!ix?qr+;7GYD7HrSjuo21X8z1sAk6FaQ7m aoXZD>;NAcO{i6f`0000a*4ZSTjY>*qCR?k#@ZsKqpdLQp>skw zdvC95QiInC=mv_n3;Spbxv5KGxw`qREM6ITF%KrQ9%7O=Kh zJIE3h@lwnn>gxew8+zKctkXT6K{^CsFQ$IMOMn;odg{ZXNKN&VVGfRjRp?00@g5Gl z2#!nL)LM~~0g*Srl59)!()!~!O^*ZbOL%Xm=;VMUV5s`iH9}ekUe-A%vv!0vhNYUa{cIp#T5?07*qoM6N<$ Ef-5nhe*gdg literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_vote/00007.png b/tests/functional/snapshots/nanos/test_sign_transaction_vote/00007.png new file mode 100644 index 0000000000000000000000000000000000000000..fbf10c596f220ae11110c5a8abe7c75081ee075d GIT binary patch literal 295 zcmV+?0oeYDP)LkR?}4hi9&l|`ydc$yFZ0AN*7y8)*i`_Ip~DYau+MF)8C z)^5N()GIV0cnLg%&j2bBF3g*12IOH)16=48c-Wa(PZ<4|b^}&7)iIRss}48e31{(4 zI^jk12WSQv(I2J~YD9l9^noU3!^hryHNVxWoXY7g{}-<_n9(6FyOrf9 zS0AOvd@ktb_f*`zQMUSB<}MXsU{GITeg<5Ur$~h%Zz)~js{;~Rc0!gx%2P=O;!fNx tLGY*ITv$Cpwkj9p-D4;K0001J`v5cmMzZ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_vote/00008.png b/tests/functional/snapshots/nanos/test_sign_transaction_vote/00008.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_vote/00009.png b/tests/functional/snapshots/nanos/test_sign_transaction_vote/00009.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3tP{{Ii&hx)K?k)WdJM)Q5H+u0J_P*5lY00029vRpj=Yx}mBwN9|AKaiml zK-<&sxcUJSytdCLu!-R}Q=O-uT?L|zx-|IJCC{rLfLMpd^eU4%wr>#!6R_JoGGf&R zJN0gS#NW1Mm=8gGAbn@C?GJ+o@E6d<7h0AFqknz3Jcwsb!Akuc4a(zhC2i=xSBSzE~ q1-Vo-B0rB(!J=jW00000VB-x)TKr!iyDtR*0000LkR?}4hi9&l|`ydc$yFZ0AN*7y8)*i`_Ip~DYau+MF)8C z)^5N()GIV0cnLg%&j2bBF3g*12IOH)16=48c-Wa(PZ<4|b^}&7)iIRss}48e31{(4 zI^jk12WSQv(I2J~YD9l9^noU3!^hryHNVxWoXY7g{}-<_n9(6FyOrf9 zS0AOvd@ktb_f*`zQMUSB<}MXsU{GITeg<5Ur$~h%Zz)~js{;~Rc0!gx%2P=O;!fNx tLGY*ITv$Cpwkj9p-D4;K0001J`v5cmMzZ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_vote_cancel/00002.png b/tests/functional/snapshots/nanos/test_sign_transaction_vote_cancel/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..66c411c2ebc833c701039f213ad4ff68cc881146 GIT binary patch literal 341 zcmV-b0jmCqP)_wxG+Yry2qARt#sf<#$}=)VJ~ zBlvESR-Jq3=$jydfC?r!$iuAw9oGJ!U-M%YMJ+y&Ch%TCM^JUq5BGkf8O_{y`#mQ} nq4{V^xv44i3V1v$0C_ea3_go|-rj`700000NkvXXu0mjfd&QW1 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanos/test_sign_transaction_vote_cancel/00003.png b/tests/functional/snapshots/nanos/test_sign_transaction_vote_cancel/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..019b9bb0edb82de019808dc9190cddcfb8938015 GIT binary patch literal 389 zcmV;00eb$4P)s;*kq)SGur26gph7etS*nbr(+ zH|+nG-UplpmwrzrA8JPRxu4;{s4|*~!L%qLJZ#v?yhiz)sF3R*cTP6(N_&f3=~09n zL}ekSiA~|`x=+kp$aqP)>RPTvT~WgU6(yBRcE!h%#Wmkd2562hk_V+x?Bi?3C|12< j<3$2UH1y;-gY56m>`To0>vx#gB46ynFTY``2@GtW@o_^!K$$ zR{veOb+4Ja&w+Fg?W@aozjdGVcJu1~aJ`SqgDL|*zIi^~{&Ad1^(%u*51)okpT5_0 z`QPVmuJIMC-py|{-}^7PRyt~Gy1!xOuIOy`S`WTsI*y+ub}R_rU-e7o_u;(cv;#Kg zLa)!)zI~tTQOkCw;Yw#x@T(hI`dVzsuN=INnYpz$-u_m9&sPE#2n-AcEA_9{iLuVp R|LhGC^mO%eS?83{1OQggqS*id literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_address_confirm_accepted/00001.png b/tests/functional/snapshots/nanosp/test_get_address_confirm_accepted/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..2cbafa446bfa451a2caf5b29e4ac91853eac84a1 GIT binary patch literal 737 zcmV<70v`Q|P)?HeN5__4CN|Eaq=2f7%=c{tTI5uE#+LQnQ00000cqTdLoOApur~PsK zt~MauuKXIGR`Ivm024JH>T0;I>m|Rgi?xYMRmFo&|$z+9sWnUcGW>S)$iN)*?{UqyiK$?(LFG4CgeQoYp8G!rA=~nRC(`DnxJayXax&Ne;ein}H z?+I$2w9=_HqxVn3000000M8_J45bHlOF|pVqh8X^e`@z+Uj;0yq;mgO!8)=wcX3Gy zizYd?wWHR*BJE{~M)qx}I#gL$YbyPq+FwhtVuq;YD{Sq^}_@mn>3qODbyMXj2aICII*UX_O(8*e0GzbroIx!si$Y%m6|x!X1 zOF|`?z#3RWX`)&YD~`*)Qa?+f{I<$j>bUtGwd2H#m|BOBLZ`GsnQ_TtHo~&gdUzi*ocn>0Jg}J$;PLc28lF%R1F=u>xk(oGrisU@rmyoXg6;D2-xNSqAii zd^nxjaz7YPFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00000.png b/tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..19c9a3e18c72d20e0070be1ba192ab60f82fdea9 GIT binary patch literal 375 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|_WKba4!+nDh2#G+(oVKx^Xd z67_fWo|~uJO_;=~6n2E?_@Dd1N1Y1Vx~Hcy0(C(^!|gqbtS_8D^XYwQEOT{HYYJ1% z3)`b6FH{xW@3-%c(s(F)x6#ja!P7_UPM!Jl>$2UH1y;-gY56m>`To0>vx#gB46ynFTY``2@GtW@o_^!K$$ zR{veOb+4Ja&w+Fg?W@aozjdGVcJu1~aJ`SqgDL|*zIi^~{&Ad1^(%u*51)okpT5_0 z`QPVmuJIMC-py|{-}^7PRyt~Gy1!xOuIOy`S`WTsI*y+ub}R_rU-e7o_u;(cv;#Kg zLa)!)zI~tTQOkCw;Yw#x@T(hI`dVzsuN=INnYpz$-u_m9&sPE#2n-AcEA_9{iLuVp R|LhGC^mO%eS?83{1OQggqS*id literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00001.png b/tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..2cbafa446bfa451a2caf5b29e4ac91853eac84a1 GIT binary patch literal 737 zcmV<70v`Q|P)?HeN5__4CN|Eaq=2f7%=c{tTI5uE#+LQnQ00000cqTdLoOApur~PsK zt~MauuKXIGR`Ivm024JH>T0;I>m|Rgi?xYMRmFo&|$z+9sWnUcGW>S)$iN)*?{UqyiK$?(LFG4CgeQoYp8G!rA=~nRC(`DnxJayXax&Ne;ein}H z?+I$2w9=_HqxVn3000000M8_J45bHlOF|pVqh8X^e`@z+Uj;0yq;mgO!8)=wcX3Gy zizYd?wWHR*BJE{~M)qx}I#gL$YbyPq+FwhtVuq;YD{Sq^}_@mn>3qODbyMXj2aICII*UX_O(8*e0GzbroIx!si$Y%m6|x!X1 zOF|`?z#3RWX`)&YD~`*)Qa?+f{I<$j>bUtGwd2H#m|BOBLZ`GsnQ_TtHo~&gdUzi*ocn>0Jg}J$;PLc28lF%R1F=u>xk(oGrisU@rmyoXg6;D2-xNSqAii zd^nxjaz7YPFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=YMjqtrV%Nn6esuj!jIMi}Btw`sohxwi1&U@}K{{10Q-!s%eVxF#kF6*2U FngGM>p?d%T literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00004.png b/tests/functional/snapshots/nanosp/test_get_address_confirm_refused/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..c80fa832578d18c8b1e4a2518b82d7f50be84ca5 GIT binary patch literal 441 zcmV;q0Y?6bP){Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_public_key_chaincode_confirm_accepted/00000.png b/tests/functional/snapshots/nanosp/test_get_public_key_chaincode_confirm_accepted/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..6212c8bfe57f68bb18b3f4a01245d360aff3d651 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|gLTOIvxd7R?ei4nr28CMd8tbJm*q^BEmI{nL+TOwRWZbCCKq zCCTuGs6$Vk)Vr)jExXIv)KVL#b???P_WnKp-zt`?VhrYMv(`oYZO-F9k+fFg*VKE_ z0S`>SD2cEqr7fFub^g-Z(f{~P9gt6b(D|ZT>DRoDeRkeH@^aJtPq@9_ee{@3iu`Z3 z%{#a2@8ABWg8BC2OZp9O#jP}c^KWF}PpJh(U`Q@*!b>6FA!+PZOk*fy(R@j96*Svc2-n88vZyyA0 r@0q@HpJS<)P=)Ycdsyf&9H_5gGX7%PmUO{a9VF=K>gTe~DWM4f&r`2^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_public_key_chaincode_confirm_accepted/00001.png b/tests/functional/snapshots/nanosp/test_get_public_key_chaincode_confirm_accepted/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..eb20fe5a337367e38f04825bcff03509c66156af GIT binary patch literal 891 zcmV->1BCpEP)^H)QY)C*VT$^%gF9Oy&)&$`kd}x(WQ-Utqo_Itv(IOJhEJvZM$=xMr0_KdIPX6qaUbbeJ z+SPX91eixOauLnsG9^WvPsl2S%eQVft6X_S`hkG?IRC&n_wcb2^aQG|FXv8vEQN=n zrfHg=2U0^laRyxIO}%g$>yw`+)OaFmA|&xd+aYi;Od}c027Sv1zXCSALr-E14To)j ziWwb+j{%i|$LzpDh(ArzE zc9nDfw2L~!MvCw*pWuDXK_nuvH<_Dxh;3iyN_;rP*iL{cNn+#e*2{@j@8xCNDV8Ms zfM|6w5hDtnrX(R5IeL7pbl-8~Yj|b1cHHm;TqG`j7Y?_bhW!lKf@}1!LJv)z_8(PV zS4+m5uz9O59@f&t4AC@A(=<)fO!j{%PYM9~P5_RHrl43Nb8g$CZ;XXn)^_tL!Y~@- zY{cT|`m3DG32e6QW{VD+?8pRsts0u<|G7MqkC}NlGJXqS)!hmDD@(pY;j=REE0@EGca9X)h<-b}NmX_}^Knx=UQe*vw&8lAMz R-^2g_002ovPDHLkV1lhXq;c2!Okry-DwXq`AvJOk#}uNQK(X?Dsu64T6Fq!*Kur0001N=PNV$^?LO`&-3&p z2Z8>hD&XsB)~B-^ZEdcl&9~TVSmQf0d00(S$(o*w_lNP|<-vp{BjqpglbNj27Ag<5 zb7lwOepjlC9p$QZ|AtxLr_0Dwa0B85_t2bWT?@!xa zJ5%D?nq)u7_#$#?sv_4YNI^HFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00000.png b/tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..6212c8bfe57f68bb18b3f4a01245d360aff3d651 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|gLTOIvxd7R?ei4nr28CMd8tbJm*q^BEmI{nL+TOwRWZbCCKq zCCTuGs6$Vk)Vr)jExXIv)KVL#b???P_WnKp-zt`?VhrYMv(`oYZO-F9k+fFg*VKE_ z0S`>SD2cEqr7fFub^g-Z(f{~P9gt6b(D|ZT>DRoDeRkeH@^aJtPq@9_ee{@3iu`Z3 z%{#a2@8ABWg8BC2OZp9O#jP}c^KWF}PpJh(U`Q@*!b>6FA!+PZOk*fy(R@j96*Svc2-n88vZyyA0 r@0q@HpJS<)P=)Ycdsyf&9H_5gGX7%PmUO{a9VF=K>gTe~DWM4f&r`2^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00001.png b/tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..eb20fe5a337367e38f04825bcff03509c66156af GIT binary patch literal 891 zcmV->1BCpEP)^H)QY)C*VT$^%gF9Oy&)&$`kd}x(WQ-Utqo_Itv(IOJhEJvZM$=xMr0_KdIPX6qaUbbeJ z+SPX91eixOauLnsG9^WvPsl2S%eQVft6X_S`hkG?IRC&n_wcb2^aQG|FXv8vEQN=n zrfHg=2U0^laRyxIO}%g$>yw`+)OaFmA|&xd+aYi;Od}c027Sv1zXCSALr-E14To)j ziWwb+j{%i|$LzpDh(ArzE zc9nDfw2L~!MvCw*pWuDXK_nuvH<_Dxh;3iyN_;rP*iL{cNn+#e*2{@j@8xCNDV8Ms zfM|6w5hDtnrX(R5IeL7pbl-8~Yj|b1cHHm;TqG`j7Y?_bhW!lKf@}1!LJv)z_8(PV zS4+m5uz9O59@f&t4AC@A(=<)fO!j{%PYM9~P5_RHrl43Nb8g$CZ;XXn)^_tL!Y~@- zY{cT|`m3DG32e6QW{VD+?8pRsts0u<|G7MqkC}NlGJXqS)!hmDD@(pY;j=REE0@EGca9X)h<-b}NmX_}^Knx=UQe*vw&8lAMz R-^2g_002ovPDHLkV1lhXq;c2!Okry-DwXq`AvJOk#}uNQK(X?Dsu64T6Fq!*Kur0001N=PNV$^?LO`&-3&p z2Z8>hD&XsB)~B-^ZEdcl&9~TVSmQf0d00(S$(o*w_lNP|<-vp{BjqpglbNj27Ag<5 zb7lwOepjlC9p$QZ|AtxLr_0Dwa0B85_t2bWT?@!xa zJ5%D?nq)u7_#$#?sv_4YNI^HFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=YMjqtrV%Nn6esuj!jIMi}Btw`sohxwi1&U@}K{{10Q-!s%eVxF#kF6*2U FngGM>p?d%T literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00005.png b/tests/functional/snapshots/nanosp/test_get_public_key_confirm_refused/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..c80fa832578d18c8b1e4a2518b82d7f50be84ca5 GIT binary patch literal 441 zcmV;q0Y?6bP){Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_public_key_no_chaincode_confirm_accepted/00000.png b/tests/functional/snapshots/nanosp/test_get_public_key_no_chaincode_confirm_accepted/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..6212c8bfe57f68bb18b3f4a01245d360aff3d651 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|gLTOIvxd7R?ei4nr28CMd8tbJm*q^BEmI{nL+TOwRWZbCCKq zCCTuGs6$Vk)Vr)jExXIv)KVL#b???P_WnKp-zt`?VhrYMv(`oYZO-F9k+fFg*VKE_ z0S`>SD2cEqr7fFub^g-Z(f{~P9gt6b(D|ZT>DRoDeRkeH@^aJtPq@9_ee{@3iu`Z3 z%{#a2@8ABWg8BC2OZp9O#jP}c^KWF}PpJh(U`Q@*!b>6FA!+PZOk*fy(R@j96*Svc2-n88vZyyA0 r@0q@HpJS<)P=)Ycdsyf&9H_5gGX7%PmUO{a9VF=K>gTe~DWM4f&r`2^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_get_public_key_no_chaincode_confirm_accepted/00001.png b/tests/functional/snapshots/nanosp/test_get_public_key_no_chaincode_confirm_accepted/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..eb20fe5a337367e38f04825bcff03509c66156af GIT binary patch literal 891 zcmV->1BCpEP)^H)QY)C*VT$^%gF9Oy&)&$`kd}x(WQ-Utqo_Itv(IOJhEJvZM$=xMr0_KdIPX6qaUbbeJ z+SPX91eixOauLnsG9^WvPsl2S%eQVft6X_S`hkG?IRC&n_wcb2^aQG|FXv8vEQN=n zrfHg=2U0^laRyxIO}%g$>yw`+)OaFmA|&xd+aYi;Od}c027Sv1zXCSALr-E14To)j ziWwb+j{%i|$LzpDh(ArzE zc9nDfw2L~!MvCw*pWuDXK_nuvH<_Dxh;3iyN_;rP*iL{cNn+#e*2{@j@8xCNDV8Ms zfM|6w5hDtnrX(R5IeL7pbl-8~Yj|b1cHHm;TqG`j7Y?_bhW!lKf@}1!LJv)z_8(PV zS4+m5uz9O59@f&t4AC@A(=<)fO!j{%PYM9~P5_RHrl43Nb8g$CZ;XXn)^_tL!Y~@- zY{cT|`m3DG32e6QW{VD+?8pRsts0u<|G7MqkC}NlGJXqS)!hmDD@(pY;j=REE0@EGca9X)h<-b}NmX_}^Knx=UQe*vw&8lAMz R-^2g_002ovPDHLkV1lhXq;c2!Okry-DwXq`AvJOk#}uNQK(X?Dsu64T6Fq!*Kur0001N=PNV$^?LO`&-3&p z2Z8>hD&XsB)~B-^ZEdcl&9~TVSmQf0d00(S$(o*w_lNP|<-vp{BjqpglbNj27Ag<5 zb7lwOepjlC9p$QZ|AtxLr_0Dwa0B85_t2bWT?@!xa zJ5%D?nq)u7_#$#?sv_4YNI^HFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00000.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..76560b8c0f3bd5e50f8a56f6718ab7bb80ca024f GIT binary patch literal 420 zcmV;V0bBlwP)x`j)$#)l2xD5^B9vd+L007`}(Kn1u*nQ(gU3$CFT~(<~$DUkDezhFAAUQ3} zEKr}6Hrvhe=ha$+4lgrCZz=Szj${XZ9Q$FKKXKgpgqT`u@~eeA0k6)fAa3Q_A}8il z^uw7iLF&k@gUxaT;buTjUb6liK3fL^007{*`rK#IpIDufBN=yN2{vMCW3^Z{TSo7C zG?k$=t7gHh_U-E*BjCD8v?L1X^y%=-$<^k!9G&w)U@|~wUpa#v| zXD_8;FU(}-E#VW>2p<7V_vwjf3fdX_qw&YGhXR>PgJ&Owg4(9VZ3LizQH(yNytDAd zcoo9pqYYiVi;G|4(*UFMK^@WD)5nT?I_6xJR7;>e^qe_gg{KQz);oB__#YnNsg!0S z(u@);#JZsN>g-IXW>P4x0;HiTfOfQ&sj&s*Q1XRS#peK;glQqBRGd9~eEvQlw1?V- zTX(|AQ0vj6D2gJ4(|_&A@)bWC5d79lDldEpG)2^}d2%xQ1og4|UG#ZP?2@-f7Q zb@Of2iw0nhqV@peVS}9HE~q#Y-nImALmrg`87zU%r50+Vw+wb_S;x-d?mp1# zO`RLyK%d@0J&&agTy94vUCaWpyr2VyQLIn}wLnNiHv;&`qAGs5SI|;lRP5~SUZ^OF zq9}@@$OZ&QLHhVK^SnB!2uk=jVhq$qNqdhWjfl;oE*ko~e9*gMI|Hv~ zx=N*Ip(JTWRqe*@KzxetlG6b7DyN%Fs*MY_oMk9G0@x?#*h5$kWRp`5+2qnRNKGk=g6Ax_=W;(A*`LN#Q(YS1 z`}YB}yJygTbP8IGGz9?w09Z;__K8^5?F4g~x)I8cDlN-Q`whC&t9#kQ) zY_$}Hy@|%!(LIr((bZAcA3f0iw&SiAqd=>{b~@!k3Zy^n3H8Wbf4a^nkzMW?lT#+D zp$nu$n&X1Bx#gPG0CbvKKrk7A?TUN9{bgj910gBGBKVc+%qVRGT^yCHH5b$e_SLa22uiZ3U z8ONe2#^ubeJQk*bckU;?1lf3x0{{R3004mL{B+j8t}FdG z&r>RSoa?$$Fgdn^gqJRz=PB8+<=L~FPfz6~s2VO&mFKIHP3|6Am-=bqx2JMR8VhVR zbnN&_4!PBop=}JlwMrDjXMi$xav@uyjMmadzeT=Ome4{P^Q{dHz(?2&V5z1sdzI$d zrl-333hfG^fc4b85~64pj{)k;;dX%RMtXY{XB(Tt;# zpwtlC(DQ(m@u$21ZEFJ66#rL4!&_fDA=!h@2V@$2zeMp`#HL0cOyH)G(Fa2bXx>3@ zNo%)Yp_-?$nIzd?e|RPUkcAKt}p-TG372 zP6jdUMgRZ+003Y;zIki?7?XAKD2D$Jnd*6bABoahk^p&-O|M0}Wuv|Qz;q2Ps;5IG zRqTC*Y>93e!ZQal{l{V3Wce8#P#$h1LO#~)(O=)gj1E{edro2A3^+PI5@pS#^j%Fg z$10lrEU$ekXL}&A^MT9~Ox*`8Ig0@R0DwXK0bfZaLS$l!#{d8T07*qoM6N<$f~@jy AAOHXW literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00004.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..426fb7d66ee4e30e948e6dca6f6e32fb7d8386aa GIT binary patch literal 784 zcmV+r1MmEaP)qeIfcqCc z+a_7jCDC1o{H#4GKFp{1AqoMglMkAR+L>Mt+%*zj2xx4xP(U*nJtk#b1vkp)|2}I(kR5wjnB!*Rng@>LfvgZz%EVCF>mzD;A zqrEu1%}rfe8h{pu!@Zbw0YIh1dEJ!R5rMS=>XcJtJ8QmWAK;dq--dENRtSP12)t87 z75a4;*z4=QhEuP8(!z}S>6xg^Z3ncfuL*$8MvU_>xbg)js!a~}X!Orw1fFmN*Pg?@ zt4Pk*Z^RC(rz}b(PrgDal~+ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00005.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..61f2e1745e00dd19c51132afae1b748eb472fd48 GIT binary patch literal 906 zcmV;519kj~P)0ulB&0U6#C*?1>3!Kg0*LMddt!fQ+8NuU{$klf2P>r%qSD*bWkXJVlj1f4 zrVOKa`g9tLu`E&(1DqCWXgU>V&!Jgh%T8XVn-HPrAC#_KO<89j+8n>j>L+SrpCbz6q9q zB}>ST2|J&VCV)THuVw|)!7;4{OQyTvIJ3M-{8XnGxeamFg6x|^Sc3Z;1Aj6reFx5R zG*d|?RFtX4X;FrU5@3O}MX3W)f#?}2f-iiw^u}(O!FexTpfr7-QuJ!$2%wvK*}P0I zv8i>K-iegcM=(1~HvC*#BpeXET6;>Bb6`2>6<#k~xiVjExc}2X2yN>CLp1xVhMuf_ zYzZ$dw33!2uSP9Br@_SiL7s#6-K83nP1a<4K%uB;7gw2(il! zDn(%Xz+V1rDW{*M^wQ~cTf|v2FjddN1iU7;SJJJP!aWUYA(N9GvqkqcjuHv~F1=+c zS4)R=ny9B3Cyn4I0}gG=eeU7Enp*?tWJ{)cYKQR3F1U)!4Jg&n8akoVcG*%*KiR;E zikW?zcPO6!K%-s|pH33eqo`!*%t@yw=5v^xW7IgYb2-yr?p&BU^8If^FGmxCq^E8{ z5Cp;Nxo|-u+VuNcbV-)pz6$!lLSVfLq6IQc9Hq-4KChf+AtYG7j7kWxOGC5??AuTW zXw^`s|1l*=kpxTFU78aW>!q+Z^!tDVxhx&(z^ve6La7DmR7`0uV~F1^wYtne&i_@x z)>-k4m6L|jvH>uWmUD_k=#Cuhn&Q?d1l@a3icg6=l6)h_{NJ( zBw+oLpW-B|x+T5~lBfMAePd6sO&ksr&?X-;5#dO02ks7DJe0keAY=2KJztAk3L1_( z_=w3rJRnmk-R!pM(vAU#$53(wkUOVs6Xpxa>exfxnc?GRuUxoQyaBLt4mVPjnU_}v zUVaW(5Sx=-Or@a3^ioigBuQc;WDhVLAWz8e3(mcZ&_0=M)WRHfO&d{K5LOhxp+*vG zLX{ME$5`U_NexQ!6~eiYVZ{h%!_Xt^8VZH33f*=gPz|+V&_tsNb>p}RAioscI}@Rq zXWax~oh~VO0=yo@R2x_C>&zmHeIUp3USR`1EaZ(#7z}UpO5dK-w>!Z3u)w*!_kY6Z z-w>WGi2ZZ!{{%M7LGrLO3nha=&N&F>j}7l|=O9&$2VoUo-m}{YzjJ3w)(?cCN8?FY zs7kiy4)Pk?<6iitRNmgFDwVLxoWe-UMW=nODvAH{7o{^9jJ?e?9 zd>@_1HcvprQuS>!I+=vOnAN7;_By$-uK>K#wZfs+e!)`>aEbBIS0z>Rl1JSGc=@}b z=aUnVBuSDeslSoe3iT=it%57kwariIu zeIY2pKadBOLzxpBtPF({`PVnUogDonNs=T9tia?Zt>>RX}puw*^Y)0Tk+y7X#U%wJ9ASI`BnfR-%jZJAoPb`R{xu2Z@EXezgq zv4DC5$Brx|VgD^rnB_dTiWS>u05NvpU~E&+kyx|Zhw1R-c1g~8u_Edo3$q!3(oJDB z7hQ-)Rk%$MRk~T#x=|g_FY!}sI-p&A(1i$&^fqv1@WN1zdIBAu_w4yBESI2Z+`BAd z{h{erDyEybLA??-j5BgI~fK!qVEP0>WIEG(FZ4q zRp=y>AV(i;1%_9CBR0L9YL8sbm)B@>#KrxKS-ci^@MPK?tu>v(Sc>R0OH{c`bgo74Zui*2#Zyv0Ol-x3-@{4jNYX%UB@Gt!!!%2)&VyLH<2hC`;UB2GY z0amm7!tXJ@Obzv+ZeZQ>4i3zKsl?b7Aj<32O0I>ew)&j|ZV&`P5Cp-U8kM^6cpW>cIbeOYG~&W)DEG(m@s{`OGg_@W3{r&MW5l-1znwX)d@nIT+CWb z$W3aJi1c;FF zE8gXk?9d}&7rLr&F|c48DvkiK^BYaUiDGdcAr7Xy-E5^Rmx?z~7Dn+>S;{*q11~=Z zZ0MVlE~ciS&9tVVAP9osAl7a?_6Rk1#ZV+ih;gp$S!{vi=Zd8P$gvBH8p0z#SPNg+0O_h#ZFR_wqBPG6ou@TT+!EizR;U)oyk!HF!yV|O2c*DdvnCDww$Q(;FKoA5$FappT^Y3jk zncp@HSUzI!SF0a3CFH4B&`xH}zFa=cy4ly9_|sRM4IFv6qx7jw)@Qx0wn~a?{w~<^ zfK9|ILX3Nu|LLFdkFeughad=o b;5+#TRPC-j*2h{e00000NkvXXu0mjfL0+7A literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00009.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00009.png new file mode 100644 index 0000000000000000000000000000000000000000..08153684a0f7b3ded3fd1a9f5b7bf708a82e570b GIT binary patch literal 767 zcmVIzVHe%2Dbu-d)!Fl(8WG`E{ldG~APJhJp%&F0Ns z-d=U^@pHfnb93+!Ln-KGq!dI5A!GsGdyG{`r@!t(7j_7}lMmnkfPHm3cR|Y0sVb?L z8`+Q z;^hvhQo&1(9#`kB3pqZq>^QF4`|+L>f$N=vPuVlj68Q?4^$9{rqlkUwrCK$sx5q!% zG@A|fZG`uoUENtTbUNan?-v&iKt?43-a!cot`9ne1!F)W3$hT2G=j`AaAiVxUwc;{ zWPHRvbPzi<=o9f%p4)1uBsyM#l!!}}h-JyFBuRqetK@dopzfH}eh-q`HzHnIEt?vQ zh^e6GCf}5`GEIy-C7HZTGc3~vV7E&mR`Jz|rUQ<*qt~)L^dRT}=o1PTFRhl5r|1b< zzawllsNX#W?SGuJw7-wv4c(uU?uOz>yK+JZAxAQ@naMuJZM84@>_IFt>z;=b%LYJ~ zIhAb;qO)3`t`vS2t6bWlR>msjXl7C_J=i4$`5j-=C57DadYN4Y!23cca(Qh@=Ajg^ xm@QU-{tp@^$~_PGYW=0kB_V_mLJ0Yt{0AG>C7lhK&fow5002ovPDHLkV1jmJWlR77 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00010.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00010.png new file mode 100644 index 0000000000000000000000000000000000000000..745d08100000048f40d136780bd924defe4a7f50 GIT binary patch literal 779 zcmV+m1N8ifP)3`Lz(ZsPkN$#==Z)h`{F!L zEoC{^b(O~47IK3RX7iI%%Oj?f=KOpI%Ir_+Bkk{bp0~@$-Q(ld^Fx`(D9h{d@DnIg zHc3W`Xbrd3pK|C9GDfjxNtKurGYpvl#xQvj#T0SSJ-5n>>PRGYh988~rlC!yDybPD zLT0OYSBuWh2e6w6!)<%43WxYA@eU}1j~IyfNG~0C4@~Y#ttZ5hxX+p&CL4mPekZq# z_+vvNRil|+=J#m)HB_7d#(Q3Cik&DH=N4)yTGQ3nO)cHIRJ@O885I9IOHCl$;@{i{ zEE$QhMk66;GFk`%0000~TKCnh1-tM!--2F5Pc2B36SVD*AwN{_iYdGm%{DEYk>B%x zD={Q^Q9I*_)grC=jV5dzKTt`S{%YtTl26;kStHhl*L1*<(A!6LjEIs?LA z9>}uESJ6D4v9EoZAjW84Qk^wtKCxM4=YJ9Xhp0}5_opGa8s47_`d}r9LMy2_8GSGm zxHrxq-)*rGv*oj16)vpDpu;y|Tg5Chh$+S?53$a2FY{a*N5pt$tsrk&wBaa35u%l@ zkwxVc_y?zV-bF-P&|k146r>*7Nx-PO09me zQ!}!#Xc%9^G--CwaoCp;o@dU2n8y|w?|90>`vZY<0RR9j;1_RoHa&N6?)d-!002ov JPDHLkV1ml}X+r=2 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00011.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00011.png new file mode 100644 index 0000000000000000000000000000000000000000..91bf38fba8ff25b52e51bb55be50515a0ad8e2f5 GIT binary patch literal 842 zcmV-Q1GW5#P)pQTr!tDd#y;^1Xq7YSrkcRW2)yh~RC%E?Eah~&5{JMJ2WvMa4jsN?ZD&-@$%rXaW9 zt5b>DK-Qem?{CTFlqu-=9qeFGgA!|2sjR6kD(}HQ#ZT!n>#E1#qheR8lz%yn{V z-@=A_8G@4lReA(D2ujLWt&3Q2jh8`6cl};Qk&z;-PhgK?iy#kq2UG(GKZHSr(qLIZ zZKc)+;Lde}#9nZC@xau!&Z=qnklA7kF2?MW8J)!hs3_essi&9#i*-35lBKf{sc<@( zIhYE&myrMQzX?a=y-F8sYGN4y0a&M0oANlW;9|?IzK$HNf*(*l6B=hk%S_u;n@@`0 zBJ@GVd4Y~ucuU(+#yjH&z2_&uRX`)Wt8LuA9KUj-ZjW)xLR1aiMO++0e7kDgpw)Z+ z9S{*0i1pvjK6Y>DF6^;4bS2j72qA=!rF_Fz(v4R^ zv%7Lls=8J|U{4B`GqG@ZR|X3bpkiA4L8K`lreb|p{;aNd#qw#CM%XGkswIhFUE9;2HlMblrfTupzxSW=qvE)bGUQZRcfQWxS%1)Y!kgzcTsAgE|I ziIlC{;eE|G7*!2+AFYRRNA_$UeJ<-|$l>H--uOM>GkB01x~~kmc>2&2Rdn_ UFe27=Hvj+t07*qoM6N<$f?M>H3jhEB literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00012.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00012.png new file mode 100644 index 0000000000000000000000000000000000000000..fd105b256a0d9a051d74421becaa741ae5e025e5 GIT binary patch literal 812 zcmV+{1JnG8P)Nkl3`I#QH|hHy$#==Z6^ei+gc#cW-y+qW(7L~TzmEAH-?ZB=qDL3T!Wy{w;YNCKuH z`wW}3`A4RjsXD`CZ3>qQ7}|!CBY<2veT%T1NEUA+BvV?0T>jR$uuV8;3m!>c3CT-i zsoA*QJ@y>1zBBqfI;Wt;a8nQf0DyJO*jK2>=8|ylYE7SSHR-YN}n zw>)`-Autl0}Ex(b}+8v)y5Va@D`e<)i!IYdK zTmdZ!(}Fntb|cEU|9{T3N#F}>fc8;Go@ZRJ%ib+UHcG9BewgL{puDwn!dMgtdmkXL zNWBP4sBv(#n*v$yB+Cj63ccqtX)QT+92`0Y#bRHL*K^{xp(}RN00000_;gn9f?B1M zlToYBM!DaK+BF$PRzc=`?CwjJExEhxU!!r^qpD~wVD*=ADvswr_LOU3Lj%ZSj&JN6 z^~-UQHJl9%(DnS~O5pov0;B6)AFXa10f~8q;FB1Qvrw1u2QI}M-I%HEIw=@qAR@&+`TYqD5XrWi}9R$zKsbbs2TU_ z5U4+xs#0~jslq>)R^B!zJPuYSqmB5e)My)syWyFe^9-^|ikOR8jGSIcrcd~Q1mr?w$iehN zF@3_vND2!bF8&ScB|Y5z^p!GrxLDP!X;R`GRW63J^X<51e{vs{e*)pn?aJ#zesT(rkYj~_AICNMkRnr5 zYf4+~lAuitoQy4L;&WmTQ|TH|<9>Ps&Te8Ys;+yybkQX1d5S5vpJMK=*(v`JHsF~<<%B@Nm>eUxgDHq;|}}=Yv5VM!K2OikO6P z!uT!KZguIT0ECXV`&cCdJ3og7U)b!bCgz5|+_RPeU4{4NuyvV`QU$Pq#a zA%u`O>3neHb7z~WK6*U>gTD<8l?{<9DSy}6mgQC}6paUCtJOCJtlXl1F82Oqr?6)f zY`J3!Kw{^BW?YW%JDf@BIi!4@*Nn6OZ+AL*UZHKbUmEs zDV1y|rBoVoS$LIXYmdJM=Q?@?QcfD`;>RX-e@ai)A1}`HtQ~iioF7WrJUsO%vicGJ z+r-L-$$TkaG^iux8_CtUOI=MkpUa zDO?ayH6n{^Tj2WkMeH&{x@$SsKPTFG2rHh`Fddr!QrWvfk&F0AUO}D25X$2?` zwUnYq(g4;3WuN9&Q`?$WgD+QUaAy@NKZY#jCAD1cZd<55rSS!3_uVB zL9iRc83{bU-keu$!cTE}iQ7M9^n|FC3e6>Kg<6lKsxHSB9`fxB=|wHRhh|<=f8~%BBy%5085(|jsyn4CPkGa%W{`2&AzpP42)>1>-+>1~5Cq@CFSr(n!@~VLx&QzG M07*qoM6N<$g4Ne}z5oCK literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00016.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00016.png new file mode 100644 index 0000000000000000000000000000000000000000..046bed7c911955e6a2a667df7da5ea4bd4679595 GIT binary patch literal 770 zcmV+d1O5DoP);YffUyeNML;HyTOr)2^Ub_;HH?)K-BQ2TNV&T`3 zhgO-*6ww>*t34%24O5JDPk13l<2XW|0A-r+Nk>z}Nq66(7uA`VmC4;Z-{=kDu}ehs z*+SP7Ad)?;;@whoHa0-7!pL3Y9lp75+-5lb0ieN03`BgU(~i3)ChyA9NQg6Woi*Q0 zZwRXPdv;5SKRQ{YYIM`e{1NqUL&YaRTseJx|4o27K)Qt^Fc>tuD= zY%&{&yT(1w0guc?U!|T9G?`Ke0ssK;7_G-q-zGuaUCdW(R>a*4_KYRVod&?a3!)N= zc(CH?f+Dih>{YR|dPK@f@KvOgrl0@ggrg652ol9{-Hh8;Ek{+<<92JM3ggw#2N}B> z%?Wf{4S-$O>o*%E{%kb>GbxGftwWLzz?=m{eDzUUGmRKa7-i=3w$i;jZSUg9da3g~ z^rAPQb4@_p#bWNaaT4yIttA+eKn%sM#u!YX(#aTuP-45+QF_qJ+c^TN<7GAH$%EK7 z`>vjb^nM$9UGUF66j_lbW+yVSKz?1-FOA;vL{ajzv~H9#(MIV=La&u`N>g@UVykaT zAp;dqN^c0VJbf!K?A3?H{)GAH8i4GDjBd6jx*U`~TNlxg0Uu_`XX{;vZr$KTm}8eY zOP0p=J9Im2hwj72!L zM5G8!l$TkZ91uQNB;tX_IRJbE%Wk3o004Y3f41IFpXXk&PXGV_07*qoM6N<$f*HDJ Af&c&j literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00017.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00017.png new file mode 100644 index 0000000000000000000000000000000000000000..db7a039a4bd171fede71181ca768d5c5a7be6319 GIT binary patch literal 718 zcmV;<0x|uGP)3`Lz(ZqoNZlJAlQ6^dv=$V{gGTe&fVED2#``nmuB00000n9f(M*?r&X;`8}v zCCj<*yA&o#m`bv=39(vPhgTrwWGp}5fi|yzsF-U!A+}BBWu4qSn}-{c4B_M_(556= zUL2cyO049Pp3SIiOJWmK;uA*A0K-$b>y;&<-{o87Mb#NepRuPPU1^8{dw4nnM972{ z?>eJ%Y=|Z~$vi6s%OZtCe3eHAD1(m}h`6Vhic5~kRjFA*bjE$w{1_cVP*v~bmJxq! zNTg~M)5Uyq4hccmpR*fIZIozHh4dy4K}N5x%*Hw|uJGER&ZXj&5R(`dGFpu$JlwJS zfcefC8!@;Oo{X_^1pol>4(|Vq8>Lqd^HW0unf5Rp2bv)BsEwE(XF~L18!@dW>4d*B zk@N`}f)^e_)tkhLA1Jhk<83_`<5)8T0_o4#D54{871`GqK>Xm>S1-9wZiB7D%dx45 zg!Z+L*I5hz zN`?)FvW0rzl`I?0;Ty62S@2ERne6mb6YG#dBZt~_!1NsKyrw_>>8aD2@|+*j)_)Jk zyzz_8b2c)-wCTT9oWUZzm|bRoGfDY8m+9=`%&(FF000002Q%UHr$+{I!G977)Af9r zJ8#7DiL3BmbBCgx%xHbG>+5q+hpE>=7`t4J=ks$1^@s6006+lFGR$%+xdJNXaE2J07*qoM6N<$f}8tP Ac>n+a literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00018.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00018.png new file mode 100644 index 0000000000000000000000000000000000000000..180b120458d3e08c64ab0b092e35920ba935c757 GIT binary patch literal 828 zcmV-C1H=4@P)Q;x7H+tdq?bA;gHgd46w$3BXf3s9c|VJ#z;Ec_x%VNI=j8Xy1#&Rl(w`V3xAF_ z&?H(ZtT)tGd&wpTNLj^_CtZ9&oZ*rkpe&QKkS$>s-FXWB=&nT6C+(`WhHA0{>DHlM z4KcL?SkP`|&q~?ZH~`&*u{oRuG^uAzS|=R;1i<9OCL+4-VBn60Nkb{k1iKQ~x#qi> zO+nqbqf<)$(LtGN&`m4(GwQz$Wp{vbpEp{f7qZQ%hf;}Tx_i4Rl^ZV=&*QudvWLc2 z3AinO=5xR;E751vlY)|wQczJ8Me#_w@{zsOj74~sy^U$_xUDP1OA${*QI!=<5aQM< zW+yIZslqdEO-YDZ8Ri^qC?oHr3Z@TYAG3& zI#--zt=R9FEf?WVc#{>x??eo8ML!KD)D`_?Y7XwCve2D$f?RWODH-7%QaU9uV9j-K zg;((pVn+FJdsnhnW8N!c4}B>@k~3-epmGo^5ITH-hp-=16P3f}y7RhH8?2AQ?%-e6 zA*0gCcGZq>t$w{NWsdNcN|6o)KK?_!GYPI%{<9- z;4^Bv2*X9{Td4yGhWll8B-LFpULi&S|giKgy7afg- zif(G`>N-+)K%fE|=+eCoWT&9y0b5>)xYgVcvL`^vvpe~3??7|Qk~aYk1=R7eDK$!) zOLeHxuOo2ez88e~JmB;6&t{eXln>ATn{ba`6h%=KtMCuW40={MxwBIM0000GDseT5Gd$9AC6K;((q`x)RX`K00000Sk8x|&3)g`FV}TR zC9iYecNxqRAq_Z@m~&034qINiv-9a_vp;2yq(86gdQw(hO+RV9ekkiGZK)j#Uye4V z%W9;s(a>1!B}q<@GK!^0n)s49!ju`H43k{Qmau~^Un+lTj>O8Q`$j5j64GR9GBg8N zs@ck3l~!lt4d^bKJhPUzrLpCx+)I2De+QI{54#Z2kzOY58JIMcQctiW(VY}!eOt`v z64cClbxB!&bgGrAGfW<7$gd=R2})#+cRhrqAz4{tT~yvJPiAE*un&33uklfF9#xkp zJ*2c+fZOBW+y}fe5`9iRJK@Dh@1pHy#f7^<&v zM-@A?uvey)LQ*Q|j^eQkY7UW-+Lzq*ik(uSFHW~`TQNEVN?m2@!@xeK-r6Vo80`S| z*daCr*{1y?#z6109Ub#w)>OIeMLaV=$%Q3Hy&_^)WutM2kQr_P000000KCJDBi6;< z$2n#rCUN>Zc$gaMkU|wB(x;ZOUv{#QTQtsf!lwhb>dBT!&3jc(#h1OIJzzUiX277G zeg2DDA~3MX1DSCtlnS5YHcP=gkSN`E$8SUFa$j9a+kDwM&a5Lz30+mz&jkmga`%LO z@CihWN1I(n!a05)a5_6a1EPrkFD(E703eWW5}SLF{{J!A00000NkvXXu0mjflwW?O literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00020.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00020.png new file mode 100644 index 0000000000000000000000000000000000000000..feca784b1272b2fffe1f1320e60d7571513ccec8 GIT binary patch literal 829 zcmV-D1H$}?P)ng za+c+kQe^k4@fh5`Zk^}Jr6KKYjdpD2r#K(#endo_0U%4I+QFy z($D-3STzg-^+rO_!*DSK006*Zo?mY)S>bHTlBM2cg58L(f`rc~^5>X^+eNT{{%{2f zJ{-eV!FVlicx<#C(hWCG87H+fi=f6SLPAPo6_;iF>+;gOoiaL8 z%Z?pzc+_b*l=ty6+g!`njz@FZ~;kwe29xu@+{cP*o*kKB&36 zyRKT4=6&57?v1dGjMje)qN&mP4}(5f38K(SltxA$+{$e8rgu-cKx4*S+29WJ53zlG zP4r}+eN9D*XoV`H#z|VpVmYIrbjqIC5rj|fp-7{u?V55jLFC>fnsGnwL`7W z^$5mi5j;!~YLVxj%KhODGoKDA_p(kOGbcDn@o#9P?<)cz&?uxO1!mdtw}=F!AStx+xfzA&|F{y5U-fbJi!yW?q-CEqQJE}4hi9S}HG`IbIdLh|WoZc~Mv zPV4o|o?-yfD|uV(FdR1h$nlZSZf&&7cfi+z4gdfE02c8JQ=D)zf(J{{00000NkvXX Hu0mjfc+!BM literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00021.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00021.png new file mode 100644 index 0000000000000000000000000000000000000000..888927745fd1eafc2468026ffed1659b8bba7fa3 GIT binary patch literal 837 zcmV-L1G@Z)P)W6#!;RN>o$Sd6#bG7tP6tV}f);ZH1+%piKxPqboqASg`6{ zHSE?*daD2?petpD-$NKDs^-!|U@jZd+-}y=jgN{)lAeU>pGK?IxU2iv zbHM(|=&R8gf;IzU2qA=!^VH5w_WUE+PO*8fh3NGI zW>$|;>S;(le}(L9g^L2GEl{%R=V3qyQfGAD08kXL#g+CJWiQsD0|HJS#6~1W5PaVy zDBD;Vf||rAF;`Yg@!>7Pf`P+QMD1vReg{;C9rBT zVq3U}%%2rKSFoW6s#UP}!>&$HYGLp1e}7;|B5Pn2I!U9GIR;Ca-@SK6SFMXidWr<= ztMSY`;rxee@5$;lJ=pd+QiQ5#hKlwHQfjBFAmq$Y5l7X+-P&q#OEz;vO__;Nv&2Hb zC5YJ-P3&9KJ$qXQL(qg30HkxHx#QMc4*D?X=jlbFLum<>rn-N1>~Ns>))Y?4(N9GE z5#tDRLQuT8ULTg!o@q6ecrXGq#b>v+I!gp4gb+dqAqA%I1By-Fwhh_DdRHhmYMJvZ zI{1bFi#+ech@bw0m_w?xd|YR#H!nwOoND1RXU!kgO1-|b|0SR)xcX@hsY9wXP8s!W zPgj9PMYbu3%743R2lTA~b)1)?PQXv1?~Rz0NvLY({px<+&;`mptV P00000NkvXXu0mjfl8uKu literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00022.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00022.png new file mode 100644 index 0000000000000000000000000000000000000000..4c25eca4a42f750d9bfc79a6559fba4a70b0c48e GIT binary patch literal 857 zcmV-f1E&0mP)e5912p>5t*a~uEw00000+|F0PCZ%*;oaZT} zEGMO;yC?a4rJv`SGf0NV{|LmM{X1Z@KV^(^K+AMCF>|G#FIYorOUv=_6R;_(ta=LT z4fWNZa>xOadMKOOlgQRJn<*ne=_WamO<_A-{;9k$d*YDEFs0-yO&UxlT_b>{8m;WF zbV_Y{0KE#uM4IlUJlU)86mJr5fO7I-CnDO@%fMZomxfYm2{wYxpqP{7LVBklGw#(- z%KW2K%~XwUidL}}9Y}l|%8meb<%})DdLnC1J@l6;&5g8tWv8&uE_@hy8DwvrRyPo? z@tNm9nmI-wfA6Dux<`|d>3S%gAVS{~ zNBPzzN9%8t%BS)?Ud*Z=TCd-#pNUe0^s;P*RX?lhtw%spN02orx&XosrjHb*pN@0h4#S+ zGTLA&!SI@5!RbM6 z3Y@z5>USoHG6gBxq4{n^S4sVuJs0{@H05N|ojy>;e;b->bso)QhW-Lak+^pQ{m#s4 z06H+GZ1lFL4JIv4l2WUO*yGH0YN+4v%GNnznot}IJL4Sz`eGY{)fCIyR@IZ{H`_8V z!g^i)wOw%r000000AvRIe}HF)%5IQ*J^%=8?D|XC9c625>OxJ02gL9lgin@XQUp~5 zuM6c+!=^NK%tXHRq#CDLLRGcojD8kdKb~5Z%fo63`cuYPsk3B{hyKJ?#*6?un}??t z1^Qug4E7zsDh4zF8;;fh-5C!08TxHiQ=a*6s&B-wDd@Ur`mB>JA>VpdZ#_}^xYJWY j1*A;?00000@F;!(KRuv#mn+1(00000NkvXXu0mjfxNwX` literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00023.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00023.png new file mode 100644 index 0000000000000000000000000000000000000000..ae2ca3f2242ff7acff0dfe67286a52e5770179bb GIT binary patch literal 765 zcmVL$rd5u@R;`b!SIgN#|sjh*B=@d-m#fH6%Dp002X1?rPqAxZ57*PPa>2owXpM!jsR&$xA#*g)VV1!-zz* z=dIXPy_7q2{+HW`mo!VUM68Dtijf!}c%#i0pU__oHPG}?KBp#R*q0>nsRM8*nMWLh zw89>WWI6q%h&$Jpr+S{GsXbPkAIW^^3K$)wmR>_yhjqRkdT z8mRH_a$~#1X&~IfMt8MQs0MqF!R~CIg|?>A$ryv7d};R@(t^_^WESe>4|yiM@65_e z5&R%yystqD{qEdSlT>prhImebcG&#V45E_c^FqI`7%idc9u3A2Q*CC8aS6K2EbYyz zXyx6f`33_pRGW%c-aVKP`4ZljsfMK%@Vn4ffJccG%RM5fUu12@kkDLntQ6zka7bPr!^#18!$Mvj15Uz=8Mp%M v9a~h1^w6x67&z6<<*Nh$00000fX@5@m1!ORo!p-<00000NkvXXu0mjf*ywJn literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00024.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00024.png new file mode 100644 index 0000000000000000000000000000000000000000..91b1ce5690e4ccbfe302ab67423fd85cfd3e65b8 GIT binary patch literal 859 zcmV-h1El3-^fdOBW*Q+Rsq9}@@DAM^8XwzD| ze!SmrspL4VHA{HcrJ?*Tyc-U6*z(?^oxk1&kDyObpW?op{@HWYfB(`~z70~Fz@WsB zw?WU<=d4#cMq(u|?yf*(ig#27k~qVbCjg9*yO1qmN8Ej>|Dg^;HSfk5qqSx<$cC*l z^#rgCk1BhW&Zn;Eu?x_|(knx?JFwUkuM+Qoe)3@_B0AFh#9f1zrc&w&HiO2DNY;jU zET)z-I|ZqEA1;CU2Q$o6&M?PT{ai;c1&oJ@Z$sH9fL%Fbi!d%^o6`tEbE&4f-IU6W zv)seD*Fg49W2+ouPQUX#;M6b-_>D|K$>2GpD2k%UrgdaGRZEOl17UBv)A%mvewWGL z@bxjAa{XG=C5yEnswl8>`Tbi`AnY20MHyw42JlrwDx}TXH@=Kv!HVFZkp7E*s7}4E zE%6)8szzK-M*Im_(&4+OFPF-8WGCdoTis)0|O~=9jGCjH& zpMaSJ4f^P0eY|oSU3j6ghh2L)zD5w;E% zN3loA0=Rv8M;if(pjS#{&06Y&HOqi}3*y9gq_RMY$YF`QfDs_=En&;q&>5vu^+-pb z_vmN9o~!aIJ!C$RaWsBB92)T(16CLBQwufvpXdWpE$%ggA4 zay&y3xg~^xb- zB?iNdxr57dHLHX2gT7wFrZS&}umm^|e3049GtP$g@~{&O008hF=$9P&{ryNS?igNB zX4@*LcWyky=XytFWsyyhOuB9zU-IUDgYutm~bGegnF z(pKm@&jGuJVMDnsE@&||9|8aX-~se+Nak&6wx7{P?t*HSIc?e8-sqHJyC8NpVP~`+ z`IF{A@0R`Qc~DWaGgXdS%uey=Db$qlny^!g7P`<&G^O&W0cPe=#;c(ULo8n7KunE# zR6$ESAh~5{MORrf>-ACw+OWCrqoM6&esx>;Ks;}>WBv$IEdS=3ITV`>3AH18>z0kWc8X0{smCem-3Ij^CscdYQ zcRmw-5U!Ij6C=xOQFIiqX`XtCEW=tL%gPg9yld*F{(`1xrFW*~UuITR=1i6g8lr=m zUT%nXYuYJts1_u$*i$zb7fSe~4p^_ywY~5hveUZ=)5lWm5f$iRzznFVgUY}W-=?ON z8Adh8A&RDF?6a(Tv{C>70002sV%gEuDWj(UKT}c6^IPsOx{X(WdP)W6bXbMgB+bn2><{9004k+{tejVobQ9{ zx>_mQ$vG?Tl@yX*E?w7E=iwQ6fn#m|8L&B@x{peSrvFFcMl`?E>paDM{xuRHFZyu2%0BO&&nu~Xs$ zi=EjJ)a`e2Nr^u?BvL(e(`ps}6gU1DD&7I&$~m?O>xrT{_pocO#Gj{+q1=s6pe%#p zsnIHc;Tk`4AFyR6j#WAmf`U{D22r*ztGB0|rb=HE2 z3Qvy77KY5J)@f_M*3y|DdCQBf-E*lWn%eLBm*)`=lsw%;y&SKqMU!Ft)lh}gM6sFZ z4ONcRl>Lt9^Hi?0TkqKm9u2^IhV z0000e_>()Nf7000000Dv2RG2tZhB_7YY00000 LNkvXXu0mjf3sr5_ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00028.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00028.png new file mode 100644 index 0000000000000000000000000000000000000000..f20a23ce404d836095de9f6a3febdefebf62785f GIT binary patch literal 857 zcmV-f1E&0mP) zEX}8;(d%6(O`26zPeU`Wr6H{|7yks*$%jouG}3Fw<=~~RlxBhrL(n6evxRwk(6R%i3PaEV8DMI=Hq%LV{BHy0)EGxrfEl6VL$m7^5 zy1|9WrAXlv%U!cR@zu(z6;MCNuUqxAEZ^Lp3HEfoY624X?}kM(+@NKugCaI(Wu9+- znB_pxL1#&=EHhVtat%m?`h-TSWyJ!Xg$6azAP9mW2!dda8oEbfM7{xFN1_Z**-e_1 z-7kx*6l7Bm)|cwwk`dko3-lnyhF%>zR3p4pnbY)>4n`MH*ikDJw zbt^aq<5NJ9cn7c1DwJ;hG_k;59uhmW+_d(k1a&ZdpP2ytyG-dbP1aLZ->p{2tvpB# zr3&^QH_Z)yt8|L4fD!Sp(GHQnJV<>trxaCEn!j%LlbWC0Wj<%Yz54N7o-Ypup%x&+wQG(8000000D#;1m1xsiyDrZ2 z)Ji^1Yt44A7aq**>(+UmS{<=`>@m*o*#@s*3{a2eSl$asdFLuW{}F7;W948~i-N|YS za^p^J8TrSCWU5Iw)mGY+zm5DhR9pe#w8}k%?Lx6R_b}3<i|w#%AF;8}S-QrWO;o z+v*;2oqp#z;8W8u(QhUN-Het)0002I8|}a)UVJ5w+Xek^&sa-}AnHf|Q#``(Yg>iq zN2lH@G6tFo5)n#gRoJVGsUKVRg2YY;@j`xg{L^l3q$$^1qw=i(qpQU2m9$x}hPr4A zYsKKE`f=aV530Kdfae*qz!%LH)}Km=Y5$#vaM#UipN%|mKX$7#>Wn=OC6nfYt^n6A z5kbd>k^V}aPTYqbSt#zR78B8?RUz`&1dFKgbhj3u3L&K0+(+~`5gh}tgXt^;3UPvr zG1y8?cpo@ORW7xkJi#Tw-0YTr6Xo`64F;`+-U%D0R_!AZLyr{2NKI=b)inD?E3rrI zXKHuj%5Jc)X|xq!NR{rfE+|IY^5m2$%`5v>c}F8GWEVYVL#U+sc%c3L{a$sZtZ~skWgK0AJTOenUf-dvL&w&w@>UC zisN_+i>sB9uG{b*0LWR-_0T;$W{69G$Is}v1|z0KYpyzLi?T*v5r4EgasNA8K22QF z%NqM~bj6Ky+bUciwhTb}%RTYS(G@q+ZL4s7*mV+Kk)>WHX{|B60wS^{Z({3?+5^qD tY^$?zSu~DolT_H@0{{R300005`~{>!-9}@e_tO9X002ovPDHLkV1h7Ymtz0` literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00030.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00030.png new file mode 100644 index 0000000000000000000000000000000000000000..92754796b6b8ca5665db7fa03bb0ffeaedea21cf GIT binary patch literal 485 zcmVEF}$}waWqk002z)waL_WY6h5!scPQU>*-MR z?Itw&@WW+Vhu2@%$KL_@;$tpEdZg!xOM_RZvepykFpRV3yPaKv4)b2zYOFtP#Y#08 z=77na>OY2>Gr-(AeVcH*(5$W_Y`m@3de2d{aaj0*Nx36?p!u@1)*QY@zw>v%r-q@U zUC$CUS#1dd0K7~8F=PHI2s=;dfN;mq+SA>1oj?G4taVr=Ly~Gw08pi&RV%#hn*bd5)?Mjf^50+=dHO3*XrIMpsVSp zWPens?^O*ZRFv0>_SKAdqJ?;su&e)z`XHb;u0nCVbRQ0a^a20?000000000000000 b0Jr%E+zz001*HVJ00000NkvXXu0mjfsx9HJ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_long/00031.png b/tests/functional/snapshots/nanosp/test_sign_message_long/00031.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_refused/00000.png b/tests/functional/snapshots/nanosp/test_sign_message_refused/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..76560b8c0f3bd5e50f8a56f6718ab7bb80ca024f GIT binary patch literal 420 zcmV;V0bBlwP)x`j)$#)l2xD5^B9vd+L007`}(Kn1u*nQ(gU3$CFT~(<~$DUkDezhFAAUQ3} zEKr}6Hrvhe=ha$+4lgrCZz=Szj${XZ9Q$FKKXKgpgqT`u@~eeA0k6)fAa3Q_A}8il z^uw7iLF&k@gUxaT;buTjUb6liK3fL^007{*`rK#IpIDufBN=yN2{vMCW3^Z{TSo7C zG?k$=t7gHh_U-E*DCwnx5w`E{%-Kc_?4k0-VF$w(-ruJPws*U2$W*oM}LZQtxEg>!_G zS#OEbyw!xRfOAfC6^*i}Wi9b3dQVlkfsm++^MO+9f zpUJLFY9&RQjHEW!1hLLKR9ahw3x;{#s&9h~i84Y;sd>BeeAhm}W#;-$f6tw8Fw*-d z004jpl=qN;Elik|do6aTUzR78fKiL94aKm0BPJaQDElu-i$4=}$=+_Xwb<(ZdLGtF zD78nVk42rTY#ybcv;r(f?fIoj+*f(r3NWVIGb}30*7hVdl%Q*HrFSglZuDAJ>&9SK ziZ~)^tw%1MFLxmw@XbS4fUo=72OY6BQ&4KBURFnWY$(SVb}JqCzTmAcKcbW2{V*6; z!~4Nt4DJL`=uSFL#uzN+ZSH+Rf4=KXI3c0eQo3~2%KBSUP!cKYk16!a%!~@6M0{mS zB|ksNwE}cl_qCgQ-OJgeswWLV5n>VXsYQRyGX`&X2#-pY>!i&KJZuGY9cR>E6E1~s zB+okdM&Nw_001u~&#j(Cxc^kf0WZ}hUB?<6Tj=%+8A-@2wp*KR4Q=MGII4@OdWA#V zH@0i{v+mZWv8>VPkWgxD!)2nS2*=QLp{j&JY4ia2-uN8-&kYHM(l@A~j>HS4&MV;Z tt<7%F^@pm3p(m}e6aWAK0001w literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_refused/00002.png b/tests/functional/snapshots/nanosp/test_sign_message_refused/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..efb803419298d803369d1c2475b424019a7d5746 GIT binary patch literal 467 zcmV;^0WAKBP)&W`2{dt|Jl;()q%d$}3*#45xi&|A#vJUNR z?q%u<$P-G9RCTvy$@UUN+{-%cOO(_36V{?RXUGarW})7EkNd#0et ztP}(QxTVo=Jqvo)Q_zCueG6)^J}?C1qkQ+>t=$}N)bH%w!b9~}&TLDpfUYWnCj#pG zH zr%^&p^e1Bsu0$5PQYXla!BB)30000000000000000000O<{!OCS)MCIjGh1h002ov JPDHLkV1hAI*pUDL literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_refused/00003.png b/tests/functional/snapshots/nanosp/test_sign_message_refused/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=YMjqtrV%Nn6esuj!jIMi}Btw`sohxwi1&U@}K{{10Q-!s%eVxF#kF6*2U FngGM>p?d%T literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_refused/00005.png b/tests/functional/snapshots/nanosp/test_sign_message_refused/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..c80fa832578d18c8b1e4a2518b82d7f50be84ca5 GIT binary patch literal 441 zcmV;q0Y?6bP){Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_short/00000.png b/tests/functional/snapshots/nanosp/test_sign_message_short/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..76560b8c0f3bd5e50f8a56f6718ab7bb80ca024f GIT binary patch literal 420 zcmV;V0bBlwP)x`j)$#)l2xD5^B9vd+L007`}(Kn1u*nQ(gU3$CFT~(<~$DUkDezhFAAUQ3} zEKr}6Hrvhe=ha$+4lgrCZz=Szj${XZ9Q$FKKXKgpgqT`u@~eeA0k6)fAa3Q_A}8il z^uw7iLF&k@gUxaT;buTjUb6liK3fL^007{*`rK#IpIDufBN=yN2{vMCW3^Z{TSo7C zG?k$=t7gHh_U-E*DCwnx5w`E{%-Kc_?4k0-VF$w(-ruJPws*U2$W*oM}LZQtxEg>!_G zS#OEbyw!xRfOAfC6^*i}Wi9b3dQVlkfsm++^MO+9f zpUJLFY9&RQjHEW!1hLLKR9ahw3x;{#s&9h~i84Y;sd>BeeAhm}W#;-$f6tw8Fw*-d z004jpl=qN;Elik|do6aTUzR78fKiL94aKm0BPJaQDElu-i$4=}$=+_Xwb<(ZdLGtF zD78nVk42rTY#ybcv;r(f?fIoj+*f(r3NWVIGb}30*7hVdl%Q*HrFSglZuDAJ>&9SK ziZ~)^tw%1MFLxmw@XbS4fUo=72OY6BQ&4KBURFnWY$(SVb}JqCzTmAcKcbW2{V*6; z!~4Nt4DJL`=uSFL#uzN+ZSH+Rf4=KXI3c0eQo3~2%KBSUP!cKYk16!a%!~@6M0{mS zB|ksNwE}cl_qCgQ-OJgeswWLV5n>VXsYQRyGX`&X2#-pY>!i&KJZuGY9cR>E6E1~s zB+okdM&Nw_001u~&#j(Cxc^kf0WZ}hUB?<6Tj=%+8A-@2wp*KR4Q=MGII4@OdWA#V zH@0i{v+mZWv8>VPkWgxD!)2nS2*=QLp{j&JY4ia2-uN8-&kYHM(l@A~j>HS4&MV;Z tt<7%F^@pm3p(m}e6aWAK0001w literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_short/00002.png b/tests/functional/snapshots/nanosp/test_sign_message_short/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..efb803419298d803369d1c2475b424019a7d5746 GIT binary patch literal 467 zcmV;^0WAKBP)&W`2{dt|Jl;()q%d$}3*#45xi&|A#vJUNR z?q%u<$P-G9RCTvy$@UUN+{-%cOO(_36V{?RXUGarW})7EkNd#0et ztP}(QxTVo=Jqvo)Q_zCueG6)^J}?C1qkQ+>t=$}N)bH%w!b9~}&TLDpfUYWnCj#pG zH zr%^&p^e1Bsu0$5PQYXla!BB)30000000000000000000O<{!OCS)MCIjGh1h002ov JPDHLkV1hAI*pUDL literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_message_short/00003.png b/tests/functional/snapshots/nanosp/test_sign_message_short/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_burn/00000.png b/tests/functional/snapshots/nanosp/test_sign_transaction_burn/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..bf069fd25715331d7ef24e9675b1e976d26ea928 GIT binary patch literal 362 zcmV-w0hRuVP)Y42EGe-emVbQt#pq64GoFG8nd>zRwRc4Vuyoq=jVx000000KmU^L19#p@e6204G(6mdm>;GxO)4{kIZSj{t=Ew9FNk|Dt;Y zRJm46{YvjDXyGz6iQg#10001h+hs2p%^CgTO(9K}I@GGQ85qf}{H|&Ag8X68?EF(#<@%NQdk}j`qj;0LS*FZjiS701n`*$3Nejz6_^ShRA0@mQFBo6i3GB@U`?5DGT z3aYjo+PFK;Al(tr@_$)}%V%g~0000)$^KNtm5K}#WUis65Gcf2zM$X6zWx$=WJq8F zhRWb}oV@)aFaav5JV)b(%nxG%f(e|04m->M00000004084Yv5^30{4fA^-pY07*qo IM6N<$f`rJMR{#J2 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_burn/00001.png b/tests/functional/snapshots/nanosp/test_sign_transaction_burn/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..d9cd2071223991e2e4bd0736b666d7b53cdad946 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|{t3ba4!+nDh2#w9p|19*4k^ zJDk7cgT6g-cUKeEsP%OEI!}Mi1tZ6x*~?gfn*Qht3Ql|x$x`9wudsBA*NeN?66Sra zbM;S{+VN!0bc3nKF6qh6a{r=HELW^`SJ&$gpTT~YzlEK1^Je5dy?xgE#lxj@i~D-( zW+gI;wI>C-*G#G@I;5ldVxQn1jSBV`S7Ow^n|_VsJg>6ccVbgXke$hrO7XS%5_2Ec z@BR$5J<0aYx+|K`uCRaof5PwRGneOIG}&hc?sD5w)+T>(W$m^2+P$CWJv{rb`AksP zhxD#xfsece^ZFMT+kL5e&oH;a#t*e`j1(5Uw@v4G^wPU*o8}6ba4!+nDh2#piq+mk85Db z9nbIkm%KUJpQYxcVWj2xVV=Hb$K30e3`%DKH8mWLU1a@1OmJiS+N~?*)!fzH#cVxC zvph7DA?;1_!sN$hX=T0d4)7^0`uUB2?bdlk_9fDjSBEg)$+VmHUr}QZi|_iMuU0(a zzq@J+i>CRbsGX}Pc~8iF^GYlcX!QRnPff4XUW~EcT3KkXt+YA+t6T0v+pme+4sW(e zy=|^9cmL+z&;@Uz1?ByM=6=dluRgi9qmgHF)$}+12lUFss|=n7=iZ*1#b6bkxs~sB z(;UU}(rv0M_N*|y^6&Q6H^)9*c)Q$&H%};9#jI{`4D0F))09j0J;J6h<$DY}j%bN= kTFG=)FarIE1RCb=WG*n<$r@27y9y-i>FVdQ&MBb@08)sKe*gdg literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_burn/00003.png b/tests/functional/snapshots/nanosp/test_sign_transaction_burn/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00000.png b/tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..3c04302b9874054e8492b2846fcbb9ab4b028ac8 GIT binary patch literal 374 zcmV-+0g3*JP)Q21>C3!FXsD!NG38aOIA9K$~l~P(6CjsKJEC2ui0002^FMehR@Huy1 z+h#T~l5a?MKumq4*bRCeux3A|JKZSZF*|?{HHntXyDE2&=b!#t392&y)BHBf6^H+# zI|G_rE2jQU?=EQJHnfO)EW`i+0D#L?Uod(w`o)VvI$h~do6_dQNG=r*O`{eRr$t%? z+7_kL?P>e(nOV`{mFDP_#`blh7{GI49I5_4jzhmtle@=5E7t+<;F=^3)!Hf-=9=u6 z(?10@dk*cKwks$%1GeHNYj^kz?F;|_fLR2didYvf>0=P-l8rmjGo_2H&dRIWQmap+ z8hT^*>;R!jAW({kc59_(7B2%_15R+f(02TzI_`N25+ZgAI)Zyp000000001q7jd=p Uy9>MuRR91007*qoM6N<$f|lZ&4*&oF literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00001.png b/tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..c3af4be088f91545b8aeeb6ce5b39903032b01d2 GIT binary patch literal 852 zcmV-a1FQUrP){#pD&$6EAfLAt;H!O>BUDvWTShoN*O7xX6-{Ys{<##P?OG%{Rqxjz2 zeQiQn43^*LdD6=4&q%|kv2y{~&a0N#4e#w@uv=@{zXkR1%%E;!=Mx~OFF2teFzn4M`L9SXxdjLwD4L~+ ztD=RmItOu7)~B8&u63;W*qc<`x2vx4$zj$AEr7gvGUbwqA+!#yMhk7%W%==UI&2kI zH7gscBULLjJ&0;h*6## z+sXj|05qVUbL4H_uEsRWv?tPtEsh#??2>0;XrijFVhm=;IBOk6M4sSS`Wg9QR_(^i zE`+k0abt9aPxq2VAF}lyzPU{QGOk}vFoaJ-5T?x|KJ1b`7JZu7G`1mgVH=4AyWDCX zodAxG9AIq9xrVm#5$V?`f2AB96uB0}e!{D%4BLWSC0XWPwOUgqti6v+q*G=pk?jEh e00000cn!bY9LNYc_Su`VojJ=b9cs_!{;p@~YhUm|>i(pu zf1C9xrJA@*kL-ICw?n2WCGlCg5E}!-4_|S8=c`|n)~^a*v~5C=(Y0BxdP5iPb($)E zI(@3Ub;N@(Y16W)g$uUnWWUws|DABh^ityPm78V$2(7z!-13vQ{lkmZZ&|l0d+M{i zn))!qL0aZf+AVFy=G!N}r37SEUv|E|Z_g!zopr02f59;Q#;t literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00003.png b/tests/functional/snapshots/nanosp/test_sign_transaction_ipfs/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00000.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..e5d8a3e9d27d0f45711d9e4b051ea22f8f990fac GIT binary patch literal 409 zcmV;K0cQS*P)Je^)7mPSWc|Mf2N`riN`VAQ0RR91006+Z`0)t~ZxIuhts$@G^6B%0mC?NC)ui7>8;8#Bu8%ViFO(YvBgq2(C%uR!WA|*GSMpOczuA z`#5>8f000000N?Ho6wMkcoL)R+00000NkvXXu0mjf D4HUFP literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00001.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..23677d364c3721455ab44a20582b814924e31224 GIT binary patch literal 767 zcmVPzR+pDzmW(Gk(vz82|tP z007V#Kg_S}Dih1R;W?)pwPC4BI?jZK94p~OGDer8;SmPNnX{wQ(jeoN(YESp=0nDG z(~4s?;yVYi=UB9K(qTv9&`Z_|oi{S&&q-DGA(Doyd#$<5D>QU{s=8ZQmaU8oU04s+4m7LH5(uM|YQ`nw;zy9~axHpR zKB_WlmXdixNh^+wztd*ow%?2k{bu=Kz2drJFEXU=d~#b_g(ra7P#=iQCsi-2zOeCY zZ549b%%~&jV_9+D>zve14Srn)9-h9mf&^xe5&hRtLXGIZ407;E@D%zaL6DJyQe=4l z9cocus^q(D_|?*xX&!8#nhWO@YO6lUb9>ERG08^b#?`w}6MI$;eY^Ry6sHjAxy)%{ z?pa}#8@8>i=AgBj=~a4OyHfAh5@4NIX}juTE0k6)%Y=2JmQHS%v&5*CB{ma~F`4X` z`Z}G)K&UNjJ7?l$ttYv3_MSzX2{-0>(92>cK@nR~um2e1ORsFjoe004k5Q%WhNtd8QJ4Mv@* zMjQPVe&UAS zb3{D>_FTAbHcU4wWQOR0U>+0({?~V4O*1=#^vRgMkRM+dtjK{oVOj#1<)AKZ2_UvYGmGq;L0%wz2JH zPoC2mggWg6%}HkVr>RUevp*SYuo78lCHCQ!m|g$?00000000000000003ggCz2BmJ TD$Wf$00000NkvXXu0mjfKiSuD literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00003.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..a5763d6efa5c6f327c85917ea7c889de4b55254c GIT binary patch literal 766 zcmVI@BeYI~9uR75x!5NM*dheFi;!muv>d=p@m68Zx zGhxvXjBaU~-n(jOY3secLhX1gg$-#z3L}6SYa_bj5~z*hXHWI16QSx1XswMga)Y`P z+REtawsv;Jqf6;|mhS+1*`RApU1*Wj=d{__e}ZQNl{VW{#7fl`M3ts4kzt`el+tLM zjYC+TLvM0D0{{R30QgQ8)zIb5FNj)+l=sn7L(ts9&xctS;#U`Z1!mu%OsfPN!cQjm z?$PnAa#?|3%E$tgB_XJ}I(^jwmcYnB35gh6GN+bXP`Iq&WMxuk11`R964GXMS*f4d z6Lo1=%f}kpYH10VKP@95GK$k>IjKR=X4#q_0d!NAe_8l{VmQ*Q%JZ{T$vu`aVf_U( zS#LpX45y~Hy(h3CoLx&UZQ7FkhqH~`MV&z}Qc{e|GK4C5e$F+-Q-g8`$h%z&*m2`% zI(3R(bf*=>=`~SS`jrcD;lEsM{uj5+-5ltft>5mQzB1OATfg0I0r=oaunRrO!pQJJ zDaqz_s!>iVA1_F3YsCrxewjh->pyhb_=SgL90#bsF8!3EQhYV|a;(O=^9p6cGBvmA zIc@b8rj=6B?ks6ylC74rK|Eg@Msfd6LJpusW=mI@?6EvhR;n!tsx&K=Wz8(Egj%V4 zYTu47djBaBkx~=do~b9_;$l9Q6@`mam=wMnS_G}JRG_+(MJIh<@gh+N%$Eb-q-sBX zAXSR{=IBe^dH)2{wxH!9Trm(m*c%CsE6O-$zS^MK*MVdzE|H&?_Z7~_&qOw)eV+9X w^5^xz#sUBU000000000000000005No2Tqnhw^wjZx&QzG07*qoM6N<$g4#`D$^ZZW literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00004.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..0345aec8bd180b1ab52119cf02f918a810bf3121 GIT binary patch literal 497 zcmVZ#dZ;%a&@P9L74LBIX{5fscJ@D8{UdOiE=<)PcoS-rIa zorhj>UjhIC{9BWEL!H-4eaL(@^?wl!nlBlx>Sh@cO!{mqi8$-MrdB-rIWLX+kn=n~ zvL_)P_AhN?47T6;;5U9%>{f*1$sk&=M|KSP1t(g)9etHKaXC|5>djzI^(_<2>pH;P zWbS6iSqw&|3ug;N#3oMn+`BrUn`pg5c_|ludGW7~?)!*a;m z=6?gaKwV6H9jWUCliF9O&#P-qdGhHr!Y1tk%_NikWsFpl{l(~motTAoVjbRz^a20? n0000000000000000AYRsY#^pDjXJ+j00000NkvXXu0mjfp{dxT literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00005.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..c279c7048c80abb5bc64f0316ee7a64ba9efbdab GIT binary patch literal 759 zcmVJwMnaxYL4b%2{PbQ|0&82~ zO#^Ovqher5YXfY32Ul}vglUn79x&;hCuh+hDUXG z@A&Tl8Me=uKI6o34t9WV?!Suug?j>c(mGH?_P|x>B%L6$54N%^yg^bWUSz>q^751Y zbK(e6?r)|@nX^0jjqZV{Rck0B!IvGbw&J^FC{$)%OHr1Fj`HekGM5I(_t!?P+Ey%r zCl*y<5vhD-We1b*1+|_?q`SN7;MX|^3Nfn+bg6Y2n0B+Cw$S$a5|%v=s4tPp@F6c< zwN%LxL`l5U*cZjX(V!d~l1G@F0r*(34-QAMldPEh`)CsTJxtDkiKMj4+B*lgvtQmT zAI*Ri{P;fT1Ef>002ovPDHLkV1kRAXT|^k literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00006.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..6f224982ac1d12e5bbb00680c10bf7593f656ad4 GIT binary patch literal 502 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|`(q>EaktG3V{fz#?Wv4u@QI z^N;`BKk5Cw(dq0MaXEI&$vxk%8g?~sXzQ{9H8CVu#;?2-oxOBQRQ4;q$yqWQsZ-jV zTZ7mBI44kb;q0_;%P&PqzYCquGd1wucBA)UpT+w_UQW9fwRY?A5cBg@2i=zTxM;d} z&f<@Fc_%e+(TQD*r{q#sl`NY3taa60C%yOe-xIdSM%Y9HDDIF`;-&8f7QdU^V7 zt|eIqe&6#3y13!|gJ*deANI(6lYK0>wdTi?57XF-nZBOdyjJD;ihYyS6YUQ!4&1BN zzWUL`9fe{w*Q3{}mGgw%{n2wG*R^C_%bBLW8BaNWvPQ4Zb3cAV(9#~oPKe%#noBYp7PuHId|9^Gk@~MTc+hh;a z6zA6cQ!m)K@A!P}SL!#HOi^Cm#hcFOp7hnG(b;l)&CfX;3q5x;Tt8V+FUcJK`0vpI qHfu%hw=GtCgzs>J!X6z=IL3c|{)Wq2!_+>4q&!{yT-G@yGywo--sBnp literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00007.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00007.png new file mode 100644 index 0000000000000000000000000000000000000000..a23b40b632e563936804fd9ee10c585adc65f423 GIT binary patch literal 804 zcmV+<1Ka$GP)%zE=pnblqUnIF2$oXQ$56QT(hEEeQ^%>c1RXQ?V=0^Y<28#w} z8nrNKcF8%bhGuPL$t9%f6}4@o;RvfDfElYJwBr(}fh>=zG*w>2l06_T*tIet)r_u2 zVaLwY-7wB%2V5%BaJHg2GWDD~@%4v#j>+_Oa2n2H$r400rY@0Tp%zMMw9c$e_*N%0 z00000fKTJg`Hr3ZSP4Ddv#Zd=>$~iQsT9%KdZrDXdtB4Kx~WN2T(yLr)90SA)h=2a zO2z!Kbo5e{Z?P~N%4P(M9$J&#q^#-VWXh^BHzg?5%b=4`>Wiem#xkQ4$+7q|&d-&` z8&<#dL#HDGs#-Y_-~@yj0o2Jf|1~j#I6f=cYXeI%+p(H7l)|g^lh{!l36*4=YrfY(;h3rqjRfox!AiAx+O4KvxxLQmg z+ofd_H7Du_SL<9;#5xEh+fSB;)lJwsyL+nNhYc!i9<|xs-K^hw@E`1JPe*2VceDQE zfe%jdZ&sm4QZX`ou#_J27D82MB!SVYil6`JtE`qEnS7y(*mc2+Bvq!P-m@b20967N zqE_C_&`r4SHfu!*EoUFETNpE3d52aG>LV*NSFvZRVX|Y$Uo+b96>8El*gRVT2;!^5@P>T+=4O6jL(|mno~29b_yH5_%z{z6nY1K9}iVwP6tU znngZ5hR!!)@qG6Pk@TunVPq$u{mQrBY$^=Swyi(VP>tdruKbKQ3q*fy@!dHwSzXQS z-j`V>*vyF9t9~B0{{R30O#=jJNo9ZOV&Y6K9r`U<88r3>@aY^Vc>wn izySaN00000d>+4|yQa;$xL?Wu0000U_w1dwyY3eGU@+4QR0h`!3^qg00000pCsp;bKV`rpK3gE zGSX(O?@8lc5ieThVfb zo&dQRxy~|)w%PS-cZ#z6b(~VN*|&39w>!RQ))sU$E~%xu^NxJ>H+c!4 zG2D13-R}65@e5FH&HnqXWbedL_hx#q!}?P=9S55A1l)+b-2LtAA+m`d;m7VB9!&rM zfdA}k>~O8m%ShQr+E>3JTHT#C<@nCmuT++#S6Oaqjj*45Iy!B-XZ$i*r0N+th)hxK zHSjZHQTQ&p1y0000qq5=8B$QzFws{ZUGz zZ4x(O>$U^{00000KEk*f>TLd+y*myb;{ECk6LNoz)O^xa1a)_-nlU9LiM3xI?xSZn z+UkLmoe!)wQ;HT%3Tlj7wc#Y}l-{TZonf%hW@oP8U@UdlJFKO=%1nxkx-cNDGpgfs z$EM(9u+Ou?hf1fqH!(@9i~P&FG?zgsf(B;Yv#McDMz*0Ta=@h7GN1pDhZ3p<#n*vZ zhTgZB>g5LzyP7sB$DU#wdwR9l%;}gmFMZYTc+ZxarV;oATw=?$Xyp*8LY<_QIq*ke z8DOH>@ zFKXj6wo$!Y-Lb_1n6Abg9AMyN%t0yAy(RC4GBt94sh(^Xm*CmG<3$QkQ-$8AW93k= z{kkACF<~rRk6t`1Ug;Ruj$IA zQ+-s;7)p~R%qg=I6uz3+>}qx+(Ig`}Hy-&;ob=r=Jny&R9=!y`NsMGy3ad{OA4oC- zwiE)>+;1vIB3jL}=deEm;!!VWj=f0w`Vf&O3*GY08M#kNUD6~eM>QJ^$gT3*?+vH_ zMd=9~D+_}Cpi~0@000000000000000006)gzu;t7l9{?t{Qv*}07*qoM6N<$fLGj<^((`$$MKiyy$APdt=T-P?As0(hUfaKzJbzvZ>^on>Kvg>gk6~9 zVjTNXT_xA-nA~kk#HxA%)R5F@$0XXz&TlVoF*ZLxyDMG7=fiDc!>dqOf@Gcxm(9+q zg=xchlg&x0Cm=4$@9YSB!!}kj0b^;7cezopLsp18Z$GLdDSQH6h<>d8wrE`Tb2hg- z(3@N`Joq$_O z%+#X)M^C`=k=yr0RXy_mJG@oj?KSy#V!M~D%E?7noYQVFO)}Zv#z{5V-;6nU5>@C) w7fEIgN|9aw000000000000000005xOHxQJHB?cehYXATM07*qoM6N<$f=09MF8}}l literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00011.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00011.png new file mode 100644 index 0000000000000000000000000000000000000000..7c26e109c6e0a6013649cd0a6d4ea0b0d247a8ee GIT binary patch literal 771 zcmV+e1N{7nP)4J@? zOUfQl{`xu5;2|izq|b6)m(EQ|LI@#bF_0Rnj*?bRPzSq9FZ6*y`KNmkG$?x!pXCP*yY^rm*dM_a z%k1a)SRLGr?Yk}pd?C*wx4>-Rp(};PsPe5I zw3WJgA8-+GwzdsY@q?pLe8O%Ff_Amj6^G#gv6fpx$7zaLyB1qIIFeBD({FI`mE z?X6e@eTTjl6w8eTm;%SL56cz6syV zLrM_q&ke8ykqK}BZswnAK_L599zqBqgb+gRM7k%ra)004mFKI*FOy|>n`>#A!a z?+&J!cvO(nm`gkISy5>d9UdR5_1?X z$7FHY{D({v(^4B>BX+)sZJ8Gb&c8D5DSsfCqsP&=cpq5q58f43T%BNNqIzWDPYl5H z=s4fu;9(H&MYbXD{@@fu)u}@Iz48IbC)%DqzSYm={h48~t*cd)k0+^i0NzTXx0(EJ zdH}Zf-21;M=i~A(sVb7$-|aoY24aI$ZSBg*qACt)4{(!A_K%sQn(QCO7(9tx=t+wt uGX|wdF8}}l000000000000000Q05zCla;)o2u0}t0000@C8d;e zCVv9$S1D6zN9o4BS-0=y5)bNxyO}>l{$up(@x|44>lA+WiFP4pSW3w`w|>{Q;h&t+ z=Mi7ovIDxAbi0Av-F9iJ3wI0M^#z`eaXTKaFd>a(;|}N+Yhriv5lUAV)bQ$k$KRXTp0V9$6wNAiFENEo4282_4uc>~KIC zFkBphF0S3#)pw^_W5t}q9x~giRDxwY`^I9`D+kNDVq6z4Z1gxQB$Pm2VDiBv@qG zU@L2ucXZzZ*Eqg-S6(4CnJC3r`OK4d!JRNp0wyGf-R;n%B|yjS%Web2nQ)iBlZ`>k zxm?fYO^jrB`N(__7bI#K(YEi@xSD>3&K^D-g&<}d@x4GI%18?pAeFJ7n9276)%c8s z7nZIVl}1<>eus#E_utd6P@=*(UmXK6@Mar)k^#t-b#1U97B`!0^n$3+Ro)6^0QaaQ z#{f#_*T0S0;YQEH*C53!dA8kw<3CceMZCjBI6Rr3(&Rdy6oOj9^WanX3EaktG3V_J@4O=h91eF^ znScD-|73TG;8mxDWVK`&->>(yX3em77V=^QYGSZB7ryG-wJ6P{*Jfp@zHoE@wb(|+ zYL3*=^0rIea@)G>uRgjE_BUB$>8AYBye}6%O!iN^c3Yb!tgXS0)a z2Jh4U2cK+ydrk{tu$=YRea;cHCn>+G4 z;nxl?{r+apW~M-^sow7=$2BCBpAM|n-?KDf3C}g&uj_X`oZ+9x_(*!okDv8zdI!FV zoVh1HJuHP^YvPHT?ddX?uX(0shx>`Gint_~Fe_zKeUIa+lm8M|9Gq;>Ixl5nO4bCf gm#iSKpaYM`;@vA-6O@g zoB_nrt%{35v!GX*?s|?MX~h#TT;$8yTg92w3)&?2pKblbW+{}A!VOnggSUb9FRRz~(a~jQ* zH&=#elMzl;X}R~+v>30;xbM;!wy+5+SX5a;ADpZ8LHHJ^=`l2Pbi zwW|^5!F1aU9?9+bVAfx0nifa5nkvpY8EdYx>+1Q4=+hZLGsk|RT|?DJM8Ey;irsRZ z2@yEM$L~TP%_PW}gQFCOH*>k?cpXg_gFmdELLr}O$lHxI2aX*?{MXiQd2-#6|Kusm zgf(ugh4=O6yLe=8!a56r3q@=`s7=26lA7R|M9!9@_4U|eFOEyS9+;}8O3?j7vapzU zFFOIrbf^u@C}uQOs!NX3)IhW0G^dQ32}1s%MQ5QHmwEATuckImh2VJ5hE}cczVTR2 z7l1kSFXwJ}e=+Fo*OiA$zv~R3m#zrG?qR-xDt=08h?!d4t{?wFwzK4w^!l5uhVr?q s6951J000000000000000002D9Hvrpt-=(510000007*qoM6N<$f;iS|lmGw# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00016.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00016.png new file mode 100644 index 0000000000000000000000000000000000000000..d93355b0efd352ebfc20e98756acdde7c7579f16 GIT binary patch literal 506 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|>Ax>EaktG3V{f$h;#8JPtEg znLqsJ{z&hygX^^1X+8!s!`|1rGE3we9-J%$)WmS0Fs^Wsx2EROImLIxrkkwPsGTxt z-MNKrHLe`Khte`@G?t2#uYb1hm7}$L<^5Q>0 zQdgI}+vpP5vWM}MMC$UAMRTv64&L1wb8lYsvegT})qP1y7T@KSr@o41X`iRfHi?lqWynWlP3jz8FP z)wS<+@ixgICo4=jdpBVFPK$r8y5;Nn@+Ld*?VS8p{OyBptF64VrskM`Rk7*cWp!)e zOa1P<8>cRu+AjL_PN?*HL2Lb_@=uQ(Zod{XeafFvxT|aEz_jZkijFt}jAoujO8RS-VvoAJJ;wMiv$2q*~x@xU7=y?2kp3Itb zBwY4qKsSso8=R@l=S7U)`=Rl~kJz?FLrkHEtPJQTE0EfL4RnG;kG6agQ;iEhOv)Zm zN)ZRVLM4>Zq>HP3AUT?z)GckZ18x)PXtgZ%Oot&8Sbw;yZ28V@8M%_O1W}8rOL$sn zi-RE(+l0I3<9xKKrS*7;)fl?AVKa5cz3G+YvJHnhd~aXD}aGHMcH2|#>uhLyY3E-`<3Qfoe}m~t7h)e3XP zI4#h`c=VJ=OXvfGCdp0JT8VFGp*h-(Vq>A#TY~5DXf&kF!}__H_HUyXW3cysJ9*o3 zTR$iGJwRI`XWK67cSdn+hj@miVqEs9I{hu)7dyS9xC>|7j4fS@Z2M_q{rijl3}Tuu z<#Pgmbp)3KjI}bb{&@T(>i2YNFXG3i`>hx|>f1^GAOmc&{z`H?&g%jI002L)*#kJ( z6%J!meqIEQp@)G34ud@aM0xMJPr(v&7&rg`00000fd9uYLyZgAxoOc%00000NkvXX Hu0mjf^;>Jp literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00018.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00018.png new file mode 100644 index 0000000000000000000000000000000000000000..31d8c9feb3adb901a0aa8b9f64423a5273634e67 GIT binary patch literal 506 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|>Ax>EaktG3V_J@4O=lJPw&x zXBYfeE}X6xFfp~ckw-1)>%FWghR5vZJeUI1!@#iav*_|&QziwSvOJ!QZwybdyv=5cUKRED`%vJeA#{a@ej_c>ok@=nG@|YE8mP|n@Xyrm#x>; zu&t*a#A%DTp5P2Pr(vHeu=d6ZzqevVmA~(5)lPrsl>MY|QB=UKp4Q$UD<|bhzMXdT z_4*YD#J*fxxa~)5or~zSv${&r&;1*6&c2=(eZQ|d+xy;qrT>B{{;I23Z8t=h)&H)V z@k(;5)Xxt$13_+Xcq}uot#9AAIqF%J-@OZW-4UEN>D=3J-)UF0Ec2u?E96T{x77R2 z|8aTa)c$ho*3!B)Z?49cevm5sr1Z@*Hb$a4H_-cEQ)u|{i&OK`XKZV|D6FcV|6upx zm*H9u+?aMPe!TMVxzh<7#c%eyanIH4xU@3o_nZ$bKFqaQFMjAO_Bt?Yq2E>J!!=35 z8|+-7r~glX!6L)oXtnM2@*7^aw!MqEEh?9r+Z!@_Ue`$%QRiFSJk35|)?ef_y||yp rvO;**h1ot$K73A!dq7^n0EvH?oTv$$`vULCn_YqH#sL7(u-8&W{OeHpL@gXsn5W9JfH5V{vLeuoP)j zt^uvJ-h1u%y$H=~^nFvuZF$EcSJMGcKy>hGV>Xg#Mw#IJlf||`lfW&UqH+qN@zE~f z!$Q2st++Y@7VRNk4GWDY%hej8HVPeukJlh#9HGOVV>$@UF$E8XF~s$LR>EKEZYD;WQeo zg6ziV_Mq<5kO}^yC+ksfN?ullk5}@60gWfqEiqb zq+%KRm8YjGc(qv849{&+(28Uu+`+~tV#X|NRP}D4l6-eNX)eNA#tz_)#g$}bc@ZT^ zqvV_yPCVv#gyN0HT~5EQZ>oTc+Q?}AV+c)+);|pT;7u?Ky@}Jv=!32B=C#yNaZ9SH zfb`T#Z^`Z;u^XTKsJEGn)<4Jd#GHApTv13=ww&u!Enp5W_ zT%+fiNgB651haBjee2xIaXLVI%W6U<6HSR1wUOsaf&9fJ?etCskM*jpuu%(I(aQ!S z6Rw9ww0n2X#q)Vs7*g@?72}TWsm{+K+?~545J|rqI;fRZ;^lcB#Z9ZrT-CB^SO0pt z=6+FCO+De`Ye3a*BE>6CW$Yboq0O!A@Oa`cO8Az>EaktG3V{fz)6P{I2`WI z-P`%yep2~O{^fkkU23kzZ})tks@A~45t!MXb-@tO>+MD@lLeb^@A&d5B)NNF%nfk!|LEH3Azi&TI z%v!!uUv0Oi-aIRit2Z=1$b6CU>&2bGSO1;_t+c-E``YJwU)7X2WwoWM&;69S&o8bs zyybq``d`4ApXc6jSc`wZQtQ7?=%@3Wxw~$dzuo1o`;$3tu7tbxuDOY~#N5i=US&<$ z`{=5&Xu-Sx4c`h)riWRyAM|2>!FRyD>zswl&5(V2&wpd_Va`qOoxW|m-u_8!uiLil ze=K@)cEi`qTf6>DUnndf*K|?*_)D#@qNQui|F7M!c}r=Ku9WEHPR+E<>=JAO w&RSG2QS?EjWTE;@mYFg+tsg)UhXHaP%lllJta|#<(@P*ZPgg&ebxsLQ0Gzbsv;Y7A literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00021.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00021.png new file mode 100644 index 0000000000000000000000000000000000000000..e51f03ab5830c97b853c516fe7b0b705f97f4db7 GIT binary patch literal 754 zcmVm@=WFUyL{t>&^8f$<0002+0n}P+t^Q9+{XCV- zl9#Fabyi&0FWaVmL_3N#ODRf)q!E2*2<143RBJ7zwDM*STE}0accE+Y;-zzP2k=cz ze~6|T3LnW9r4-T7Lt9?ruVz+gD?@1&=KKyAj1}05tRSvr#swJHgzAeN;E{)a+9Kt5| z+|~d90002MAL=i&uR~4olU|e8@qZnnBvXw5N{WRW=Wx8{m*O{sBGak8G803;r>^;2 zpc%wCyN*P{blQg~X@G`fR4qO?o&*LLFwUi6bJ~>51TJm3 z+4y^Syp-_J>kmotgBUxYN`YuYBt%to&f*=00000 k0000000000008{_02b3g$>BR6&Hw-a07*qoM6N<$f>$EaktG3V_J$D*SO91gk5 z%|HHg|D+fD#QboBQs$8@_4lGvc?4LFdT0XmFfhD#%wD_o+ZJ*CHO7}GuKVvf`BzNd z$1g?Ed~+_8Jiak?%~mU>%Hp41n^tG6y&Bb@Ifs9#d9JC_)+w^7UR|2A&vi)M*z`NOJm#94Ompx=| zsWz#6!&;vPowNUDs%>1I|GBD1L^blowYu8Bd_P*(Z~ArnabniC*5m>z66lS)chCyvF9aP+uM+4U;w{+HtCvpjqpw&&Z- zomVXJW9x~H^7}Xx*3IQ7zfh2jr>mdKI;Vst0CL>i$p8QV literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00023.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00023.png new file mode 100644 index 0000000000000000000000000000000000000000..e199c6b9e42fc12ac38477815aa014045621cc51 GIT binary patch literal 778 zcmV+l1NHogP)kf{mgQ7(A(Bu{5ex3V-Lz8JYto+ zqve&^lQ{#_Tr0u3EIXpss&@2LSC*^_P1IUPaztI3sSPI#8@m_dI$dyraq)J6zfTj7N(xv(&WmX6kc6F#ZQ&b}nN6Ik6LwaDtP)zg7hac_$wQS5pEC z&7@vM-W-7+djO{T>Ux4}C0;dU&#JPAM+=c3MH6c@Q%Bm1q|;2CgM&5=^j&Z@O|?o}|CujT|*}5({t0F`QB9?E;-{o&j>jKVATt zb6N^Fni|?m&5~^ zj=`zO?v4F6bVCa)>$BrZbX5|qx|u>A_i}F7iXoLIH>=(T>)6iE@DVVq<|tXSZ3Of;vkLfLJcF|QtR(d8efyqU`#TuT~w zG7-OB)m;_(BQb5%R!hQiv}r60L-Ooc>kcP^_VbH`sjvgqecXZhzYX0}1@Y;hxId! z(82dvC<40mj87psq48dH?_b07*qo IM6N<$f^L>$r~m)} literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00024.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00024.png new file mode 100644 index 0000000000000000000000000000000000000000..2cee104f73f19cd2f377ce9721118371c54ec2ba GIT binary patch literal 510 zcmVoX0Q;M8E_)(|f+G48g^9)+S@z_pk12n4Xvf8-hs)e7c0APdq;o$Eoh^m?dq?$hub){ z`po`O55&9%006*AkFue+iN;atvHsfqTo_e1%IFl(=!&a_(!73Z4r?kx{bM|Yq4+edzMMpPHcYWJ2O zm?i!L&`lTL-i)ys*lUrF?~+|GvLm7aZTSt(1902XIm&X>iVJFl3$8@@y-am{n zcoVD8o7jinME3#!000000000000000003cr0V>kle){0A3IG5A07*qoM6N<$f|wuh Ab^rhX literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00025.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00025.png new file mode 100644 index 0000000000000000000000000000000000000000..84261e22c9e71e10af139a875e076974f22eb9cf GIT binary patch literal 731 zcmV<10wn#3P)&(Js(p&2FXGoVPv-k000000KnsXm1`VhwAOm> z$tI`&4U^{YiEqg>*8ZweG+D!=<9sj7lKvOj)P(naRVDl`*Qk;l&lsck?l0KP75~1W zg-@=Y$_QX~vuH@hvUG&HVAnPDWdj{xSZgILaMpdQI*=cRx7^nrcI zqIeHzWPMf92`zH^rR*`)-q_*FCSch_!oFO_`gRz)%g(TvR*Q?0sIXh7J?*f@yMlH>W1Bei(Z1I?d+<4U1(+)wIRE?^^6GqPj$ zzfYWk*e;qut;=s|_#7U3BX$Xvlzt+70=AOrL2%@ei8$kK*+&|gX|mLY8Yb4x9BeH= zC2tJk{;L_x|MG9OT87o*&}h(i2QeqlP47v|$t0t;X7ZBySJlIs!W5J-$^X~aV&;A_y=rLH`l8F^VB@kVT>b~|+Ron0m=hrPL-k9| z(59<97&V5i+1~qO`{&TAwg=y>0ssI20000000000000000001>kU#LoBwQ9uam4@t N002ovPDHLkV1lHeVY~nU literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00026.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00026.png new file mode 100644 index 0000000000000000000000000000000000000000..fb49d2231b4f1787dacab86aae004fdc0a6f6b90 GIT binary patch literal 522 zcmV+l0`>igP)_?LtJqz7N(_wNA?3hAO3u-lfv>i~T8?(f6x5WgJai4(Bk0*1D`WzkL-`Zcz69NECnrE2&HjZZ*`;^?V)WlAukLB)UFUbe zg@(#A!Cnv3dRp<7`$OFUe`%)z004ZDE78zy;LuM|#k*e#qvB2;8~O25-pQO^p(j;J z#-m0xoTNSryAAbI{K%K{hq?V0-Fn!nXQhSRQoA1(+aF@@%y3*t>rQpapXy6gIJ&#X zryG2fqKc~+b+piRb8G^-QQ~RSoy)*Ki){TtK?NsFqM9W0uRAjV(}A`D#jS>3o5+LI ze}3%rU)~}ICSW~Ywx0k0T3kWu-j`8EnX+D1Ww0r>lHGc2e*dN2n!62K-*%InLHifd zaF7}O+jNGS(Z3mU@FY&5CvguyiQxqR000000000000000006@L0=(qv6@%r$vj6}9 M07*qoM6N<$f-VU4TmS$7 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00027.png b/tests/functional/snapshots/nanosp/test_sign_transaction_transfer/00027.png new file mode 100644 index 0000000000000000000000000000000000000000..8bc79a8c5395a1e77033767290edb4ee16a90a33 GIT binary patch literal 768 zcmV+b1ONPqP){5>yM$^gsGNo!BD)&%q58SkETRU3$;;N zqcVw2ILLF}*#H0l006#+fA($p7HHQGdM|?VHMF(MYt_FE&9(5rz+9k&!YqnvU!kiK~qE=Xi}NJ6GCT>V!75 zoCHYa-s-{b4n1l-PeYa|u9oo#>e@I9D*@E2U7R^D*rblvXM!toWI(wzb>??nh;960 zTyAlo(>5Y6cj|92C_rpNyxKhvA4;WCUD6&93T^ z_P@o%HXceq{HRS;*6rt4EX(2I8ef{-9iOMqMXi26$M|SjDPIkhYtBRJi|@t084%wm z?M+y=s6QDR1A7-Nj_ZY_SuD&wj2 zcO2w%uDDCTZ9XuJlC3us3nBD%9N}w)P(h3_gm6yaDjc~9i<-2TkRwE;&4f&+hJ78! znfV0>)y1q*BkE??)9Mgu_p2O25Mp&rc63d5$37;9prbH>64^LATO*eai|kuvz5^b$ z2&bG{b*xg|9X(8QKpL9u)htE7ckAB7@Int{4{CHAXYv=&p=BEV_442e*~h?V_sowK z0002s?fI}DmvSuG-C=3hDC$M#C*278a{yVH+4F}O#b_hsALhi3A#}6Oqk}jB9_DGV zv=i59UVFF^nV!T(Q;nxkm17?@tb@ z4uM+!SupbIRoWb2WR?9mGtbi*)LbZBz07bjdLg4Tg{ggYeMyLZRp-j=ZgbLSTo0oT zD8&s=JlQGpu}BBl6U(jvO^i$Elj(`h*W9&0Pq=RyqM{|NqiAHTzm1HkvHoW8!JQC= z?xbR5e6SR4-byxfC#8*DQ~vUJZ6fud!S4Rw@uU)4GpVJ5Eow76{tfM8@FiVw;#w{7|7S6&yAV5vajd?oKS1+@ogVUDJ{zFtC_gCOnZR&nETd$2@)?s z+k1TbtgIh&Dbo_vnIX;<_b%lUBomvwn=k+X!2fjfG1NRSnpyrKQnyfRb?TZGheZE` zDhtcLde;dKxWh$_pXHP>Tb8+g$!qPO8t{#`ObLDo56|Nq?UA3*b>v-;UN_7XXF=0- z{oA2~OWaIh6L4ffzgD;B?rjgceOc0(h9~a(mc9*@xBT1l52@T~dtZ7+@3r&<=%YyB zU?%zH{_Y%Cbk>lf%j^wI*FDmjS;oxL?dZg7J~WczKfLUAgG}_NF+xrBCu0sGu?j_E uAC5$L0RR9100000000000001h$NT_)aXhDS9(efx0000Q1u%C1o#tK#D?soP-JR0rxy1#!%xlmd0gS0001h)BRnYK+1c+9ysS} zXP)G9bpmhqy*hy^@4a&_eEpL@h2wQw#KG}Z`rGJ!J0Mg!ls=q~7o&K|vRym{H(P+X z+?}P&!=%oLNiRTAXyyG~DDM7J)dv6ozyQA$P8K7Z zx0;{dxG8Cz{Vd7niIlS6^n~}_aONnYIDp> z)E=#nk6Maz2|nHH)FSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00000.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..ae7bbe82e009fbf63c2a0db72f0a29abaa24bc55 GIT binary patch literal 379 zcmV->0fhdEP)Y42I!pyvgo=q~66JCZyRaI1twl-{*%xf~ItAY=u$)000000Prtvvjf=A%$Dt1 z>%>TokZb^-dQY(#^crBvzE5|!Q^I|A06R5_mdm>;GxOum`d106Jpj|ZyUZ0Y|DxLi znp`WU{zY#VRG5Y)agBu-0001Ry6g)^b4Gu7Qb=EyI@G4LIWdw``BT%V1^I3fR)PAW zbhtm<{=Hgj(#tE%(N{M5&xw2hkBM=F)}J^I{X=1(nM1H6K3k~mar%UqaivY*cS z5Y!wwba1$xLAoB$^S7+c%V+3d0000W(9hYk&El``^EH%c+XyVgLd|N+SJ|3k2FtNS zHtP+a@60Lt^MIwaFj~e^c~@6;2->7F@?`G;m#6V^Za@C?_t@~ZTy(ku00000004k< ZJpq+01iQ(jZk_-D002ovPDHLkV1le-t3dz& literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00001.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..abfab404bbec2215be1a6876ba3a7ba97fe2c070 GIT binary patch literal 381 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|@9dba4!+nDh2lG~Xcw0f&oO zcRauESNZmcom0_xPnIBC)%o_7H=HB|TB>A#nht!MQ+&>{_KxcF7)Pa}u0_-NKhF!w z>h?anIC-wkTO0rXuR4vFZ#kG=GtqP5Cnddq4(z9wPuaXmEh^!W^n%4QkF^U$d1@W^$J~~Q*Q)x z-QTp~l|zp2bpE2ww6piQt9F={Ih)^G5xJPr<;CRaobE}^6V4U}+dIdHEahU$o>6@( z??ae$r*-{t`J4~E+w^~mTq|i8s(*a5Oy|~uu+=BpW|>JO?5(U&ZxIJtg$#bo*8lU3 UZykTsZEcXSr>mdKI;Vst0DXa-MgRZ+ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00002.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..b3f6946dbbfff01a313f38a692d477b1b20d0367 GIT binary patch literal 420 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|`Jlba4!+nDh2#Zr))9o`#2O zZuu7dSN^H@x3O&kFJJc04U@kAG~9ZoH9>vJ!sCoUeRp~~Iy!1?m)zczuD+?%W|b?~ z+Wzw&X4yI{|MzLhhR-&qxBI2M&YiZ)>i>!pH%))cy;bc!Z|baqnRkkwS>6r(SAVr* zdT)2`4yK%G#cWqCBWzW3!^>V4RDI(=Q+GmMnotldw z?)tZLCH_79t=`{wUXTB4Eu)((Cj-OAt!AQg)^gZa{C)S#_r}_^`s0V{1ON4^ohtj1 zY`c`<=(onnx={XJ=NC{IBZJF(7{v?nj>yh*2gL(} Mr>mdKI;Vst02>m%=>Px# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00003.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..90e4d1036258213cf3407d1f5e57d140f2ce5ae0 GIT binary patch literal 470 zcmV;{0V)28P)QdBpLO zo^w~JXWe3luA7-JcxVPkPzj&UiSe|}Uy>*>q+dM#qk=097}>`c|x zzx;!1am5PgfpDOgR_tXn(zzm^QZ zk~;waz~oFBx=-~5IMMZ`*#4vpm1fJ5)ZVzeDT+?9{pZGeE24b2>bwn!_NlSnxEF6~ z_Q{)ixS{TJ9RRW9bphjvz5dRnXwX_Htsmd*4PI#ZjzM^Ds0#kP zW{`=#n@XsOzB9()B(l&+gCH{oTM=FW000000000000000003Z{Z_k)Yzfd$tv;Y7A M07*qoM6N<$g1YA4HUIzs literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00004.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..a21acddfd274b5016d446164fe031bd1752d81a9 GIT binary patch literal 435 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|_8Bba4!+nDh2VVBTQ`o`%Ho zSH4C6l?$iaE^yOhYxkN_areKikE~}*+JVFlpe}~nwvU{q2e~}4=zI2g(gv$f8f*4l zu}QVAytm+eVbl6g!cw(Cny&x<{+s)0p2B~>-&1OrY?If&oBr6wd2#to%{8}kx&ByM z7(35ZHM;uPV|RE%@bp=nH|F-6g;Yw`o_4R@99v|y!Q}zNoW1X_-8_}~^4iioH?_-G zbmOZg=(XD%;#JMKl=07O^^?WZ-JPPnC!Brh;~m4ksNBMsY5T&du`ln+K74Ujr`cq# z^pVqlmwxe@c3Hddv`E_7{M^OOf8xE_5!@bG?4eeA8v`6ga7>+>Gg zU$77MER)+Aue(Wiy$kb#^WRfr_pWO{!xjBCflg-#^Ut&<6z` b5)gPMUQ?7fDe>ts9+0S~tDnm{r-UW|4dcNl literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00005.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..df76ba3cb2251b22bc9b624794fc2ce9c58ad6c4 GIT binary patch literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|@{*ba4!+nDh2#E?=_(PebCi zH){9(d)!I2Khd!`V5ZaB&$V@u?mx5=4m$z$Fr2aNx!rBpCNM2kb6)$EJ?qRgwa)8? zoqi&vW7~WCwRm!j|K+rYfA-Xfy#Ku3Yvw;O_e#m_*C)Bh`E=bee4X@rR>9Gud;#Z{ zCe774T_!tePxTawlSXTOji;6}d{S6_yl~N;mp0Q==A_t6Nj^1cy7G$2f8C3=eePGV zTyC4+X7Z%5RBBd;|JyGM_PjZ%zxwEuXNStAw6fi%&o8>Ra_XJy6Bu}2asoYe&eQq( z#P4%m*(5!bmj8Nr>5*1UysJ#)b@ugsf=vWr`XvhVZ7X5HRsV*PB}@!u74eoOP` z?cUx0S@5nBTi)HLBA+soCv_eS@zDo`5fU&sE8WO1#dJ4s3OMvUUHx3vIVCg!06C|( AMF0Q* literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00006.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..41036987218951429360fe85cddb772919995f2f GIT binary patch literal 431 zcmV;g0Z{&lP)QU z!nTpMu=Q5`h#W&5*szZge3x(6=! z;0QjHSQFry{SrLd|5mXkz)5><5$*K~Gy(1Te%e>B%OP{X)E9w{qr0QAnE7%Sq&`k} zmf9_?#khOY}6ba4!+nDh2#piq+mk85Db z9nbIkm%KUJpQYxcVWj2xVV=Hb$K30e3`%DKH8mWLU1a@1OmJiS+N~?*)!fzH#cVxC zvph7DA?;1_!sN$hX=T0d4)7^0`uUB2?bdlk_9fDjSBEg)$+VmHUr}QZi|_iMuU0(a zzq@J+i>CRbsGX}Pc~8iF^GYlcX!QRnPff4XUW~EcT3KkXt+YA+t6T0v+pme+4sW(e zy=|^9cmL+z&;@Uz1?ByM=6=dluRgi9qmgHF)$}+12lUFss|=n7=iZ*1#b6bkxs~sB z(;UU}(rv0M_N*|y^6&Q6H^)9*c)Q$&H%};9#jI{`4D0F))09j0J;J6h<$DY}j%bN= kTFG=)FarIE1RCb=WG*n<$r@27y9y-i>FVdQ&MBb@08)sKe*gdg literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00008.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote/00008.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote_cancel/00000.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote_cancel/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..fdad622d21afa99ddaa01c4bb33fac7577b771b3 GIT binary patch literal 431 zcmV;g0Z{&lP)41i&GGdJP>N8&E~!^AYD!vG`DuJ7~1Fh&sze$eqa00000008h5Kf4<+F6Vre zQ%W0K@{N!kAVV)j?1p$9a7AB++gusK@9qW+Qh^Q^_o#Bt^8Qo*8A8-60NcD9<`IYg z5%&sEv5pw}Q@ppJgV#_e{>MZN0001(&ijNh3%xr|YSQgoH&vxJH@0Ldd1^6oLGrRN zvp{81+FWmz*Gnlm9bRUPZYh+@jbsB}8{1*3|Kr$IgHJhUd1~%D;B1@O6&C-cj zIWsE1?RodLkD6W$&$i5Z&gGXid)GJ&TM`VF+^2cC_R8xijTttlB8JcNtNY5#v>)wDjZLmPf9}6ba4!+nDh2#piq+mk85Db z9nbIkm%KUJpQYxcVWj2xVV=Hb$K30e3`%DKH8mWLU1a@1OmJiS+N~?*)!fzH#cVxC zvph7DA?;1_!sN$hX=T0d4)7^0`uUB2?bdlk_9fDjSBEg)$+VmHUr}QZi|_iMuU0(a zzq@J+i>CRbsGX}Pc~8iF^GYlcX!QRnPff4XUW~EcT3KkXt+YA+t6T0v+pme+4sW(e zy=|^9cmL+z&;@Uz1?ByM=6=dluRgi9qmgHF)$}+12lUFss|=n7=iZ*1#b6bkxs~sB z(;UU}(rv0M_N*|y^6&Q6H^)9*c)Q$&H%};9#jI{`4D0F))09j0J;J6h<$DY}j%bN= kTFG=)FarIE1RCb=WG*n<$r@27y9y-i>FVdQ&MBb@08)sKe*gdg literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanosp/test_sign_transaction_vote_cancel/00002.png b/tests/functional/snapshots/nanosp/test_sign_transaction_vote_cancel/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00000.png b/tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..19c9a3e18c72d20e0070be1ba192ab60f82fdea9 GIT binary patch literal 375 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|_WKba4!+nDh2#G+(oVKx^Xd z67_fWo|~uJO_;=~6n2E?_@Dd1N1Y1Vx~Hcy0(C(^!|gqbtS_8D^XYwQEOT{HYYJ1% z3)`b6FH{xW@3-%c(s(F)x6#ja!P7_UPM!Jl>$2UH1y;-gY56m>`To0>vx#gB46ynFTY``2@GtW@o_^!K$$ zR{veOb+4Ja&w+Fg?W@aozjdGVcJu1~aJ`SqgDL|*zIi^~{&Ad1^(%u*51)okpT5_0 z`QPVmuJIMC-py|{-}^7PRyt~Gy1!xOuIOy`S`WTsI*y+ub}R_rU-e7o_u;(cv;#Kg zLa)!)zI~tTQOkCw;Yw#x@T(hI`dVzsuN=INnYpz$-u_m9&sPE#2n-AcEA_9{iLuVp R|LhGC^mO%eS?83{1OQggqS*id literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00001.png b/tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..2cbafa446bfa451a2caf5b29e4ac91853eac84a1 GIT binary patch literal 737 zcmV<70v`Q|P)?HeN5__4CN|Eaq=2f7%=c{tTI5uE#+LQnQ00000cqTdLoOApur~PsK zt~MauuKXIGR`Ivm024JH>T0;I>m|Rgi?xYMRmFo&|$z+9sWnUcGW>S)$iN)*?{UqyiK$?(LFG4CgeQoYp8G!rA=~nRC(`DnxJayXax&Ne;ein}H z?+I$2w9=_HqxVn3000000M8_J45bHlOF|pVqh8X^e`@z+Uj;0yq;mgO!8)=wcX3Gy zizYd?wWHR*BJE{~M)qx}I#gL$YbyPq+FwhtVuq;YD{Sq^}_@mn>3qODbyMXj2aICII*UX_O(8*e0GzbroIx!si$Y%m6|x!X1 zOF|`?z#3RWX`)&YD~`*)Qa?+f{I<$j>bUtGwd2H#m|BOBLZ`GsnQ_TtHo~&gdUzi*ocn>0Jg}J$;PLc28lF%R1F=u>xk(oGrisU@rmyoXg6;D2-xNSqAii zd^nxjaz7YPFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00000.png b/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..19c9a3e18c72d20e0070be1ba192ab60f82fdea9 GIT binary patch literal 375 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|_WKba4!+nDh2#G+(oVKx^Xd z67_fWo|~uJO_;=~6n2E?_@Dd1N1Y1Vx~Hcy0(C(^!|gqbtS_8D^XYwQEOT{HYYJ1% z3)`b6FH{xW@3-%c(s(F)x6#ja!P7_UPM!Jl>$2UH1y;-gY56m>`To0>vx#gB46ynFTY``2@GtW@o_^!K$$ zR{veOb+4Ja&w+Fg?W@aozjdGVcJu1~aJ`SqgDL|*zIi^~{&Ad1^(%u*51)okpT5_0 z`QPVmuJIMC-py|{-}^7PRyt~Gy1!xOuIOy`S`WTsI*y+ub}R_rU-e7o_u;(cv;#Kg zLa)!)zI~tTQOkCw;Yw#x@T(hI`dVzsuN=INnYpz$-u_m9&sPE#2n-AcEA_9{iLuVp R|LhGC^mO%eS?83{1OQggqS*id literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00001.png b/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..2cbafa446bfa451a2caf5b29e4ac91853eac84a1 GIT binary patch literal 737 zcmV<70v`Q|P)?HeN5__4CN|Eaq=2f7%=c{tTI5uE#+LQnQ00000cqTdLoOApur~PsK zt~MauuKXIGR`Ivm024JH>T0;I>m|Rgi?xYMRmFo&|$z+9sWnUcGW>S)$iN)*?{UqyiK$?(LFG4CgeQoYp8G!rA=~nRC(`DnxJayXax&Ne;ein}H z?+I$2w9=_HqxVn3000000M8_J45bHlOF|pVqh8X^e`@z+Uj;0yq;mgO!8)=wcX3Gy zizYd?wWHR*BJE{~M)qx}I#gL$YbyPq+FwhtVuq;YD{Sq^}_@mn>3qODbyMXj2aICII*UX_O(8*e0GzbroIx!si$Y%m6|x!X1 zOF|`?z#3RWX`)&YD~`*)Qa?+f{I<$j>bUtGwd2H#m|BOBLZ`GsnQ_TtHo~&gdUzi*ocn>0Jg}J$;PLc28lF%R1F=u>xk(oGrisU@rmyoXg6;D2-xNSqAii zd^nxjaz7YPFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=YMjqtrV%Nn6esuj!jIMi}Btw`sohxwi1&U@}K{{10Q-!s%eVxF#kF6*2U FngGM>p?d%T literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00004.png b/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..c80fa832578d18c8b1e4a2518b82d7f50be84ca5 GIT binary patch literal 441 zcmV;q0Y?6bP){Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00000.png b/tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..6212c8bfe57f68bb18b3f4a01245d360aff3d651 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|gLTOIvxd7R?ei4nr28CMd8tbJm*q^BEmI{nL+TOwRWZbCCKq zCCTuGs6$Vk)Vr)jExXIv)KVL#b???P_WnKp-zt`?VhrYMv(`oYZO-F9k+fFg*VKE_ z0S`>SD2cEqr7fFub^g-Z(f{~P9gt6b(D|ZT>DRoDeRkeH@^aJtPq@9_ee{@3iu`Z3 z%{#a2@8ABWg8BC2OZp9O#jP}c^KWF}PpJh(U`Q@*!b>6FA!+PZOk*fy(R@j96*Svc2-n88vZyyA0 r@0q@HpJS<)P=)Ycdsyf&9H_5gGX7%PmUO{a9VF=K>gTe~DWM4f&r`2^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00001.png b/tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..eb20fe5a337367e38f04825bcff03509c66156af GIT binary patch literal 891 zcmV->1BCpEP)^H)QY)C*VT$^%gF9Oy&)&$`kd}x(WQ-Utqo_Itv(IOJhEJvZM$=xMr0_KdIPX6qaUbbeJ z+SPX91eixOauLnsG9^WvPsl2S%eQVft6X_S`hkG?IRC&n_wcb2^aQG|FXv8vEQN=n zrfHg=2U0^laRyxIO}%g$>yw`+)OaFmA|&xd+aYi;Od}c027Sv1zXCSALr-E14To)j ziWwb+j{%i|$LzpDh(ArzE zc9nDfw2L~!MvCw*pWuDXK_nuvH<_Dxh;3iyN_;rP*iL{cNn+#e*2{@j@8xCNDV8Ms zfM|6w5hDtnrX(R5IeL7pbl-8~Yj|b1cHHm;TqG`j7Y?_bhW!lKf@}1!LJv)z_8(PV zS4+m5uz9O59@f&t4AC@A(=<)fO!j{%PYM9~P5_RHrl43Nb8g$CZ;XXn)^_tL!Y~@- zY{cT|`m3DG32e6QW{VD+?8pRsts0u<|G7MqkC}NlGJXqS)!hmDD@(pY;j=REE0@EGca9X)h<-b}NmX_}^Knx=UQe*vw&8lAMz R-^2g_002ovPDHLkV1lhXq;c2!Okry-DwXq`AvJOk#}uNQK(X?Dsu64T6Fq!*Kur0001N=PNV$^?LO`&-3&p z2Z8>hD&XsB)~B-^ZEdcl&9~TVSmQf0d00(S$(o*w_lNP|<-vp{BjqpglbNj27Ag<5 zb7lwOepjlC9p$QZ|AtxLr_0Dwa0B85_t2bWT?@!xa zJ5%D?nq)u7_#$#?sv_4YNI^HFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00000.png b/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..6212c8bfe57f68bb18b3f4a01245d360aff3d651 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|gLTOIvxd7R?ei4nr28CMd8tbJm*q^BEmI{nL+TOwRWZbCCKq zCCTuGs6$Vk)Vr)jExXIv)KVL#b???P_WnKp-zt`?VhrYMv(`oYZO-F9k+fFg*VKE_ z0S`>SD2cEqr7fFub^g-Z(f{~P9gt6b(D|ZT>DRoDeRkeH@^aJtPq@9_ee{@3iu`Z3 z%{#a2@8ABWg8BC2OZp9O#jP}c^KWF}PpJh(U`Q@*!b>6FA!+PZOk*fy(R@j96*Svc2-n88vZyyA0 r@0q@HpJS<)P=)Ycdsyf&9H_5gGX7%PmUO{a9VF=K>gTe~DWM4f&r`2^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00001.png b/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..eb20fe5a337367e38f04825bcff03509c66156af GIT binary patch literal 891 zcmV->1BCpEP)^H)QY)C*VT$^%gF9Oy&)&$`kd}x(WQ-Utqo_Itv(IOJhEJvZM$=xMr0_KdIPX6qaUbbeJ z+SPX91eixOauLnsG9^WvPsl2S%eQVft6X_S`hkG?IRC&n_wcb2^aQG|FXv8vEQN=n zrfHg=2U0^laRyxIO}%g$>yw`+)OaFmA|&xd+aYi;Od}c027Sv1zXCSALr-E14To)j ziWwb+j{%i|$LzpDh(ArzE zc9nDfw2L~!MvCw*pWuDXK_nuvH<_Dxh;3iyN_;rP*iL{cNn+#e*2{@j@8xCNDV8Ms zfM|6w5hDtnrX(R5IeL7pbl-8~Yj|b1cHHm;TqG`j7Y?_bhW!lKf@}1!LJv)z_8(PV zS4+m5uz9O59@f&t4AC@A(=<)fO!j{%PYM9~P5_RHrl43Nb8g$CZ;XXn)^_tL!Y~@- zY{cT|`m3DG32e6QW{VD+?8pRsts0u<|G7MqkC}NlGJXqS)!hmDD@(pY;j=REE0@EGca9X)h<-b}NmX_}^Knx=UQe*vw&8lAMz R-^2g_002ovPDHLkV1lhXq;c2!Okry-DwXq`AvJOk#}uNQK(X?Dsu64T6Fq!*Kur0001N=PNV$^?LO`&-3&p z2Z8>hD&XsB)~B-^ZEdcl&9~TVSmQf0d00(S$(o*w_lNP|<-vp{BjqpglbNj27Ag<5 zb7lwOepjlC9p$QZ|AtxLr_0Dwa0B85_t2bWT?@!xa zJ5%D?nq)u7_#$#?sv_4YNI^HFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=YMjqtrV%Nn6esuj!jIMi}Btw`sohxwi1&U@}K{{10Q-!s%eVxF#kF6*2U FngGM>p?d%T literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00005.png b/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..c80fa832578d18c8b1e4a2518b82d7f50be84ca5 GIT binary patch literal 441 zcmV;q0Y?6bP){Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00000.png b/tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..6212c8bfe57f68bb18b3f4a01245d360aff3d651 GIT binary patch literal 400 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|gLTOIvxd7R?ei4nr28CMd8tbJm*q^BEmI{nL+TOwRWZbCCKq zCCTuGs6$Vk)Vr)jExXIv)KVL#b???P_WnKp-zt`?VhrYMv(`oYZO-F9k+fFg*VKE_ z0S`>SD2cEqr7fFub^g-Z(f{~P9gt6b(D|ZT>DRoDeRkeH@^aJtPq@9_ee{@3iu`Z3 z%{#a2@8ABWg8BC2OZp9O#jP}c^KWF}PpJh(U`Q@*!b>6FA!+PZOk*fy(R@j96*Svc2-n88vZyyA0 r@0q@HpJS<)P=)Ycdsyf&9H_5gGX7%PmUO{a9VF=K>gTe~DWM4f&r`2^ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00001.png b/tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..eb20fe5a337367e38f04825bcff03509c66156af GIT binary patch literal 891 zcmV->1BCpEP)^H)QY)C*VT$^%gF9Oy&)&$`kd}x(WQ-Utqo_Itv(IOJhEJvZM$=xMr0_KdIPX6qaUbbeJ z+SPX91eixOauLnsG9^WvPsl2S%eQVft6X_S`hkG?IRC&n_wcb2^aQG|FXv8vEQN=n zrfHg=2U0^laRyxIO}%g$>yw`+)OaFmA|&xd+aYi;Od}c027Sv1zXCSALr-E14To)j ziWwb+j{%i|$LzpDh(ArzE zc9nDfw2L~!MvCw*pWuDXK_nuvH<_Dxh;3iyN_;rP*iL{cNn+#e*2{@j@8xCNDV8Ms zfM|6w5hDtnrX(R5IeL7pbl-8~Yj|b1cHHm;TqG`j7Y?_bhW!lKf@}1!LJv)z_8(PV zS4+m5uz9O59@f&t4AC@A(=<)fO!j{%PYM9~P5_RHrl43Nb8g$CZ;XXn)^_tL!Y~@- zY{cT|`m3DG32e6QW{VD+?8pRsts0u<|G7MqkC}NlGJXqS)!hmDD@(pY;j=REE0@EGca9X)h<-b}NmX_}^Knx=UQe*vw&8lAMz R-^2g_002ovPDHLkV1lhXq;c2!Okry-DwXq`AvJOk#}uNQK(X?Dsu64T6Fq!*Kur0001N=PNV$^?LO`&-3&p z2Z8>hD&XsB)~B-^ZEdcl&9~TVSmQf0d00(S$(o*w_lNP|<-vp{BjqpglbNj27Ag<5 zb7lwOepjlC9p$QZ|AtxLr_0Dwa0B85_t2bWT?@!xa zJ5%D?nq)u7_#$#?sv_4YNI^HFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00000.png b/tests/functional/snapshots/nanox/test_sign_message_long/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..76560b8c0f3bd5e50f8a56f6718ab7bb80ca024f GIT binary patch literal 420 zcmV;V0bBlwP)x`j)$#)l2xD5^B9vd+L007`}(Kn1u*nQ(gU3$CFT~(<~$DUkDezhFAAUQ3} zEKr}6Hrvhe=ha$+4lgrCZz=Szj${XZ9Q$FKKXKgpgqT`u@~eeA0k6)fAa3Q_A}8il z^uw7iLF&k@gUxaT;buTjUb6liK3fL^007{*`rK#IpIDufBN=yN2{vMCW3^Z{TSo7C zG?k$=t7gHh_U-E*BjCD8v?L1X^y%=-$<^k!9G&w)U@|~wUpa#v| zXD_8;FU(}-E#VW>2p<7V_vwjf3fdX_qw&YGhXR>PgJ&Owg4(9VZ3LizQH(yNytDAd zcoo9pqYYiVi;G|4(*UFMK^@WD)5nT?I_6xJR7;>e^qe_gg{KQz);oB__#YnNsg!0S z(u@);#JZsN>g-IXW>P4x0;HiTfOfQ&sj&s*Q1XRS#peK;glQqBRGd9~eEvQlw1?V- zTX(|AQ0vj6D2gJ4(|_&A@)bWC5d79lDldEpG)2^}d2%xQ1og4|UG#ZP?2@-f7Q zb@Of2iw0nhqV@peVS}9HE~q#Y-nImALmrg`87zU%r50+Vw+wb_S;x-d?mp1# zO`RLyK%d@0J&&agTy94vUCaWpyr2VyQLIn}wLnNiHv;&`qAGs5SI|;lRP5~SUZ^OF zq9}@@$OZ&QLHhVK^SnB!2uk=jVhq$qNqdhWjfl;oE*ko~e9*gMI|Hv~ zx=N*Ip(JTWRqe*@KzxetlG6b7DyN%Fs*MY_oMk9G0@x?#*h5$kWRp`5+2qnRNKGk=g6Ax_=W;(A*`LN#Q(YS1 z`}YB}yJygTbP8IGGz9?w09Z;__K8^5?F4g~x)I8cDlN-Q`whC&t9#kQ) zY_$}Hy@|%!(LIr((bZAcA3f0iw&SiAqd=>{b~@!k3Zy^n3H8Wbf4a^nkzMW?lT#+D zp$nu$n&X1Bx#gPG0CbvKKrk7A?TUN9{bgj910gBGBKVc+%qVRGT^yCHH5b$e_SLa22uiZ3U z8ONe2#^ubeJQk*bckU;?1lf3x0{{R3004mL{B+j8t}FdG z&r>RSoa?$$Fgdn^gqJRz=PB8+<=L~FPfz6~s2VO&mFKIHP3|6Am-=bqx2JMR8VhVR zbnN&_4!PBop=}JlwMrDjXMi$xav@uyjMmadzeT=Ome4{P^Q{dHz(?2&V5z1sdzI$d zrl-333hfG^fc4b85~64pj{)k;;dX%RMtXY{XB(Tt;# zpwtlC(DQ(m@u$21ZEFJ66#rL4!&_fDA=!h@2V@$2zeMp`#HL0cOyH)G(Fa2bXx>3@ zNo%)Yp_-?$nIzd?e|RPUkcAKt}p-TG372 zP6jdUMgRZ+003Y;zIki?7?XAKD2D$Jnd*6bABoahk^p&-O|M0}Wuv|Qz;q2Ps;5IG zRqTC*Y>93e!ZQal{l{V3Wce8#P#$h1LO#~)(O=)gj1E{edro2A3^+PI5@pS#^j%Fg z$10lrEU$ekXL}&A^MT9~Ox*`8Ig0@R0DwXK0bfZaLS$l!#{d8T07*qoM6N<$f~@jy AAOHXW literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00004.png b/tests/functional/snapshots/nanox/test_sign_message_long/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..426fb7d66ee4e30e948e6dca6f6e32fb7d8386aa GIT binary patch literal 784 zcmV+r1MmEaP)qeIfcqCc z+a_7jCDC1o{H#4GKFp{1AqoMglMkAR+L>Mt+%*zj2xx4xP(U*nJtk#b1vkp)|2}I(kR5wjnB!*Rng@>LfvgZz%EVCF>mzD;A zqrEu1%}rfe8h{pu!@Zbw0YIh1dEJ!R5rMS=>XcJtJ8QmWAK;dq--dENRtSP12)t87 z75a4;*z4=QhEuP8(!z}S>6xg^Z3ncfuL*$8MvU_>xbg)js!a~}X!Orw1fFmN*Pg?@ zt4Pk*Z^RC(rz}b(PrgDal~+ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00005.png b/tests/functional/snapshots/nanox/test_sign_message_long/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..61f2e1745e00dd19c51132afae1b748eb472fd48 GIT binary patch literal 906 zcmV;519kj~P)0ulB&0U6#C*?1>3!Kg0*LMddt!fQ+8NuU{$klf2P>r%qSD*bWkXJVlj1f4 zrVOKa`g9tLu`E&(1DqCWXgU>V&!Jgh%T8XVn-HPrAC#_KO<89j+8n>j>L+SrpCbz6q9q zB}>ST2|J&VCV)THuVw|)!7;4{OQyTvIJ3M-{8XnGxeamFg6x|^Sc3Z;1Aj6reFx5R zG*d|?RFtX4X;FrU5@3O}MX3W)f#?}2f-iiw^u}(O!FexTpfr7-QuJ!$2%wvK*}P0I zv8i>K-iegcM=(1~HvC*#BpeXET6;>Bb6`2>6<#k~xiVjExc}2X2yN>CLp1xVhMuf_ zYzZ$dw33!2uSP9Br@_SiL7s#6-K83nP1a<4K%uB;7gw2(il! zDn(%Xz+V1rDW{*M^wQ~cTf|v2FjddN1iU7;SJJJP!aWUYA(N9GvqkqcjuHv~F1=+c zS4)R=ny9B3Cyn4I0}gG=eeU7Enp*?tWJ{)cYKQR3F1U)!4Jg&n8akoVcG*%*KiR;E zikW?zcPO6!K%-s|pH33eqo`!*%t@yw=5v^xW7IgYb2-yr?p&BU^8If^FGmxCq^E8{ z5Cp;Nxo|-u+VuNcbV-)pz6$!lLSVfLq6IQc9Hq-4KChf+AtYG7j7kWxOGC5??AuTW zXw^`s|1l*=kpxTFU78aW>!q+Z^!tDVxhx&(z^ve6La7DmR7`0uV~F1^wYtne&i_@x z)>-k4m6L|jvH>uWmUD_k=#Cuhn&Q?d1l@a3icg6=l6)h_{NJ( zBw+oLpW-B|x+T5~lBfMAePd6sO&ksr&?X-;5#dO02ks7DJe0keAY=2KJztAk3L1_( z_=w3rJRnmk-R!pM(vAU#$53(wkUOVs6Xpxa>exfxnc?GRuUxoQyaBLt4mVPjnU_}v zUVaW(5Sx=-Or@a3^ioigBuQc;WDhVLAWz8e3(mcZ&_0=M)WRHfO&d{K5LOhxp+*vG zLX{ME$5`U_NexQ!6~eiYVZ{h%!_Xt^8VZH33f*=gPz|+V&_tsNb>p}RAioscI}@Rq zXWax~oh~VO0=yo@R2x_C>&zmHeIUp3USR`1EaZ(#7z}UpO5dK-w>!Z3u)w*!_kY6Z z-w>WGi2ZZ!{{%M7LGrLO3nha=&N&F>j}7l|=O9&$2VoUo-m}{YzjJ3w)(?cCN8?FY zs7kiy4)Pk?<6iitRNmgFDwVLxoWe-UMW=nODvAH{7o{^9jJ?e?9 zd>@_1HcvprQuS>!I+=vOnAN7;_By$-uK>K#wZfs+e!)`>aEbBIS0z>Rl1JSGc=@}b z=aUnVBuSDeslSoe3iT=it%57kwariIu zeIY2pKadBOLzxpBtPF({`PVnUogDonNs=T9tia?Zt>>RX}puw*^Y)0Tk+y7X#U%wJ9ASI`BnfR-%jZJAoPb`R{xu2Z@EXezgq zv4DC5$Brx|VgD^rnB_dTiWS>u05NvpU~E&+kyx|Zhw1R-c1g~8u_Edo3$q!3(oJDB z7hQ-)Rk%$MRk~T#x=|g_FY!}sI-p&A(1i$&^fqv1@WN1zdIBAu_w4yBESI2Z+`BAd z{h{erDyEybLA??-j5BgI~fK!qVEP0>WIEG(FZ4q zRp=y>AV(i;1%_9CBR0L9YL8sbm)B@>#KrxKS-ci^@MPK?tu>v(Sc>R0OH{c`bgo74Zui*2#Zyv0Ol-x3-@{4jNYX%UB@Gt!!!%2)&VyLH<2hC`;UB2GY z0amm7!tXJ@Obzv+ZeZQ>4i3zKsl?b7Aj<32O0I>ew)&j|ZV&`P5Cp-U8kM^6cpW>cIbeOYG~&W)DEG(m@s{`OGg_@W3{r&MW5l-1znwX)d@nIT+CWb z$W3aJi1c;FF zE8gXk?9d}&7rLr&F|c48DvkiK^BYaUiDGdcAr7Xy-E5^Rmx?z~7Dn+>S;{*q11~=Z zZ0MVlE~ciS&9tVVAP9osAl7a?_6Rk1#ZV+ih;gp$S!{vi=Zd8P$gvBH8p0z#SPNg+0O_h#ZFR_wqBPG6ou@TT+!EizR;U)oyk!HF!yV|O2c*DdvnCDww$Q(;FKoA5$FappT^Y3jk zncp@HSUzI!SF0a3CFH4B&`xH}zFa=cy4ly9_|sRM4IFv6qx7jw)@Qx0wn~a?{w~<^ zfK9|ILX3Nu|LLFdkFeughad=o b;5+#TRPC-j*2h{e00000NkvXXu0mjfL0+7A literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00009.png b/tests/functional/snapshots/nanox/test_sign_message_long/00009.png new file mode 100644 index 0000000000000000000000000000000000000000..08153684a0f7b3ded3fd1a9f5b7bf708a82e570b GIT binary patch literal 767 zcmVIzVHe%2Dbu-d)!Fl(8WG`E{ldG~APJhJp%&F0Ns z-d=U^@pHfnb93+!Ln-KGq!dI5A!GsGdyG{`r@!t(7j_7}lMmnkfPHm3cR|Y0sVb?L z8`+Q z;^hvhQo&1(9#`kB3pqZq>^QF4`|+L>f$N=vPuVlj68Q?4^$9{rqlkUwrCK$sx5q!% zG@A|fZG`uoUENtTbUNan?-v&iKt?43-a!cot`9ne1!F)W3$hT2G=j`AaAiVxUwc;{ zWPHRvbPzi<=o9f%p4)1uBsyM#l!!}}h-JyFBuRqetK@dopzfH}eh-q`HzHnIEt?vQ zh^e6GCf}5`GEIy-C7HZTGc3~vV7E&mR`Jz|rUQ<*qt~)L^dRT}=o1PTFRhl5r|1b< zzawllsNX#W?SGuJw7-wv4c(uU?uOz>yK+JZAxAQ@naMuJZM84@>_IFt>z;=b%LYJ~ zIhAb;qO)3`t`vS2t6bWlR>msjXl7C_J=i4$`5j-=C57DadYN4Y!23cca(Qh@=Ajg^ xm@QU-{tp@^$~_PGYW=0kB_V_mLJ0Yt{0AG>C7lhK&fow5002ovPDHLkV1jmJWlR77 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00010.png b/tests/functional/snapshots/nanox/test_sign_message_long/00010.png new file mode 100644 index 0000000000000000000000000000000000000000..745d08100000048f40d136780bd924defe4a7f50 GIT binary patch literal 779 zcmV+m1N8ifP)3`Lz(ZsPkN$#==Z)h`{F!L zEoC{^b(O~47IK3RX7iI%%Oj?f=KOpI%Ir_+Bkk{bp0~@$-Q(ld^Fx`(D9h{d@DnIg zHc3W`Xbrd3pK|C9GDfjxNtKurGYpvl#xQvj#T0SSJ-5n>>PRGYh988~rlC!yDybPD zLT0OYSBuWh2e6w6!)<%43WxYA@eU}1j~IyfNG~0C4@~Y#ttZ5hxX+p&CL4mPekZq# z_+vvNRil|+=J#m)HB_7d#(Q3Cik&DH=N4)yTGQ3nO)cHIRJ@O885I9IOHCl$;@{i{ zEE$QhMk66;GFk`%0000~TKCnh1-tM!--2F5Pc2B36SVD*AwN{_iYdGm%{DEYk>B%x zD={Q^Q9I*_)grC=jV5dzKTt`S{%YtTl26;kStHhl*L1*<(A!6LjEIs?LA z9>}uESJ6D4v9EoZAjW84Qk^wtKCxM4=YJ9Xhp0}5_opGa8s47_`d}r9LMy2_8GSGm zxHrxq-)*rGv*oj16)vpDpu;y|Tg5Chh$+S?53$a2FY{a*N5pt$tsrk&wBaa35u%l@ zkwxVc_y?zV-bF-P&|k146r>*7Nx-PO09me zQ!}!#Xc%9^G--CwaoCp;o@dU2n8y|w?|90>`vZY<0RR9j;1_RoHa&N6?)d-!002ov JPDHLkV1ml}X+r=2 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00011.png b/tests/functional/snapshots/nanox/test_sign_message_long/00011.png new file mode 100644 index 0000000000000000000000000000000000000000..91bf38fba8ff25b52e51bb55be50515a0ad8e2f5 GIT binary patch literal 842 zcmV-Q1GW5#P)pQTr!tDd#y;^1Xq7YSrkcRW2)yh~RC%E?Eah~&5{JMJ2WvMa4jsN?ZD&-@$%rXaW9 zt5b>DK-Qem?{CTFlqu-=9qeFGgA!|2sjR6kD(}HQ#ZT!n>#E1#qheR8lz%yn{V z-@=A_8G@4lReA(D2ujLWt&3Q2jh8`6cl};Qk&z;-PhgK?iy#kq2UG(GKZHSr(qLIZ zZKc)+;Lde}#9nZC@xau!&Z=qnklA7kF2?MW8J)!hs3_essi&9#i*-35lBKf{sc<@( zIhYE&myrMQzX?a=y-F8sYGN4y0a&M0oANlW;9|?IzK$HNf*(*l6B=hk%S_u;n@@`0 zBJ@GVd4Y~ucuU(+#yjH&z2_&uRX`)Wt8LuA9KUj-ZjW)xLR1aiMO++0e7kDgpw)Z+ z9S{*0i1pvjK6Y>DF6^;4bS2j72qA=!rF_Fz(v4R^ zv%7Lls=8J|U{4B`GqG@ZR|X3bpkiA4L8K`lreb|p{;aNd#qw#CM%XGkswIhFUE9;2HlMblrfTupzxSW=qvE)bGUQZRcfQWxS%1)Y!kgzcTsAgE|I ziIlC{;eE|G7*!2+AFYRRNA_$UeJ<-|$l>H--uOM>GkB01x~~kmc>2&2Rdn_ UFe27=Hvj+t07*qoM6N<$f?M>H3jhEB literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00012.png b/tests/functional/snapshots/nanox/test_sign_message_long/00012.png new file mode 100644 index 0000000000000000000000000000000000000000..fd105b256a0d9a051d74421becaa741ae5e025e5 GIT binary patch literal 812 zcmV+{1JnG8P)Nkl3`I#QH|hHy$#==Z6^ei+gc#cW-y+qW(7L~TzmEAH-?ZB=qDL3T!Wy{w;YNCKuH z`wW}3`A4RjsXD`CZ3>qQ7}|!CBY<2veT%T1NEUA+BvV?0T>jR$uuV8;3m!>c3CT-i zsoA*QJ@y>1zBBqfI;Wt;a8nQf0DyJO*jK2>=8|ylYE7SSHR-YN}n zw>)`-Autl0}Ex(b}+8v)y5Va@D`e<)i!IYdK zTmdZ!(}Fntb|cEU|9{T3N#F}>fc8;Go@ZRJ%ib+UHcG9BewgL{puDwn!dMgtdmkXL zNWBP4sBv(#n*v$yB+Cj63ccqtX)QT+92`0Y#bRHL*K^{xp(}RN00000_;gn9f?B1M zlToYBM!DaK+BF$PRzc=`?CwjJExEhxU!!r^qpD~wVD*=ADvswr_LOU3Lj%ZSj&JN6 z^~-UQHJl9%(DnS~O5pov0;B6)AFXa10f~8q;FB1Qvrw1u2QI}M-I%HEIw=@qAR@&+`TYqD5XrWi}9R$zKsbbs2TU_ z5U4+xs#0~jslq>)R^B!zJPuYSqmB5e)My)syWyFe^9-^|ikOR8jGSIcrcd~Q1mr?w$iehN zF@3_vND2!bF8&ScB|Y5z^p!GrxLDP!X;R`GRW63J^X<51e{vs{e*)pn?aJ#zesT(rkYj~_AICNMkRnr5 zYf4+~lAuitoQy4L;&WmTQ|TH|<9>Ps&Te8Ys;+yybkQX1d5S5vpJMK=*(v`JHsF~<<%B@Nm>eUxgDHq;|}}=Yv5VM!K2OikO6P z!uT!KZguIT0ECXV`&cCdJ3og7U)b!bCgz5|+_RPeU4{4NuyvV`QU$Pq#a zA%u`O>3neHb7z~WK6*U>gTD<8l?{<9DSy}6mgQC}6paUCtJOCJtlXl1F82Oqr?6)f zY`J3!Kw{^BW?YW%JDf@BIi!4@*Nn6OZ+AL*UZHKbUmEs zDV1y|rBoVoS$LIXYmdJM=Q?@?QcfD`;>RX-e@ai)A1}`HtQ~iioF7WrJUsO%vicGJ z+r-L-$$TkaG^iux8_CtUOI=MkpUa zDO?ayH6n{^Tj2WkMeH&{x@$SsKPTFG2rHh`Fddr!QrWvfk&F0AUO}D25X$2?` zwUnYq(g4;3WuN9&Q`?$WgD+QUaAy@NKZY#jCAD1cZd<55rSS!3_uVB zL9iRc83{bU-keu$!cTE}iQ7M9^n|FC3e6>Kg<6lKsxHSB9`fxB=|wHRhh|<=f8~%BBy%5085(|jsyn4CPkGa%W{`2&AzpP42)>1>-+>1~5Cq@CFSr(n!@~VLx&QzG M07*qoM6N<$g4Ne}z5oCK literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00016.png b/tests/functional/snapshots/nanox/test_sign_message_long/00016.png new file mode 100644 index 0000000000000000000000000000000000000000..046bed7c911955e6a2a667df7da5ea4bd4679595 GIT binary patch literal 770 zcmV+d1O5DoP);YffUyeNML;HyTOr)2^Ub_;HH?)K-BQ2TNV&T`3 zhgO-*6ww>*t34%24O5JDPk13l<2XW|0A-r+Nk>z}Nq66(7uA`VmC4;Z-{=kDu}ehs z*+SP7Ad)?;;@whoHa0-7!pL3Y9lp75+-5lb0ieN03`BgU(~i3)ChyA9NQg6Woi*Q0 zZwRXPdv;5SKRQ{YYIM`e{1NqUL&YaRTseJx|4o27K)Qt^Fc>tuD= zY%&{&yT(1w0guc?U!|T9G?`Ke0ssK;7_G-q-zGuaUCdW(R>a*4_KYRVod&?a3!)N= zc(CH?f+Dih>{YR|dPK@f@KvOgrl0@ggrg652ol9{-Hh8;Ek{+<<92JM3ggw#2N}B> z%?Wf{4S-$O>o*%E{%kb>GbxGftwWLzz?=m{eDzUUGmRKa7-i=3w$i;jZSUg9da3g~ z^rAPQb4@_p#bWNaaT4yIttA+eKn%sM#u!YX(#aTuP-45+QF_qJ+c^TN<7GAH$%EK7 z`>vjb^nM$9UGUF66j_lbW+yVSKz?1-FOA;vL{ajzv~H9#(MIV=La&u`N>g@UVykaT zAp;dqN^c0VJbf!K?A3?H{)GAH8i4GDjBd6jx*U`~TNlxg0Uu_`XX{;vZr$KTm}8eY zOP0p=J9Im2hwj72!L zM5G8!l$TkZ91uQNB;tX_IRJbE%Wk3o004Y3f41IFpXXk&PXGV_07*qoM6N<$f*HDJ Af&c&j literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00017.png b/tests/functional/snapshots/nanox/test_sign_message_long/00017.png new file mode 100644 index 0000000000000000000000000000000000000000..db7a039a4bd171fede71181ca768d5c5a7be6319 GIT binary patch literal 718 zcmV;<0x|uGP)3`Lz(ZqoNZlJAlQ6^dv=$V{gGTe&fVED2#``nmuB00000n9f(M*?r&X;`8}v zCCj<*yA&o#m`bv=39(vPhgTrwWGp}5fi|yzsF-U!A+}BBWu4qSn}-{c4B_M_(556= zUL2cyO049Pp3SIiOJWmK;uA*A0K-$b>y;&<-{o87Mb#NepRuPPU1^8{dw4nnM972{ z?>eJ%Y=|Z~$vi6s%OZtCe3eHAD1(m}h`6Vhic5~kRjFA*bjE$w{1_cVP*v~bmJxq! zNTg~M)5Uyq4hccmpR*fIZIozHh4dy4K}N5x%*Hw|uJGER&ZXj&5R(`dGFpu$JlwJS zfcefC8!@;Oo{X_^1pol>4(|Vq8>Lqd^HW0unf5Rp2bv)BsEwE(XF~L18!@dW>4d*B zk@N`}f)^e_)tkhLA1Jhk<83_`<5)8T0_o4#D54{871`GqK>Xm>S1-9wZiB7D%dx45 zg!Z+L*I5hz zN`?)FvW0rzl`I?0;Ty62S@2ERne6mb6YG#dBZt~_!1NsKyrw_>>8aD2@|+*j)_)Jk zyzz_8b2c)-wCTT9oWUZzm|bRoGfDY8m+9=`%&(FF000002Q%UHr$+{I!G977)Af9r zJ8#7DiL3BmbBCgx%xHbG>+5q+hpE>=7`t4J=ks$1^@s6006+lFGR$%+xdJNXaE2J07*qoM6N<$f}8tP Ac>n+a literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00018.png b/tests/functional/snapshots/nanox/test_sign_message_long/00018.png new file mode 100644 index 0000000000000000000000000000000000000000..180b120458d3e08c64ab0b092e35920ba935c757 GIT binary patch literal 828 zcmV-C1H=4@P)Q;x7H+tdq?bA;gHgd46w$3BXf3s9c|VJ#z;Ec_x%VNI=j8Xy1#&Rl(w`V3xAF_ z&?H(ZtT)tGd&wpTNLj^_CtZ9&oZ*rkpe&QKkS$>s-FXWB=&nT6C+(`WhHA0{>DHlM z4KcL?SkP`|&q~?ZH~`&*u{oRuG^uAzS|=R;1i<9OCL+4-VBn60Nkb{k1iKQ~x#qi> zO+nqbqf<)$(LtGN&`m4(GwQz$Wp{vbpEp{f7qZQ%hf;}Tx_i4Rl^ZV=&*QudvWLc2 z3AinO=5xR;E751vlY)|wQczJ8Me#_w@{zsOj74~sy^U$_xUDP1OA${*QI!=<5aQM< zW+yIZslqdEO-YDZ8Ri^qC?oHr3Z@TYAG3& zI#--zt=R9FEf?WVc#{>x??eo8ML!KD)D`_?Y7XwCve2D$f?RWODH-7%QaU9uV9j-K zg;((pVn+FJdsnhnW8N!c4}B>@k~3-epmGo^5ITH-hp-=16P3f}y7RhH8?2AQ?%-e6 zA*0gCcGZq>t$w{NWsdNcN|6o)KK?_!GYPI%{<9- z;4^Bv2*X9{Td4yGhWll8B-LFpULi&S|giKgy7afg- zif(G`>N-+)K%fE|=+eCoWT&9y0b5>)xYgVcvL`^vvpe~3??7|Qk~aYk1=R7eDK$!) zOLeHxuOo2ez88e~JmB;6&t{eXln>ATn{ba`6h%=KtMCuW40={MxwBIM0000GDseT5Gd$9AC6K;((q`x)RX`K00000Sk8x|&3)g`FV}TR zC9iYecNxqRAq_Z@m~&034qINiv-9a_vp;2yq(86gdQw(hO+RV9ekkiGZK)j#Uye4V z%W9;s(a>1!B}q<@GK!^0n)s49!ju`H43k{Qmau~^Un+lTj>O8Q`$j5j64GR9GBg8N zs@ck3l~!lt4d^bKJhPUzrLpCx+)I2De+QI{54#Z2kzOY58JIMcQctiW(VY}!eOt`v z64cClbxB!&bgGrAGfW<7$gd=R2})#+cRhrqAz4{tT~yvJPiAE*un&33uklfF9#xkp zJ*2c+fZOBW+y}fe5`9iRJK@Dh@1pHy#f7^<&v zM-@A?uvey)LQ*Q|j^eQkY7UW-+Lzq*ik(uSFHW~`TQNEVN?m2@!@xeK-r6Vo80`S| z*daCr*{1y?#z6109Ub#w)>OIeMLaV=$%Q3Hy&_^)WutM2kQr_P000000KCJDBi6;< z$2n#rCUN>Zc$gaMkU|wB(x;ZOUv{#QTQtsf!lwhb>dBT!&3jc(#h1OIJzzUiX277G zeg2DDA~3MX1DSCtlnS5YHcP=gkSN`E$8SUFa$j9a+kDwM&a5Lz30+mz&jkmga`%LO z@CihWN1I(n!a05)a5_6a1EPrkFD(E703eWW5}SLF{{J!A00000NkvXXu0mjflwW?O literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00020.png b/tests/functional/snapshots/nanox/test_sign_message_long/00020.png new file mode 100644 index 0000000000000000000000000000000000000000..feca784b1272b2fffe1f1320e60d7571513ccec8 GIT binary patch literal 829 zcmV-D1H$}?P)ng za+c+kQe^k4@fh5`Zk^}Jr6KKYjdpD2r#K(#endo_0U%4I+QFy z($D-3STzg-^+rO_!*DSK006*Zo?mY)S>bHTlBM2cg58L(f`rc~^5>X^+eNT{{%{2f zJ{-eV!FVlicx<#C(hWCG87H+fi=f6SLPAPo6_;iF>+;gOoiaL8 z%Z?pzc+_b*l=ty6+g!`njz@FZ~;kwe29xu@+{cP*o*kKB&36 zyRKT4=6&57?v1dGjMje)qN&mP4}(5f38K(SltxA$+{$e8rgu-cKx4*S+29WJ53zlG zP4r}+eN9D*XoV`H#z|VpVmYIrbjqIC5rj|fp-7{u?V55jLFC>fnsGnwL`7W z^$5mi5j;!~YLVxj%KhODGoKDA_p(kOGbcDn@o#9P?<)cz&?uxO1!mdtw}=F!AStx+xfzA&|F{y5U-fbJi!yW?q-CEqQJE}4hi9S}HG`IbIdLh|WoZc~Mv zPV4o|o?-yfD|uV(FdR1h$nlZSZf&&7cfi+z4gdfE02c8JQ=D)zf(J{{00000NkvXX Hu0mjfc+!BM literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00021.png b/tests/functional/snapshots/nanox/test_sign_message_long/00021.png new file mode 100644 index 0000000000000000000000000000000000000000..888927745fd1eafc2468026ffed1659b8bba7fa3 GIT binary patch literal 837 zcmV-L1G@Z)P)W6#!;RN>o$Sd6#bG7tP6tV}f);ZH1+%piKxPqboqASg`6{ zHSE?*daD2?petpD-$NKDs^-!|U@jZd+-}y=jgN{)lAeU>pGK?IxU2iv zbHM(|=&R8gf;IzU2qA=!^VH5w_WUE+PO*8fh3NGI zW>$|;>S;(le}(L9g^L2GEl{%R=V3qyQfGAD08kXL#g+CJWiQsD0|HJS#6~1W5PaVy zDBD;Vf||rAF;`Yg@!>7Pf`P+QMD1vReg{;C9rBT zVq3U}%%2rKSFoW6s#UP}!>&$HYGLp1e}7;|B5Pn2I!U9GIR;Ca-@SK6SFMXidWr<= ztMSY`;rxee@5$;lJ=pd+QiQ5#hKlwHQfjBFAmq$Y5l7X+-P&q#OEz;vO__;Nv&2Hb zC5YJ-P3&9KJ$qXQL(qg30HkxHx#QMc4*D?X=jlbFLum<>rn-N1>~Ns>))Y?4(N9GE z5#tDRLQuT8ULTg!o@q6ecrXGq#b>v+I!gp4gb+dqAqA%I1By-Fwhh_DdRHhmYMJvZ zI{1bFi#+ech@bw0m_w?xd|YR#H!nwOoND1RXU!kgO1-|b|0SR)xcX@hsY9wXP8s!W zPgj9PMYbu3%743R2lTA~b)1)?PQXv1?~Rz0NvLY({px<+&;`mptV P00000NkvXXu0mjfl8uKu literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00022.png b/tests/functional/snapshots/nanox/test_sign_message_long/00022.png new file mode 100644 index 0000000000000000000000000000000000000000..4c25eca4a42f750d9bfc79a6559fba4a70b0c48e GIT binary patch literal 857 zcmV-f1E&0mP)e5912p>5t*a~uEw00000+|F0PCZ%*;oaZT} zEGMO;yC?a4rJv`SGf0NV{|LmM{X1Z@KV^(^K+AMCF>|G#FIYorOUv=_6R;_(ta=LT z4fWNZa>xOadMKOOlgQRJn<*ne=_WamO<_A-{;9k$d*YDEFs0-yO&UxlT_b>{8m;WF zbV_Y{0KE#uM4IlUJlU)86mJr5fO7I-CnDO@%fMZomxfYm2{wYxpqP{7LVBklGw#(- z%KW2K%~XwUidL}}9Y}l|%8meb<%})DdLnC1J@l6;&5g8tWv8&uE_@hy8DwvrRyPo? z@tNm9nmI-wfA6Dux<`|d>3S%gAVS{~ zNBPzzN9%8t%BS)?Ud*Z=TCd-#pNUe0^s;P*RX?lhtw%spN02orx&XosrjHb*pN@0h4#S+ zGTLA&!SI@5!RbM6 z3Y@z5>USoHG6gBxq4{n^S4sVuJs0{@H05N|ojy>;e;b->bso)QhW-Lak+^pQ{m#s4 z06H+GZ1lFL4JIv4l2WUO*yGH0YN+4v%GNnznot}IJL4Sz`eGY{)fCIyR@IZ{H`_8V z!g^i)wOw%r000000AvRIe}HF)%5IQ*J^%=8?D|XC9c625>OxJ02gL9lgin@XQUp~5 zuM6c+!=^NK%tXHRq#CDLLRGcojD8kdKb~5Z%fo63`cuYPsk3B{hyKJ?#*6?un}??t z1^Qug4E7zsDh4zF8;;fh-5C!08TxHiQ=a*6s&B-wDd@Ur`mB>JA>VpdZ#_}^xYJWY j1*A;?00000@F;!(KRuv#mn+1(00000NkvXXu0mjfxNwX` literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00023.png b/tests/functional/snapshots/nanox/test_sign_message_long/00023.png new file mode 100644 index 0000000000000000000000000000000000000000..ae2ca3f2242ff7acff0dfe67286a52e5770179bb GIT binary patch literal 765 zcmVL$rd5u@R;`b!SIgN#|sjh*B=@d-m#fH6%Dp002X1?rPqAxZ57*PPa>2owXpM!jsR&$xA#*g)VV1!-zz* z=dIXPy_7q2{+HW`mo!VUM68Dtijf!}c%#i0pU__oHPG}?KBp#R*q0>nsRM8*nMWLh zw89>WWI6q%h&$Jpr+S{GsXbPkAIW^^3K$)wmR>_yhjqRkdT z8mRH_a$~#1X&~IfMt8MQs0MqF!R~CIg|?>A$ryv7d};R@(t^_^WESe>4|yiM@65_e z5&R%yystqD{qEdSlT>prhImebcG&#V45E_c^FqI`7%idc9u3A2Q*CC8aS6K2EbYyz zXyx6f`33_pRGW%c-aVKP`4ZljsfMK%@Vn4ffJccG%RM5fUu12@kkDLntQ6zka7bPr!^#18!$Mvj15Uz=8Mp%M v9a~h1^w6x67&z6<<*Nh$00000fX@5@m1!ORo!p-<00000NkvXXu0mjf*ywJn literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00024.png b/tests/functional/snapshots/nanox/test_sign_message_long/00024.png new file mode 100644 index 0000000000000000000000000000000000000000..91b1ce5690e4ccbfe302ab67423fd85cfd3e65b8 GIT binary patch literal 859 zcmV-h1El3-^fdOBW*Q+Rsq9}@@DAM^8XwzD| ze!SmrspL4VHA{HcrJ?*Tyc-U6*z(?^oxk1&kDyObpW?op{@HWYfB(`~z70~Fz@WsB zw?WU<=d4#cMq(u|?yf*(ig#27k~qVbCjg9*yO1qmN8Ej>|Dg^;HSfk5qqSx<$cC*l z^#rgCk1BhW&Zn;Eu?x_|(knx?JFwUkuM+Qoe)3@_B0AFh#9f1zrc&w&HiO2DNY;jU zET)z-I|ZqEA1;CU2Q$o6&M?PT{ai;c1&oJ@Z$sH9fL%Fbi!d%^o6`tEbE&4f-IU6W zv)seD*Fg49W2+ouPQUX#;M6b-_>D|K$>2GpD2k%UrgdaGRZEOl17UBv)A%mvewWGL z@bxjAa{XG=C5yEnswl8>`Tbi`AnY20MHyw42JlrwDx}TXH@=Kv!HVFZkp7E*s7}4E zE%6)8szzK-M*Im_(&4+OFPF-8WGCdoTis)0|O~=9jGCjH& zpMaSJ4f^P0eY|oSU3j6ghh2L)zD5w;E% zN3loA0=Rv8M;if(pjS#{&06Y&HOqi}3*y9gq_RMY$YF`QfDs_=En&;q&>5vu^+-pb z_vmN9o~!aIJ!C$RaWsBB92)T(16CLBQwufvpXdWpE$%ggA4 zay&y3xg~^xb- zB?iNdxr57dHLHX2gT7wFrZS&}umm^|e3049GtP$g@~{&O008hF=$9P&{ryNS?igNB zX4@*LcWyky=XytFWsyyhOuB9zU-IUDgYutm~bGegnF z(pKm@&jGuJVMDnsE@&||9|8aX-~se+Nak&6wx7{P?t*HSIc?e8-sqHJyC8NpVP~`+ z`IF{A@0R`Qc~DWaGgXdS%uey=Db$qlny^!g7P`<&G^O&W0cPe=#;c(ULo8n7KunE# zR6$ESAh~5{MORrf>-ACw+OWCrqoM6&esx>;Ks;}>WBv$IEdS=3ITV`>3AH18>z0kWc8X0{smCem-3Ij^CscdYQ zcRmw-5U!Ij6C=xOQFIiqX`XtCEW=tL%gPg9yld*F{(`1xrFW*~UuITR=1i6g8lr=m zUT%nXYuYJts1_u$*i$zb7fSe~4p^_ywY~5hveUZ=)5lWm5f$iRzznFVgUY}W-=?ON z8Adh8A&RDF?6a(Tv{C>70002sV%gEuDWj(UKT}c6^IPsOx{X(WdP)W6bXbMgB+bn2><{9004k+{tejVobQ9{ zx>_mQ$vG?Tl@yX*E?w7E=iwQ6fn#m|8L&B@x{peSrvFFcMl`?E>paDM{xuRHFZyu2%0BO&&nu~Xs$ zi=EjJ)a`e2Nr^u?BvL(e(`ps}6gU1DD&7I&$~m?O>xrT{_pocO#Gj{+q1=s6pe%#p zsnIHc;Tk`4AFyR6j#WAmf`U{D22r*ztGB0|rb=HE2 z3Qvy77KY5J)@f_M*3y|DdCQBf-E*lWn%eLBm*)`=lsw%;y&SKqMU!Ft)lh}gM6sFZ z4ONcRl>Lt9^Hi?0TkqKm9u2^IhV z0000e_>()Nf7000000Dv2RG2tZhB_7YY00000 LNkvXXu0mjf3sr5_ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00028.png b/tests/functional/snapshots/nanox/test_sign_message_long/00028.png new file mode 100644 index 0000000000000000000000000000000000000000..f20a23ce404d836095de9f6a3febdefebf62785f GIT binary patch literal 857 zcmV-f1E&0mP) zEX}8;(d%6(O`26zPeU`Wr6H{|7yks*$%jouG}3Fw<=~~RlxBhrL(n6evxRwk(6R%i3PaEV8DMI=Hq%LV{BHy0)EGxrfEl6VL$m7^5 zy1|9WrAXlv%U!cR@zu(z6;MCNuUqxAEZ^Lp3HEfoY624X?}kM(+@NKugCaI(Wu9+- znB_pxL1#&=EHhVtat%m?`h-TSWyJ!Xg$6azAP9mW2!dda8oEbfM7{xFN1_Z**-e_1 z-7kx*6l7Bm)|cwwk`dko3-lnyhF%>zR3p4pnbY)>4n`MH*ikDJw zbt^aq<5NJ9cn7c1DwJ;hG_k;59uhmW+_d(k1a&ZdpP2ytyG-dbP1aLZ->p{2tvpB# zr3&^QH_Z)yt8|L4fD!Sp(GHQnJV<>trxaCEn!j%LlbWC0Wj<%Yz54N7o-Ypup%x&+wQG(8000000D#;1m1xsiyDrZ2 z)Ji^1Yt44A7aq**>(+UmS{<=`>@m*o*#@s*3{a2eSl$asdFLuW{}F7;W948~i-N|YS za^p^J8TrSCWU5Iw)mGY+zm5DhR9pe#w8}k%?Lx6R_b}3<i|w#%AF;8}S-QrWO;o z+v*;2oqp#z;8W8u(QhUN-Het)0002I8|}a)UVJ5w+Xek^&sa-}AnHf|Q#``(Yg>iq zN2lH@G6tFo5)n#gRoJVGsUKVRg2YY;@j`xg{L^l3q$$^1qw=i(qpQU2m9$x}hPr4A zYsKKE`f=aV530Kdfae*qz!%LH)}Km=Y5$#vaM#UipN%|mKX$7#>Wn=OC6nfYt^n6A z5kbd>k^V}aPTYqbSt#zR78B8?RUz`&1dFKgbhj3u3L&K0+(+~`5gh}tgXt^;3UPvr zG1y8?cpo@ORW7xkJi#Tw-0YTr6Xo`64F;`+-U%D0R_!AZLyr{2NKI=b)inD?E3rrI zXKHuj%5Jc)X|xq!NR{rfE+|IY^5m2$%`5v>c}F8GWEVYVL#U+sc%c3L{a$sZtZ~skWgK0AJTOenUf-dvL&w&w@>UC zisN_+i>sB9uG{b*0LWR-_0T;$W{69G$Is}v1|z0KYpyzLi?T*v5r4EgasNA8K22QF z%NqM~bj6Ky+bUciwhTb}%RTYS(G@q+ZL4s7*mV+Kk)>WHX{|B60wS^{Z({3?+5^qD tY^$?zSu~DolT_H@0{{R300005`~{>!-9}@e_tO9X002ovPDHLkV1h7Ymtz0` literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00030.png b/tests/functional/snapshots/nanox/test_sign_message_long/00030.png new file mode 100644 index 0000000000000000000000000000000000000000..92754796b6b8ca5665db7fa03bb0ffeaedea21cf GIT binary patch literal 485 zcmVEF}$}waWqk002z)waL_WY6h5!scPQU>*-MR z?Itw&@WW+Vhu2@%$KL_@;$tpEdZg!xOM_RZvepykFpRV3yPaKv4)b2zYOFtP#Y#08 z=77na>OY2>Gr-(AeVcH*(5$W_Y`m@3de2d{aaj0*Nx36?p!u@1)*QY@zw>v%r-q@U zUC$CUS#1dd0K7~8F=PHI2s=;dfN;mq+SA>1oj?G4taVr=Ly~Gw08pi&RV%#hn*bd5)?Mjf^50+=dHO3*XrIMpsVSp zWPens?^O*ZRFv0>_SKAdqJ?;su&e)z`XHb;u0nCVbRQ0a^a20?000000000000000 b0Jr%E+zz001*HVJ00000NkvXXu0mjfsx9HJ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00031.png b/tests/functional/snapshots/nanox/test_sign_message_long/00031.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_refused/00000.png b/tests/functional/snapshots/nanox/test_sign_message_refused/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..76560b8c0f3bd5e50f8a56f6718ab7bb80ca024f GIT binary patch literal 420 zcmV;V0bBlwP)x`j)$#)l2xD5^B9vd+L007`}(Kn1u*nQ(gU3$CFT~(<~$DUkDezhFAAUQ3} zEKr}6Hrvhe=ha$+4lgrCZz=Szj${XZ9Q$FKKXKgpgqT`u@~eeA0k6)fAa3Q_A}8il z^uw7iLF&k@gUxaT;buTjUb6liK3fL^007{*`rK#IpIDufBN=yN2{vMCW3^Z{TSo7C zG?k$=t7gHh_U-E*DCwnx5w`E{%-Kc_?4k0-VF$w(-ruJPws*U2$W*oM}LZQtxEg>!_G zS#OEbyw!xRfOAfC6^*i}Wi9b3dQVlkfsm++^MO+9f zpUJLFY9&RQjHEW!1hLLKR9ahw3x;{#s&9h~i84Y;sd>BeeAhm}W#;-$f6tw8Fw*-d z004jpl=qN;Elik|do6aTUzR78fKiL94aKm0BPJaQDElu-i$4=}$=+_Xwb<(ZdLGtF zD78nVk42rTY#ybcv;r(f?fIoj+*f(r3NWVIGb}30*7hVdl%Q*HrFSglZuDAJ>&9SK ziZ~)^tw%1MFLxmw@XbS4fUo=72OY6BQ&4KBURFnWY$(SVb}JqCzTmAcKcbW2{V*6; z!~4Nt4DJL`=uSFL#uzN+ZSH+Rf4=KXI3c0eQo3~2%KBSUP!cKYk16!a%!~@6M0{mS zB|ksNwE}cl_qCgQ-OJgeswWLV5n>VXsYQRyGX`&X2#-pY>!i&KJZuGY9cR>E6E1~s zB+okdM&Nw_001u~&#j(Cxc^kf0WZ}hUB?<6Tj=%+8A-@2wp*KR4Q=MGII4@OdWA#V zH@0i{v+mZWv8>VPkWgxD!)2nS2*=QLp{j&JY4ia2-uN8-&kYHM(l@A~j>HS4&MV;Z tt<7%F^@pm3p(m}e6aWAK0001w literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_refused/00002.png b/tests/functional/snapshots/nanox/test_sign_message_refused/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..efb803419298d803369d1c2475b424019a7d5746 GIT binary patch literal 467 zcmV;^0WAKBP)&W`2{dt|Jl;()q%d$}3*#45xi&|A#vJUNR z?q%u<$P-G9RCTvy$@UUN+{-%cOO(_36V{?RXUGarW})7EkNd#0et ztP}(QxTVo=Jqvo)Q_zCueG6)^J}?C1qkQ+>t=$}N)bH%w!b9~}&TLDpfUYWnCj#pG zH zr%^&p^e1Bsu0$5PQYXla!BB)30000000000000000000O<{!OCS)MCIjGh1h002ov JPDHLkV1hAI*pUDL literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_refused/00003.png b/tests/functional/snapshots/nanox/test_sign_message_refused/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=YMjqtrV%Nn6esuj!jIMi}Btw`sohxwi1&U@}K{{10Q-!s%eVxF#kF6*2U FngGM>p?d%T literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_refused/00005.png b/tests/functional/snapshots/nanox/test_sign_message_refused/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..c80fa832578d18c8b1e4a2518b82d7f50be84ca5 GIT binary patch literal 441 zcmV;q0Y?6bP){Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_short/00000.png b/tests/functional/snapshots/nanox/test_sign_message_short/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..76560b8c0f3bd5e50f8a56f6718ab7bb80ca024f GIT binary patch literal 420 zcmV;V0bBlwP)x`j)$#)l2xD5^B9vd+L007`}(Kn1u*nQ(gU3$CFT~(<~$DUkDezhFAAUQ3} zEKr}6Hrvhe=ha$+4lgrCZz=Szj${XZ9Q$FKKXKgpgqT`u@~eeA0k6)fAa3Q_A}8il z^uw7iLF&k@gUxaT;buTjUb6liK3fL^007{*`rK#IpIDufBN=yN2{vMCW3^Z{TSo7C zG?k$=t7gHh_U-E*DCwnx5w`E{%-Kc_?4k0-VF$w(-ruJPws*U2$W*oM}LZQtxEg>!_G zS#OEbyw!xRfOAfC6^*i}Wi9b3dQVlkfsm++^MO+9f zpUJLFY9&RQjHEW!1hLLKR9ahw3x;{#s&9h~i84Y;sd>BeeAhm}W#;-$f6tw8Fw*-d z004jpl=qN;Elik|do6aTUzR78fKiL94aKm0BPJaQDElu-i$4=}$=+_Xwb<(ZdLGtF zD78nVk42rTY#ybcv;r(f?fIoj+*f(r3NWVIGb}30*7hVdl%Q*HrFSglZuDAJ>&9SK ziZ~)^tw%1MFLxmw@XbS4fUo=72OY6BQ&4KBURFnWY$(SVb}JqCzTmAcKcbW2{V*6; z!~4Nt4DJL`=uSFL#uzN+ZSH+Rf4=KXI3c0eQo3~2%KBSUP!cKYk16!a%!~@6M0{mS zB|ksNwE}cl_qCgQ-OJgeswWLV5n>VXsYQRyGX`&X2#-pY>!i&KJZuGY9cR>E6E1~s zB+okdM&Nw_001u~&#j(Cxc^kf0WZ}hUB?<6Tj=%+8A-@2wp*KR4Q=MGII4@OdWA#V zH@0i{v+mZWv8>VPkWgxD!)2nS2*=QLp{j&JY4ia2-uN8-&kYHM(l@A~j>HS4&MV;Z tt<7%F^@pm3p(m}e6aWAK0001w literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_short/00002.png b/tests/functional/snapshots/nanox/test_sign_message_short/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..efb803419298d803369d1c2475b424019a7d5746 GIT binary patch literal 467 zcmV;^0WAKBP)&W`2{dt|Jl;()q%d$}3*#45xi&|A#vJUNR z?q%u<$P-G9RCTvy$@UUN+{-%cOO(_36V{?RXUGarW})7EkNd#0et ztP}(QxTVo=Jqvo)Q_zCueG6)^J}?C1qkQ+>t=$}N)bH%w!b9~}&TLDpfUYWnCj#pG zH zr%^&p^e1Bsu0$5PQYXla!BB)30000000000000000000O<{!OCS)MCIjGh1h002ov JPDHLkV1hAI*pUDL literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_message_short/00003.png b/tests/functional/snapshots/nanox/test_sign_message_short/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_burn/00000.png b/tests/functional/snapshots/nanox/test_sign_transaction_burn/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..bf069fd25715331d7ef24e9675b1e976d26ea928 GIT binary patch literal 362 zcmV-w0hRuVP)Y42EGe-emVbQt#pq64GoFG8nd>zRwRc4Vuyoq=jVx000000KmU^L19#p@e6204G(6mdm>;GxO)4{kIZSj{t=Ew9FNk|Dt;Y zRJm46{YvjDXyGz6iQg#10001h+hs2p%^CgTO(9K}I@GGQ85qf}{H|&Ag8X68?EF(#<@%NQdk}j`qj;0LS*FZjiS701n`*$3Nejz6_^ShRA0@mQFBo6i3GB@U`?5DGT z3aYjo+PFK;Al(tr@_$)}%V%g~0000)$^KNtm5K}#WUis65Gcf2zM$X6zWx$=WJq8F zhRWb}oV@)aFaav5JV)b(%nxG%f(e|04m->M00000004084Yv5^30{4fA^-pY07*qo IM6N<$f`rJMR{#J2 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_burn/00001.png b/tests/functional/snapshots/nanox/test_sign_transaction_burn/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..d9cd2071223991e2e4bd0736b666d7b53cdad946 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|{t3ba4!+nDh2#w9p|19*4k^ zJDk7cgT6g-cUKeEsP%OEI!}Mi1tZ6x*~?gfn*Qht3Ql|x$x`9wudsBA*NeN?66Sra zbM;S{+VN!0bc3nKF6qh6a{r=HELW^`SJ&$gpTT~YzlEK1^Je5dy?xgE#lxj@i~D-( zW+gI;wI>C-*G#G@I;5ldVxQn1jSBV`S7Ow^n|_VsJg>6ccVbgXke$hrO7XS%5_2Ec z@BR$5J<0aYx+|K`uCRaof5PwRGneOIG}&hc?sD5w)+T>(W$m^2+P$CWJv{rb`AksP zhxD#xfsece^ZFMT+kL5e&oH;a#t*e`j1(5Uw@v4G^wPU*o8}6ba4!+nDh2#piq+mk85Db z9nbIkm%KUJpQYxcVWj2xVV=Hb$K30e3`%DKH8mWLU1a@1OmJiS+N~?*)!fzH#cVxC zvph7DA?;1_!sN$hX=T0d4)7^0`uUB2?bdlk_9fDjSBEg)$+VmHUr}QZi|_iMuU0(a zzq@J+i>CRbsGX}Pc~8iF^GYlcX!QRnPff4XUW~EcT3KkXt+YA+t6T0v+pme+4sW(e zy=|^9cmL+z&;@Uz1?ByM=6=dluRgi9qmgHF)$}+12lUFss|=n7=iZ*1#b6bkxs~sB z(;UU}(rv0M_N*|y^6&Q6H^)9*c)Q$&H%};9#jI{`4D0F))09j0J;J6h<$DY}j%bN= kTFG=)FarIE1RCb=WG*n<$r@27y9y-i>FVdQ&MBb@08)sKe*gdg literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_burn/00003.png b/tests/functional/snapshots/nanox/test_sign_transaction_burn/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00000.png b/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..3c04302b9874054e8492b2846fcbb9ab4b028ac8 GIT binary patch literal 374 zcmV-+0g3*JP)Q21>C3!FXsD!NG38aOIA9K$~l~P(6CjsKJEC2ui0002^FMehR@Huy1 z+h#T~l5a?MKumq4*bRCeux3A|JKZSZF*|?{HHntXyDE2&=b!#t392&y)BHBf6^H+# zI|G_rE2jQU?=EQJHnfO)EW`i+0D#L?Uod(w`o)VvI$h~do6_dQNG=r*O`{eRr$t%? z+7_kL?P>e(nOV`{mFDP_#`blh7{GI49I5_4jzhmtle@=5E7t+<;F=^3)!Hf-=9=u6 z(?10@dk*cKwks$%1GeHNYj^kz?F;|_fLR2didYvf>0=P-l8rmjGo_2H&dRIWQmap+ z8hT^*>;R!jAW({kc59_(7B2%_15R+f(02TzI_`N25+ZgAI)Zyp000000001q7jd=p Uy9>MuRR91007*qoM6N<$f|lZ&4*&oF literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00001.png b/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..c3af4be088f91545b8aeeb6ce5b39903032b01d2 GIT binary patch literal 852 zcmV-a1FQUrP){#pD&$6EAfLAt;H!O>BUDvWTShoN*O7xX6-{Ys{<##P?OG%{Rqxjz2 zeQiQn43^*LdD6=4&q%|kv2y{~&a0N#4e#w@uv=@{zXkR1%%E;!=Mx~OFF2teFzn4M`L9SXxdjLwD4L~+ ztD=RmItOu7)~B8&u63;W*qc<`x2vx4$zj$AEr7gvGUbwqA+!#yMhk7%W%==UI&2kI zH7gscBULLjJ&0;h*6## z+sXj|05qVUbL4H_uEsRWv?tPtEsh#??2>0;XrijFVhm=;IBOk6M4sSS`Wg9QR_(^i zE`+k0abt9aPxq2VAF}lyzPU{QGOk}vFoaJ-5T?x|KJ1b`7JZu7G`1mgVH=4AyWDCX zodAxG9AIq9xrVm#5$V?`f2AB96uB0}e!{D%4BLWSC0XWPwOUgqti6v+q*G=pk?jEh e00000cn!bY9LNYc_Su`VojJ=b9cs_!{;p@~YhUm|>i(pu zf1C9xrJA@*kL-ICw?n2WCGlCg5E}!-4_|S8=c`|n)~^a*v~5C=(Y0BxdP5iPb($)E zI(@3Ub;N@(Y16W)g$uUnWWUws|DABh^ityPm78V$2(7z!-13vQ{lkmZZ&|l0d+M{i zn))!qL0aZf+AVFy=G!N}r37SEUv|E|Z_g!zopr02f59;Q#;t literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00003.png b/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00000.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..e5d8a3e9d27d0f45711d9e4b051ea22f8f990fac GIT binary patch literal 409 zcmV;K0cQS*P)Je^)7mPSWc|Mf2N`riN`VAQ0RR91006+Z`0)t~ZxIuhts$@G^6B%0mC?NC)ui7>8;8#Bu8%ViFO(YvBgq2(C%uR!WA|*GSMpOczuA z`#5>8f000000N?Ho6wMkcoL)R+00000NkvXXu0mjf D4HUFP literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00001.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..23677d364c3721455ab44a20582b814924e31224 GIT binary patch literal 767 zcmVPzR+pDzmW(Gk(vz82|tP z007V#Kg_S}Dih1R;W?)pwPC4BI?jZK94p~OGDer8;SmPNnX{wQ(jeoN(YESp=0nDG z(~4s?;yVYi=UB9K(qTv9&`Z_|oi{S&&q-DGA(Doyd#$<5D>QU{s=8ZQmaU8oU04s+4m7LH5(uM|YQ`nw;zy9~axHpR zKB_WlmXdixNh^+wztd*ow%?2k{bu=Kz2drJFEXU=d~#b_g(ra7P#=iQCsi-2zOeCY zZ549b%%~&jV_9+D>zve14Srn)9-h9mf&^xe5&hRtLXGIZ407;E@D%zaL6DJyQe=4l z9cocus^q(D_|?*xX&!8#nhWO@YO6lUb9>ERG08^b#?`w}6MI$;eY^Ry6sHjAxy)%{ z?pa}#8@8>i=AgBj=~a4OyHfAh5@4NIX}juTE0k6)%Y=2JmQHS%v&5*CB{ma~F`4X` z`Z}G)K&UNjJ7?l$ttYv3_MSzX2{-0>(92>cK@nR~um2e1ORsFjoe004k5Q%WhNtd8QJ4Mv@* zMjQPVe&UAS zb3{D>_FTAbHcU4wWQOR0U>+0({?~V4O*1=#^vRgMkRM+dtjK{oVOj#1<)AKZ2_UvYGmGq;L0%wz2JH zPoC2mggWg6%}HkVr>RUevp*SYuo78lCHCQ!m|g$?00000000000000003ggCz2BmJ TD$Wf$00000NkvXXu0mjfKiSuD literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00003.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..a5763d6efa5c6f327c85917ea7c889de4b55254c GIT binary patch literal 766 zcmVI@BeYI~9uR75x!5NM*dheFi;!muv>d=p@m68Zx zGhxvXjBaU~-n(jOY3secLhX1gg$-#z3L}6SYa_bj5~z*hXHWI16QSx1XswMga)Y`P z+REtawsv;Jqf6;|mhS+1*`RApU1*Wj=d{__e}ZQNl{VW{#7fl`M3ts4kzt`el+tLM zjYC+TLvM0D0{{R30QgQ8)zIb5FNj)+l=sn7L(ts9&xctS;#U`Z1!mu%OsfPN!cQjm z?$PnAa#?|3%E$tgB_XJ}I(^jwmcYnB35gh6GN+bXP`Iq&WMxuk11`R964GXMS*f4d z6Lo1=%f}kpYH10VKP@95GK$k>IjKR=X4#q_0d!NAe_8l{VmQ*Q%JZ{T$vu`aVf_U( zS#LpX45y~Hy(h3CoLx&UZQ7FkhqH~`MV&z}Qc{e|GK4C5e$F+-Q-g8`$h%z&*m2`% zI(3R(bf*=>=`~SS`jrcD;lEsM{uj5+-5ltft>5mQzB1OATfg0I0r=oaunRrO!pQJJ zDaqz_s!>iVA1_F3YsCrxewjh->pyhb_=SgL90#bsF8!3EQhYV|a;(O=^9p6cGBvmA zIc@b8rj=6B?ks6ylC74rK|Eg@Msfd6LJpusW=mI@?6EvhR;n!tsx&K=Wz8(Egj%V4 zYTu47djBaBkx~=do~b9_;$l9Q6@`mam=wMnS_G}JRG_+(MJIh<@gh+N%$Eb-q-sBX zAXSR{=IBe^dH)2{wxH!9Trm(m*c%CsE6O-$zS^MK*MVdzE|H&?_Z7~_&qOw)eV+9X w^5^xz#sUBU000000000000000005No2Tqnhw^wjZx&QzG07*qoM6N<$g4#`D$^ZZW literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00004.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..0345aec8bd180b1ab52119cf02f918a810bf3121 GIT binary patch literal 497 zcmVZ#dZ;%a&@P9L74LBIX{5fscJ@D8{UdOiE=<)PcoS-rIa zorhj>UjhIC{9BWEL!H-4eaL(@^?wl!nlBlx>Sh@cO!{mqi8$-MrdB-rIWLX+kn=n~ zvL_)P_AhN?47T6;;5U9%>{f*1$sk&=M|KSP1t(g)9etHKaXC|5>djzI^(_<2>pH;P zWbS6iSqw&|3ug;N#3oMn+`BrUn`pg5c_|ludGW7~?)!*a;m z=6?gaKwV6H9jWUCliF9O&#P-qdGhHr!Y1tk%_NikWsFpl{l(~motTAoVjbRz^a20? n0000000000000000AYRsY#^pDjXJ+j00000NkvXXu0mjfp{dxT literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00005.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..c279c7048c80abb5bc64f0316ee7a64ba9efbdab GIT binary patch literal 759 zcmVJwMnaxYL4b%2{PbQ|0&82~ zO#^Ovqher5YXfY32Ul}vglUn79x&;hCuh+hDUXG z@A&Tl8Me=uKI6o34t9WV?!Suug?j>c(mGH?_P|x>B%L6$54N%^yg^bWUSz>q^751Y zbK(e6?r)|@nX^0jjqZV{Rck0B!IvGbw&J^FC{$)%OHr1Fj`HekGM5I(_t!?P+Ey%r zCl*y<5vhD-We1b*1+|_?q`SN7;MX|^3Nfn+bg6Y2n0B+Cw$S$a5|%v=s4tPp@F6c< zwN%LxL`l5U*cZjX(V!d~l1G@F0r*(34-QAMldPEh`)CsTJxtDkiKMj4+B*lgvtQmT zAI*Ri{P;fT1Ef>002ovPDHLkV1kRAXT|^k literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00006.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..6f224982ac1d12e5bbb00680c10bf7593f656ad4 GIT binary patch literal 502 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|`(q>EaktG3V{fz#?Wv4u@QI z^N;`BKk5Cw(dq0MaXEI&$vxk%8g?~sXzQ{9H8CVu#;?2-oxOBQRQ4;q$yqWQsZ-jV zTZ7mBI44kb;q0_;%P&PqzYCquGd1wucBA)UpT+w_UQW9fwRY?A5cBg@2i=zTxM;d} z&f<@Fc_%e+(TQD*r{q#sl`NY3taa60C%yOe-xIdSM%Y9HDDIF`;-&8f7QdU^V7 zt|eIqe&6#3y13!|gJ*deANI(6lYK0>wdTi?57XF-nZBOdyjJD;ihYyS6YUQ!4&1BN zzWUL`9fe{w*Q3{}mGgw%{n2wG*R^C_%bBLW8BaNWvPQ4Zb3cAV(9#~oPKe%#noBYp7PuHId|9^Gk@~MTc+hh;a z6zA6cQ!m)K@A!P}SL!#HOi^Cm#hcFOp7hnG(b;l)&CfX;3q5x;Tt8V+FUcJK`0vpI qHfu%hw=GtCgzs>J!X6z=IL3c|{)Wq2!_+>4q&!{yT-G@yGywo--sBnp literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00007.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00007.png new file mode 100644 index 0000000000000000000000000000000000000000..a23b40b632e563936804fd9ee10c585adc65f423 GIT binary patch literal 804 zcmV+<1Ka$GP)%zE=pnblqUnIF2$oXQ$56QT(hEEeQ^%>c1RXQ?V=0^Y<28#w} z8nrNKcF8%bhGuPL$t9%f6}4@o;RvfDfElYJwBr(}fh>=zG*w>2l06_T*tIet)r_u2 zVaLwY-7wB%2V5%BaJHg2GWDD~@%4v#j>+_Oa2n2H$r400rY@0Tp%zMMw9c$e_*N%0 z00000fKTJg`Hr3ZSP4Ddv#Zd=>$~iQsT9%KdZrDXdtB4Kx~WN2T(yLr)90SA)h=2a zO2z!Kbo5e{Z?P~N%4P(M9$J&#q^#-VWXh^BHzg?5%b=4`>Wiem#xkQ4$+7q|&d-&` z8&<#dL#HDGs#-Y_-~@yj0o2Jf|1~j#I6f=cYXeI%+p(H7l)|g^lh{!l36*4=YrfY(;h3rqjRfox!AiAx+O4KvxxLQmg z+ofd_H7Du_SL<9;#5xEh+fSB;)lJwsyL+nNhYc!i9<|xs-K^hw@E`1JPe*2VceDQE zfe%jdZ&sm4QZX`ou#_J27D82MB!SVYil6`JtE`qEnS7y(*mc2+Bvq!P-m@b20967N zqE_C_&`r4SHfu!*EoUFETNpE3d52aG>LV*NSFvZRVX|Y$Uo+b96>8El*gRVT2;!^5@P>T+=4O6jL(|mno~29b_yH5_%z{z6nY1K9}iVwP6tU znngZ5hR!!)@qG6Pk@TunVPq$u{mQrBY$^=Swyi(VP>tdruKbKQ3q*fy@!dHwSzXQS z-j`V>*vyF9t9~B0{{R30O#=jJNo9ZOV&Y6K9r`U<88r3>@aY^Vc>wn izySaN00000d>+4|yQa;$xL?Wu0000U_w1dwyY3eGU@+4QR0h`!3^qg00000pCsp;bKV`rpK3gE zGSX(O?@8lc5ieThVfb zo&dQRxy~|)w%PS-cZ#z6b(~VN*|&39w>!RQ))sU$E~%xu^NxJ>H+c!4 zG2D13-R}65@e5FH&HnqXWbedL_hx#q!}?P=9S55A1l)+b-2LtAA+m`d;m7VB9!&rM zfdA}k>~O8m%ShQr+E>3JTHT#C<@nCmuT++#S6Oaqjj*45Iy!B-XZ$i*r0N+th)hxK zHSjZHQTQ&p1y0000qq5=8B$QzFws{ZUGz zZ4x(O>$U^{00000KEk*f>TLd+y*myb;{ECk6LNoz)O^xa1a)_-nlU9LiM3xI?xSZn z+UkLmoe!)wQ;HT%3Tlj7wc#Y}l-{TZonf%hW@oP8U@UdlJFKO=%1nxkx-cNDGpgfs z$EM(9u+Ou?hf1fqH!(@9i~P&FG?zgsf(B;Yv#McDMz*0Ta=@h7GN1pDhZ3p<#n*vZ zhTgZB>g5LzyP7sB$DU#wdwR9l%;}gmFMZYTc+ZxarV;oATw=?$Xyp*8LY<_QIq*ke z8DOH>@ zFKXj6wo$!Y-Lb_1n6Abg9AMyN%t0yAy(RC4GBt94sh(^Xm*CmG<3$QkQ-$8AW93k= z{kkACF<~rRk6t`1Ug;Ruj$IA zQ+-s;7)p~R%qg=I6uz3+>}qx+(Ig`}Hy-&;ob=r=Jny&R9=!y`NsMGy3ad{OA4oC- zwiE)>+;1vIB3jL}=deEm;!!VWj=f0w`Vf&O3*GY08M#kNUD6~eM>QJ^$gT3*?+vH_ zMd=9~D+_}Cpi~0@000000000000000006)gzu;t7l9{?t{Qv*}07*qoM6N<$fLGj<^((`$$MKiyy$APdt=T-P?As0(hUfaKzJbzvZ>^on>Kvg>gk6~9 zVjTNXT_xA-nA~kk#HxA%)R5F@$0XXz&TlVoF*ZLxyDMG7=fiDc!>dqOf@Gcxm(9+q zg=xchlg&x0Cm=4$@9YSB!!}kj0b^;7cezopLsp18Z$GLdDSQH6h<>d8wrE`Tb2hg- z(3@N`Joq$_O z%+#X)M^C`=k=yr0RXy_mJG@oj?KSy#V!M~D%E?7noYQVFO)}Zv#z{5V-;6nU5>@C) w7fEIgN|9aw000000000000000005xOHxQJHB?cehYXATM07*qoM6N<$f=09MF8}}l literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00011.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00011.png new file mode 100644 index 0000000000000000000000000000000000000000..7c26e109c6e0a6013649cd0a6d4ea0b0d247a8ee GIT binary patch literal 771 zcmV+e1N{7nP)4J@? zOUfQl{`xu5;2|izq|b6)m(EQ|LI@#bF_0Rnj*?bRPzSq9FZ6*y`KNmkG$?x!pXCP*yY^rm*dM_a z%k1a)SRLGr?Yk}pd?C*wx4>-Rp(};PsPe5I zw3WJgA8-+GwzdsY@q?pLe8O%Ff_Amj6^G#gv6fpx$7zaLyB1qIIFeBD({FI`mE z?X6e@eTTjl6w8eTm;%SL56cz6syV zLrM_q&ke8ykqK}BZswnAK_L599zqBqgb+gRM7k%ra)004mFKI*FOy|>n`>#A!a z?+&J!cvO(nm`gkISy5>d9UdR5_1?X z$7FHY{D({v(^4B>BX+)sZJ8Gb&c8D5DSsfCqsP&=cpq5q58f43T%BNNqIzWDPYl5H z=s4fu;9(H&MYbXD{@@fu)u}@Iz48IbC)%DqzSYm={h48~t*cd)k0+^i0NzTXx0(EJ zdH}Zf-21;M=i~A(sVb7$-|aoY24aI$ZSBg*qACt)4{(!A_K%sQn(QCO7(9tx=t+wt uGX|wdF8}}l000000000000000Q05zCla;)o2u0}t0000@C8d;e zCVv9$S1D6zN9o4BS-0=y5)bNxyO}>l{$up(@x|44>lA+WiFP4pSW3w`w|>{Q;h&t+ z=Mi7ovIDxAbi0Av-F9iJ3wI0M^#z`eaXTKaFd>a(;|}N+Yhriv5lUAV)bQ$k$KRXTp0V9$6wNAiFENEo4282_4uc>~KIC zFkBphF0S3#)pw^_W5t}q9x~giRDxwY`^I9`D+kNDVq6z4Z1gxQB$Pm2VDiBv@qG zU@L2ucXZzZ*Eqg-S6(4CnJC3r`OK4d!JRNp0wyGf-R;n%B|yjS%Web2nQ)iBlZ`>k zxm?fYO^jrB`N(__7bI#K(YEi@xSD>3&K^D-g&<}d@x4GI%18?pAeFJ7n9276)%c8s z7nZIVl}1<>eus#E_utd6P@=*(UmXK6@Mar)k^#t-b#1U97B`!0^n$3+Ro)6^0QaaQ z#{f#_*T0S0;YQEH*C53!dA8kw<3CceMZCjBI6Rr3(&Rdy6oOj9^WanX3EaktG3V_J@4O=h91eF^ znScD-|73TG;8mxDWVK`&->>(yX3em77V=^QYGSZB7ryG-wJ6P{*Jfp@zHoE@wb(|+ zYL3*=^0rIea@)G>uRgjE_BUB$>8AYBye}6%O!iN^c3Yb!tgXS0)a z2Jh4U2cK+ydrk{tu$=YRea;cHCn>+G4 z;nxl?{r+apW~M-^sow7=$2BCBpAM|n-?KDf3C}g&uj_X`oZ+9x_(*!okDv8zdI!FV zoVh1HJuHP^YvPHT?ddX?uX(0shx>`Gint_~Fe_zKeUIa+lm8M|9Gq;>Ixl5nO4bCf gm#iSKpaYM`;@vA-6O@g zoB_nrt%{35v!GX*?s|?MX~h#TT;$8yTg92w3)&?2pKblbW+{}A!VOnggSUb9FRRz~(a~jQ* zH&=#elMzl;X}R~+v>30;xbM;!wy+5+SX5a;ADpZ8LHHJ^=`l2Pbi zwW|^5!F1aU9?9+bVAfx0nifa5nkvpY8EdYx>+1Q4=+hZLGsk|RT|?DJM8Ey;irsRZ z2@yEM$L~TP%_PW}gQFCOH*>k?cpXg_gFmdELLr}O$lHxI2aX*?{MXiQd2-#6|Kusm zgf(ugh4=O6yLe=8!a56r3q@=`s7=26lA7R|M9!9@_4U|eFOEyS9+;}8O3?j7vapzU zFFOIrbf^u@C}uQOs!NX3)IhW0G^dQ32}1s%MQ5QHmwEATuckImh2VJ5hE}cczVTR2 z7l1kSFXwJ}e=+Fo*OiA$zv~R3m#zrG?qR-xDt=08h?!d4t{?wFwzK4w^!l5uhVr?q s6951J000000000000000002D9Hvrpt-=(510000007*qoM6N<$f;iS|lmGw# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00016.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00016.png new file mode 100644 index 0000000000000000000000000000000000000000..d93355b0efd352ebfc20e98756acdde7c7579f16 GIT binary patch literal 506 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|>Ax>EaktG3V{f$h;#8JPtEg znLqsJ{z&hygX^^1X+8!s!`|1rGE3we9-J%$)WmS0Fs^Wsx2EROImLIxrkkwPsGTxt z-MNKrHLe`Khte`@G?t2#uYb1hm7}$L<^5Q>0 zQdgI}+vpP5vWM}MMC$UAMRTv64&L1wb8lYsvegT})qP1y7T@KSr@o41X`iRfHi?lqWynWlP3jz8FP z)wS<+@ixgICo4=jdpBVFPK$r8y5;Nn@+Ld*?VS8p{OyBptF64VrskM`Rk7*cWp!)e zOa1P<8>cRu+AjL_PN?*HL2Lb_@=uQ(Zod{XeafFvxT|aEz_jZkijFt}jAoujO8RS-VvoAJJ;wMiv$2q*~x@xU7=y?2kp3Itb zBwY4qKsSso8=R@l=S7U)`=Rl~kJz?FLrkHEtPJQTE0EfL4RnG;kG6agQ;iEhOv)Zm zN)ZRVLM4>Zq>HP3AUT?z)GckZ18x)PXtgZ%Oot&8Sbw;yZ28V@8M%_O1W}8rOL$sn zi-RE(+l0I3<9xKKrS*7;)fl?AVKa5cz3G+YvJHnhd~aXD}aGHMcH2|#>uhLyY3E-`<3Qfoe}m~t7h)e3XP zI4#h`c=VJ=OXvfGCdp0JT8VFGp*h-(Vq>A#TY~5DXf&kF!}__H_HUyXW3cysJ9*o3 zTR$iGJwRI`XWK67cSdn+hj@miVqEs9I{hu)7dyS9xC>|7j4fS@Z2M_q{rijl3}Tuu z<#Pgmbp)3KjI}bb{&@T(>i2YNFXG3i`>hx|>f1^GAOmc&{z`H?&g%jI002L)*#kJ( z6%J!meqIEQp@)G34ud@aM0xMJPr(v&7&rg`00000fd9uYLyZgAxoOc%00000NkvXX Hu0mjf^;>Jp literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00018.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00018.png new file mode 100644 index 0000000000000000000000000000000000000000..31d8c9feb3adb901a0aa8b9f64423a5273634e67 GIT binary patch literal 506 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|>Ax>EaktG3V_J@4O=lJPw&x zXBYfeE}X6xFfp~ckw-1)>%FWghR5vZJeUI1!@#iav*_|&QziwSvOJ!QZwybdyv=5cUKRED`%vJeA#{a@ej_c>ok@=nG@|YE8mP|n@Xyrm#x>; zu&t*a#A%DTp5P2Pr(vHeu=d6ZzqevVmA~(5)lPrsl>MY|QB=UKp4Q$UD<|bhzMXdT z_4*YD#J*fxxa~)5or~zSv${&r&;1*6&c2=(eZQ|d+xy;qrT>B{{;I23Z8t=h)&H)V z@k(;5)Xxt$13_+Xcq}uot#9AAIqF%J-@OZW-4UEN>D=3J-)UF0Ec2u?E96T{x77R2 z|8aTa)c$ho*3!B)Z?49cevm5sr1Z@*Hb$a4H_-cEQ)u|{i&OK`XKZV|D6FcV|6upx zm*H9u+?aMPe!TMVxzh<7#c%eyanIH4xU@3o_nZ$bKFqaQFMjAO_Bt?Yq2E>J!!=35 z8|+-7r~glX!6L)oXtnM2@*7^aw!MqEEh?9r+Z!@_Ue`$%QRiFSJk35|)?ef_y||yp rvO;**h1ot$K73A!dq7^n0EvH?oTv$$`vULCn_YqH#sL7(u-8&W{OeHpL@gXsn5W9JfH5V{vLeuoP)j zt^uvJ-h1u%y$H=~^nFvuZF$EcSJMGcKy>hGV>Xg#Mw#IJlf||`lfW&UqH+qN@zE~f z!$Q2st++Y@7VRNk4GWDY%hej8HVPeukJlh#9HGOVV>$@UF$E8XF~s$LR>EKEZYD;WQeo zg6ziV_Mq<5kO}^yC+ksfN?ullk5}@60gWfqEiqb zq+%KRm8YjGc(qv849{&+(28Uu+`+~tV#X|NRP}D4l6-eNX)eNA#tz_)#g$}bc@ZT^ zqvV_yPCVv#gyN0HT~5EQZ>oTc+Q?}AV+c)+);|pT;7u?Ky@}Jv=!32B=C#yNaZ9SH zfb`T#Z^`Z;u^XTKsJEGn)<4Jd#GHApTv13=ww&u!Enp5W_ zT%+fiNgB651haBjee2xIaXLVI%W6U<6HSR1wUOsaf&9fJ?etCskM*jpuu%(I(aQ!S z6Rw9ww0n2X#q)Vs7*g@?72}TWsm{+K+?~545J|rqI;fRZ;^lcB#Z9ZrT-CB^SO0pt z=6+FCO+De`Ye3a*BE>6CW$Yboq0O!A@Oa`cO8Az>EaktG3V{fz)6P{I2`WI z-P`%yep2~O{^fkkU23kzZ})tks@A~45t!MXb-@tO>+MD@lLeb^@A&d5B)NNF%nfk!|LEH3Azi&TI z%v!!uUv0Oi-aIRit2Z=1$b6CU>&2bGSO1;_t+c-E``YJwU)7X2WwoWM&;69S&o8bs zyybq``d`4ApXc6jSc`wZQtQ7?=%@3Wxw~$dzuo1o`;$3tu7tbxuDOY~#N5i=US&<$ z`{=5&Xu-Sx4c`h)riWRyAM|2>!FRyD>zswl&5(V2&wpd_Va`qOoxW|m-u_8!uiLil ze=K@)cEi`qTf6>DUnndf*K|?*_)D#@qNQui|F7M!c}r=Ku9WEHPR+E<>=JAO w&RSG2QS?EjWTE;@mYFg+tsg)UhXHaP%lllJta|#<(@P*ZPgg&ebxsLQ0Gzbsv;Y7A literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00021.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00021.png new file mode 100644 index 0000000000000000000000000000000000000000..e51f03ab5830c97b853c516fe7b0b705f97f4db7 GIT binary patch literal 754 zcmVm@=WFUyL{t>&^8f$<0002+0n}P+t^Q9+{XCV- zl9#Fabyi&0FWaVmL_3N#ODRf)q!E2*2<143RBJ7zwDM*STE}0accE+Y;-zzP2k=cz ze~6|T3LnW9r4-T7Lt9?ruVz+gD?@1&=KKyAj1}05tRSvr#swJHgzAeN;E{)a+9Kt5| z+|~d90002MAL=i&uR~4olU|e8@qZnnBvXw5N{WRW=Wx8{m*O{sBGak8G803;r>^;2 zpc%wCyN*P{blQg~X@G`fR4qO?o&*LLFwUi6bJ~>51TJm3 z+4y^Syp-_J>kmotgBUxYN`YuYBt%to&f*=00000 k0000000000008{_02b3g$>BR6&Hw-a07*qoM6N<$f>$EaktG3V_J$D*SO91gk5 z%|HHg|D+fD#QboBQs$8@_4lGvc?4LFdT0XmFfhD#%wD_o+ZJ*CHO7}GuKVvf`BzNd z$1g?Ed~+_8Jiak?%~mU>%Hp41n^tG6y&Bb@Ifs9#d9JC_)+w^7UR|2A&vi)M*z`NOJm#94Ompx=| zsWz#6!&;vPowNUDs%>1I|GBD1L^blowYu8Bd_P*(Z~ArnabniC*5m>z66lS)chCyvF9aP+uM+4U;w{+HtCvpjqpw&&Z- zomVXJW9x~H^7}Xx*3IQ7zfh2jr>mdKI;Vst0CL>i$p8QV literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00023.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00023.png new file mode 100644 index 0000000000000000000000000000000000000000..e199c6b9e42fc12ac38477815aa014045621cc51 GIT binary patch literal 778 zcmV+l1NHogP)kf{mgQ7(A(Bu{5ex3V-Lz8JYto+ zqve&^lQ{#_Tr0u3EIXpss&@2LSC*^_P1IUPaztI3sSPI#8@m_dI$dyraq)J6zfTj7N(xv(&WmX6kc6F#ZQ&b}nN6Ik6LwaDtP)zg7hac_$wQS5pEC z&7@vM-W-7+djO{T>Ux4}C0;dU&#JPAM+=c3MH6c@Q%Bm1q|;2CgM&5=^j&Z@O|?o}|CujT|*}5({t0F`QB9?E;-{o&j>jKVATt zb6N^Fni|?m&5~^ zj=`zO?v4F6bVCa)>$BrZbX5|qx|u>A_i}F7iXoLIH>=(T>)6iE@DVVq<|tXSZ3Of;vkLfLJcF|QtR(d8efyqU`#TuT~w zG7-OB)m;_(BQb5%R!hQiv}r60L-Ooc>kcP^_VbH`sjvgqecXZhzYX0}1@Y;hxId! z(82dvC<40mj87psq48dH?_b07*qo IM6N<$f^L>$r~m)} literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00024.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00024.png new file mode 100644 index 0000000000000000000000000000000000000000..2cee104f73f19cd2f377ce9721118371c54ec2ba GIT binary patch literal 510 zcmVoX0Q;M8E_)(|f+G48g^9)+S@z_pk12n4Xvf8-hs)e7c0APdq;o$Eoh^m?dq?$hub){ z`po`O55&9%006*AkFue+iN;atvHsfqTo_e1%IFl(=!&a_(!73Z4r?kx{bM|Yq4+edzMMpPHcYWJ2O zm?i!L&`lTL-i)ys*lUrF?~+|GvLm7aZTSt(1902XIm&X>iVJFl3$8@@y-am{n zcoVD8o7jinME3#!000000000000000003cr0V>kle){0A3IG5A07*qoM6N<$f|wuh Ab^rhX literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00025.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00025.png new file mode 100644 index 0000000000000000000000000000000000000000..84261e22c9e71e10af139a875e076974f22eb9cf GIT binary patch literal 731 zcmV<10wn#3P)&(Js(p&2FXGoVPv-k000000KnsXm1`VhwAOm> z$tI`&4U^{YiEqg>*8ZweG+D!=<9sj7lKvOj)P(naRVDl`*Qk;l&lsck?l0KP75~1W zg-@=Y$_QX~vuH@hvUG&HVAnPDWdj{xSZgILaMpdQI*=cRx7^nrcI zqIeHzWPMf92`zH^rR*`)-q_*FCSch_!oFO_`gRz)%g(TvR*Q?0sIXh7J?*f@yMlH>W1Bei(Z1I?d+<4U1(+)wIRE?^^6GqPj$ zzfYWk*e;qut;=s|_#7U3BX$Xvlzt+70=AOrL2%@ei8$kK*+&|gX|mLY8Yb4x9BeH= zC2tJk{;L_x|MG9OT87o*&}h(i2QeqlP47v|$t0t;X7ZBySJlIs!W5J-$^X~aV&;A_y=rLH`l8F^VB@kVT>b~|+Ron0m=hrPL-k9| z(59<97&V5i+1~qO`{&TAwg=y>0ssI20000000000000000001>kU#LoBwQ9uam4@t N002ovPDHLkV1lHeVY~nU literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00026.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00026.png new file mode 100644 index 0000000000000000000000000000000000000000..fb49d2231b4f1787dacab86aae004fdc0a6f6b90 GIT binary patch literal 522 zcmV+l0`>igP)_?LtJqz7N(_wNA?3hAO3u-lfv>i~T8?(f6x5WgJai4(Bk0*1D`WzkL-`Zcz69NECnrE2&HjZZ*`;^?V)WlAukLB)UFUbe zg@(#A!Cnv3dRp<7`$OFUe`%)z004ZDE78zy;LuM|#k*e#qvB2;8~O25-pQO^p(j;J z#-m0xoTNSryAAbI{K%K{hq?V0-Fn!nXQhSRQoA1(+aF@@%y3*t>rQpapXy6gIJ&#X zryG2fqKc~+b+piRb8G^-QQ~RSoy)*Ki){TtK?NsFqM9W0uRAjV(}A`D#jS>3o5+LI ze}3%rU)~}ICSW~Ywx0k0T3kWu-j`8EnX+D1Ww0r>lHGc2e*dN2n!62K-*%InLHifd zaF7}O+jNGS(Z3mU@FY&5CvguyiQxqR000000000000000006@L0=(qv6@%r$vj6}9 M07*qoM6N<$f-VU4TmS$7 literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00027.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00027.png new file mode 100644 index 0000000000000000000000000000000000000000..8bc79a8c5395a1e77033767290edb4ee16a90a33 GIT binary patch literal 768 zcmV+b1ONPqP){5>yM$^gsGNo!BD)&%q58SkETRU3$;;N zqcVw2ILLF}*#H0l006#+fA($p7HHQGdM|?VHMF(MYt_FE&9(5rz+9k&!YqnvU!kiK~qE=Xi}NJ6GCT>V!75 zoCHYa-s-{b4n1l-PeYa|u9oo#>e@I9D*@E2U7R^D*rblvXM!toWI(wzb>??nh;960 zTyAlo(>5Y6cj|92C_rpNyxKhvA4;WCUD6&93T^ z_P@o%HXceq{HRS;*6rt4EX(2I8ef{-9iOMqMXi26$M|SjDPIkhYtBRJi|@t084%wm z?M+y=s6QDR1A7-Nj_ZY_SuD&wj2 zcO2w%uDDCTZ9XuJlC3us3nBD%9N}w)P(h3_gm6yaDjc~9i<-2TkRwE;&4f&+hJ78! znfV0>)y1q*BkE??)9Mgu_p2O25Mp&rc63d5$37;9prbH>64^LATO*eai|kuvz5^b$ z2&bG{b*xg|9X(8QKpL9u)htE7ckAB7@Int{4{CHAXYv=&p=BEV_442e*~h?V_sowK z0002s?fI}DmvSuG-C=3hDC$M#C*278a{yVH+4F}O#b_hsALhi3A#}6Oqk}jB9_DGV zv=i59UVFF^nV!T(Q;nxkm17?@tb@ z4uM+!SupbIRoWb2WR?9mGtbi*)LbZBz07bjdLg4Tg{ggYeMyLZRp-j=ZgbLSTo0oT zD8&s=JlQGpu}BBl6U(jvO^i$Elj(`h*W9&0Pq=RyqM{|NqiAHTzm1HkvHoW8!JQC= z?xbR5e6SR4-byxfC#8*DQ~vUJZ6fud!S4Rw@uU)4GpVJ5Eow76{tfM8@FiVw;#w{7|7S6&yAV5vajd?oKS1+@ogVUDJ{zFtC_gCOnZR&nETd$2@)?s z+k1TbtgIh&Dbo_vnIX;<_b%lUBomvwn=k+X!2fjfG1NRSnpyrKQnyfRb?TZGheZE` zDhtcLde;dKxWh$_pXHP>Tb8+g$!qPO8t{#`ObLDo56|Nq?UA3*b>v-;UN_7XXF=0- z{oA2~OWaIh6L4ffzgD;B?rjgceOc0(h9~a(mc9*@xBT1l52@T~dtZ7+@3r&<=%YyB zU?%zH{_Y%Cbk>lf%j^wI*FDmjS;oxL?dZg7J~WczKfLUAgG}_NF+xrBCu0sGu?j_E uAC5$L0RR9100000000000001h$NT_)aXhDS9(efx0000Q1u%C1o#tK#D?soP-JR0rxy1#!%xlmd0gS0001h)BRnYK+1c+9ysS} zXP)G9bpmhqy*hy^@4a&_eEpL@h2wQw#KG}Z`rGJ!J0Mg!ls=q~7o&K|vRym{H(P+X z+?}P&!=%oLNiRTAXyyG~DDM7J)dv6ozyQA$P8K7Z zx0;{dxG8Cz{Vd7niIlS6^n~}_aONnYIDp> z)E=#nk6Maz2|nHH)FSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00000.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..ae7bbe82e009fbf63c2a0db72f0a29abaa24bc55 GIT binary patch literal 379 zcmV->0fhdEP)Y42I!pyvgo=q~66JCZyRaI1twl-{*%xf~ItAY=u$)000000Prtvvjf=A%$Dt1 z>%>TokZb^-dQY(#^crBvzE5|!Q^I|A06R5_mdm>;GxOum`d106Jpj|ZyUZ0Y|DxLi znp`WU{zY#VRG5Y)agBu-0001Ry6g)^b4Gu7Qb=EyI@G4LIWdw``BT%V1^I3fR)PAW zbhtm<{=Hgj(#tE%(N{M5&xw2hkBM=F)}J^I{X=1(nM1H6K3k~mar%UqaivY*cS z5Y!wwba1$xLAoB$^S7+c%V+3d0000W(9hYk&El``^EH%c+XyVgLd|N+SJ|3k2FtNS zHtP+a@60Lt^MIwaFj~e^c~@6;2->7F@?`G;m#6V^Za@C?_t@~ZTy(ku00000004k< ZJpq+01iQ(jZk_-D002ovPDHLkV1le-t3dz& literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00001.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00001.png new file mode 100644 index 0000000000000000000000000000000000000000..abfab404bbec2215be1a6876ba3a7ba97fe2c070 GIT binary patch literal 381 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|@9dba4!+nDh2lG~Xcw0f&oO zcRauESNZmcom0_xPnIBC)%o_7H=HB|TB>A#nht!MQ+&>{_KxcF7)Pa}u0_-NKhF!w z>h?anIC-wkTO0rXuR4vFZ#kG=GtqP5Cnddq4(z9wPuaXmEh^!W^n%4QkF^U$d1@W^$J~~Q*Q)x z-QTp~l|zp2bpE2ww6piQt9F={Ih)^G5xJPr<;CRaobE}^6V4U}+dIdHEahU$o>6@( z??ae$r*-{t`J4~E+w^~mTq|i8s(*a5Oy|~uu+=BpW|>JO?5(U&ZxIJtg$#bo*8lU3 UZykTsZEcXSr>mdKI;Vst0DXa-MgRZ+ literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00002.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..b3f6946dbbfff01a313f38a692d477b1b20d0367 GIT binary patch literal 420 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|`Jlba4!+nDh2#Zr))9o`#2O zZuu7dSN^H@x3O&kFJJc04U@kAG~9ZoH9>vJ!sCoUeRp~~Iy!1?m)zczuD+?%W|b?~ z+Wzw&X4yI{|MzLhhR-&qxBI2M&YiZ)>i>!pH%))cy;bc!Z|baqnRkkwS>6r(SAVr* zdT)2`4yK%G#cWqCBWzW3!^>V4RDI(=Q+GmMnotldw z?)tZLCH_79t=`{wUXTB4Eu)((Cj-OAt!AQg)^gZa{C)S#_r}_^`s0V{1ON4^ohtj1 zY`c`<=(onnx={XJ=NC{IBZJF(7{v?nj>yh*2gL(} Mr>mdKI;Vst02>m%=>Px# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00003.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00003.png new file mode 100644 index 0000000000000000000000000000000000000000..90e4d1036258213cf3407d1f5e57d140f2ce5ae0 GIT binary patch literal 470 zcmV;{0V)28P)QdBpLO zo^w~JXWe3luA7-JcxVPkPzj&UiSe|}Uy>*>q+dM#qk=097}>`c|x zzx;!1am5PgfpDOgR_tXn(zzm^QZ zk~;waz~oFBx=-~5IMMZ`*#4vpm1fJ5)ZVzeDT+?9{pZGeE24b2>bwn!_NlSnxEF6~ z_Q{)ixS{TJ9RRW9bphjvz5dRnXwX_Htsmd*4PI#ZjzM^Ds0#kP zW{`=#n@XsOzB9()B(l&+gCH{oTM=FW000000000000000003Z{Z_k)Yzfd$tv;Y7A M07*qoM6N<$g1YA4HUIzs literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00004.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00004.png new file mode 100644 index 0000000000000000000000000000000000000000..a21acddfd274b5016d446164fe031bd1752d81a9 GIT binary patch literal 435 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|_8Bba4!+nDh2VVBTQ`o`%Ho zSH4C6l?$iaE^yOhYxkN_areKikE~}*+JVFlpe}~nwvU{q2e~}4=zI2g(gv$f8f*4l zu}QVAytm+eVbl6g!cw(Cny&x<{+s)0p2B~>-&1OrY?If&oBr6wd2#to%{8}kx&ByM z7(35ZHM;uPV|RE%@bp=nH|F-6g;Yw`o_4R@99v|y!Q}zNoW1X_-8_}~^4iioH?_-G zbmOZg=(XD%;#JMKl=07O^^?WZ-JPPnC!Brh;~m4ksNBMsY5T&du`ln+K74Ujr`cq# z^pVqlmwxe@c3Hddv`E_7{M^OOf8xE_5!@bG?4eeA8v`6ga7>+>Gg zU$77MER)+Aue(Wiy$kb#^WRfr_pWO{!xjBCflg-#^Ut&<6z` b5)gPMUQ?7fDe>ts9+0S~tDnm{r-UW|4dcNl literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00005.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00005.png new file mode 100644 index 0000000000000000000000000000000000000000..df76ba3cb2251b22bc9b624794fc2ce9c58ad6c4 GIT binary patch literal 408 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|@{*ba4!+nDh2#E?=_(PebCi zH){9(d)!I2Khd!`V5ZaB&$V@u?mx5=4m$z$Fr2aNx!rBpCNM2kb6)$EJ?qRgwa)8? zoqi&vW7~WCwRm!j|K+rYfA-Xfy#Ku3Yvw;O_e#m_*C)Bh`E=bee4X@rR>9Gud;#Z{ zCe774T_!tePxTawlSXTOji;6}d{S6_yl~N;mp0Q==A_t6Nj^1cy7G$2f8C3=eePGV zTyC4+X7Z%5RBBd;|JyGM_PjZ%zxwEuXNStAw6fi%&o8>Ra_XJy6Bu}2asoYe&eQq( z#P4%m*(5!bmj8Nr>5*1UysJ#)b@ugsf=vWr`XvhVZ7X5HRsV*PB}@!u74eoOP` z?cUx0S@5nBTi)HLBA+soCv_eS@zDo`5fU&sE8WO1#dJ4s3OMvUUHx3vIVCg!06C|( AMF0Q* literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00006.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00006.png new file mode 100644 index 0000000000000000000000000000000000000000..41036987218951429360fe85cddb772919995f2f GIT binary patch literal 431 zcmV;g0Z{&lP)QU z!nTpMu=Q5`h#W&5*szZge3x(6=! z;0QjHSQFry{SrLd|5mXkz)5><5$*K~Gy(1Te%e>B%OP{X)E9w{qr0QAnE7%Sq&`k} zmf9_?#khOY}6ba4!+nDh2#piq+mk85Db z9nbIkm%KUJpQYxcVWj2xVV=Hb$K30e3`%DKH8mWLU1a@1OmJiS+N~?*)!fzH#cVxC zvph7DA?;1_!sN$hX=T0d4)7^0`uUB2?bdlk_9fDjSBEg)$+VmHUr}QZi|_iMuU0(a zzq@J+i>CRbsGX}Pc~8iF^GYlcX!QRnPff4XUW~EcT3KkXt+YA+t6T0v+pme+4sW(e zy=|^9cmL+z&;@Uz1?ByM=6=dluRgi9qmgHF)$}+12lUFss|=n7=iZ*1#b6bkxs~sB z(;UU}(rv0M_N*|y^6&Q6H^)9*c)Q$&H%};9#jI{`4D0F))09j0J;J6h<$DY}j%bN= kTFG=)FarIE1RCb=WG*n<$r@27y9y-i>FVdQ&MBb@08)sKe*gdg literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00008.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00008.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00000.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00000.png new file mode 100644 index 0000000000000000000000000000000000000000..fdad622d21afa99ddaa01c4bb33fac7577b771b3 GIT binary patch literal 431 zcmV;g0Z{&lP)41i&GGdJP>N8&E~!^AYD!vG`DuJ7~1Fh&sze$eqa00000008h5Kf4<+F6Vre zQ%W0K@{N!kAVV)j?1p$9a7AB++gusK@9qW+Qh^Q^_o#Bt^8Qo*8A8-60NcD9<`IYg z5%&sEv5pw}Q@ppJgV#_e{>MZN0001(&ijNh3%xr|YSQgoH&vxJH@0Ldd1^6oLGrRN zvp{81+FWmz*Gnlm9bRUPZYh+@jbsB}8{1*3|Kr$IgHJhUd1~%D;B1@O6&C-cj zIWsE1?RodLkD6W$&$i5Z&gGXid)GJ&TM`VF+^2cC_R8xijTttlB8JcNtNY5#v>)wDjZLmPf9}6ba4!+nDh2#piq+mk85Db z9nbIkm%KUJpQYxcVWj2xVV=Hb$K30e3`%DKH8mWLU1a@1OmJiS+N~?*)!fzH#cVxC zvph7DA?;1_!sN$hX=T0d4)7^0`uUB2?bdlk_9fDjSBEg)$+VmHUr}QZi|_iMuU0(a zzq@J+i>CRbsGX}Pc~8iF^GYlcX!QRnPff4XUW~EcT3KkXt+YA+t6T0v+pme+4sW(e zy=|^9cmL+z&;@Uz1?ByM=6=dluRgi9qmgHF)$}+12lUFss|=n7=iZ*1#b6bkxs~sB z(;UU}(rv0M_N*|y^6&Q6H^)9*c)Q$&H%};9#jI{`4D0F))09j0J;J6h<$DY}j%bN= kTFG=)FarIE1RCb=WG*n<$r@27y9y-i>FVdQ&MBb@08)sKe*gdg literal 0 HcmV?d00001 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00002.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00002.png new file mode 100644 index 0000000000000000000000000000000000000000..53ae65195fbea5b281a1bc1a80351dbf1cd79ff8 GIT binary patch literal 364 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h6`U|=-%ba4!+nDh2#AYZeBfa}G~ z%X2sUSKTFSd4J{-YHcY(QO5;J{<~e9q=7F?O4)!WO}6UUdH! zS+Hz=(4})vCM2-VD4nt3W%LdvkyzeG%km#`1t_mu*zR}#jNB{EKZnW}g5-=Bym-_% z`=7%C>zxJL|9msNSMXnbQRayy^)nr>EU7olTHqoc^vG(B%bo(Id*|kR{84!`z2x6n zZ`;PkbrPvd6U}A>Y0chs_tyHmLi6kw6c{>JvYiQ=+MTFTx8d*9^V|R0+_75oZt9or zLetinU!`YMvFyLCb8XxElhO0{v2rTkNR$jMW7~4}*8a52+MC^J%KMbxPN-JRb2RNP zEsp0ebAPS3=e2G53#Z$XZAI6Yd=Y{Hn%&a~x zr36OuZ{N`Ye7bxIFtfJfpE`>tIBefs3CMa4*lXopSfRk>v5zDj;t;}qlYJ4#+SL-i%uK_Enp#bnq=`Lcq95k)WsK zYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-QAocA^DH{zg*pK|=(>|?_edL2v3N}W- zvX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7R3Ga2F5d5im7~7_-@MYrIDZLk$LMBX z5gfq)007YS(&Zy-(_qR8P}zw28y&iRR(E{wY5PWB$ZJ1St?(7>uzq=^4(bo;j0u$y z(3+Xm$3DA6eh jH^hIq0RR910EqVk15WqZ`7wFp00000NkvXXu0mjf6KcW# literal 0 HcmV?d00001 diff --git a/tests/functional/test_address_cmd.py b/tests/functional/test_address_cmd.py index a73ee685..3f8647f7 100644 --- a/tests/functional/test_address_cmd.py +++ b/tests/functional/test_address_cmd.py @@ -1,50 +1,125 @@ import pytest -from client.exception import * -from speculos.client import ApduException -from client.cmd_builder import InsType +from ragger.error import ExceptionRAPDU +from ragger.navigator import NavInsID, NavIns +from utils import ROOT_SCREENSHOT_PATH +from application_client.solar_command_sender import ( + CLA, + InsType, + SolarCommandSender, + Errors, +) +from application_client.solar_response_unpacker import unpack_get_address_response +from constants import ( + NETWORK_MAINNET, + NETWORK_TESTNET, + NETWORKS, + PATH_MAINNET, + PATH_TESTNET, +) -def test_get_address(cmd): - # No Display, Solar Mainnet - address = cmd.get_address(bip32_path="44'/3333'/0'/0/0", display=0, network=0x3F) +# In this test we check that the GET_ADDRESS works in non-confirmation mode +def test_get_address_no_confirm(backend): + client = SolarCommandSender(backend) - assert len(address) == 34 + for network in NETWORKS: + response = client.get_address( + path=PATH_TESTNET if network is NETWORK_TESTNET else PATH_MAINNET, + network=network, + ).data + + address_len, address = unpack_get_address_response(response) + + assert address_len == 34 + assert address[0] == (ord("D") if network is NETWORK_TESTNET else ord("S")) + + +# In this test we check that the GET_ADDRESS throws on unsupported networks +def test_get_address_unsupported_network(backend): + client = SolarCommandSender(backend) + no_confirm = 0x00 + unsupported_network = 0x3E + + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, ins=InsType.GET_ADDRESS, p1=no_confirm, p2=unsupported_network + ) + assert e.value.status == Errors.SW_WRONG_P1P2 + + +# In this test we check that the GET_ADDRESS works in confirmation mode +def test_get_address_confirm_accepted(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + with client.get_address_with_confirmation( + path=PATH_MAINNET, network=NETWORK_MAINNET + ): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: + # instructions = [ + # NavInsID.USE_CASE_REVIEW_TAP, + # NavIns(NavInsID.TOUCH, (200, 335)), + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_EXIT_QR, + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_TAP, + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS + # ] + # navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + # test_name, + # instructions) + response = client.get_async_response().data + address_len, address = unpack_get_address_response(response) + + assert address_len == 34 assert address[0] == ord("S") - # No Display, Solar Testnet - address2 = cmd.get_address(bip32_path="44'/1'/0'/0/0", display=0, network=0x1E) - - assert len(address2) == 34 - assert address2[0] == ord("D") - - # Display, Solar Mainnet - address3 = cmd.get_address( - bip32_path="44'/3333'/0'/0/0", - display=1, - network=0x3F, - n_screens=4, - ) - - assert len(address3) == 34 - assert address3[0] == ord("S") - - # Display, Solar Testnet - address4 = cmd.get_address( - bip32_path="44'/1'/0'/0/0", - display=1, - network=0x1E, - n_screens=4, - ) - - assert len(address4) == 34 - assert address4[0] == ord("D") - - -@pytest.mark.xfail(raises=WrongP1P2Error, strict=True) -def test_wrong_network(cmd): - try: - cmd.get_address(bip32_path="44'/3333'/0'/0/0", display=0, network=0x3E) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_GET_ADDRESS) + +# In this test we check that the GET_ADDRESS in confirmation mode replies an error if the user refuses +def test_get_address_confirm_refused(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + # if firmware.device.startswith("nano"): + with pytest.raises(ExceptionRAPDU) as e: + with client.get_address_with_confirmation( + path=PATH_MAINNET, network=NETWORK_MAINNET + ): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Reject", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # Assert that we have received a refusal + assert e.value.status == Errors.SW_DENY + assert len(e.value.data) == 0 + # else: # stax + # instructions_set = [ + # [ + # NavInsID.USE_CASE_REVIEW_REJECT, + # NavInsID.USE_CASE_STATUS_DISMISS + # ], + # [ + # NavInsID.USE_CASE_REVIEW_TAP, + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CANCEL, + # NavInsID.USE_CASE_STATUS_DISMISS + # ] + # ] + # for i, instructions in enumerate(instructions_set): + # with pytest.raises(ExceptionRAPDU) as e: + # with client.get_public_key_with_confirmation(path=path): + # navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + # test_name + f"/part{i}", + # instructions) + # # Assert that we have received a refusal + # assert e.value.status == Errors.SW_DENY + # assert len(e.value.data) == 0 diff --git a/tests/functional/test_appname_cmd.py b/tests/functional/test_appname_cmd.py index 871df1c2..929fff28 100644 --- a/tests/functional/test_appname_cmd.py +++ b/tests/functional/test_appname_cmd.py @@ -1,2 +1,12 @@ -def test_app_name(cmd): - assert cmd.get_app_name() == "Solar" +from application_client.solar_command_sender import SolarCommandSender +from application_client.solar_response_unpacker import unpack_get_app_name_response + + +# In this test we check that the GET_APP_NAME replies the application name +def test_app_name(backend): + # Use the app interface instead of raw interface + client = SolarCommandSender(backend) + # Send the GET_APP_NAME instruction to the app + response = client.get_app_name() + # Assert that we have received the correct appname + assert unpack_get_app_name_response(response.data) == "Solar" diff --git a/tests/functional/test_error_cmd.py b/tests/functional/test_error_cmd.py index 194c9945..1e25a52e 100644 --- a/tests/functional/test_error_cmd.py +++ b/tests/functional/test_error_cmd.py @@ -1,140 +1,67 @@ import pytest -from client.exception import * -from speculos.client import ApduException +from ragger.error import ExceptionRAPDU +from application_client.solar_command_sender import CLA, InsType, P1, P2, Errors -@pytest.mark.xfail(raises=ClaNotSupportedError, strict=True) -def test_bad_cla(cmd): - try: - cmd.transport.apdu_exchange( - cla=0xA0, ins=0xB2, p1=0x00, p2=0x00, cdata=b"" # 0xa0 instead of 0xe0 - ) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=0xB2) +# Ensure the app returns an error when a bad CLA is used +def test_bad_cla(backend): + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange(cla=CLA + 1, ins=InsType.GET_VERSION) + assert e.value.status == Errors.SW_CLA_NOT_SUPPORTED -@pytest.mark.xfail(raises=InsNotSupportedError, strict=True) -def test_bad_ins(cmd): - try: - cmd.transport.apdu_exchange( - cla=0xE0, ins=0xFF, p1=0x00, p2=0x00, cdata=b"" # bad INS - ) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=0xFF) +# Ensure the app returns an error when a bad INS is used +def test_bad_ins(backend): + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange(cla=CLA, ins=0xFF) + assert e.value.status == Errors.SW_INS_NOT_SUPPORTED -@pytest.mark.xfail(raises=WrongP1P2Error, strict=True) -def test_wrong_p1p2(cmd): - try: - cmd.transport.apdu_exchange( - cla=0xE0, ins=0xA1, p1=0x01, p2=0x00, cdata=b"" # 0x01 instead of 0x00 +# Ensure the app returns an error when a bad P1 or P2 is used +def test_wrong_p1p2(backend): + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, ins=InsType.GET_VERSION, p1=P1.P1_START + 1, p2=P2.P2_LAST ) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=0xA1) - - -@pytest.mark.xfail(raises=WrongDataLengthError, strict=True) -def test_wrong_data_length(cmd): - try: - # APDUs must be at least 5 bytes: CLA, INS, P1, P2, Lc. - cmd.transport.apdu_exchange_raw("E000") - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=None) - - -@pytest.mark.xfail(raises=OutOfOrderReqError, strict=True) -def test_wrong_order(cmd): - try: - cmd.transport.apdu_exchange( - cla=0xE0, - ins=0xC1, - p1=0x00, - p2=0x80, - cdata=bytes.fromhex("058000002c80000d05800000000000000000000000"), + assert e.value.status == Errors.SW_WRONG_P1P2 + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, ins=InsType.GET_VERSION, p1=P1.P1_START, p2=P2.P2_MORE ) - - cmd.transport.apdu_exchange( - cla=0xE0, ins=0xC1, p1=0x01, p2=0x80, cdata=b"a" * 255 + assert e.value.status == Errors.SW_WRONG_P1P2 + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, ins=InsType.GET_APP_NAME, p1=P1.P1_START + 1, p2=P2.P2_LAST ) - - cmd.transport.apdu_exchange( - cla=0xE0, ins=0xC1, p1=0x03, p2=0x00, cdata=b"a" # wrong p1 - ) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=0xC1) - - -@pytest.mark.xfail(raises=WrongTxLengthError, strict=True) -def test_not_full_req(cmd): - try: - cmd.transport.apdu_exchange( - cla=0xE0, - ins=0xC1, - p1=0x00, - p2=0x80, - cdata=bytes.fromhex("058000002c80000d05800000000000000000000000"), - ) - - cmd.transport.apdu_exchange( - cla=0xE0, ins=0xC1, p1=0x01, p2=0x80, cdata=b"a" * 255 - ) - - cmd.transport.apdu_exchange( - cla=0xE0, - ins=0xC1, - p1=0x02, - p2=0x80, - cdata=b"a" * 254, # more but chunk not full - ) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=0xC1) - - -@pytest.mark.xfail(raises=BadStateError, strict=True) -def test_instruction_swap(cmd): - try: - cmd.transport.apdu_exchange( - cla=0xE0, - ins=0xC1, - p1=0x00, - p2=0x80, - cdata=bytes.fromhex("058000002c80000d05800000000000000000000000"), - ) - - cmd.transport.apdu_exchange( - cla=0xE0, ins=0xC1, p1=0x01, p2=0x80, cdata=b"a" * 255 - ) - - cmd.transport.apdu_exchange( - cla=0xE0, ins=0xC2, p1=0x02, p2=0x80, cdata=b"b" * 255 - ) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=0xC2) - - -@pytest.mark.xfail(raises=BadStateError, strict=True) -def test_state_cleared(cmd): - try: - cmd.transport.apdu_exchange( - cla=0xE0, - ins=0xC1, - p1=0x00, - p2=0x80, - cdata=bytes.fromhex("058000002c80000d05800000000000000000000000"), - ) - - cmd.transport.apdu_exchange_with_buttons( - cla=0xE0, - ins=0xC1, - p1=0x01, - p2=0x00, - cdata=bytes.fromhex("fd00" + "63" * 253), - n_screens=13, - ) - - cmd.transport.apdu_exchange( - cla=0xE0, ins=0xC1, p1=0x02, p2=0x00, cdata=b"b" * 255 + assert e.value.status == Errors.SW_WRONG_P1P2 + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, ins=InsType.GET_APP_NAME, p1=P1.P1_START, p2=P2.P2_MORE ) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=0xC1) + assert e.value.status == Errors.SW_WRONG_P1P2 + + +# Ensure the app returns an error when a bad data length is used +def test_wrong_data_length(backend): + # APDUs must be at least 5 bytes: CLA, INS, P1, P2, Lc. + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange_raw(b"E0030000") + assert e.value.status == Errors.SW_WRONG_DATA_LENGTH + # APDUs advertises a too long length + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange_raw(b"E003000005") + assert e.value.status == Errors.SW_WRONG_DATA_LENGTH + + +# Ensure there is no state confusion when trying wrong APDU sequences +def test_invalid_state(backend): + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START + 1, # Try to continue a flow instead of start a new one + p2=P2.P2_MORE, + data=b"abcde", + ) # data is not parsed in this case + assert e.value.status == Errors.SW_BAD_STATE diff --git a/tests/functional/test_message_sign_cmd.py b/tests/functional/test_message_sign_cmd.py deleted file mode 100644 index f9fec92d..00000000 --- a/tests/functional/test_message_sign_cmd.py +++ /dev/null @@ -1,136 +0,0 @@ -from btclib.ecc import ssa -import pytest -from client.exception import * -from speculos.client import ApduException -from client.cmd_builder import InsType - - -message1="We are the music makers,\n the dreamers of dreams...\n" - -message2="[T]he phrase \"debugging a computer\" was coined in 1947 when Harvard researchers found a moth crushed between the jaws of a relay switch in a Mark II Aiken Relay Calculator. The dead moth was taped to the machine's logbook, which now resides at the National Museum of American History of the Smithsonian Institution.\r\nWhenever the machine broke down, which was often, operators would quip that they were \"debugging\" it.\r\n" - -message3="The size and age of the Cosmos are beyond ordinary human understanding. Lost somewhere between immensity and eternity is our tiny planetary home. In a cosmic perspective, most human concerns seem insignificant, even petty. And yet our species is young and curious and brave and shows much promise. In the last few millennia we have made the most astonishing and unexpected discoveries about the Cosmos and our place within it, explorations that are exhilarating to consider. They remind us that humans have evolved to wonder, that understanding is a joy, that knowledge is prerequisite to survival. I believe our future depends on how well we know this Cosmos in which we float like a mote of dust in the morning sky." - -message4="A man is flying in a hot air balloon and realizes he is lost. He reduces height and spots a man down below. He lowers the balloon further and shouts: \"Excuse me, can you tell me where I am?\"\nThe man below says: \"Yes you're in a hot air balloon, hovering 30 feet above this field.\"\n\"You must be a software developer,\" says the balloonist.\n\"I am,\" replies the man. \"How did you know?\"\n\"Well,\" says the balloonist, \"everything you have told me is technically correct, but it's of no use to anyone.\"\nThe man below says, \"You must work in business as a manager.\"\n\"I do,\" replies the balloonist, \"but how did you know?\"\n\"Well,\" says the man, \"you don't know where you are or where you are going, but you expect me to be able to help. You're in the same position you were before we met but now it's my fault.\"" - -message5="\"Okay. About twenty years ago A.T.&T. made a multi-billion-dollar decision to operate its entire long-distance switching system on twelve electronically generated combinations of twelve master tones. Those are the tones you sometimes hear in the background after you've dialed a long-distance number. They decided to use some very simple tones -- the tone for each number is just two fixed single-frequency tones played simultaneously to create a certain beat frequency. Like 1300 cycles per second and 900 cycles per second played together give you the tone for digit 5. Now, what some of these phone phreaks have done is get themselves access to an electric organ. Any cheap family home-entertainment organ. Since the frequencies are public knowledge now -- one blind phone phreak has even had them recorded in one of the talking books for the blind -- they just have to find the musical notes on the organ which correspond to the phone tones. Then they tape them. For instance, to get Ma Bell's tone for the number 1, you press down organ keys F~5 and A~5 (900 and 700 cycles per second) at the same time. To produce the tone for 2 it's F~5 and C~6 (1100 and 700 c.p.s). The phone phreaks circulate the whole list of notes so there's no trial and error anymore.\"" - -message6="Man is the Reasoning Animal. Such is the claim. I think it is open to dispute. Indeed, my experiments have proven to me that he is the Unreasoning Animal... In truth, man is incurably foolish. Simple things which other animals easily learn, he is incapable of learning. Among my experiments was this. In an hour I taught a cat and a dog to be friends. I put them in a cage. In another hour I taught them to be friends with a rabbit. In the course of two days I was able to add a fox, a goose, a squirrel and some doves. Finally a monkey. They lived together in peace; even affectionately.\n Next, in another cage I confined an Irish Catholic from Tipperary, and as soon as he seemed tame I added a Scotch Presbyterian from Aberdeen. Next a Turk from Constantinople; a Greek Christian from Crete; an Armenian; a Methodist from the wilds of Arkansas; a Buddhist from China; a Brahman from Benares. Finally, a Salvation Army Colonel from Wapping. Then I stayed away for two whole days. When I came back to note results, the cage of Higher Animals was all right, but in the other there was but a chaos of gory odds and ends of turbans and fezzes and plaids and bones and flesh--not a specimen left alive. These Reasoning Animals had disagreed on a theological detail and carried the matter to a Higher Court." - -message7="A long, long time ago the World was in an age of Chaos. In the midst of the chaos, in a little kingdom in the land of Hyrule, a legend was being handed down from generation to generation, the legend of the 'Triforce': golden triangles possessing mystical powers. One day, an evil army led by Ganon, the powerful Prince of Darkness, attacked and stole the Triforce of Power. Fearing his wicked rule, princess Zelda split the Triforce of Wisdom into eight fragments and hid them throughout the realm. She commanded her most trustworthy nursemaid, Impa, to escape and search for someone courageous enough to destroy the evil Ganon. Upon hearing this, Ganon grew angry, imprisoned the princess, and sent out a party in search of Impa. Braving forests and mountains, Impa fled for her life from her pursuers. As she reached the very limit of her energy she found herself surrounded by Ganon's evil henchmen. Cornered! What could she do? But wait! All was not lost. A young lad appeared, driving off Ganon's henchmen and saving Impa from a fate worse than death. His name was Link. Impa told Link the story of Zelda and the evil Ganon. Burning with a sense of justice, Link resolved to save Zelda. But Ganon was a powerful opponent. He held the Triforce of Power. Link had to bring the scattered eight fragments of the Triforce of Wisdom together to rebuild the mystical triangle or there would be no chance he could fight his way into Death Mountain where Ganon lived. Can Link really destroy Ganon and save princess Zelda? Only your skill can answer that question. Good luck. Use the Triforce wisely." - - -@pytest.fixture(autouse=True) -def context(cmd): - bip32_path: str = "44'/3333'/0'/0/0" - - pub_key, chain_code = cmd.get_public_key( - bip32_path=bip32_path, display=0, chaincode=0 - ) - - context = {"pkey": pub_key, "chain_code": chain_code, "bip32": bip32_path} - yield context - - -def test_sign_message(cmd, context): - - schnorr_sig = cmd.sign_message( - bip32_path=context["bip32"], message=message1, n_screens=5 - ) - assert ( - ssa.verify(message1.encode("ascii"), context["pkey"][1:], schnorr_sig) is True - ) - - schnorr_sig = cmd.sign_message( - bip32_path=context["bip32"], message=message2, n_screens=26 - ) - assert ( - ssa.verify(message2.encode("ascii"), context["pkey"][1:], schnorr_sig) is True - ) - - schnorr_sig = cmd.sign_message( - bip32_path=context["bip32"], message=message3, n_screens=43 - ) - assert ( - ssa.verify(message3.encode("ascii"), context["pkey"][1:], schnorr_sig) is True - ) - - schnorr_sig = cmd.sign_message( - bip32_path=context["bip32"], message=message4, n_screens=45 - ) - assert ( - ssa.verify(message4.encode("ascii"), context["pkey"][1:], schnorr_sig) is True - ) - - schnorr_sig = cmd.sign_message( - bip32_path=context["bip32"], message=message5, n_screens=69 - ) - assert ( - ssa.verify(message5.encode("ascii"), context["pkey"][1:], schnorr_sig) is True - ) - - schnorr_sig = cmd.sign_message( - bip32_path=context["bip32"], message=message6, n_screens=70 - ) - assert ( - ssa.verify(message6.encode("ascii"), context["pkey"][1:], schnorr_sig) is True - ) - - schnorr_sig = cmd.sign_message( - bip32_path=context["bip32"], message=message7, n_screens=89 - ) - assert ( - ssa.verify(message7.encode("ascii"), context["pkey"][1:], schnorr_sig) is True - ) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_too_long_message(cmd, context): - try: - message = "a" * 1598 - - cmd.sign_message(bip32_path=context["bip32"], message=message) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_MESSAGE) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_not_ascii(cmd, context): - try: - message = "\0this should not work" - - cmd.sign_message(bip32_path=context["bip32"], message=message) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_MESSAGE) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_not_ascii2(cmd, context): - try: - message = "this should not work\r" - - cmd.sign_message(bip32_path=context["bip32"], message=message) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_MESSAGE) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_length_validation(cmd): - try: - cmd.transport.apdu_exchange( - cla=0xE0, - ins=0xC1, - p1=0x00, - p2=0x80, - cdata=bytes.fromhex("058000002c80000d05800000000000000000000000"), - ) - - cmd.transport.apdu_exchange( - cla=0xE0, - ins=0xC1, - p1=0x01, - p2=0x00, - cdata=bytes.fromhex("fe00" + "63" * 253), - ) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_MESSAGE) diff --git a/tests/functional/test_name_version.py b/tests/functional/test_name_version.py index 98247395..399b9226 100644 --- a/tests/functional/test_name_version.py +++ b/tests/functional/test_name_version.py @@ -1,7 +1,17 @@ -def test_get_app_and_version(cmd, hid): - if hid: - # for now it doesn't work with Speculos - app_name, version = cmd.get_app_and_version() +from application_client.solar_command_sender import SolarCommandSender +from application_client.solar_response_unpacker import ( + unpack_get_app_and_version_response, +) - assert app_name == "Solar" - assert version == "1.0.0" + +# Test a specific APDU asking BOLOS (and not the app) the name and version of the current app +def test_get_app_and_version(backend, backend_name): + # Use the app interface instead of raw interface + client = SolarCommandSender(backend) + # Send the special instruction to BOLOS + response = client.get_app_and_version() + # Use an helper to parse the response, assert the values + app_name, version = unpack_get_app_and_version_response(response.data) + + assert app_name == "Solar" + assert version == "1.0.0" diff --git a/tests/functional/test_pubkey_cmd.py b/tests/functional/test_pubkey_cmd.py index 8e6028b6..d9664102 100644 --- a/tests/functional/test_pubkey_cmd.py +++ b/tests/functional/test_pubkey_cmd.py @@ -1,62 +1,161 @@ import pytest -from client.exception import * -from speculos.client import ApduException -from client.cmd_builder import InsType +from application_client.solar_command_sender import SolarCommandSender, Errors +from application_client.solar_response_unpacker import ( + unpack_get_public_key_response, + unpack_get_public_key_chaincode_response +) +from ragger.bip import calculate_public_key_and_chaincode, CurveChoice +from ragger.error import ExceptionRAPDU +from ragger.navigator import NavInsID, NavIns +from utils import ROOT_SCREENSHOT_PATH -def test_get_public_key(cmd): - # No Display, No Chain Code - pub_key, chain_code = cmd.get_public_key( - bip32_path="44'/3333'/0'/0/0", display=0, chaincode=0 - ) +# In this test we check that the GET_PUBLIC_KEY works in non-confirmation mode +def test_get_public_key_no_chaincode_no_confirm(backend): + client = SolarCommandSender(backend) + path = "m/44'/3333'/0'/0/0" - assert len(pub_key) == 33 - assert len(chain_code) == 0 + response = client.get_public_key(path=path).data + _, public_key = unpack_get_public_key_response(response) - # Display, No Chain Code - pub_key2, chain_code2 = cmd.get_public_key( - bip32_path="44'/3333'/0'/0/0", - display=1, - chaincode=0, - n_screens=5, + ref_public_key, _ = calculate_public_key_and_chaincode( + CurveChoice.Secp256k1, path=path, compress_public_key=True ) - assert len(pub_key2) == 33 - assert len(chain_code2) == 0 + assert public_key.hex() == ref_public_key + + +# In this test we check that the GET_PUBLIC_KEY with a chaincode works in non-confirmation mode +def test_get_public_key_chaincode_no_confirm(backend): + client = SolarCommandSender(backend) + path = "m/44'/3333'/0'/0/0" - # Display, Chain Code - pub_key3, chain_code3 = cmd.get_public_key( - bip32_path="44'/3333'/0'/0/0", - display=1, - chaincode=1, - n_screens=5, + response = client.get_public_key(path=path, chaincode=1).data + _, public_key, _, chain_code = unpack_get_public_key_chaincode_response(response) + + ref_public_key, ref_chain_code = calculate_public_key_and_chaincode( + CurveChoice.Secp256k1, path=path, compress_public_key=True ) - assert len(pub_key3) == 33 - assert len(chain_code3) == 32 + assert public_key.hex() == ref_public_key + assert chain_code.hex() == ref_chain_code + + +# In this test we check that the GET_PUBLIC_KEY works in confirmation mode +def test_get_public_key_no_chaincode_confirm_accepted( + firmware, backend, navigator, test_name +): + client = SolarCommandSender(backend) + path = "m/44'/3333'/0'/0/0" - # No Display, Chain Code - pub_key4, chain_code4 = cmd.get_public_key( - bip32_path="44'/3333'/0'/0/0", display=0, chaincode=1 + with client.get_public_key_with_confirmation(path=path): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: # stax + # instructions = [ + # NavInsID.USE_CASE_REVIEW_TAP, + # NavIns(NavInsID.TOUCH, (200, 335)), + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_EXIT_QR, + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_TAP, + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS + # ] + # navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + # test_name, + # instructions) + response = client.get_async_response().data + _, public_key = unpack_get_public_key_response(response) + + ref_public_key, _ = calculate_public_key_and_chaincode( + CurveChoice.Secp256k1, path=path, compress_public_key=True ) - assert len(pub_key4) == 33 - assert len(chain_code4) == 32 + assert public_key.hex() == ref_public_key + + +# In this test we check that the GET_PUBLIC_KEY with a chaincode works in confirmation mode +def test_get_public_key_chaincode_confirm_accepted( + firmware, backend, navigator, test_name +): + client = SolarCommandSender(backend) + path = "m/44'/3333'/0'/0/0" + + with client.get_public_key_with_confirmation(path=path, chaincode=1): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: # stax + # instructions = [ + # NavInsID.USE_CASE_REVIEW_TAP, + # NavIns(NavInsID.TOUCH, (200, 335)), + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_EXIT_QR, + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_TAP, + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS + # ] + # navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + # test_name, + # instructions) + response = client.get_async_response().data + _, public_key, _, chain_code = unpack_get_public_key_chaincode_response(response) + + ref_public_key, ref_chain_code = calculate_public_key_and_chaincode( + CurveChoice.Secp256k1, path=path, compress_public_key=True + ) + assert public_key.hex() == ref_public_key + assert chain_code.hex() == ref_chain_code -@pytest.mark.xfail(raises=WrongP1P2Error, strict=True) -def test_wrong_chaincode_option(cmd): - try: - cmd.get_public_key(bip32_path="44'/3333'/0'/0/0", display=0, chaincode=2) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_GET_PUBLIC_KEY) +# In this test we check that the GET_PUBLIC_KEY in confirmation mode replies an error if the user refuses +def test_get_public_key_confirm_refused(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + path = "m/44'/3333'/0'/0/0" -@pytest.mark.xfail(raises=WrongP1P2Error, strict=True) -def test_wrong_display_option(cmd): - try: - cmd.get_public_key(bip32_path="44'/3333'/0'/0/0", display=2, chaincode=0) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_GET_PUBLIC_KEY) + # if firmware.device.startswith("nano"): + with pytest.raises(ExceptionRAPDU) as e: + with client.get_public_key_with_confirmation(path=path): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Reject", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # Assert that we have received a refusal + assert e.value.status == Errors.SW_DENY + assert len(e.value.data) == 0 + # else: # stax + # instructions_set = [ + # [ + # NavInsID.USE_CASE_REVIEW_REJECT, + # NavInsID.USE_CASE_STATUS_DISMISS + # ], + # [ + # NavInsID.USE_CASE_REVIEW_TAP, + # NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CANCEL, + # NavInsID.USE_CASE_STATUS_DISMISS + # ] + # ] + # for i, instructions in enumerate(instructions_set): + # with pytest.raises(ExceptionRAPDU) as e: + # with client.get_public_key_with_confirmation(path=path): + # navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + # test_name + f"/part{i}", + # instructions) + # # Assert that we have received a refusal + # assert e.value.status == Errors.SW_DENY + # assert len(e.value.data) == 0 diff --git a/tests/functional/test_sign_cmd.py b/tests/functional/test_sign_cmd.py deleted file mode 100644 index 15f33634..00000000 --- a/tests/functional/test_sign_cmd.py +++ /dev/null @@ -1,326 +0,0 @@ -from btclib.ecc import ssa -import pytest -from client.exception import * - -from speculos.client import ApduException -from client.cmd_builder import InsType - -from client.transaction import Transaction -from transactions.multi_signature_registration import Multisignature -from transactions.ipfs import Ipfs -from transactions.transfer import Transfer -from transactions.htlc_lock import HtlcLock -from transactions.htlc_refund import HtlcRefund -from transactions.htlc_claim import HtlcClaim -from transactions.burn import Burn -from transactions.vote import Vote - - -@pytest.fixture(autouse=True) -def context(cmd): - bip32_path: str = "44'/3333'/0'/0/0" - - pub_key, chain_code = cmd.get_public_key( - bip32_path=bip32_path, display=0, chaincode=0 - ) - - context = {"pkey": pub_key, "chain_code": chain_code, "bip32": bip32_path} - yield context - - -def test_transfer_tx(cmd, context): - - tx = Transfer( - 1, - context["pkey"], - 5645365, - "This is a test memo.", - ["3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3"], - [123456], - ) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=7) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - tx = Transfer( - 1, - context["pkey"], - 5645365, - "", - [ - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - ], - [ - 123456, - 1234567, - 12345678, - 123456789, - 1234567890, - 12345678900, - 123456789000, - 1234567890000, - 12345678900000, - 123456789000000, - 1234567890000000, - 12345678900000000, - 123456789000000000, - 18446744073709551615, - ], - ) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=60) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_transfer_limit(cmd, context): - - tx = Transfer( - 1, - context["pkey"], - 5645365, - "", - ["3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3" for _ in range(41)], - [1 for _ in range(41)], - ) - cmd.sign_tx(bip32_path=context["bip32"], transaction=tx) - - -def test_burn_tx(cmd, context): - - tx = Burn(3, context["pkey"], 0, "", 250000000000) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=3) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - -def test_htlc_lock_tx(cmd, context): - tx = HtlcLock( - 4, - context["pkey"], - 645365, - "", - 123456789, - "9c1a3815d49e0c9f78b872bfb017e825ea2db708158b70815526a830c85912b4", - 1, - 1234, - "3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3", - ) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=11) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - -def test_htlc_claim_tx(cmd, context): - - tx = HtlcClaim( - 5, - context["pkey"], - 645365, - "", - 0, - "cfb37ec05433841cd8d25c3e8d353dc519a6dcb583edd75085b671bff4075b40", - "c27f1ce845d8c29eebc9006be932b604fd06755521b1a8b0be4204c65377151a", - ) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=10) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - -def test_htlc_refund_tx(cmd, context): - - tx = HtlcRefund( - 6, - context["pkey"], - 645365, - "", - "cfb37ec05433841cd8d25c3e8d353dc519a6dcb583edd75085b671bff4075b40", - ) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=6) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - -def test_ipfs_tx(cmd, context): - - tx = Ipfs( - 7, - context["pkey"], - 645365, - "", - "122040e8c8cc86493d35f01b603190499ad4046cf2d097f5d34de034cebbba904804", - ) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=5) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - -def test_multisignature_tx(cmd, context): - - tx = Multisignature( - 8, - context["pkey"], - 645365, - "", - 2, - [ - "03e5ea82082ea33c9956ec03109118c7d588f82eb7a0c3c1794de67103bb0c85f9", - "022f69d427310705c3e02ebb5519bcd545f41a2eed543660fafe0e7191930eb747", - "03d39fb4797d0c428bebed6d80203e2273a9fdbcaafe0b29761ef3183c2151e211", - ], - ) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=15) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - -def test_vote_tx(cmd, context): - - tx = Vote( - 2, - context["pkey"], - 10000000, - "", - [["gym", 2000], ["cactus1549", 4000], ["sl33p", 4000]], - ) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=8) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - tx = Vote( - 2, - context["pkey"], - 10000000, - "", - [], - ) - schnorr_sig = cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=2) - assert ssa.verify(tx.serialise(), context["pkey"][1:], schnorr_sig) is True - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def vote_sum_equal_100(cmd, context): - try: - tx = Vote( - 2, - context["pkey"], - 10000000, - "", - [["gym", 2001], ["cactus1549", 4000], ["sl33p", 4000]], - ) - cmd.sign_tx(bip32_path=context["bip32"], transaction=tx, n_screens=2) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_accept_v3_only(cmd, context): - try: - tx = Transfer( - 1, - context["pkey"], - 5645365, - "", - ["3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3"], - [123456], - version=2, - ) - cmd.sign_tx(bip32_path=context["bip32"], transaction=tx) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_network_byte(cmd, context): - try: - tx = Transfer( - 1, - context["pkey"], - 5645365, - "", - ["3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3"], - [123456], - network=62, - ) - cmd.sign_tx(bip32_path=context["bip32"], transaction=tx) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_starting_byte(cmd, context): - try: - tx = Transfer( - 1, - context["pkey"], - 5645365, - "", - ["3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3"], - [123456], - startingByte=0xFE, - ) - cmd.sign_tx(bip32_path=context["bip32"], transaction=tx) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_memo_encoding(cmd, context): - try: - tx = Transfer( - 1, - context["pkey"], - 5645365, - "eco\nuter", - ["3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3"], - [123456], - ) - cmd.sign_tx(bip32_path=context["bip32"], transaction=tx) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_wrong_typegroup(cmd, context): - try: - tx = Transaction(3, 0, 13, context["pkey"], 2000000, "") - cmd.sign_tx(bip32_path=context["bip32"], transaction=tx) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_wrong_type(cmd, context): - try: - tx = Transaction(1, 20, 13, context["pkey"], 2000000, "") - cmd.sign_tx(bip32_path=context["bip32"], transaction=tx) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) - - -@pytest.mark.xfail(raises=TxParsingFailError, strict=True) -def test_wrong_memo_length(cmd): - try: - cmd.transport.apdu_exchange( - cla=0xE0, - ins=0xC2, - p1=0x00, - p2=0x80, - cdata=bytes.fromhex("058000002c80000d05800000000000000000000000"), - ) - - cmd.transport.apdu_exchange( - cla=0xE0, - ins=0xC2, - p1=0x01, - p2=0x00, - cdata=bytes.fromhex( - "ff033f010000000600010000000000000002937e1b9294d07c91b46d511851d698ad606a64950dd3a332fcfac9c0a3fb0bad352456000000000005616161616161010040e20100000000003fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3" - ), - ) - except ApduException as error: - raise DeviceException(error_code=error.sw, ins=InsType.INS_SIGN_TX) diff --git a/tests/functional/test_sign_message_cmd.py b/tests/functional/test_sign_message_cmd.py new file mode 100644 index 00000000..e3cd6a9a --- /dev/null +++ b/tests/functional/test_sign_message_cmd.py @@ -0,0 +1,111 @@ +import pytest + +from ragger.error import ExceptionRAPDU +from ragger.navigator import NavInsID, NavIns +from utils import ROOT_SCREENSHOT_PATH + +from btclib.ecc import ssa + +from application_client.solar_command_sender import ( + SolarCommandSender, + Errors, +) +from application_client.solar_response_unpacker import ( + unpack_get_public_key_response, +) +from constants import PATH_MAINNET + + +MESSAGE_SHORT: str = "We are the music makers,\n the dreamers of dreams...\n" +MESSAGE_LONG: str = "A long, long time ago the World was in an age of Chaos. In the midst of the chaos, in a little kingdom in the land of Hyrule, a legend was being handed down from generation to generation, the legend of the 'Triforce': golden triangles possessing mystical powers. One day, an evil army led by Ganon, the powerful Prince of Darkness, attacked and stole the Triforce of Power. Fearing his wicked rule, princess Zelda split the Triforce of Wisdom into eight fragments and hid them throughout the realm. She commanded her most trustworthy nursemaid, Impa, to escape and search for someone courageous enough to destroy the evil Ganon. Upon hearing this, Ganon grew angry, imprisoned the princess, and sent out a party in search of Impa. Braving forests and mountains, Impa fled for her life from her pursuers. As she reached the very limit of her energy she found herself surrounded by Ganon's evil henchmen. Cornered! What could she do? But wait! All was not lost. A young lad appeared, driving off Ganon's henchmen and saving Impa from a fate worse than death. His name was Link. Impa told Link the story of Zelda and the evil Ganon. Burning with a sense of justice, Link resolved to save Zelda. But Ganon was a powerful opponent. He held the Triforce of Power. Link had to bring the scattered eight fragments of the Triforce of Wisdom together to rebuild the mystical triangle or there would be no chance he could fight his way into Death Mountain where Ganon lived. Can Link really destroy Ganon and save princess Zelda? Only your skill can answer that question. Good luck. Use the Triforce wisely." + + +# In this tests we check the behaviour of the device when asked to sign a short message +def test_sign_message_short(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + with client.sign_message(path=PATH_MAINNET, message=MESSAGE_SHORT): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: + # navigator.navigate_until_text_and_compare(NavInsID.USE_CASE_REVIEW_TAP, + # [NavInsID.USE_CASE_REVIEW_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS], + # "Hold to sign", + # ROOT_SCREENSHOT_PATH, + # test_name) + response = client.get_async_response().data + + assert ssa.verify(MESSAGE_SHORT.encode("ascii"), public_key, response) is True + + +# In this tests we check the behaviour of the device when asked to sign a long message +def test_sign_message_long(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + # First we need to get the public key of the device in order to build the transaction + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + with client.sign_message(path=PATH_MAINNET, message=MESSAGE_LONG): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: + # navigator.navigate_until_text_and_compare(NavInsID.USE_CASE_REVIEW_TAP, + # [NavInsID.USE_CASE_REVIEW_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS], + # "Hold to sign", + # ROOT_SCREENSHOT_PATH, + # test_name) + response = client.get_async_response().data + + assert ssa.verify(MESSAGE_LONG.encode("ascii"), public_key, response) is True + + +# Message signature refused test +# The test will ask for a message signature that will be refused on screen +def test_sign_message_refused(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + # if firmware.device.startswith("nano"): + with pytest.raises(ExceptionRAPDU) as e: + with client.sign_message(path=PATH_MAINNET, message=MESSAGE_SHORT): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Reject", + ROOT_SCREENSHOT_PATH, + test_name, + ) + assert e.value.status == Errors.SW_DENY + assert len(e.value.data) == 0 + # else: + # for i in range(3): + # instructions = [NavInsID.USE_CASE_REVIEW_TAP] * i + # instructions += [NavInsID.USE_CASE_REVIEW_REJECT, + # NavInsID.USE_CASE_CHOICE_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS] + # with pytest.raises(ExceptionRAPDU) as e: + # with client.sign_tx(path=PATH_MAINNET, transaction=transaction): + # navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + # test_name + f"/part{i}", + # instructions) + # # Assert that we have received a refusal + # assert e.value.status == Errors.SW_DENY + # assert len(e.value.data) == 0 diff --git a/tests/functional/test_sign_transaction_cmd.py b/tests/functional/test_sign_transaction_cmd.py new file mode 100644 index 00000000..d00b7851 --- /dev/null +++ b/tests/functional/test_sign_transaction_cmd.py @@ -0,0 +1,549 @@ +import pytest + +from ragger.error import ExceptionRAPDU +from ragger.navigator import NavInsID, NavIns +from utils import ROOT_SCREENSHOT_PATH + +from btclib.ecc import ssa + +from application_client.solar_command_sender import ( + CLA, + InsType, + P1, + P2, + MAX_APDU_LEN, + SolarCommandSender, + split_message, + Errors, +) +from application_client.solar_response_unpacker import ( + unpack_get_public_key_response, +) +from transactions.transfer import Transfer +from transactions.vote import Vote +from transactions.burn import Burn +from transactions.ipfs import Ipfs +from application_client.solar_transaction import ( + Transaction, +) +from constants import PATH_MAINNET + + +# Check the behaviour of the device when asked to sign an ipfs transaction. +# TypeGroup 1, Type 5 +def test_sign_transaction_ipfs(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + ipfs_transaction = Ipfs( + nonce=1, + senderPkey=public_key, + fee=645365, + memo="", + ipfs="122040e8c8cc86493d35f01b603190499ad4046cf2d097f5d34de034cebbba904804", + ) + + with client.sign_transaction(path=PATH_MAINNET, transaction=ipfs_transaction): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: + # navigator.navigate_until_text_and_compare(NavInsID.USE_CASE_REVIEW_TAP, + # [NavInsID.USE_CASE_REVIEW_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS], + # "Hold to sign", + # ROOT_SCREENSHOT_PATH, + # test_name) + response = client.get_async_response().data + + assert ssa.verify(ipfs_transaction.serialise(), public_key, response) is True + + +# Check the behaviour of the device when asked to sign a transfer transaction. +# TypeGroup 1, Type 6 +def test_sign_transaction_transfer(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + transfer_transaction = Transfer( + nonce=2, + senderPkey=public_key, + fee=5645365, + memo="This is an optional memo.", + addresses=[ + "3f091327b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3f192327b917bf2b464e9b8f1acf1588f4cb6e7bb3", + "3f293327b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3f394327b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3f495327b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3f596327b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3f697327b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3f798327b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3f899327b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3f990327b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3fa91427b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3fb91527b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3fc91627b917bf2b464e9b8f1acf0588f4cb6e7bb3", + "3fd91727b917bf2b464e9b8f1acf0588f4cb6e7bb3", + ], + amounts=[ + 123456, + 1234567, + 12345678, + 123456789, + 1234567890, + 12345678900, + 123456789000, + 1234567890000, + 12345678900000, + 123456789000000, + 1234567890000000, + 12345678900000000, + 123456789000000000, + 18446744073709551615, + ], + ) + + with client.sign_transaction(path=PATH_MAINNET, transaction=transfer_transaction): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: + # navigator.navigate_until_text_and_compare(NavInsID.USE_CASE_REVIEW_TAP, + # [NavInsID.USE_CASE_REVIEW_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS], + # "Hold to sign", + # ROOT_SCREENSHOT_PATH, + # test_name) + response = client.get_async_response().data + + assert ssa.verify(transfer_transaction.serialise(), public_key, response) is True + + +# Check the behaviour of the device when asked to sign a burn transaction. +# TypeGroup 2, Type 0 +def test_sign_transaction_burn(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + burn_transaction = Burn( + nonce=3, + senderPkey=public_key, + fee=10000000, + memo="", + amount=250000000000, + ) + + with client.sign_transaction(path=PATH_MAINNET, transaction=burn_transaction): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: + # navigator.navigate_until_text_and_compare(NavInsID.USE_CASE_REVIEW_TAP, + # [NavInsID.USE_CASE_REVIEW_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS], + # "Hold to sign", + # ROOT_SCREENSHOT_PATH, + # test_name) + response = client.get_async_response().data + + assert ssa.verify(burn_transaction.serialise(), public_key, response) is True + + +# Check the behaviour of the device when asked to sign a vote transaction. +# TypeGroup 2, Type 2 +def test_sign_transaction_vote(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + vote_transaction = Vote( + nonce=4, + senderPkey=public_key, + fee=10000000, + memo="", + votes=[["gym", 2000], ["cactus1549", 4000], ["sl33p", 4000]], + ) + + with client.sign_transaction(path=PATH_MAINNET, transaction=vote_transaction): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: + # navigator.navigate_until_text_and_compare(NavInsID.USE_CASE_REVIEW_TAP, + # [NavInsID.USE_CASE_REVIEW_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS], + # "Hold to sign", + # ROOT_SCREENSHOT_PATH, + # test_name) + response = client.get_async_response().data + + assert ssa.verify(vote_transaction.serialise(), public_key, response) is True + + +# Check the behaviour of the device when asked to sign a cancel vote transaction. +# TypeGroup 2, Type 2 +def test_sign_transaction_vote_cancel(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + cancel_vote_transaction = Vote( + nonce=5, + senderPkey=public_key, + fee=10000000, + memo="", + votes=[], + ) + + with client.sign_transaction(path=PATH_MAINNET, transaction=cancel_vote_transaction): + # if firmware.device.startswith("nano"): + navigator.navigate_until_text_and_compare( + NavInsID.RIGHT_CLICK, + [NavInsID.BOTH_CLICK], + "Approve", + ROOT_SCREENSHOT_PATH, + test_name, + ) + # else: + # navigator.navigate_until_text_and_compare(NavInsID.USE_CASE_REVIEW_TAP, + # [NavInsID.USE_CASE_REVIEW_CONFIRM, + # NavInsID.USE_CASE_STATUS_DISMISS], + # "Hold to sign", + # ROOT_SCREENSHOT_PATH, + # test_name) + response = client.get_async_response().data + + assert ssa.verify(cancel_vote_transaction.serialise(), public_key, response) is True + + +# Check the behaviour of the device when the transfer uses an invalid typegroup. +def test_sign_transaction_type_group_invalid(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + transaction = Transaction( + typeGroup=3, + type=0, + nonce=6, + senderPkey=public_key, + fee=2000000, + memo="", + ) + + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=bytes.fromhex("058000002c80000d05800000000000000000000000"), + ) + + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START + 1, + p2=P2.P2_LAST, + data=transaction.serialise(), + ) + assert e.value.status == Errors.SW_TX_PARSING_FAIL + + +# Check the behaviour of the device when the transfer uses an invalid type. +def test_sign_transaction_type_invalid(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + transaction = Transaction( + typeGroup=20, + type=20, + nonce=6, + senderPkey=public_key, + fee=2000000, + memo="", + ) + + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=bytes.fromhex("058000002c80000d05800000000000000000000000"), + ) + + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START + 1, + p2=P2.P2_LAST, + data=transaction.serialise(), + ) + assert e.value.status == Errors.SW_TX_PARSING_FAIL + +# Check the behaviour of the device when the transfer limit is exceeded. +def test_sign_transfer_limit_exceeded(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + transfer_transaction = Transfer( + nonce=2, + senderPkey=public_key, + fee=5645365, + memo="", + addresses=["3fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3" for _ in range(41)], + amounts=[1 for _ in range(41)], + ) + + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=bytes.fromhex("058000002c80000d05800000000000000000000000"), + ) + chunks = split_message(transfer_transaction.serialise(), MAX_APDU_LEN) + idx: int = P1.P1_START + 1 + + for chunk in chunks: + backend.exchange( + cla=CLA, ins=InsType.SIGN_TX, p1=idx, p2=P2.P2_MORE, data=chunk + ) + idx += 1 + + assert e.value.status == Errors.SW_WRONG_TX_LENGTH + + +# Check the behaviour of the device when the transfer uses an unsupported version. +def test_sign_transfer_version_unsupported(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + transfer_transaction = Transfer( + version=2, + nonce=2, + senderPkey=public_key, + fee=5645365, + memo="", + addresses=["3f091327b917bf2b464e9b8f1acf0588f4cb6e7bb3"], + amounts=[123456], + ) + + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=bytes.fromhex("058000002c80000d05800000000000000000000000"), + ) + + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START + 1, + p2=P2.P2_LAST, + data=transfer_transaction.serialise(), + ) + assert e.value.status == Errors.SW_TX_PARSING_FAIL + + +# Check the behaviour of the device when the transfer uses an unsupported network. +def test_sign_transfer_network_unsupported(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + transfer_transaction = Transfer( + network=62, + nonce=2, + senderPkey=public_key, + fee=5645365, + memo="", + addresses=["3f091327b917bf2b464e9b8f1acf0588f4cb6e7bb3"], + amounts=[123456], + ) + + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=bytes.fromhex("058000002c80000d05800000000000000000000000"), + ) + + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START + 1, + p2=P2.P2_LAST, + data=transfer_transaction.serialise(), + ) + assert e.value.status == Errors.SW_TX_PARSING_FAIL + + +# Check the behaviour of the device when the transfer uses an invalid starting byte. +def test_sign_transfer_starting_byte_invalid(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + transfer_transaction = Transfer( + startingByte=0xFE, + nonce=2, + senderPkey=public_key, + fee=5645365, + memo="", + addresses=["3f091327b917bf2b464e9b8f1acf0588f4cb6e7bb3"], + amounts=[123456], + ) + + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=bytes.fromhex("058000002c80000d05800000000000000000000000"), + ) + + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START + 1, + p2=P2.P2_LAST, + data=transfer_transaction.serialise(), + ) + assert e.value.status == Errors.SW_TX_PARSING_FAIL + + +# Check the behaviour of the device when the transfer uses an invalid memo encoding. +def test_sign_transfer_memo_invalid(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + transfer_transaction = Transfer( + nonce=2, + senderPkey=public_key, + fee=5645365, + memo="this\nis\nnot\nvalid", + addresses=["3f091327b917bf2b464e9b8f1acf0588f4cb6e7bb3"], + amounts=[123456], + ) + + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=bytes.fromhex("058000002c80000d05800000000000000000000000"), + ) + + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START + 1, + p2=P2.P2_LAST, + data=transfer_transaction.serialise(), + ) + assert e.value.status == Errors.SW_TX_PARSING_FAIL + + +# Check the behaviour of the device when the data length is invalid. +def test_transaction_data_length_invalid(backend): + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + ) + + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START + 1, + p2=P2.P2_LAST, + data=bytes.fromhex( + "ff033f010000000600010000000000000002937e1b9294d07c91b46d511851d698ad606a64950dd3a332fcfac9c0a3fb0bad352456000000000005616161616161010040e20100000000003fc91327b917bf2b464e9b8f1acf0588f4cb6e7bb3" + ), + ) + assert e.value.status == Errors.SW_WRONG_DATA_LENGTH + + +# Check the behaviour of the device when the transfer uses an invalid vote sum. +def test_sign_transfer_vote_sum_invalid(firmware, backend, navigator, test_name): + client = SolarCommandSender(backend) + + rapdu = client.get_public_key(path=PATH_MAINNET) + _, public_key = unpack_get_public_key_response(rapdu.data) + + vote_transaction = Vote( + nonce=6, + senderPkey=public_key, + fee=10000000, + memo="", + votes=[["gym", 2001], ["cactus1549", 4000], ["sl33p", 4000]], + ) + + with pytest.raises(ExceptionRAPDU) as e: + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START, + p2=P2.P2_MORE, + data=bytes.fromhex("058000002c80000d05800000000000000000000000"), + ) + + backend.exchange( + cla=CLA, + ins=InsType.SIGN_TX, + p1=P1.P1_START + 1, + p2=P2.P2_LAST, + data=vote_transaction.serialise(), + ) + assert e.value.status == Errors.SW_TX_PARSING_FAIL diff --git a/tests/functional/test_status_word.py b/tests/functional/test_status_word.py deleted file mode 100644 index 0a492f09..00000000 --- a/tests/functional/test_status_word.py +++ /dev/null @@ -1,39 +0,0 @@ -from pathlib import Path -from typing import List, Dict, Any, Tuple -import re - -from client.exception import DeviceException - - -SW_RE = re.compile(r"""(?x) - \# # character '#' - define # string 'define' - \s+ # spaces - (?PSW(?:_[A-Z0-9]+)*) # identifier (e.g. 'SW_OK') - \s+ # spaces - 0x(?P[a-fA-F0-9]{4}) # 4 bytes status word -""") - - -def parse_sw(path: Path) -> List[Tuple[str, int]]: - if not path.is_file(): - raise FileNotFoundError(f"Can't find file: '{path}'") - - sw_h: str = path.read_text() - - return [(identifier, int(sw, base=16)) - for identifier, sw in SW_RE.findall(sw_h) if sw != "9000"] - - -def test_status_word(sw_h_path): - expected_status_words: List[Tuple[str, int]] = parse_sw(sw_h_path) - status_words: Dict[int, Any] = DeviceException.exc - - assert len(expected_status_words) == len(status_words), ( - f"{expected_status_words} doesn't match {status_words}") - - # just keep status words - expected_status_words = [sw for (identifier, sw) in expected_status_words] - - for sw in status_words.keys(): - assert sw in expected_status_words, f"{status_words[sw]}({hex(sw)}) not found in sw.h!" diff --git a/tests/functional/test_version_cmd.py b/tests/functional/test_version_cmd.py index 6d18ce6a..7657dcc5 100644 --- a/tests/functional/test_version_cmd.py +++ b/tests/functional/test_version_cmd.py @@ -1,2 +1,17 @@ -def test_version(cmd): - assert cmd.get_version() == (1, 0, 0) +from application_client.solar_command_sender import SolarCommandSender +from application_client.solar_response_unpacker import unpack_get_version_response + + +# Taken from the Makefile, to update every time the Makefile version is bumped +MAJOR = 1 +MINOR = 0 +PATCH = 0 + +# In this test we check the behaviour of the device when asked to provide the app version +def test_version(backend): + # Use the app interface instead of raw interface + client = SolarCommandSender(backend) + # Send the GET_VERSION instruction + rapdu = client.get_version() + # Use an helper to parse the response, assert the values + assert unpack_get_version_response(rapdu.data) == (MAJOR, MINOR, PATCH) diff --git a/tests/functional/transactions/burn.py b/tests/functional/transactions/burn.py index 4ec6a124..b1567fdd 100644 --- a/tests/functional/transactions/burn.py +++ b/tests/functional/transactions/burn.py @@ -1,7 +1,7 @@ from typing import Union -from client.utils import UINT64_MAX -from client.transaction import Transaction, TransactionError +from application_client.solar_utils import UINT64_MAX +from application_client.solar_transaction import Transaction, TransactionError class Burn(Transaction): diff --git a/tests/functional/transactions/htlc_claim.py b/tests/functional/transactions/htlc_claim.py deleted file mode 100644 index 1f8a7b20..00000000 --- a/tests/functional/transactions/htlc_claim.py +++ /dev/null @@ -1,53 +0,0 @@ -from typing import Union - -from client.utils import UINT8_MAX -from client.transaction import Transaction, TransactionError - - -class HtlcClaim(Transaction): - def __init__( - self, - nonce: int, - senderPkey: Union[str, bytes], - fee: int, - memo: str, - hashType: int, - lockId: Union[str, bytes], - unlockSecret: Union[str, bytes], - network: int = 63, - version: int = 3, - startingByte: int = 0xFF, - ) -> None: - super().__init__( - 1, 9, nonce, senderPkey, fee, memo, network, version, startingByte - ) - - self.hashType: int = hashType - - self.lockId: bytes = ( - bytes.fromhex(lockId) if isinstance(lockId, str) else lockId - ) - self.unlockSecret: bytes = ( - bytes.fromhex(unlockSecret) - if isinstance(unlockSecret, str) - else unlockSecret - ) - - if not (0 <= self.hashType <= UINT8_MAX): - raise TransactionError(f"Bad amount: '{self.amount}'!") - - if len(self.lockId) != 32: - raise TransactionError(f"Bad lockId: '{self.lockId}'!") - - if len(self.unlockSecret) > UINT8_MAX: - raise TransactionError(f"Bad unlockSecret: '{self.unlockSecret}'!") - - def serialise(self) -> bytes: - return super().serialise() + b"".join( - [ - self.hashType.to_bytes(1, byteorder="little"), - self.lockId, - len(self.unlockSecret).to_bytes(1, byteorder="little"), - self.unlockSecret, - ] - ) diff --git a/tests/functional/transactions/htlc_lock.py b/tests/functional/transactions/htlc_lock.py deleted file mode 100644 index e5bb5920..00000000 --- a/tests/functional/transactions/htlc_lock.py +++ /dev/null @@ -1,61 +0,0 @@ -from typing import Union - -from client.utils import UINT64_MAX, UINT32_MAX, UINT8_MAX -from client.transaction import Transaction, TransactionError - - -class HtlcLock(Transaction): - def __init__( - self, - nonce: int, - senderPkey: Union[str, bytes], - fee: int, - memo: str, - amount: int, - secretHash: Union[str, bytes], - expirationType: int, - expirationValue: int, - recipientId: Union[str, bytes], - network: int = 63, - version: int = 3, - startingByte: int = 0xFF, - ) -> None: - super().__init__( - 1, 8, nonce, senderPkey, fee, memo, network, version, startingByte - ) - self.amount: int = amount - self.secretHash: bytes = ( - bytes.fromhex(secretHash) if isinstance(secretHash, str) else secretHash - ) - self.expirationType: int = expirationType - self.expirationValue: int = expirationValue - self.recipientId: bytes = ( - bytes.fromhex(recipientId) if isinstance(recipientId, str) else recipientId - ) - - if not (0 <= self.amount <= UINT64_MAX): - raise TransactionError(f"Bad amount: '{self.amount}'!") - - if len(self.secretHash) > UINT8_MAX: - raise TransactionError(f"Bad secretHash: '{self.secretHash}'!") - - if not (0 <= self.expirationType <= UINT8_MAX): - raise TransactionError(f"Bad expirationType: '{self.expirationType}'!") - - if not (0 <= self.expirationValue <= UINT32_MAX): - raise TransactionError(f"Bad expirationValue: '{self.expirationValue}'!") - - if len(self.recipientId) != 21: - raise TransactionError(f"Bad recipientId: '{self.recipientId}'!") - - def serialise(self) -> bytes: - return super().serialise() + b"".join( - [ - self.amount.to_bytes(8, byteorder="little"), - len(self.secretHash).to_bytes(1, byteorder="little"), - self.secretHash, - self.expirationType.to_bytes(1, byteorder="little"), - self.expirationValue.to_bytes(4, byteorder="little"), - self.recipientId, - ] - ) diff --git a/tests/functional/transactions/htlc_refund.py b/tests/functional/transactions/htlc_refund.py deleted file mode 100644 index b17d3dae..00000000 --- a/tests/functional/transactions/htlc_refund.py +++ /dev/null @@ -1,30 +0,0 @@ -from typing import Union - -from client.utils import UINT64_MAX -from client.transaction import Transaction, TransactionError - - -class HtlcRefund(Transaction): - def __init__( - self, - nonce: int, - senderPkey: Union[str, bytes], - fee: int, - memo: str, - lockId: Union[str, bytes], - network: int = 63, - version: int = 3, - startingByte: int = 0xFF, - ) -> None: - super().__init__( - 1, 10, nonce, senderPkey, fee, memo, network, version, startingByte - ) - self.lockId: bytes = ( - bytes.fromhex(lockId) if isinstance(lockId, str) else lockId - ) - - if len(self.lockId) != 32: - raise TransactionError(f"Bad lockId: '{self.lockId}'!") - - def serialise(self) -> bytes: - return super().serialise() + b"".join([self.lockId]) diff --git a/tests/functional/transactions/ipfs.py b/tests/functional/transactions/ipfs.py index f4427376..c32036c3 100644 --- a/tests/functional/transactions/ipfs.py +++ b/tests/functional/transactions/ipfs.py @@ -1,7 +1,7 @@ from typing import Union -from client.utils import UINT64_MAX -from client.transaction import Transaction, TransactionError +from application_client.solar_utils import UINT64_MAX +from application_client.solar_transaction import Transaction, TransactionError class Ipfs(Transaction): diff --git a/tests/functional/transactions/multi_signature_registration.py b/tests/functional/transactions/multi_signature_registration.py deleted file mode 100644 index 3df18aca..00000000 --- a/tests/functional/transactions/multi_signature_registration.py +++ /dev/null @@ -1,43 +0,0 @@ -from typing import Union, List - -from client.utils import write_varint, UINT8_MAX -from client.transaction import Transaction, TransactionError - - -class Multisignature(Transaction): - def __init__( - self, - nonce: int, - senderPkey: Union[str, bytes], - fee: int, - memo: str, - min: int, - pkeys: List[Union[bytes, str]], - network: int = 63, - version: int = 3, - startingByte: int = 0xFF, - ) -> None: - super().__init__( - 1, 4, nonce, senderPkey, fee, memo, network, version, startingByte - ) - self.min: int = min - self.pkeys = [] - for key in pkeys: - if len(key) != 66: - raise TransactionError(f"Bad pkeys: '{key}'!") - self.pkeys.append(bytes.fromhex(key) if isinstance(key, str) else key) - - if not (0 <= self.min <= UINT8_MAX): - raise TransactionError(f"Bad min: '{self.min}'!") - - if len(self.pkeys) < 1 or len(self.pkeys) > 16: - raise TransactionError(f"Bad pkeys: '{self.pkeys}'!") - - def serialise(self) -> bytes: - return super().serialise() + b"".join( - [ - self.min.to_bytes(1, byteorder="little"), - write_varint(len(self.pkeys)), - *self.pkeys, - ] - ) diff --git a/tests/functional/transactions/transfer.py b/tests/functional/transactions/transfer.py index 8ba09353..ad7d0418 100644 --- a/tests/functional/transactions/transfer.py +++ b/tests/functional/transactions/transfer.py @@ -1,7 +1,7 @@ from typing import Union, List -from client.utils import write_varint, UINT64_MAX -from client.transaction import Transaction, TransactionError +from application_client.solar_utils import write_varint, UINT64_MAX +from application_client.solar_transaction import Transaction, TransactionError class Transfer(Transaction): diff --git a/tests/functional/transactions/vote.py b/tests/functional/transactions/vote.py index ccfade64..4d33e5d7 100644 --- a/tests/functional/transactions/vote.py +++ b/tests/functional/transactions/vote.py @@ -1,7 +1,7 @@ from typing import Union, List -from client.utils import UINT16_MAX -from client.transaction import Transaction, TransactionError +from application_client.solar_utils import UINT16_MAX +from application_client.solar_transaction import Transaction, TransactionError class Vote(Transaction): diff --git a/tests/functional/utils.py b/tests/functional/utils.py new file mode 100644 index 00000000..040dc66f --- /dev/null +++ b/tests/functional/utils.py @@ -0,0 +1,28 @@ +from pathlib import Path +from hashlib import sha256 + +# from sha3 import keccak_256 + +from btclib.ecc import ssa + +from ecdsa.curves import SECP256k1 + +# from ecdsa.keys import VerifyingKey +# from ecdsa.util import sigdecode_der + + +ROOT_SCREENSHOT_PATH = Path(__file__).parent.resolve() + + +# Check if a signature of a given message is valid +def check_signature_validity( + public_key: bytes, signature: bytes, message: bytes +) -> bool: + ssa.verify(message1.encode("ascii"), context["pkey"][1:], schnorr_sig) is True + + pk: VerifyingKey = VerifyingKey.from_string( + public_key, curve=SECP256k1, hashfunc=sha256 + ) + return pk.verify( + signature=signature, data=message, hashfunc=sha256, sigdecode=sigdecode_der + ) diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt index 670ef02b..d48b767d 100644 --- a/tests/unit-tests/CMakeLists.txt +++ b/tests/unit-tests/CMakeLists.txt @@ -7,7 +7,7 @@ endif() # project information project(unit_tests VERSION 0.1 - DESCRIPTION "Unit tests for Ledger Nano application" + DESCRIPTION "Unit tests for Ledger Nano application" LANGUAGES C) @@ -35,47 +35,38 @@ endif() add_compile_definitions(TEST) -add_definitions(-DNANO_PXLS_PER_LINE=114 -DIS_NANOS=1) +if(TARGET_NAME STREQUAL "TARGET_NANOS") + add_definitions(-DTARGET_NANOS=1) +endif() include_directories(../../src) -add_executable(test_base58 test_base58.c) -add_executable(test_bip32 test_bip32.c) -add_executable(test_buffer test_buffer.c) -add_executable(test_format test_format.c) -add_executable(test_write test_write.c) -add_executable(test_apdu_parser test_apdu_parser.c) add_executable(test_tx_parser test_tx_parser.c) add_executable(test_tx_utils test_tx_utils.c) add_library(nano_char_table nano_char_table.c) - -add_library(base58 SHARED ../../src/common/base58.c) -add_library(bip32 SHARED ../../src/common/bip32.c) -add_library(buffer SHARED ../../src/common/buffer.c) -add_library(read SHARED ../../src/common/read.c) -add_library(write SHARED ../../src/common/write.c) -add_library(format SHARED ../../src/common/format.c) -add_library(varint SHARED ../../src/common/varint.c) -add_library(apdu_parser SHARED ../../src/apdu/parser.c) +include_directories( + $ENV{BOLOS_SDK}/include + $ENV{BOLOS_SDK}/lib_standard_app +) + +add_library(base58 SHARED $ENV{BOLOS_SDK}/lib_standard_app/base58.c) +add_library(bip32 SHARED $ENV{BOLOS_SDK}/lib_standard_app/bip32.c) +add_library(buffer SHARED $ENV{BOLOS_SDK}/lib_standard_app/buffer.c) +add_library(read SHARED $ENV{BOLOS_SDK}/lib_standard_app/read.c) +add_library(write SHARED $ENV{BOLOS_SDK}/lib_standard_app/write.c) +add_library(format SHARED $ENV{BOLOS_SDK}/lib_standard_app/format.c) +add_library(varint SHARED $ENV{BOLOS_SDK}/lib_standard_app/varint.c) +add_library(apdu_parser SHARED $ENV{BOLOS_SDK}/lib_standard_app/parser.c) add_library(transaction_deserialise ../../src/transaction/deserialise.c) -add_library(transaction_utils ../../src/transaction/utils.c) -add_library(transaction_types_multi_signature_registration ../../src/transaction/types/multi_signature_registration.c) +add_library(transaction_utils ../../src/transaction/transaction_utils.c ../../src/ui/ui_utils.c) add_library(transaction_types_ipfs ../../src/transaction/types/ipfs.c) add_library(transaction_types_transfer ../../src/transaction/types/transfer.c) -add_library(transaction_types_htlc_lock ../../src/transaction/types/htlc_lock.c) -add_library(transaction_types_htlc_refund ../../src/transaction/types/htlc_refund.c) -add_library(transaction_types_htlc_claim ../../src/transaction/types/htlc_claim.c) add_library(transaction_types_burn ../../src/transaction/types/burn.c) add_library(transaction_types_vote ../../src/transaction/types/vote.c) +target_link_libraries(transaction_utils PUBLIC cmocka gcov format nano_char_table) -target_link_libraries(test_base58 PUBLIC cmocka gcov base58) -target_link_libraries(test_bip32 PUBLIC cmocka gcov bip32 read) -target_link_libraries(test_buffer PUBLIC cmocka gcov buffer bip32 varint write read) -target_link_libraries(test_format PUBLIC cmocka gcov format nano_char_table) -target_link_libraries(test_write PUBLIC cmocka gcov write) -target_link_libraries(test_apdu_parser PUBLIC cmocka gcov apdu_parser) target_link_libraries(test_tx_parser PUBLIC transaction_deserialise buffer @@ -85,25 +76,15 @@ target_link_libraries(test_tx_parser PUBLIC gcov write read - transaction_types_burn - transaction_types_htlc_claim - transaction_types_htlc_lock - transaction_types_htlc_refund transaction_types_ipfs - transaction_types_multi_signature_registration transaction_types_transfer transaction_types_vote + transaction_types_burn transaction_utils) target_link_libraries(test_tx_utils PUBLIC cmocka gcov transaction_utils) -add_test(test_base58 test_base58) -add_test(test_bip32 test_bip32) -add_test(test_buffer test_buffer) -add_test(test_format test_format) -add_test(test_write test_write) -add_test(test_apdu_parser test_apdu_parser) add_test(test_tx_parser test_tx_parser) add_test(test_tx_utils test_tx_utils) diff --git a/tests/unit-tests/README.md b/tests/unit-tests/README.md index ef41ce48..f41d4dd2 100644 --- a/tests/unit-tests/README.md +++ b/tests/unit-tests/README.md @@ -27,7 +27,7 @@ CTEST_OUTPUT_ON_FAILURE=1 make -C build test ## Generate code coverage -Just execute in `tests/unit-tests` folder +Just execute in `unit-tests` folder ``` ./gen_coverage.sh diff --git a/tests/unit-tests/test_apdu_parser.c b/tests/unit-tests/test_apdu_parser.c deleted file mode 100644 index 555ede41..00000000 --- a/tests/unit-tests/test_apdu_parser.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#include "types.h" -#include "apdu/parser.h" - -static void test_apdu_parser(void **state) { - (void) state; - uint8_t apdu_bad_min_len[] = {0xE0, 0xB2, 0x00, 0x00}; // less than 5 bytes - uint8_t apdu_bad_lc[] = {0xE0, 0xB2, 0x00, 0x00, 0x01}; // Lc = 1 but no data - uint8_t apdu[] = {0xE0, 0xB2, 0x01, 0x02, 0x05, 0x00, 0x01, 0x02, 0x03, 0x04}; - - command_t cmd; - - memset(&cmd, 0, sizeof(cmd)); - assert_false(apdu_parser(&cmd, apdu_bad_min_len, sizeof(apdu_bad_min_len))); - - memset(&cmd, 0, sizeof(cmd)); - assert_false(apdu_parser(&cmd, apdu_bad_lc, sizeof(apdu_bad_min_len))); - - memset(&cmd, 0, sizeof(cmd)); - assert_true(apdu_parser(&cmd, apdu, sizeof(apdu))); - assert_int_equal(cmd.cla, 0xE0); - assert_int_equal(cmd.ins, 0xB2); - assert_int_equal(cmd.p1, 0x01); - assert_int_equal(cmd.p2, 0x02); - assert_int_equal(cmd.lc, 5); - assert_memory_equal(cmd.data, ((uint8_t[]){0x00, 0x01, 0x02, 0x03, 0x04}), cmd.lc); -} - -int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_apdu_parser)}; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/tests/unit-tests/test_base58.c b/tests/unit-tests/test_base58.c deleted file mode 100644 index f7f5e457..00000000 --- a/tests/unit-tests/test_base58.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#include "common/base58.h" - -static void test_base58(void **state) { - (void) state; - - const char in[] = "USm3fpXnKG5EUBx2ndxBDMPVciP5hGey2Jh4NDv6gmeo1LkMeiKrLJUUBk6Z"; - const char expected_out[] = "The quick brown fox jumps over the lazy dog."; - uint8_t out[100] = {0}; - int out_len = base58_decode(in, sizeof(in) - 1, out, sizeof(out)); - assert_int_equal(out_len, strlen(expected_out)); - assert_string_equal((char *) out, expected_out); - - const char in2[] = "The quick brown fox jumps over the lazy dog."; - const char expected_out2[] = "USm3fpXnKG5EUBx2ndxBDMPVciP5hGey2Jh4NDv6gmeo1LkMeiKrLJUUBk6Z"; - char out2[100] = {0}; - int out_len2 = base58_encode((uint8_t *) in2, sizeof(in2) - 1, out2, sizeof(out2)); - assert_int_equal(out_len2, strlen(expected_out2)); - assert_string_equal((char *) out2, expected_out2); -} - -int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_base58)}; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/tests/unit-tests/test_bip32.c b/tests/unit-tests/test_bip32.c deleted file mode 100644 index f71383b0..00000000 --- a/tests/unit-tests/test_bip32.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include "common/bip32.h" - -static void test_bip32_format(void **state) { - (void) state; - - char output[30]; - bool b = false; - - b = bip32_path_format((const uint32_t[5]){0x8000002C, 0x80000000, 0x80000000, 0, 0}, - 5, - output, - sizeof(output)); - assert_true(b); - assert_string_equal(output, "44'/0'/0'/0/0"); - - b = bip32_path_format((const uint32_t[5]){0x8000002C, 0x80000001, 0x80000000, 0, 0}, - 5, - output, - sizeof(output)); - assert_true(b); - assert_string_equal(output, "44'/1'/0'/0/0"); -} - -static void test_bad_bip32_format(void **state) { - (void) state; - - char output[30]; - bool b = true; - - // More than MAX_BIP32_PATH (=10) - b = bip32_path_format( - (const uint32_t[11]){0x8000002C, 0x80000000, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0}, - 11, - output, - sizeof(output)); - assert_false(b); - - // No BIP32 path (=0) - b = bip32_path_format(NULL, 0, output, sizeof(output)); - assert_false(b); -} - -static void test_bip32_read(void **state) { - (void) state; - - // clang-format off - uint8_t input[20] = { - 0x80, 0x00, 0x00, 0x2C, - 0x80, 0x00, 0x00, 0x01, - 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - uint32_t expected[5] = {0x8000002C, 0x80000001, 0x80000000, 0, 0}; - uint32_t output[5] = {0}; - bool b = false; - - b = bip32_path_read(input, sizeof(input), output, 5); - assert_true(b); - assert_memory_equal(output, expected, 5); -} - -static void test_bad_bip32_read(void **state) { - (void) state; - - // clang-format off - uint8_t input[20] = { - 0x80, 0x00, 0x00, 0x2C, - 0x80, 0x00, 0x00, 0x01, - 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - }; - uint32_t output[10] = {0}; - - // buffer too small (5 BIP32 paths instead of 10) - assert_false(bip32_path_read(input, sizeof(input), output, 10)); - - // No BIP32 path - assert_false(bip32_path_read(input, sizeof(input), output, 0)); - - // More than MAX_BIP32_PATH (=10) - assert_false(bip32_path_read(input, sizeof(input), output, 20)); -} - -int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_bip32_format), - cmocka_unit_test(test_bad_bip32_format), - cmocka_unit_test(test_bip32_read), - cmocka_unit_test(test_bad_bip32_read)}; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/tests/unit-tests/test_buffer.c b/tests/unit-tests/test_buffer.c deleted file mode 100644 index e2d1efa5..00000000 --- a/tests/unit-tests/test_buffer.c +++ /dev/null @@ -1,155 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include "common/buffer.h" - -static void test_buffer_can_read(void **state) { - (void) state; - - uint8_t temp[20] = {0}; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - assert_true(buffer_can_read(&buf, 20)); - - assert_true(buffer_seek_cur(&buf, 20)); - assert_false(buffer_can_read(&buf, 1)); -} - -static void test_buffer_seek(void **state) { - (void) state; - - uint8_t temp[20] = {0}; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - assert_true(buffer_can_read(&buf, 20)); - - assert_true(buffer_seek_cur(&buf, 20)); // seek at offset 20 - assert_false(buffer_can_read(&buf, 1)); // can't read 1 byte - assert_false(buffer_seek_cur(&buf, 1)); // can't move at offset 21 - - assert_true(buffer_seek_end(&buf, 19)); - assert_int_equal(buf.offset, 1); - assert_false(buffer_seek_end(&buf, 21)); // can't seek at offset -1 - - assert_true(buffer_seek_set(&buf, 10)); - assert_int_equal(buf.offset, 10); - assert_false(buffer_seek_set(&buf, 21)); // can't seek at offset 21 -} - -static void test_buffer_read(void **state) { - (void) state; - - // clang-format off - uint8_t temp[15] = { - 0xFF, - 0x01, 0x02, - 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E - }; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - uint8_t first = 0; - assert_true(buffer_read_u8(&buf, &first)); - assert_int_equal(first, 255); // 0xFF - assert_true(buffer_seek_end(&buf, 0)); // seek at offset 19 - assert_false(buffer_read_u8(&buf, &first)); // can't read 1 byte - - uint16_t second = 0; - assert_true(buffer_seek_set(&buf, 1)); // set back to offset 1 - assert_true(buffer_read_u16(&buf, &second, BE)); // big endian - assert_int_equal(second, 258); // 0x01 0x02 - assert_true(buffer_seek_set(&buf, 1)); // set back to offset 1 - assert_true(buffer_read_u16(&buf, &second, LE)); // little endian - assert_int_equal(second, 513); // 0x02 0x01 - assert_true(buffer_seek_set(&buf, 14)); // seek at offset 14 - assert_false(buffer_read_u16(&buf, &second, BE)); // can't read 2 bytes - - uint32_t third = 0; - assert_true(buffer_seek_set(&buf, 3)); // set back to offset 3 - assert_true(buffer_read_u32(&buf, &third, BE)); // big endian - assert_int_equal(third, 50595078); // 0x03 0x04 0x05 0x06 - assert_true(buffer_seek_set(&buf, 3)); // set back to offset 3 - assert_true(buffer_read_u32(&buf, &third, LE)); // little endian - assert_int_equal(third, 100992003); // 0x06 0x05 0x04 0x03 - assert_true(buffer_seek_set(&buf, 12)); // seek at offset 12 - assert_false(buffer_read_u32(&buf, &third, BE)); // can't read 4 bytes - - uint64_t fourth = 0; - assert_true(buffer_seek_set(&buf, 7)); // set back to offset 7 - assert_true(buffer_read_u64(&buf, &fourth, BE)); // big endian - assert_int_equal(fourth, 506664896818842894); // 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E - assert_true(buffer_seek_set(&buf, 7)); // set back to offset 7 - assert_true(buffer_read_u64(&buf, &fourth, LE)); // little endian - assert_int_equal(fourth, 1012478732780767239); // 0x0E 0x0D 0x0C 0x0B 0x0A 0x09 0x08 0x07 - assert_true(buffer_seek_set(&buf, 8)); // seek at offset 8 - assert_false(buffer_read_u64(&buf, &fourth, BE)); // can't read 8 bytes - - // clang-format off - uint8_t temp_varint[] = { - 0xFC, // 1 byte varint - 0xFD, 0x00, 0x01, // 2 bytes varint - 0xFE, 0x00, 0x01, 0x02, 0x03, // 4 bytes varint - 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 // 8 bytes varint - - }; - buffer_t buf_varint = {.ptr = temp_varint, .size = sizeof(temp_varint), .offset = 0}; - uint64_t varint = 0; - assert_true(buffer_read_varint(&buf_varint, &varint)); - assert_int_equal(varint, 0xFC); - assert_true(buffer_read_varint(&buf_varint, &varint)); - assert_int_equal(varint, 0x0100); - assert_true(buffer_read_varint(&buf_varint, &varint)); - assert_int_equal(varint, 0x03020100); - assert_true(buffer_read_varint(&buf_varint, &varint)); - assert_int_equal(varint, 0x0706050403020100); - assert_false(buffer_read_varint(&buf_varint, &varint)); -} - -static void test_buffer_copy(void **state) { - (void) state; - - uint8_t output[5] = {0}; - uint8_t temp[5] = {0x01, 0x02, 0x03, 0x04, 0x05}; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - assert_true(buffer_copy(&buf, output, sizeof(output))); - assert_memory_equal(output, temp, sizeof(output)); - - uint8_t output2[3] = {0}; - assert_true(buffer_seek_set(&buf, 2)); - assert_true(buffer_copy(&buf, output2, sizeof(output2))); - assert_memory_equal(output2, ((uint8_t[3]){0x03, 0x04, 0x05}), 3); - assert_true(buffer_seek_set(&buf, 0)); // seek at offset 0 - assert_false(buffer_copy(&buf, output2, sizeof(output2))); // can't read 5 bytes -} - -static void test_buffer_move(void **state) { - (void) state; - - uint8_t output[5] = {0}; - uint8_t temp[5] = {0x01, 0x02, 0x03, 0x04, 0x05}; - buffer_t buf = {.ptr = temp, .size = sizeof(temp), .offset = 0}; - - assert_true(buffer_move(&buf, output, sizeof(output))); - assert_memory_equal(output, temp, sizeof(output)); - assert_int_equal(buf.offset, sizeof(output)); - - uint8_t output2[3] = {0}; - assert_true(buffer_seek_set(&buf, 0)); // seek at offset 0 - assert_false(buffer_move(&buf, output2, sizeof(output2))); // can't read 5 bytes -} - -int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_buffer_can_read), - cmocka_unit_test(test_buffer_seek), - cmocka_unit_test(test_buffer_read), - cmocka_unit_test(test_buffer_copy), - cmocka_unit_test(test_buffer_move)}; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/tests/unit-tests/test_format.c b/tests/unit-tests/test_format.c deleted file mode 100644 index f41ac27a..00000000 --- a/tests/unit-tests/test_format.c +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#include "common/format.h" - -static void test_format_i64(void **state) { - (void) state; - - char temp[22] = {0}; - - int64_t value = 0; - assert_true(format_i64(temp, sizeof(temp), value)); - assert_string_equal(temp, "0"); - - value = (int64_t) 9223372036854775807ull; // MAX_INT64 - memset(temp, 0, sizeof(temp)); - assert_true(format_i64(temp, sizeof(temp), value)); - assert_string_equal(temp, "9223372036854775807"); - - // buffer too small - assert_false(format_i64(temp, sizeof(temp) - 5, value)); - - value = (int64_t) -9223372036854775808ull; // MIN_INT64 - memset(temp, 0, sizeof(temp)); - assert_true(format_i64(temp, sizeof(temp), value)); - assert_string_equal(temp, "-9223372036854775808"); -} - -static void test_format_u64(void **state) { - (void) state; - - char temp[21] = {0}; - - uint64_t value = 0; - assert_true(format_u64(temp, sizeof(temp), value)); - assert_string_equal(temp, "0"); - - value = (uint64_t) 18446744073709551615ull; // MAX_UNT64 - memset(temp, 0, sizeof(temp)); - assert_true(format_u64(temp, sizeof(temp), value)); - assert_string_equal(temp, "18446744073709551615"); - - // buffer too small - assert_false(format_u64(temp, sizeof(temp) - 5, value)); -} - -static void test_format_fpu64(void **state) { - (void) state; - - char temp[22] = {0}; - - uint64_t amount = 100000000ull; - memset(temp, 0, sizeof(temp)); - assert_true(format_fpu64(temp, sizeof(temp), amount, 8)); - assert_string_equal(temp, "1.00000000"); - - amount = 24964823ull; - memset(temp, 0, sizeof(temp)); - assert_true(format_fpu64(temp, sizeof(temp), amount, 8)); - assert_string_equal(temp, "0.24964823"); - - amount = 100ull; - memset(temp, 0, sizeof(temp)); - assert_true(format_fpu64(temp, sizeof(temp), amount, 8)); - assert_string_equal(temp, "0.00000100"); - - amount = 10000000000000000000ull; - assert_true(format_fpu64(temp, sizeof(temp), amount, 8)); - assert_string_equal(temp, "100000000000.00000000"); - - // buffer too small - assert_false(format_fpu64(temp, sizeof(temp) - 1, amount, 8)); -} - -static void test_format_amount(void **state) { - (void) state; - - char temp[22 + 5] = {0}; - - uint64_t amount = 100000000ull; - memset(temp, 0, sizeof(temp)); - assert_true(format_amount(temp, sizeof(temp), amount, 8, "SXP", 3)); - - assert_string_equal(temp, "1.00 SXP"); - - amount = 24964823ull; - memset(temp, 0, sizeof(temp)); - assert_true(format_amount(temp, sizeof(temp), amount, 8, "SXP", 3)); - assert_string_equal(temp, "0.24964823 SXP"); - - amount = 100ull; - memset(temp, 0, sizeof(temp)); - assert_true(format_amount(temp, sizeof(temp), amount, 8, "SXP", 3)); - assert_string_equal(temp, "0.000001 SXP"); - - amount = 10000000000000000000ull; - assert_true(format_amount(temp, sizeof(temp), amount, 8, "SXP", 3)); - assert_string_equal(temp, "100000000000.00 SXP"); - - // buffer too small - assert_false(format_amount(temp, sizeof(temp) - 1, amount, 8, "SXP", 3)); -} - -static void test_format_percentage(void **state) { - (void) state; - - char temp[9] = {0}; - - uint16_t amount = 10000ull; - memset(temp, 0, sizeof(temp)); - assert_true(format_percentage(temp, sizeof(temp), amount, 2)); - assert_string_equal(temp, "100.00%"); - - amount = 0ull; - memset(temp, 0, sizeof(temp)); - assert_true(format_percentage(temp, sizeof(temp), amount, 2)); - assert_string_equal(temp, "0.00%"); - - amount = 1234ull; - memset(temp, 0, sizeof(temp)); - assert_true(format_percentage(temp, sizeof(temp), amount, 2)); - assert_string_equal(temp, "12.34%"); - - amount = 22ull; - assert_true(format_percentage(temp, sizeof(temp), amount, 2)); - assert_string_equal(temp, "0.22%"); - - // buffer too small - amount = 100ull; - assert_false(format_percentage(temp, sizeof(temp) - 1, amount, 2)); -} - -static void test_format_hex(void **state) { - (void) state; - - uint8_t public_key[] = {0x03, 0xd3, 0x9f, 0xb4, 0x79, 0x7d, 0x0c, 0x42, 0x8b, 0xeb, 0xed, - 0x6d, 0x80, 0x20, 0x3e, 0x22, 0x73, 0xa9, 0xfd, 0xbc, 0xaa, 0xfe, - 0x0b, 0x29, 0x76, 0x1e, 0xf3, 0x18, 0x3c, 0x21, 0x51, 0xe2, 0x11}; - char output[2 * sizeof(public_key) + 1] = {0}; - - assert_int_equal(2 * sizeof(public_key) + 1, - format_hex(public_key, sizeof(public_key), output, sizeof(output))); - assert_string_equal(output, - "03d39fb4797d0c428bebed6d80203e2273a9fdbcaafe0b29761ef3183c2151e211"); - assert_int_equal(-1, format_hex(public_key, sizeof(public_key), output, sizeof(public_key))); -} - -int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_format_i64), - cmocka_unit_test(test_format_u64), - cmocka_unit_test(test_format_fpu64), - cmocka_unit_test(test_format_hex), - cmocka_unit_test(test_format_amount), - cmocka_unit_test(test_format_percentage)}; - - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/tests/unit-tests/test_tx_parser.c b/tests/unit-tests/test_tx_parser.c index 52f77f8f..89cb8aa3 100644 --- a/tests/unit-tests/test_tx_parser.c +++ b/tests/unit-tests/test_tx_parser.c @@ -421,14 +421,14 @@ static void test_tx_vote_serialization(void **state) { 0x02, // length username 1 (1) 0x0a, - // delegate username 1 + // bp username 1 0x63, 0x61, 0x63, 0x74, 0x75, 0x73, 0x31, 0x35, 0x34, 0x39, // percentage 1 (2) 0x88, 0x13, // length username 2 (1) 0x03, - // delegate username 2 + // bp username 2 0x66, 0x75, 0x6E, // percentage 2 (2) 0x88, 0x13 @@ -451,14 +451,14 @@ static void test_tx_vote_serialization(void **state) { 0x03, // length username 1 (1) 0x0a, - // delegate username 1 + // bp username 1 0x63, 0x61, 0x63, 0x74, 0x75, 0x73, 0x31, 0x35, 0x34, 0x39, // percentage 1 (2) 0x88, 0x13, // length username 2 (1) 0x03, - // delegate username 2 + // bp username 2 0x66, 0x75, 0x6E, // percentage 2 (2) 0x88, 0x13 @@ -469,14 +469,14 @@ static void test_tx_vote_serialization(void **state) { 0x01, // length username 1 (1) 0x0a, - // delegate username 1 + // bp username 1 0x63, 0x61, 0x63, 0x74, 0x75, 0x73, 0x31, 0x35, 0x34, 0x39, // percentage 1 (2) 0x10, 0x27, // length username 2 (1) 0x03, - // delegate username 2 + // bp username 2 0x66, 0x75, 0x6E, // percentage 2 (2) 0x88, 0x13 @@ -487,7 +487,7 @@ static void test_tx_vote_serialization(void **state) { 0x01, // length username 1 (1) 0x15, - // delegate username 1 + // bp username 1 0x63, 0x61, 0x63, 0x74, 0x75, 0x73, 0x31, 0x35, 0x34, 0x39, 0x63, 0x61, 0x63, 0x74, 0x75, 0x73, 0x31, 0x35, 0x34, 0x39, 0x63, @@ -500,7 +500,7 @@ static void test_tx_vote_serialization(void **state) { 0x01, // length username 1 (1) 0x0b, - // delegate username 1 + // bp username 1 0x63, 0x61, 0x63, 0x74, 0x75, 0x73, 0x31, 0x35, 0x34, 0x39, // percentage 1 (2) @@ -512,7 +512,7 @@ static void test_tx_vote_serialization(void **state) { 0x01, // length username 1 (1) 0x0a, - // delegate username 1 + // bp username 1 0x63, 0x61, 0x63, 0x74, 0x75, 0x73, 0x31, 0x35, 0x34, 0x0a, // percentage 1 (2) @@ -524,14 +524,14 @@ static void test_tx_vote_serialization(void **state) { 0x02, // length username 1 (1) 0x0a, - // delegate username 1 + // bp username 1 0x63, 0x61, 0x63, 0x74, 0x75, 0x73, 0x31, 0x35, 0x34, 0x39, // percentage 1 (2) 0x88, 0x13, // length username 2 (1) 0x03, - // delegate username 2 + // bp username 2 0x66, 0x75, 0x6E, // percentage 2 (2) 0x88, 0x12 @@ -542,14 +542,14 @@ static void test_tx_vote_serialization(void **state) { 0x02, // length username 1 (1) 0x0a, - // delegate username 1 + // bp username 1 0x63, 0x61, 0x63, 0x74, 0x75, 0x73, 0x31, 0x35, 0x34, 0x39, // percentage 1 (2) 0x00, 0x00, // length username 2 (1) 0x03, - // delegate username 2 + // bp username 2 0x66, 0x75, 0x6E, // percentage 2 (2) 0x10, 0x27 @@ -636,174 +636,6 @@ static void test_tx_vote_serialization(void **state) { } -static void test_tx_multisignature_serialization(void **state) { - (void) state; - - transaction_asset_t tx; - // clang-format off - uint8_t core_asset[] = { - // Minimum (1) - 0x02, - // count (1) - 0x04, - // PublicKey 1 (33) - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, - 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, - 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26, - // PublicKey 2 (33) - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, - 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, - 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26, - // PublicKey 3 (33) - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, - 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, - 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26, - // PublicKey 4 (33) - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, - 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, - 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26 - }; - - uint8_t *pkeys_ptr = (uint8_t *) core_asset + 2; - - uint8_t zero_count[] = { - // Minimum (1) - 0x02, - // count (1) - 0x00 - }; - - uint8_t exceed_maximum[] = { - // Minimum (1) - 0x02, - // count (1) - 0x11, - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, - 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, - 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, - 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, - 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, - 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, - 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, - 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, - 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, - 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, - 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, - 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, - 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, - 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, - 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, - 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, - 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, - 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, - 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, - 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, - 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, 0xf9, - 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, 0x7a, - 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, 0x06, - 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, 0x3f, - 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, 0xa0, - 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, 0x25, - 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, 0x4d, - 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, 0x37, - 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, 0x03, - 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, 0x22, - 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, 0x26, - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26 - }; - - uint8_t wrong_count1[] = { - // Minimum (1) - 0x02, - // count (1) - 0x02, - // PublicKey 1 (33) - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, - 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, - 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26 - }; - - uint8_t wrong_count2[] = { - // Minimum (1) - 0x02, - // count (1) - 0x02, - // PublicKey 1 (33) - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, - 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, - 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26, - // PublicKey 2 (33) - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, - 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, - 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26, - // PublicKey 3 (33) - 0x03, 0x4d, 0xa0, 0x06, 0xf9, 0x58, 0xbe, 0xba, - 0x78, 0xec, 0x54, 0x44, 0x3d, 0xf4, 0xa3, 0xf5, - 0x22, 0x37, 0x25, 0x3f, 0x7a, 0xe8, 0xcb, 0xdb, - 0x17, 0xdc, 0xcf, 0x3f, 0xea, 0xa5, 0x7f, 0x31, - 0x26 - }; - - for (uint16_t i = 0; i < sizeof(core_asset); i++) { - buffer_t buf = {.ptr = core_asset, .size = i, .offset = 0}; - parser_status_e status = transaction_deserialise_core_asset(&buf, &tx, 4, 1); - - assert_int_equal(status, WRONG_LENGTH_ERROR); - } - - buffer_t buf1 = {.ptr = core_asset, .size = sizeof(core_asset), .offset = 0}; - buffer_t buf2 = {.ptr = zero_count, .size = sizeof(zero_count), .offset = 0}; - buffer_t buf3 = {.ptr = exceed_maximum, .size = sizeof(exceed_maximum), .offset = 0}; - buffer_t buf4 = {.ptr = wrong_count1, .size = sizeof(wrong_count1), .offset = 0}; - buffer_t buf5 = {.ptr = wrong_count2, .size = sizeof(wrong_count2), .offset = 0}; - - parser_status_e status = transaction_deserialise_core_asset(&buf1, &tx, 4, 1); - - assert_int_equal(status, PARSING_OK); - assert_int_equal(tx.Multisignature.min, 0x2); - assert_int_equal(tx.Multisignature.pkey_length, 0x4); - assert_ptr_equal(tx.Multisignature.pkeys, pkeys_ptr); - - memset(&status, 0, sizeof(status)); - - status = transaction_deserialise_core_asset(&buf2, &tx, 4, 1); - - assert_int_equal(status, CORE_ASSET_PARSING_ERROR); - memset(&status, 0, sizeof(status)); - - status = transaction_deserialise_core_asset(&buf3, &tx, 4, 1); - - assert_int_equal(status, CORE_ASSET_PARSING_ERROR); - memset(&status, 0, sizeof(status)); - - status = transaction_deserialise_core_asset(&buf4, &tx, 4, 1); - - assert_int_equal(status, WRONG_LENGTH_ERROR); - memset(&status, 0, sizeof(status)); - - status = transaction_deserialise_core_asset(&buf5, &tx, 4, 1); - - assert_int_equal(status, WRONG_LENGTH_ERROR); -} - static void test_tx_ipfs_serialization(void **state) { (void) state; @@ -1113,233 +945,6 @@ static void test_tx_transfer_serialization(void **state) { } -static void test_tx_htlc_lock_serialization(void **state) { - (void) state; - - transaction_asset_t tx; - // clang-format off - uint8_t core_asset[] = { - // amount (8) - 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // hash length (2) - 0x20, - // Secret hash (32) - 0x0d, 0x36, 0xcc, 0x85, 0x68, 0x98, 0x30, 0xa1, - 0xe2, 0xb0, 0x97, 0xb1, 0xf7, 0x0a, 0xbd, 0x21, - 0x1a, 0x11, 0x47, 0xd8, 0xc2, 0xe0, 0x50, 0x34, - 0x04, 0xfd, 0xbd, 0x13, 0xac, 0x4c, 0x00, 0x0e, - // Expiration type (1) - 0x01, - // Expiration Value (4) - 0x01, 0x00, 0x00, 0x00, - // RecipientId (21) - 0x3f, 0xc9, 0x13, 0x27, 0xb9, 0x17, 0xbf, 0x2b, - 0x46, 0x4e, 0x9b, 0x8f, 0x1a, 0xcf, 0x05, 0x88, - 0xf4, 0xcb, 0x6e, 0x7b, 0xb3 - }; - - uint8_t *secret_ptr = (uint8_t *) core_asset + 9; - uint8_t *recipient_ptr = (uint8_t *) core_asset + 46; - - uint8_t hash_length_over_max[] = { - // amount (8) - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // hash length (2) - 0xff - }; - - uint8_t wrong_hash_length[] = { - // amount (8) - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // hash length (2) - 0x21, - // Secret hash (32) - 0x0d, 0x36, 0xcc, 0x85, 0x68, 0x98, 0x30, 0xa1, - 0xe2, 0xb0, 0x97, 0xb1, 0xf7, 0x0a, 0xbd, 0x21, - 0x1a, 0x11, 0x47, 0xd8, 0xc2, 0xe0, 0x50, 0x34, - 0x04, 0xfd, 0xbd, 0x13, 0xac, 0x4c, 0x00, 0x0e, - // Expiration type (1) - 0x01, - // Expiration Value (4) - 0x01, 0x00, 0x00, 0x00, - // RecipientId (21) - 0x3f, 0xc9, 0x13, 0x27, 0xb9, 0x17, 0xbf, 0x2b, - 0x46, 0x4e, 0x9b, 0x8f, 0x1a, 0xcf, 0x05, 0x88, - 0xf4, 0xcb, 0x6e, 0x7b, 0xb3 - }; - - for (uint16_t i = 0; i < sizeof(core_asset); i++) { - buffer_t buf = {.ptr = core_asset, .size = i, .offset = 0}; - parser_status_e status = transaction_deserialise_core_asset(&buf, &tx, 8, 1); - - assert_int_equal(status, WRONG_LENGTH_ERROR); - } - - buffer_t buf1 = {.ptr = core_asset, .size = sizeof(core_asset), .offset = 0}; - buffer_t buf2 = {.ptr = hash_length_over_max, .size = sizeof(hash_length_over_max), .offset = 0}; - buffer_t buf3 = {.ptr = wrong_hash_length, .size = sizeof(wrong_hash_length), .offset = 0}; - - parser_status_e status = transaction_deserialise_core_asset(&buf1, &tx, 8, 1); - - assert_int_equal(status, PARSING_OK); - assert_int_equal(tx.Htlc_lock.amount, 0x501); - assert_int_equal(tx.Htlc_lock.secret_hash_length, 0x20); - assert_int_equal(tx.Htlc_lock.expiration_type, 0x1); - assert_int_equal(tx.Htlc_lock.expiration_value, 0x1); - assert_ptr_equal(tx.Htlc_lock.secret_hash, secret_ptr); - assert_ptr_equal(tx.Htlc_lock.recipientId, recipient_ptr); - - memset(&status, 0, sizeof(status)); - - status = transaction_deserialise_core_asset(&buf2, &tx, 8, 1); - - assert_int_equal(status, CORE_ASSET_PARSING_ERROR); - - memset(&status, 0, sizeof(status)); - - status = transaction_deserialise_core_asset(&buf3, &tx, 8, 1); - - assert_int_equal(status, WRONG_LENGTH_ERROR); - -} - -static void test_tx_htlc_claim_serialization(void **state) { - (void) state; - - transaction_asset_t tx; - // clang-format off - uint8_t core_asset[] = { - // hash type (1) - 0x00, - // lock transaction id (32) - 0x0d, 0x36, 0xcc, 0x85, 0x68, 0x98, 0x30, 0xa1, - 0xe2, 0xb0, 0x97, 0xb1, 0xf7, 0x0a, 0xbd, 0x21, - 0x1a, 0x11, 0x47, 0xd8, 0xc2, 0xe0, 0x50, 0x34, - 0x04, 0xfd, 0xbd, 0x13, 0xac, 0x4c, 0x00, 0x0e, - // hash length (2) - 0x21, - // Secret Hash (32) - 0x84, 0x51, 0xf7, 0x7c, 0x4e, 0x77, 0x3c, 0x1f, - 0xf3, 0xb0, 0x15, 0xb9, 0x92, 0x47, 0x4d, 0x70, - 0x28, 0x97, 0xd4, 0xac, 0x2a, 0x35, 0x9d, 0x85, - 0x8a, 0xa4, 0xd8, 0xbe, 0x20, 0x27, 0xc1, 0x5a, - 0x5a - - }; - - uint8_t *lockid_ptr = (uint8_t *) core_asset + 1; - uint8_t *secret_ptr = (uint8_t *) core_asset + 34; - - uint8_t hash_length_over_max[] = { - // hash type (1) - 0x00, - // lock transaction id (32) - 0x0d, 0x36, 0xcc, 0x85, 0x68, 0x98, 0x30, 0xa1, - 0xe2, 0xb0, 0x97, 0xb1, 0xf7, 0x0a, 0xbd, 0x21, - 0x1a, 0x11, 0x47, 0xd8, 0xc2, 0xe0, 0x50, 0x34, - 0x04, 0xfd, 0xbd, 0x13, 0xac, 0x4c, 0x00, 0x0e, - // hash length (2) - 0xff - }; - - uint8_t wrong_hash_length[] = { - // hash type (1) - 0x00, - // lock transaction id (32) - 0x0d, 0x36, 0xcc, 0x85, 0x68, 0x98, 0x30, 0xa1, - 0xe2, 0xb0, 0x97, 0xb1, 0xf7, 0x0a, 0xbd, 0x21, - 0x1a, 0x11, 0x47, 0xd8, 0xc2, 0xe0, 0x50, 0x34, - 0x04, 0xfd, 0xbd, 0x13, 0xac, 0x4c, 0x00, 0x0e, - // hash length (2) - 0x21, - // Secret Hash (32) - 0x84, 0x51, 0xf7, 0x7c, 0x4e, 0x77, 0x3c, 0x1f, - 0xf3, 0xb0, 0x15, 0xb9, 0x92, 0x47, 0x4d, 0x70, - 0x28, 0x97, 0xd4, 0xac, 0x2a, 0x35, 0x9d, 0x85, - 0x8a, 0xa4, 0xd8, 0xbe, 0x20, 0x27, 0xc1, 0x5a - }; - - for (uint16_t i = 0; i < sizeof(core_asset); i++) { - buffer_t buf = {.ptr = core_asset, .size = i, .offset = 0}; - parser_status_e status = transaction_deserialise_core_asset(&buf, &tx, 9, 1); - - assert_int_equal(status, WRONG_LENGTH_ERROR); - } - - buffer_t buf1 = {.ptr = core_asset, .size = sizeof(core_asset), .offset = 0}; - buffer_t buf2 = {.ptr = hash_length_over_max, .size = sizeof(hash_length_over_max), .offset = 0}; - buffer_t buf3 = {.ptr = wrong_hash_length, .size = sizeof(wrong_hash_length), .offset = 0}; - - parser_status_e status = transaction_deserialise_core_asset(&buf1, &tx, 9, 1); - - assert_int_equal(status, PARSING_OK); - assert_int_equal(tx.Htlc_claim.hash_type, 0x0); - assert_int_equal(tx.Htlc_claim.unlock_secret_length, 0x21); - assert_ptr_equal(tx.Htlc_claim.lockId, lockid_ptr); - assert_ptr_equal(tx.Htlc_claim.unlock_secret, secret_ptr); - - memset(&status, 0, sizeof(status)); - - status = transaction_deserialise_core_asset(&buf2, &tx, 9, 1); - - assert_int_equal(status, CORE_ASSET_PARSING_ERROR); - - memset(&status, 0, sizeof(status)); - - status = transaction_deserialise_core_asset(&buf3, &tx, 9, 1); - - assert_int_equal(status, WRONG_LENGTH_ERROR); - -} - -static void test_tx_htlc_refund_serialization(void **state) { - (void) state; - - transaction_asset_t tx; - // clang-format off - uint8_t core_asset[] = { - // lock transaction id (32) - 0x0d, 0x36, 0xcc, 0x85, 0x68, 0x98, 0x30, 0xa1, - 0xe2, 0xb0, 0x97, 0xb1, 0xf7, 0x0a, 0xbd, 0x21, - 0x1a, 0x11, 0x47, 0xd8, 0xc2, 0xe0, 0x50, 0x34, - 0x04, 0xfd, 0xbd, 0x13, 0xac, 0x4c, 0x00, 0x0e - - }; - - uint8_t *lockid_ptr = (uint8_t *) core_asset; - - uint8_t missing_id_byte[] = { - // lock transaction id (32) - 0x0d, 0x36, 0xcc, 0x85, 0x68, 0x98, 0x30, 0xa1, - 0xe2, 0xb0, 0x97, 0xb1, 0xf7, 0x0a, 0xbd, 0x21, - 0x1a, 0x11, 0x47, 0xd8, 0xc2, 0xe0, 0x50, 0x34, - 0x04, 0xfd, 0xbd, 0x13, 0xac, 0x4c, 0x00, //0x0e - }; - - for (uint16_t i = 0; i < sizeof(core_asset); i++) { - buffer_t buf = {.ptr = core_asset, .size = i, .offset = 0}; - parser_status_e status = transaction_deserialise_core_asset(&buf, &tx, 10, 1); - - assert_int_equal(status, WRONG_LENGTH_ERROR); - } - - buffer_t buf1 = {.ptr = core_asset, .size = sizeof(core_asset), .offset = 0}; - buffer_t buf2 = {.ptr = missing_id_byte, .size = sizeof(missing_id_byte), .offset = 0}; - - parser_status_e status = transaction_deserialise_core_asset(&buf1, &tx, 10, 1); - - assert_int_equal(status, PARSING_OK); - assert_ptr_equal(tx.Htlc_refund.lockId, lockid_ptr); - - - memset(&status, 0, sizeof(status)); - - status = transaction_deserialise_core_asset(&buf2, &tx, 10, 1); - - assert_int_equal(status, WRONG_LENGTH_ERROR); - -} - static void test_tx_burn_serialization(void **state) { (void) state; @@ -1501,11 +1106,7 @@ int main() { cmocka_unit_test(test_tx_common_serialization), cmocka_unit_test(test_tx_transfer_serialization), cmocka_unit_test(test_tx_vote_serialization), - cmocka_unit_test(test_tx_multisignature_serialization), cmocka_unit_test(test_tx_ipfs_serialization), - cmocka_unit_test(test_tx_htlc_lock_serialization), - cmocka_unit_test(test_tx_htlc_claim_serialization), - cmocka_unit_test(test_tx_htlc_refund_serialization), cmocka_unit_test(test_tx_burn_serialization), cmocka_unit_test(test_wrong_type), cmocka_unit_test(test_wrong_typegroup), diff --git a/tests/unit-tests/test_tx_utils.c b/tests/unit-tests/test_tx_utils.c index ff3fe8ea..9f309df6 100644 --- a/tests/unit-tests/test_tx_utils.c +++ b/tests/unit-tests/test_tx_utils.c @@ -7,10 +7,70 @@ #include -#include "transaction/utils.h" +#include "format.h" + +#include "transaction/transaction_utils.h" #include "transaction/types.h" -static void test_tx_utils(void **state) { +static void test_tx_utils_format_amount(void **state) { + (void) state; + + char temp[23 + 5] = {0}; + + uint64_t amount = 100000000ull; + memset(temp, 0, sizeof(temp)); + assert_true(format_amount(temp, sizeof(temp), amount, 8, "SXP", 3)); + + assert_string_equal(temp, "1.00 SXP"); + + amount = 24964823ull; + memset(temp, 0, sizeof(temp)); + assert_true(format_amount(temp, sizeof(temp), amount, 8, "SXP", 3)); + assert_string_equal(temp, "0.24964823 SXP"); + + amount = 100ull; + memset(temp, 0, sizeof(temp)); + assert_true(format_amount(temp, sizeof(temp), amount, 8, "SXP", 3)); + assert_string_equal(temp, "0.000001 SXP"); + + amount = 10000000000000000000ull; + assert_true(format_amount(temp, sizeof(temp), amount, 8, "SXP", 3)); + assert_string_equal(temp, "100000000000.00 SXP"); + + // buffer too small + assert_false(format_amount(temp, sizeof(temp) - 2, amount, 8, "SXP", 3)); +} + +static void test_tx_utils_format_percentage(void **state) { + (void) state; + + char temp[9] = {0}; + + uint16_t amount = 10000ull; + memset(temp, 0, sizeof(temp)); + assert_true(format_percentage(temp, sizeof(temp), amount, 2)); + assert_string_equal(temp, "100.00%"); + + amount = 0ull; + memset(temp, 0, sizeof(temp)); + assert_true(format_percentage(temp, sizeof(temp), amount, 2)); + assert_string_equal(temp, "0.00%"); + + amount = 1234ull; + memset(temp, 0, sizeof(temp)); + assert_true(format_percentage(temp, sizeof(temp), amount, 2)); + assert_string_equal(temp, "12.34%"); + + amount = 22ull; + assert_true(format_percentage(temp, sizeof(temp), amount, 2)); + assert_string_equal(temp, "0.22%"); + + // buffer too small + amount = 100ull; + assert_false(format_percentage(temp, sizeof(temp) - 1, amount, 2)); +} + +static void test_tx_utils_check_ascii(void **state) { (void) state; const uint8_t good_ascii[] = {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x21}; // Hello! @@ -30,7 +90,9 @@ static void test_tx_utils(void **state) { } int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_tx_utils)}; + const struct CMUnitTest tests[] = {cmocka_unit_test(test_tx_utils_format_amount), + cmocka_unit_test(test_tx_utils_format_percentage), + cmocka_unit_test(test_tx_utils_check_ascii)}; return cmocka_run_group_tests(tests, NULL, NULL); } diff --git a/tests/unit-tests/test_write.c b/tests/unit-tests/test_write.c deleted file mode 100644 index 08f37f71..00000000 --- a/tests/unit-tests/test_write.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#include "common/write.h" - -static void test_write(void **state) { - (void) state; - - uint8_t tmp2[2] = {0}; - - uint8_t expected2[2] = {0x01, 0x07}; - write_u16_be(tmp2, 0, (uint16_t) 263U); - assert_memory_equal(tmp2, expected2, sizeof(expected2)); - - memset(tmp2, 0, sizeof(tmp2)); - expected2[0] = 0x07; - expected2[1] = 0x01; - write_u16_le(tmp2, 0, (uint16_t) 263U); - assert_memory_equal(tmp2, expected2, sizeof(expected2)); - - uint8_t tmp4[4] = {0}; - - uint8_t expected4[4] = {0x01, 0x3B, 0xAC, 0xC7}; - write_u32_be(tmp4, 0, (uint32_t) 20688071UL); - assert_memory_equal(tmp4, expected4, sizeof(expected4)); - - memset(tmp4, 0, sizeof(tmp4)); - expected4[0] = 0xC7; - expected4[1] = 0xAC; - expected4[2] = 0x3B; - expected4[3] = 0x01; - write_u32_le(tmp4, 0, (uint32_t) 20688071UL); - assert_memory_equal(tmp4, expected4, sizeof(expected4)); - - uint8_t tmp8[8] = {0}; - - uint8_t expected8[8] = {0xEB, 0x68, 0x44, 0xC0, 0x2C, 0x61, 0xB0, 0x99}; - write_u64_be(tmp8, 0, (uint64_t) 16962883588659982489ULL); - assert_memory_equal(tmp8, expected8, sizeof(expected8)); - - memset(tmp8, 0, sizeof(tmp8)); - expected8[0] = 0x99; - expected8[1] = 0xB0; - expected8[2] = 0x61; - expected8[3] = 0x2C; - expected8[4] = 0xC0; - expected8[5] = 0x44; - expected8[6] = 0x68; - expected8[7] = 0xEB; - write_u64_le(tmp8, 0, (uint64_t) 16962883588659982489ULL); - assert_memory_equal(tmp8, expected8, sizeof(expected8)); -} - -int main() { - const struct CMUnitTest tests[] = {cmocka_unit_test(test_write)}; - - return cmocka_run_group_tests(tests, NULL, NULL); -} From 281067ca2efdd4bef5b639ba5fff14c0939714d7 Mon Sep 17 00:00:00 2001 From: sleepdefic1t Date: Thu, 8 Jun 2023 19:32:22 -0400 Subject: [PATCH 2/9] chore: version bump --- .vscode/c_cpp_properties.json | 4 ++-- CHANGELOG.md | 33 ++++++++++++++++++++++++++- Makefile | 2 +- doc/COMMANDS.md | 4 ++-- tests/functional/test_name_version.py | 2 +- tests/functional/test_version_cmd.py | 2 +- tests/unit-tests/CMakeLists.txt | 2 +- 7 files changed, 40 insertions(+), 9 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 2fad6a93..5c8d4fb1 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -24,10 +24,10 @@ "HAVE_USB_APDU", "USB_SEGMENT_SIZE=64", "UNUSED(x)=(void)x", - "APPVERSION=\"1.0.0\"", + "APPVERSION=\"1.1.0\"", "APPNAME=\"Solar\"", "MAJOR_VERSION=1", - "MINOR_VERSION=0", + "MINOR_VERSION=1", "PATCH_VERSION=0", "IO_SEPROXYHAL_BUFFER_SIZE_B=128", "HAVE_UX_FLOW", diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ba4a0ac..b2155a23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.0] - 2023-06-08 + +### Added + +- Expanded and improved CI workflows +- Introduced Ragger for enhanced functional testing + +### Changed + +- Refactored to align with LedgerHQ's SDKs +- Updated app menu copyright message +- Renamed icons to conform to LedgerHQ's naming conventions +- Revised documentation +- Updated Makefile to match LedgerHQ conventions +- Updated vote terminology +- Improved '.vscode' dev environment files +- Updated license headers in source files +- Enhanced unit-tests to cover recent changes + +### Removed + +- Removed HTLC transaction support +- Removed MultiSignature Registration transaction support + +### Fixed + +- Fixed outdated Ledger dev doc links in README +- Resolved clang static analysis failures +- Corrected typos + ## [1.0.0] - 2022-07-09 ### Added @@ -20,4 +50,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated functional and unit tests - Refreshed documentation -[1.0.0]: https://github.com/Solar-network/ledger-app-solar/compare/LedgerHQ:app-boilerplate:master...1.0.0 +[1.1.0]: https://github.com/Solar-network/ledger-app-solar/compare/1.0.0...1.1.0 +[1.0.0]: https://github.com/Solar-network/ledger-app-solar/compare/LedgerHQ:app-boilerplate:d7c7ca843e43f7b4982b87f1ac1d7bd66045448c...1.0.0 diff --git a/Makefile b/Makefile index 6deb3250..b5b305aa 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ APPNAME = "Solar" # Application version APPVERSION_M = 1 -APPVERSION_N = 0 +APPVERSION_N = 1 APPVERSION_P = 0 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" diff --git a/doc/COMMANDS.md b/doc/COMMANDS.md index 022b3abe..3c5ac4a4 100644 --- a/doc/COMMANDS.md +++ b/doc/COMMANDS.md @@ -77,8 +77,8 @@ For the `GET_VERSION` instruction, both P1 and P2 values are not used and should ```shell => e0a2000000 -<= 0100009000 - # "1 0 0", 0x9000 +<= 0101009000 + # "1 1 0", 0x9000 ``` ## GET_PUBLIC_KEY diff --git a/tests/functional/test_name_version.py b/tests/functional/test_name_version.py index 399b9226..1465b38b 100644 --- a/tests/functional/test_name_version.py +++ b/tests/functional/test_name_version.py @@ -14,4 +14,4 @@ def test_get_app_and_version(backend, backend_name): app_name, version = unpack_get_app_and_version_response(response.data) assert app_name == "Solar" - assert version == "1.0.0" + assert version == "1.1.0" diff --git a/tests/functional/test_version_cmd.py b/tests/functional/test_version_cmd.py index 7657dcc5..b86b2058 100644 --- a/tests/functional/test_version_cmd.py +++ b/tests/functional/test_version_cmd.py @@ -4,7 +4,7 @@ # Taken from the Makefile, to update every time the Makefile version is bumped MAJOR = 1 -MINOR = 0 +MINOR = 1 PATCH = 0 # In this test we check the behaviour of the device when asked to provide the app version diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt index d48b767d..ab117ed1 100644 --- a/tests/unit-tests/CMakeLists.txt +++ b/tests/unit-tests/CMakeLists.txt @@ -6,7 +6,7 @@ endif() # project information project(unit_tests - VERSION 0.1 + VERSION 1.1.0 DESCRIPTION "Unit tests for Ledger Nano application" LANGUAGES C) From d656a4f7cdd2849a044b1de0695c212645654ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=82=B4=E2=B1=A033=E2=82=B1?= Date: Sat, 10 Jun 2023 17:20:22 -0400 Subject: [PATCH 3/9] fix: code warnings (#3) --- src/transaction/types/vote.c | 2 +- src/transaction/types/vote.h | 1 - src/ui/transactions/burn_display.c | 4 +-- src/ui/transactions/ipfs_display.c | 4 +-- src/ui/transactions/transfer_display.c | 39 +++++++++++--------------- src/ui/transactions/vote_display.c | 4 +-- tests/functional/requirements.txt | 12 +++----- tests/functional/utils.py | 26 +---------------- 8 files changed, 29 insertions(+), 63 deletions(-) diff --git a/src/transaction/types/vote.c b/src/transaction/types/vote.c index fab411e5..7517158e 100644 --- a/src/transaction/types/vote.c +++ b/src/transaction/types/vote.c @@ -22,7 +22,7 @@ parser_status_e vote_type_deserialise(buffer_t *buf, vote_transaction_asset_t *t return WRONG_LENGTH_ERROR; } - if (tx->vote_length < MIN_NUM_VOTES || tx->vote_length > MAX_NUM_VOTES) { + if (tx->vote_length > MAX_NUM_VOTES) { return CORE_ASSET_PARSING_ERROR; } diff --git a/src/transaction/types/vote.h b/src/transaction/types/vote.h index ef51891c..1feac84d 100644 --- a/src/transaction/types/vote.h +++ b/src/transaction/types/vote.h @@ -6,7 +6,6 @@ #include "transaction/errors.h" -#define MIN_NUM_VOTES 0 #define MAX_NUM_VOTES 53 #define MIN_USERNAME_LENGTH 1 #define MAX_USERNAME_LENGTH 20 diff --git a/src/ui/transactions/burn_display.c b/src/ui/transactions/burn_display.c index b0c092e9..c998c29d 100644 --- a/src/ui/transactions/burn_display.c +++ b/src/ui/transactions/burn_display.c @@ -23,7 +23,7 @@ bool burn_type_display(transaction_t *tx, char title[], char text[], uint16_t st switch (step) { case 0: { // Amount - snprintf(title, MAX_TITLE_LEN, "%s", "Amount"); + snprintf(title, MAX_TITLE_LEN, "Amount"); format_amount(text, MAX_TEXT_LEN, tx->core_asset.Burn.amount, @@ -34,7 +34,7 @@ bool burn_type_display(transaction_t *tx, char title[], char text[], uint16_t st } case 1: { // Fee - snprintf(title, MAX_TITLE_LEN, "%s", "Fee"); + snprintf(title, MAX_TITLE_LEN, "Fee"); format_amount(text, MAX_TEXT_LEN, tx->fee, diff --git a/src/ui/transactions/ipfs_display.c b/src/ui/transactions/ipfs_display.c index 111f04a9..77ca2270 100644 --- a/src/ui/transactions/ipfs_display.c +++ b/src/ui/transactions/ipfs_display.c @@ -25,7 +25,7 @@ bool ipfs_type_display(transaction_t *tx, char title[], char text[], uint16_t st switch (step) { case 0: { // IPFS hash - snprintf(title, MAX_TITLE_LEN, "%s", "Content ID"); + snprintf(title, MAX_TITLE_LEN, "Content ID"); char encoded[100] = {0}; int base58_length = base58_encode(tx->core_asset.Ipfs.ipfs, tx->core_asset.Ipfs.ipfs_length, @@ -36,7 +36,7 @@ bool ipfs_type_display(transaction_t *tx, char title[], char text[], uint16_t st } case 1: { // Fee - snprintf(title, MAX_TITLE_LEN, "%s", "Fee"); + snprintf(title, MAX_TITLE_LEN, "Fee"); format_amount(text, MAX_TEXT_LEN, tx->fee, diff --git a/src/ui/transactions/transfer_display.c b/src/ui/transactions/transfer_display.c index eb5c035b..9d13f8ae 100644 --- a/src/ui/transactions/transfer_display.c +++ b/src/ui/transactions/transfer_display.c @@ -24,15 +24,16 @@ bool transfer_type_display(transaction_t *tx, char title[], char text[], uint16_t step) { // transfers (amount + recipient) uint16_t number_recipients = step / 2; + if (number_recipients < tx->core_asset.Transfer.transfers_length) { uint16_t offset = number_recipients * (ADDRESS_HASH_LEN + 8); + if (step % 2 == 0) { - // Recipient + // Prepare the recipient[n] screen offset += 8; snprintf(title, MAX_TITLE_LEN, - "%s %d/%d", - "Address", + "Address %d/%d", number_recipients + 1, tx->core_asset.Transfer.transfers_length); base58_encode_address(&tx->core_asset.Transfer.transfers[offset], @@ -40,11 +41,10 @@ bool transfer_type_display(transaction_t *tx, char title[], char text[], uint16_ text, MAX_TEXT_LEN); } else { - // Amount + // Prepare the amount[n] screen snprintf(title, MAX_TITLE_LEN, - "%s %d/%d", - "Amount", + "Amount %d/%d", number_recipients + 1, tx->core_asset.Transfer.transfers_length); format_amount(text, @@ -58,22 +58,17 @@ bool transfer_type_display(transaction_t *tx, char title[], char text[], uint16_ return true; } - switch (step - (tx->core_asset.Transfer.transfers_length * 2)) { - case 0: { - // Fee - snprintf(title, MAX_TITLE_LEN, "%s", "Fee"); - format_amount(text, - MAX_TEXT_LEN, - tx->fee, - EXPONENT_SMALLEST_UNIT, - TICKER_DEFAULT, - sizeof(TICKER_DEFAULT)); - break; - } - default: { - return false; - } + // Prepare the fee screen + if (step - (tx->core_asset.Transfer.transfers_length * 2) == 0) { + snprintf(title, MAX_TITLE_LEN, "Fee"); + format_amount(text, + MAX_TEXT_LEN, + tx->fee, + EXPONENT_SMALLEST_UNIT, + TICKER_DEFAULT, + sizeof(TICKER_DEFAULT)); + return true; } - return true; + return false; } diff --git a/src/ui/transactions/vote_display.c b/src/ui/transactions/vote_display.c index 216acc68..d8fc7df3 100644 --- a/src/ui/transactions/vote_display.c +++ b/src/ui/transactions/vote_display.c @@ -32,7 +32,7 @@ bool vote_type_display(transaction_t *tx, char title[], char text[], uint16_t st vote_search(tx->core_asset.Vote.votes, vote_count, tx->core_asset.Vote.vote_length, &asset); if (step % 2 == 0) { - // Prepare the vote screen + // Prepare the vote[n] screen snprintf(title, MAX_TITLE_LEN, "Vote (%d/%d)", @@ -40,7 +40,7 @@ bool vote_type_display(transaction_t *tx, char title[], char text[], uint16_t st tx->core_asset.Vote.vote_length); snprintf(text, MAX_TEXT_LEN, "%.*s", asset.username_length, asset.username); } else { - // Prepare the vote percentage screen + // Prepare the vote percentage[n] screen snprintf(title, MAX_TITLE_LEN, "Vote %% (%d/%d)", diff --git a/tests/functional/requirements.txt b/tests/functional/requirements.txt index 085b7583..8e6372c6 100644 --- a/tests/functional/requirements.txt +++ b/tests/functional/requirements.txt @@ -1,8 +1,4 @@ -pytest -btclib -ragger[speculos]>=1.6.0 -ragger[ledgerwallet]>=1.6.0 -Jinja2==3.1.2 -Flask==2.1.2 -ecdsa>=0.16.1,<0.17.0 -pysha3>=1.0.0,<2.0.0 +pytest==7.3.1 +btclib==2023.2.3 +ragger[speculos]==1.8.2 +ragger[ledgerwallet]==1.8.2 diff --git a/tests/functional/utils.py b/tests/functional/utils.py index 040dc66f..79c5ac30 100644 --- a/tests/functional/utils.py +++ b/tests/functional/utils.py @@ -1,28 +1,4 @@ from pathlib import Path -from hashlib import sha256 - -# from sha3 import keccak_256 - -from btclib.ecc import ssa - -from ecdsa.curves import SECP256k1 - -# from ecdsa.keys import VerifyingKey -# from ecdsa.util import sigdecode_der - +# Used by Ragger navigator for snapshot validation ROOT_SCREENSHOT_PATH = Path(__file__).parent.resolve() - - -# Check if a signature of a given message is valid -def check_signature_validity( - public_key: bytes, signature: bytes, message: bytes -) -> bool: - ssa.verify(message1.encode("ascii"), context["pkey"][1:], schnorr_sig) is True - - pk: VerifyingKey = VerifyingKey.from_string( - public_key, curve=SECP256k1, hashfunc=sha256 - ) - return pk.verify( - signature=signature, data=message, hashfunc=sha256, sigdecode=sigdecode_der - ) From c88859be49afd080e9d65b8864290bfc92dacb96 Mon Sep 17 00:00:00 2001 From: sleepdefic1t Date: Sat, 10 Jun 2023 18:43:57 -0400 Subject: [PATCH 4/9] chore: version bump --- .vscode/c_cpp_properties.json | 4 ++-- CHANGELOG.md | 15 +++++++++++++++ Makefile | 2 +- doc/COMMANDS.md | 4 ++-- tests/functional/test_name_version.py | 2 +- tests/functional/test_version_cmd.py | 2 +- tests/unit-tests/CMakeLists.txt | 2 +- 7 files changed, 23 insertions(+), 8 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 5c8d4fb1..e86cded4 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -24,11 +24,11 @@ "HAVE_USB_APDU", "USB_SEGMENT_SIZE=64", "UNUSED(x)=(void)x", - "APPVERSION=\"1.1.0\"", + "APPVERSION=\"1.1.1\"", "APPNAME=\"Solar\"", "MAJOR_VERSION=1", "MINOR_VERSION=1", - "PATCH_VERSION=0", + "PATCH_VERSION=1", "IO_SEPROXYHAL_BUFFER_SIZE_B=128", "HAVE_UX_FLOW", "DEBUG=1", diff --git a/CHANGELOG.md b/CHANGELOG.md index b2155a23..baa8fe01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.1] - 2023-06-10 + +### Changed + +- Refactored transaction display code for better readability +- Set explicit versions for functional test dependencies + +### Removed + +- Simplified code by removing trivial switch statement +- Removed unnecessary vote minimum check +- Removed redundant functional test dependencies +- Cleaned up functional tests by removing unused utilities + ## [1.1.0] - 2023-06-08 ### Added @@ -50,5 +64,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated functional and unit tests - Refreshed documentation +[1.1.1]: https://github.com/Solar-network/ledger-app-solar/compare/1.1.0...1.1.1 [1.1.0]: https://github.com/Solar-network/ledger-app-solar/compare/1.0.0...1.1.0 [1.0.0]: https://github.com/Solar-network/ledger-app-solar/compare/LedgerHQ:app-boilerplate:d7c7ca843e43f7b4982b87f1ac1d7bd66045448c...1.0.0 diff --git a/Makefile b/Makefile index b5b305aa..fc821032 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ APPNAME = "Solar" # Application version APPVERSION_M = 1 APPVERSION_N = 1 -APPVERSION_P = 0 +APPVERSION_P = 1 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" # Application source files diff --git a/doc/COMMANDS.md b/doc/COMMANDS.md index 3c5ac4a4..e73963b7 100644 --- a/doc/COMMANDS.md +++ b/doc/COMMANDS.md @@ -77,8 +77,8 @@ For the `GET_VERSION` instruction, both P1 and P2 values are not used and should ```shell => e0a2000000 -<= 0101009000 - # "1 1 0", 0x9000 +<= 0101019000 + # "1 1 1", 0x9000 ``` ## GET_PUBLIC_KEY diff --git a/tests/functional/test_name_version.py b/tests/functional/test_name_version.py index 1465b38b..64b06e2d 100644 --- a/tests/functional/test_name_version.py +++ b/tests/functional/test_name_version.py @@ -14,4 +14,4 @@ def test_get_app_and_version(backend, backend_name): app_name, version = unpack_get_app_and_version_response(response.data) assert app_name == "Solar" - assert version == "1.1.0" + assert version == "1.1.1" diff --git a/tests/functional/test_version_cmd.py b/tests/functional/test_version_cmd.py index b86b2058..af25afde 100644 --- a/tests/functional/test_version_cmd.py +++ b/tests/functional/test_version_cmd.py @@ -5,7 +5,7 @@ # Taken from the Makefile, to update every time the Makefile version is bumped MAJOR = 1 MINOR = 1 -PATCH = 0 +PATCH = 1 # In this test we check the behaviour of the device when asked to provide the app version def test_version(backend): diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt index ab117ed1..0e5c7ee5 100644 --- a/tests/unit-tests/CMakeLists.txt +++ b/tests/unit-tests/CMakeLists.txt @@ -6,7 +6,7 @@ endif() # project information project(unit_tests - VERSION 1.1.0 + VERSION 1.1.1 DESCRIPTION "Unit tests for Ledger Nano application" LANGUAGES C) From 61d757c3207de02c418e1867e6ac8963edfc88bf Mon Sep 17 00:00:00 2001 From: sleepdefic1t Date: Wed, 16 Aug 2023 12:51:57 -0400 Subject: [PATCH 5/9] chore: version bump --- .vscode/c_cpp_properties.json | 4 ++-- CHANGELOG.md | 9 +++++++++ Makefile | 2 +- doc/COMMANDS.md | 4 ++-- tests/functional/test_name_version.py | 2 +- tests/functional/test_version_cmd.py | 2 +- tests/unit-tests/CMakeLists.txt | 2 +- 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index e86cded4..9329a5f3 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -24,11 +24,11 @@ "HAVE_USB_APDU", "USB_SEGMENT_SIZE=64", "UNUSED(x)=(void)x", - "APPVERSION=\"1.1.1\"", + "APPVERSION=\"1.1.2\"", "APPNAME=\"Solar\"", "MAJOR_VERSION=1", "MINOR_VERSION=1", - "PATCH_VERSION=1", + "PATCH_VERSION=2", "IO_SEPROXYHAL_BUFFER_SIZE_B=128", "HAVE_UX_FLOW", "DEBUG=1", diff --git a/CHANGELOG.md b/CHANGELOG.md index baa8fe01..5dcafdec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.1.2] - 2023-08-16 + +### Added + +- Merged LedgerHQ downstream commits +- Added 'pending security review flag' + ## [1.1.1] - 2023-06-10 ### Changed @@ -64,6 +72,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated functional and unit tests - Refreshed documentation +[1.1.2]: https://github.com/Solar-network/ledger-app-solar/compare/1.1.1...1.1.2 [1.1.1]: https://github.com/Solar-network/ledger-app-solar/compare/1.1.0...1.1.1 [1.1.0]: https://github.com/Solar-network/ledger-app-solar/compare/1.0.0...1.1.0 [1.0.0]: https://github.com/Solar-network/ledger-app-solar/compare/LedgerHQ:app-boilerplate:d7c7ca843e43f7b4982b87f1ac1d7bd66045448c...1.0.0 diff --git a/Makefile b/Makefile index 4873806a..0a7ebeb0 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ APPNAME = "Solar" # Application version APPVERSION_M = 1 APPVERSION_N = 1 -APPVERSION_P = 1 +APPVERSION_P = 2 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" # Application source files diff --git a/doc/COMMANDS.md b/doc/COMMANDS.md index e73963b7..e14196f5 100644 --- a/doc/COMMANDS.md +++ b/doc/COMMANDS.md @@ -77,8 +77,8 @@ For the `GET_VERSION` instruction, both P1 and P2 values are not used and should ```shell => e0a2000000 -<= 0101019000 - # "1 1 1", 0x9000 +<= 0101029000 + # "1 1 2", 0x9000 ``` ## GET_PUBLIC_KEY diff --git a/tests/functional/test_name_version.py b/tests/functional/test_name_version.py index 64b06e2d..87a5f736 100644 --- a/tests/functional/test_name_version.py +++ b/tests/functional/test_name_version.py @@ -14,4 +14,4 @@ def test_get_app_and_version(backend, backend_name): app_name, version = unpack_get_app_and_version_response(response.data) assert app_name == "Solar" - assert version == "1.1.1" + assert version == "1.1.2" diff --git a/tests/functional/test_version_cmd.py b/tests/functional/test_version_cmd.py index af25afde..60cec1ba 100644 --- a/tests/functional/test_version_cmd.py +++ b/tests/functional/test_version_cmd.py @@ -5,7 +5,7 @@ # Taken from the Makefile, to update every time the Makefile version is bumped MAJOR = 1 MINOR = 1 -PATCH = 1 +PATCH = 2 # In this test we check the behaviour of the device when asked to provide the app version def test_version(backend): diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt index 0e5c7ee5..26b14e1b 100644 --- a/tests/unit-tests/CMakeLists.txt +++ b/tests/unit-tests/CMakeLists.txt @@ -6,7 +6,7 @@ endif() # project information project(unit_tests - VERSION 1.1.1 + VERSION 1.1.2 DESCRIPTION "Unit tests for Ledger Nano application" LANGUAGES C) From abb01047062e2d63e756ee28471fb0c3b8c883f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=82=B4=E2=B1=A033=E2=82=B1?= Date: Thu, 17 Aug 2023 13:05:20 -0400 Subject: [PATCH 6/9] refactor: resolve warnings (#4) --- src/address.c | 14 +++++++-- src/app_main.c | 66 ++++++++++++++++--------------------------- src/context.c | 2 ++ src/crypto/crypto.c | 63 +++++++++++++---------------------------- src/handler/sign_tx.c | 24 ++++++++-------- 5 files changed, 72 insertions(+), 97 deletions(-) diff --git a/src/address.c b/src/address.c index b8d954f3..0ddc9144 100644 --- a/src/address.c +++ b/src/address.c @@ -40,6 +40,7 @@ #include "os.h" #include "constants.h" +#include "sw.h" bool address_from_pubkey(const uint8_t public_key[static 33], uint8_t *out, @@ -52,9 +53,18 @@ bool address_from_pubkey(const uint8_t public_key[static 33], return false; } - cx_ripemd160_init(&ctx); + if (cx_ripemd160_init_no_throw(&ctx) != CX_OK) { + return false; + } - cx_hash((cx_hash_t *) &ctx, CX_LAST, public_key, PUBLIC_KEY_LEN, address, ADDRESS_HASH_LEN); + if (cx_hash_no_throw((cx_hash_t *) &ctx, + CX_LAST, + public_key, + PUBLIC_KEY_LEN, + address, + ADDRESS_HASH_LEN) != CX_OK) { + return false; + } memmove(out + 1, address, ADDRESS_HASH_LEN - 1); out[0] = network; diff --git a/src/app_main.c b/src/app_main.c index 705e7027..cd6b9617 100644 --- a/src/app_main.c +++ b/src/app_main.c @@ -20,14 +20,15 @@ #include "io.h" #include "os.h" -#include "sw.h" #include "ux.h" #include "context.h" #include "globals.h" +#include "sw.h" #include "types.h" #include "apdu/dispatcher.h" + #include "ui/menu.h" global_ctx_t G_context; @@ -49,49 +50,32 @@ void app_main() { reset_app_context(); for (;;) { - BEGIN_TRY { - TRY { - // Reset structured APDU command - memset(&cmd, 0, sizeof(cmd)); - - // Receive command bytes in G_io_apdu_buffer - if ((input_len = io_recv_command()) < 0) { - CLOSE_TRY; - return; - } + // Receive command bytes in G_io_apdu_buffer + if ((input_len = io_recv_command()) < 0) { + PRINTF("=> io_recv_command failure\n"); + return; + } - // Parse APDU command from G_io_apdu_buffer - if (!apdu_parser(&cmd, G_io_apdu_buffer, input_len)) { - PRINTF("=> /!\\ BAD LENGTH: %.*H\n", input_len, G_io_apdu_buffer); - io_send_sw(SW_WRONG_DATA_LENGTH); - CLOSE_TRY; - continue; - } + // Parse APDU command from G_io_apdu_buffer + if (!apdu_parser(&cmd, G_io_apdu_buffer, input_len)) { + PRINTF("=> /!\\ BAD LENGTH: %.*H\n", input_len, G_io_apdu_buffer); + io_send_sw(SW_WRONG_DATA_LENGTH); + continue; + } - PRINTF("=> CLA=%02X | INS=%02X | P1=%02X | P2=%02X | Lc=%02X | CData=%.*H\n", - cmd.cla, - cmd.ins, - cmd.p1, - cmd.p2, - cmd.lc, - cmd.lc, - cmd.data); + PRINTF("=> CLA=%02X | INS=%02X | P1=%02X | P2=%02X | Lc=%02X | CData=%.*H\n", + cmd.cla, + cmd.ins, + cmd.p1, + cmd.p2, + cmd.lc, + cmd.lc, + cmd.data); - // Dispatch structured APDU command to handler - if (apdu_dispatcher(&cmd) < 0) { - CLOSE_TRY; - return; - } - } - CATCH(EXCEPTION_IO_RESET) { - THROW(EXCEPTION_IO_RESET); - } - CATCH_OTHER(e) { - io_send_sw(e); - } - FINALLY { - } - END_TRY; + // Dispatch structured APDU command to handler + if (apdu_dispatcher(&cmd) < 0) { + PRINTF("=> apdu_dispatcher failure\n"); + return; } } } diff --git a/src/context.c b/src/context.c index 497f7c68..b9797a73 100644 --- a/src/context.c +++ b/src/context.c @@ -9,6 +9,8 @@ #include // explicit_bzero +#include "os.h" // PRINTF + #include "globals.h" void reset_app_context() { diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c index bbdca36a..eaca5df0 100644 --- a/src/crypto/crypto.c +++ b/src/crypto/crypto.c @@ -31,6 +31,8 @@ #include // uint*_t #include // memset, explicit_bzero +#include "crypto_helpers.h" + #include "crypto.h" #include "globals.h" @@ -39,30 +41,13 @@ int crypto_derive_private_key(cx_ecfp_private_key_t *private_key, uint8_t chain_code[32], const uint32_t *bip32_path, uint8_t bip32_path_len) { - uint8_t raw_private_key[32] = {0}; - - BEGIN_TRY { - TRY { - // derive the seed with bip32_path - os_perso_derive_node_bip32(CX_CURVE_256K1, - bip32_path, - bip32_path_len, - raw_private_key, - chain_code); - // new private_key from raw - cx_ecfp_init_private_key(CX_CURVE_256K1, - raw_private_key, - sizeof(raw_private_key), - private_key); - } - CATCH_OTHER(e) { - THROW(e); - } - FINALLY { - explicit_bzero(&raw_private_key, sizeof(raw_private_key)); - } + if (bip32_derive_init_privkey_256(CX_CURVE_256K1, + bip32_path, + bip32_path_len, + private_key, + chain_code) != CX_OK) { + return -1; } - END_TRY; return 0; } @@ -71,7 +56,9 @@ int crypto_init_public_key(cx_ecfp_private_key_t *private_key, cx_ecfp_public_key_t *public_key, uint8_t raw_public_key[33]) { // generate corresponding public key - cx_ecfp_generate_pair(CX_CURVE_256K1, public_key, private_key, 1); + if (cx_ecfp_generate_pair_no_throw(CX_CURVE_256K1, public_key, private_key, true) != CX_OK) { + return -1; + } raw_public_key[0] = ((*(public_key->W + 64) & 1) ? 0x03 : 0x02); memmove(raw_public_key + 1, public_key->W + 1, 32); @@ -82,29 +69,19 @@ int crypto_init_public_key(cx_ecfp_private_key_t *private_key, int crypto_sign_message() { cx_ecfp_private_key_t private_key = {0}; size_t signature_len = sizeof(G_context.tx_info.signature); - cx_err_t error = CX_INTERNAL_ERROR; // derive private key according to BIP32 path crypto_derive_private_key(&private_key, NULL, G_context.bip32_path, G_context.bip32_path_len); - BEGIN_TRY { - TRY { - error = cx_ecschnorr_sign_no_throw(&private_key, - CX_ECSCHNORR_BIP0340 | CX_RND_TRNG, - CX_SHA256, - G_context.tx_info.m_hash, - sizeof(G_context.tx_info.m_hash), - G_context.tx_info.signature, - &signature_len); - } - CATCH_OTHER(e) { - THROW(e); - } - FINALLY { - explicit_bzero(&private_key, sizeof(private_key)); - } - } - END_TRY; + cx_err_t error = cx_ecschnorr_sign_no_throw(&private_key, + CX_ECSCHNORR_BIP0340 | CX_RND_TRNG, + CX_SHA256, + G_context.tx_info.m_hash, + sizeof(G_context.tx_info.m_hash), + G_context.tx_info.signature, + &signature_len); + + explicit_bzero(&private_key, sizeof(private_key)); if (error != CX_OK) { return -1; diff --git a/src/handler/sign_tx.c b/src/handler/sign_tx.c index 31a44618..01c9dabf 100644 --- a/src/handler/sign_tx.c +++ b/src/handler/sign_tx.c @@ -120,17 +120,19 @@ int handler_sign_tx(buffer_t *cdata, uint8_t chunk, bool more, bool is_message) G_context.state = STATE_PARSED; cx_sha256_t sha256; - cx_sha256_init(&sha256); - cx_hash(&sha256.header, - CX_LAST, - (G_context.req_type == CONFIRM_MESSAGE) ? G_context.tx_info.raw_tx + 2 - : G_context.tx_info.raw_tx, - (G_context.req_type == CONFIRM_MESSAGE) ? G_context.tx_info.raw_tx_len - 2 - : G_context.tx_info.raw_tx_len, - G_context.tx_info.m_hash, - sizeof(G_context.tx_info.m_hash)); - - PRINTF("Hash: %.*H\n", sizeof(G_context.tx_info.m_hash), G_context.tx_info.m_hash); + + if (cx_sha256_init_no_throw(&sha256) != CX_OK) { + return io_send_sw(SW_TX_HASH_FAIL); + } + + if (cx_hash_no_throw((cx_hash_t *) &sha256, + CX_LAST, + G_context.tx_info.raw_tx, + G_context.tx_info.raw_tx_len, + G_context.tx_info.m_hash, + HASH_32_LEN) != CX_OK) { + return io_send_sw(SW_TX_HASH_FAIL); + } if (G_context.req_type == CONFIRM_TRANSACTION) { return ui_display_transaction(); From 7eb0ed279f529b91b55c54a7ed7fe910cc0c65b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=82=B4=E2=B1=A033=E2=82=B1?= Date: Thu, 17 Aug 2023 13:06:10 -0400 Subject: [PATCH 7/9] test(functional): update ragger (#5) --- tests/functional/requirements.txt | 4 ++-- .../test_get_address_confirm_accepted/00001.png | Bin 737 -> 735 bytes .../test_get_address_confirm_accepted/00003.png | Bin 441 -> 440 bytes .../test_get_address_confirm_refused/00001.png | Bin 737 -> 735 bytes .../test_get_address_confirm_refused/00003.png | Bin 365 -> 366 bytes .../test_get_address_confirm_refused/00004.png | Bin 441 -> 440 bytes .../00000.png | Bin 400 -> 402 bytes .../00001.png | Bin 891 -> 890 bytes .../00002.png | Bin 547 -> 546 bytes .../00004.png | Bin 441 -> 440 bytes .../00000.png | Bin 400 -> 402 bytes .../00001.png | Bin 891 -> 890 bytes .../00002.png | Bin 547 -> 546 bytes .../00004.png | Bin 365 -> 366 bytes .../00005.png | Bin 441 -> 440 bytes .../00000.png | Bin 400 -> 402 bytes .../00001.png | Bin 891 -> 890 bytes .../00002.png | Bin 547 -> 546 bytes .../00004.png | Bin 441 -> 440 bytes .../nanox/test_sign_message_long/00001.png | Bin 866 -> 865 bytes .../nanox/test_sign_message_long/00002.png | Bin 841 -> 843 bytes .../nanox/test_sign_message_long/00003.png | Bin 770 -> 769 bytes .../nanox/test_sign_message_long/00005.png | Bin 906 -> 902 bytes .../nanox/test_sign_message_long/00007.png | Bin 794 -> 794 bytes .../nanox/test_sign_message_long/00008.png | Bin 849 -> 848 bytes .../nanox/test_sign_message_long/00009.png | Bin 767 -> 764 bytes .../nanox/test_sign_message_long/00010.png | Bin 779 -> 781 bytes .../nanox/test_sign_message_long/00012.png | Bin 812 -> 810 bytes .../nanox/test_sign_message_long/00013.png | Bin 804 -> 804 bytes .../nanox/test_sign_message_long/00014.png | Bin 771 -> 773 bytes .../nanox/test_sign_message_long/00015.png | Bin 834 -> 835 bytes .../nanox/test_sign_message_long/00016.png | Bin 770 -> 769 bytes .../nanox/test_sign_message_long/00017.png | Bin 718 -> 719 bytes .../nanox/test_sign_message_long/00018.png | Bin 828 -> 830 bytes .../nanox/test_sign_message_long/00019.png | Bin 821 -> 815 bytes .../nanox/test_sign_message_long/00020.png | Bin 829 -> 830 bytes .../nanox/test_sign_message_long/00021.png | Bin 837 -> 834 bytes .../nanox/test_sign_message_long/00022.png | Bin 857 -> 854 bytes .../nanox/test_sign_message_long/00023.png | Bin 765 -> 765 bytes .../nanox/test_sign_message_long/00024.png | Bin 859 -> 854 bytes .../nanox/test_sign_message_long/00026.png | Bin 810 -> 810 bytes .../nanox/test_sign_message_long/00028.png | Bin 857 -> 857 bytes .../nanox/test_sign_message_long/00029.png | Bin 867 -> 864 bytes .../nanox/test_sign_message_long/00032.png | Bin 441 -> 440 bytes .../nanox/test_sign_message_refused/00001.png | Bin 711 -> 709 bytes .../nanox/test_sign_message_refused/00004.png | Bin 365 -> 366 bytes .../nanox/test_sign_message_refused/00005.png | Bin 441 -> 440 bytes .../nanox/test_sign_message_short/00001.png | Bin 711 -> 709 bytes .../nanox/test_sign_message_short/00004.png | Bin 441 -> 440 bytes .../nanox/test_sign_transaction_burn/00001.png | Bin 392 -> 395 bytes .../nanox/test_sign_transaction_burn/00002.png | Bin 345 -> 348 bytes .../nanox/test_sign_transaction_burn/00004.png | Bin 441 -> 440 bytes .../nanox/test_sign_transaction_ipfs/00001.png | Bin 852 -> 863 bytes .../nanox/test_sign_transaction_ipfs/00002.png | Bin 399 -> 399 bytes .../nanox/test_sign_transaction_ipfs/00004.png | Bin 441 -> 440 bytes .../test_sign_transaction_transfer/00001.png | Bin 767 -> 763 bytes .../test_sign_transaction_transfer/00002.png | Bin 477 -> 473 bytes .../test_sign_transaction_transfer/00003.png | Bin 766 -> 760 bytes .../test_sign_transaction_transfer/00004.png | Bin 497 -> 492 bytes .../test_sign_transaction_transfer/00005.png | Bin 759 -> 757 bytes .../test_sign_transaction_transfer/00006.png | Bin 502 -> 501 bytes .../test_sign_transaction_transfer/00007.png | Bin 804 -> 808 bytes .../test_sign_transaction_transfer/00008.png | Bin 492 -> 487 bytes .../test_sign_transaction_transfer/00009.png | Bin 770 -> 764 bytes .../test_sign_transaction_transfer/00010.png | Bin 506 -> 507 bytes .../test_sign_transaction_transfer/00011.png | Bin 771 -> 754 bytes .../test_sign_transaction_transfer/00012.png | Bin 504 -> 497 bytes .../test_sign_transaction_transfer/00013.png | Bin 762 -> 762 bytes .../test_sign_transaction_transfer/00014.png | Bin 493 -> 490 bytes .../test_sign_transaction_transfer/00015.png | Bin 762 -> 760 bytes .../test_sign_transaction_transfer/00016.png | Bin 506 -> 505 bytes .../test_sign_transaction_transfer/00017.png | Bin 777 -> 782 bytes .../test_sign_transaction_transfer/00018.png | Bin 506 -> 507 bytes .../test_sign_transaction_transfer/00019.png | Bin 752 -> 752 bytes .../test_sign_transaction_transfer/00020.png | Bin 510 -> 505 bytes .../test_sign_transaction_transfer/00021.png | Bin 754 -> 738 bytes .../test_sign_transaction_transfer/00022.png | Bin 498 -> 493 bytes .../test_sign_transaction_transfer/00023.png | Bin 778 -> 781 bytes .../test_sign_transaction_transfer/00024.png | Bin 510 -> 508 bytes .../test_sign_transaction_transfer/00025.png | Bin 731 -> 732 bytes .../test_sign_transaction_transfer/00026.png | Bin 522 -> 518 bytes .../test_sign_transaction_transfer/00027.png | Bin 768 -> 765 bytes .../test_sign_transaction_transfer/00028.png | Bin 612 -> 612 bytes .../test_sign_transaction_transfer/00029.png | Bin 400 -> 399 bytes .../test_sign_transaction_transfer/00030.png | Bin 471 -> 472 bytes .../test_sign_transaction_transfer/00032.png | Bin 441 -> 440 bytes .../nanox/test_sign_transaction_vote/00002.png | Bin 420 -> 422 bytes .../nanox/test_sign_transaction_vote/00004.png | Bin 435 -> 441 bytes .../nanox/test_sign_transaction_vote/00006.png | Bin 431 -> 432 bytes .../nanox/test_sign_transaction_vote/00007.png | Bin 345 -> 348 bytes .../nanox/test_sign_transaction_vote/00009.png | Bin 441 -> 440 bytes .../test_sign_transaction_vote_cancel/00001.png | Bin 345 -> 348 bytes .../test_sign_transaction_vote_cancel/00003.png | Bin 441 -> 440 bytes tests/functional/test_sign_message_cmd.py | 12 ++++++++++-- 94 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/functional/requirements.txt b/tests/functional/requirements.txt index 8e6372c6..b5d9277b 100644 --- a/tests/functional/requirements.txt +++ b/tests/functional/requirements.txt @@ -1,4 +1,4 @@ pytest==7.3.1 btclib==2023.2.3 -ragger[speculos]==1.8.2 -ragger[ledgerwallet]==1.8.2 +ragger[speculos]==1.11.4 +ragger[ledgerwallet]==1.11.4 diff --git a/tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00001.png b/tests/functional/snapshots/nanox/test_get_address_confirm_accepted/00001.png index 2cbafa446bfa451a2caf5b29e4ac91853eac84a1..0159f2db16f7c22a9db2a999cc934c320899993b 100644 GIT binary patch delta 711 zcmV;&0yzEQ1>XgbB!8w!L_t(|ob8)ij>8}fMVZm;B>P_ydzp_)5%rr_fcBoR$_3-t zfWc`~0ssI2007`S$vNko<6jx=kK=c>0qJ(-$N030ztsk)i183t!*yLR`E^~SO);;i7@Z_`kET#M+Ftbfk|X+l!H3XA{PsS#42sAMAnTT0MQ6zNN%fZgs7o&6Cgtm(I)CF`$DYXtz;&?>VcXj}ZivBX6XB-k-jjN^)y*H3!9FRq4rBbsNP$QJJdhA?TJMFOK` zkq9&Ze0JPpXcEmtS7>V}g=B^rIhjaY%IDQK9AaK@6o0XqGfURKnmB?<=e;qizkwlM z5|qIEK}I&)huY?hM&Hbe!HCFvpsdB!8$$L_t(|ob8)ij>8}fMVZm;B>P_ydzp_)k?R-cRiL@&t8&3O zHehhtlmGw#0001ZCOPMvbNnl({c-%RHXz-u{2HHD@weIl6Ez;{YPhcJCBLqVwTVks zv3LbAhqBecT%!t^lDm!SXx3LsKF<~_fH^BT_uDj3k6RJ_B!BC3K$?(LFG4CgeQoYp z8G!rA=~nRC(`DnxJayXax&Ne;ein}H?+I$2w9=_HqxVn3000000M8_J45bHlOF|pV zqh8X^e`@z+Uj;0yq;mgO!8)=wcX3GyizYd?wWHR*BJE{~M)qx}I#gL$YbyPq+Fwht zf~f5DMBAv-E)|2!G9stW`!xT_SM7@Ogik1QT+sl zcu7$L?*|!}rDv%IMX(F4q~K)4U@9ZsD}PHuC7Hk)SVC!{S`jOb%f3=SOQHO>%312T z`5m?6#EY0(hmb<2v_hG2$znH>{9cc$8qTT+brs{JeLa^PhpbF zI@NBm0%p^kEx-X_F9HCZ%gVnfjbc<;2K0h_I6|G;az7YP%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00001.png b/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00001.png index 2cbafa446bfa451a2caf5b29e4ac91853eac84a1..0159f2db16f7c22a9db2a999cc934c320899993b 100644 GIT binary patch delta 711 zcmV;&0yzEQ1>XgbB!8w!L_t(|ob8)ij>8}fMVZm;B>P_ydzp_)5%rr_fcBoR$_3-t zfWc`~0ssI2007`S$vNko<6jx=kK=c>0qJ(-$N030ztsk)i183t!*yLR`E^~SO);;i7@Z_`kET#M+Ftbfk|X+l!H3XA{PsS#42sAMAnTT0MQ6zNN%fZgs7o&6Cgtm(I)CF`$DYXtz;&?>VcXj}ZivBX6XB-k-jjN^)y*H3!9FRq4rBbsNP$QJJdhA?TJMFOK` zkq9&Ze0JPpXcEmtS7>V}g=B^rIhjaY%IDQK9AaK@6o0XqGfURKnmB?<=e;qizkwlM z5|qIEK}I&)huY?hM&Hbe!HCFvpsdB!8$$L_t(|ob8)ij>8}fMVZm;B>P_ydzp_)k?R-cRiL@&t8&3O zHehhtlmGw#0001ZCOPMvbNnl({c-%RHXz-u{2HHD@weIl6Ez;{YPhcJCBLqVwTVks zv3LbAhqBecT%!t^lDm!SXx3LsKF<~_fH^BT_uDj3k6RJ_B!BC3K$?(LFG4CgeQoYp z8G!rA=~nRC(`DnxJayXax&Ne;ein}H?+I$2w9=_HqxVn3000000M8_J45bHlOF|pV zqh8X^e`@z+Uj;0yq;mgO!8)=wcX3GyizYd?wWHR*BJE{~M)qx}I#gL$YbyPq+Fwht zf~f5DMBAv-E)|2!G9stW`!xT_SM7@Ogik1QT+sl zcu7$L?*|!}rDv%IMX(F4q~K)4U@9ZsD}PHuC7Hk)SVC!{S`jOb%f3=SOQHO>%312T z`5m?6#EY0(hmb<2v_hG2$znH>{9cc$8qTT+brs{JeLa^PhpbF zI@NBm0%p^kEx-X_F9HCZ%gVnfjbc<;2K0h_I6|G;az7YP`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPV-0__5jB!4tXL_t(|obB3M4uUWggyExcC+vSoXD>c9AxK+NNJwY!|DH5f zQqS}jFaiJo000000001hjLgi;YoBU*&+fn#%_`fKzAy`5S(fr*SMK%g+Q5Zb0MW|8 zxB3zBn%#km>IKKK`r$YOie0%)s~^4rJcerky-nDTWdPe|_^ zZ|I#keKYt8ATuqF6U|Oq^!$k3*m)GHKOY&)M+Wne0sf27-O%mi8#z;!_V%Yw9qR+d z`<^TcKC}GH?!b`dv zk6Zv{vkh9gndMc6<}wUO9Xc(j|DNyg+>kf~aQ< ke*gdg00000007+Y3sw)mR9g3FCIA2c07*qoM6N<$f+Jg>jsO4v diff --git a/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00004.png b/tests/functional/snapshots/nanox/test_get_address_confirm_refused/00004.png index c80fa832578d18c8b1e4a2518b82d7f50be84ca5..d3ed6d6af1cf7ff977e87495112cca07a48ef1cb 100644 GIT binary patch delta 414 zcmV;P0b%~R1Goc_B!7QNL_t(|obB6Tl7cV{hGE?CCcXcWa+m$VY^OF*U{Ue~-{+Tt z>%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00000.png b/tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00000.png index 6212c8bfe57f68bb18b3f4a01245d360aff3d651..33eefd2c139f645e4a38e895d3a6243b5a224482 100644 GIT binary patch delta 375 zcmV--0f_#P1Cj%fB!5{+L_t(|obB3Ka)clhg<+D)PT2pF?q2d>7onIGTD_jm|2=dm zPIws<=@0+_0000000000;4)v{8CYj#X*tH|n3H!%7C;{QoMJKP6+nu99`0tMgm3Q* zEGhym7k5==miIs7RSBvs0B(BKT(SBG-4;;9S~2t+y|6jePWD{x@Ekq^$n_1lE5F){{sL3000000002|55F}p VHHLO`4o?68002ovPDHLkV1l}At}6fl delta 373 zcmV-*0gC>T1CRrdB!5>)L_t(|obB3K5`r)gMbT)v6ZXHP-isetF_lRYf#&Hw9~Oiu zbOs191ONa4000000000u%*{Ik^UN$RFU#VXlW#~CKpOg#Vln6yK#YDG?rNfhyLSdA zWr3E9yDBqF`=9=*1l1M*H?3-}Sp9=;3&>)v82XjoTTtLN^nW502V!QXlGUH3+gtt) z%D^9G;ECvaBKn?)zCKG#A0C%a$VThC#l}2jANvNgxwkLBx9oTW+vCzNfbADLDEg1l z1F8eLaz3OSrmiXLZ%j!yt?Ai;Lo+SuI5S&ron&ISa_4O8fy3R8wW(TPT9v53bLYV6 zi5lfHS{pm1VHk)raQ;{NDteWY4GS)`{MK ztOdl&#MLnVs615vDb>l|mb-}U;8M4Ym$|+{bxIO=6a7B`0000000000z<+oGGxRlv TV$e+|00000NkvXXu0mjf;>fJ} diff --git a/tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00001.png b/tests/functional/snapshots/nanox/test_get_public_key_chaincode_confirm_accepted/00001.png index eb20fe5a337367e38f04825bcff03509c66156af..4d5a34c990dfea7be043a92a9da984a9709a2074 100644 GIT binary patch delta 798 zcmV+(1L6Gp2Kok&B!59kL_t(|ob8-ha@;TsM441>GWS2y+$A5WV$oQd4G_}E4&GNx zg8&3BL-xoSqiLF^X_}^KZs*rw|M&a7{`h*mu%$3q8%+c3XGY)l0^ZiXItLt1bWia6 zr1Ru3iRmQg=cM}JN8#Tb3DAq=&q-&GnX5OUhE+9Tygry&Vt?S=jE+~BS;uV-=hUnK z9`Z3}vAksg_KG=4*V&5qmXTe5dO<{~8Gu9vpbPJ9TCV>%+!KUz@S#;g%@%ag^28C% zLW@j1vmAx4CU&v;5A4}n(sA-z!=YiBvPn-c4dQ&f)#`@&v2{oR`nn+1J z(KZB5hG`^|*`ROv;8(zgcj!rsp>Ws+sF=|xd=B^&@Q7pR4JSGCR(JyAjj^ehqdg6a z6s1Epd`b^-q6rUxSIUV{gH1xy2W;GAO1F^+9UB1gsDHRFUavG}xNS;eBhDqm^dhSv z2n@hQYw(0nT}b=F&feS@>aPCH^cZ}S-i1ENrpP@8m!iwNS3@V}H|)%bP;^i0h`dP2OP!bL;Dgcl4KpFM$n~4&${4vyAnB(gjAI{WRdokxc?d|Xw>ZKh$bb8)Qv!-bsnx<)* crg;i~0gSB}1}e(DeE^H)QY)C*VT$^%gF9Oy&)&$`kd}x(WQ-Utqo_Itv z(IOJhEJvZM$=xMr0_KdIPX6qaUbbeJ+SPX91eixOauLnsG9^WvPsl2S%eQVft6X_S z`hkG?IRC&n_kZxQ67&SBt}o|Kek_HDqNZt@p9fMyJ#hwH=uN$F8tapvC)9W%Ya%4^ zMB5>7FiayE%m#hS2fqR~yhBf73=M~EfQlI%g^vNB0v>S;z2PKh-U?4(yfHTQaPBh^O@KQMuYOqOY`GCSrhIAW=p<@#u9)A_*#p{*E9BvzuD8#v7m|kQy z1c3>-Xb+wc$_r^cxAVC-0%ckBrbjz4!50#{S4TGYxJ-} z4^5u-A5~sgOU9e9d8;oT*3!fblc@qVe-4}M$OL??8k*++xjd7PnRz!fdIb$BdZ8gg zkoQur2BOtYqG9h#$^DNscj?DS2;l_>JEWSv_mzpf z5F3og#{mEU006L^uZ;5R_3D3~=jlrh0{u%>z_-)9PqiFtP1myKd+aT&@tsi~R+BWc zW+xN<;dzMi;KGuT@|XC@D66!E%1!O;*+IDfDmBE8an-wj!hfvy(`Do-I012j-_U|( z9SbY^O}fun$d~f&?tMcU0omnq>cwiAChlRAsJFP=anco4!Xi(8EeB zF_nm9vfQg|EkO+@XTfyFd#6i#R;F-yg+cC0fZCr0cTfv%d{_1=5v`$i%OWO?sD-Y) zB7GW8K9Uzkm4A_EO3+`RYTL5?O-lAS0Kf;cJ`J@-p|Sy0Co0onjwL2ts6)zOZO&?a z#i>&%xe4`tlTEaG69%UUQcQK>%Uc%whpE%S#qw>xqYYjA7y3`AA4fkzd?ryPRz)fS zas>ZgbpIUDz2s4KF-)Q5+79=Y>XBlXzUwNf1SF?Daew)YixTepLswja)W`;RO;9Y8 zyk+ilI<}$lBPQE2t67xQK&`XWHq>&VwxLcdY}r@ErcULDI84IJ z&5(m9p$a|8B*^68RtPTu000000000000000000000002MZTte~!t2B%SdDN10000< LMNUMnLIPldq+|FP delta 522 zcmV+l0`>i(1fv9yB!B8jL_t(|ob8xhj>I4cfV-Q$N$-E8xywFGVvPJqh1$*R_dPic zf`TH$aR2}S003;~D>M1^di6ig^YkSLf&QZ^;OlADr?VVwZLX!wx7ce~<2y5XSWQyN znx2gJhw!xaJ5%D?nq)u7_#$#?sv_4YNI^Hm)4G@&*rhqXDY z^(Rh^O36*A@0%>5)t4~XMUY~u318mQ;18xo2NTP${f;tp?O*6Wp}rmc2=Sgol~@(2 z0LT{nd(r(kGWU{2)x^++mTNoQSE@&fUE0@GQUOSIdw=5c851Sk_lK@H1*x75o|>Ro zCV0!-XLKw><5x_UWmd5$vw@mtr)8*RLM=m`QrOb3icO8mjW|r)OXp+*rjzmhHWXLm z{ml@ACm{%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00000.png b/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00000.png index 6212c8bfe57f68bb18b3f4a01245d360aff3d651..33eefd2c139f645e4a38e895d3a6243b5a224482 100644 GIT binary patch delta 375 zcmV--0f_#P1Cj%fB!5{+L_t(|obB3Ka)clhg<+D)PT2pF?q2d>7onIGTD_jm|2=dm zPIws<=@0+_0000000000;4)v{8CYj#X*tH|n3H!%7C;{QoMJKP6+nu99`0tMgm3Q* zEGhym7k5==miIs7RSBvs0B(BKT(SBG-4;;9S~2t+y|6jePWD{x@Ekq^$n_1lE5F){{sL3000000002|55F}p VHHLO`4o?68002ovPDHLkV1l}At}6fl delta 373 zcmV-*0gC>T1CRrdB!5>)L_t(|obB3K5`r)gMbT)v6ZXHP-isetF_lRYf#&Hw9~Oiu zbOs191ONa4000000000u%*{Ik^UN$RFU#VXlW#~CKpOg#Vln6yK#YDG?rNfhyLSdA zWr3E9yDBqF`=9=*1l1M*H?3-}Sp9=;3&>)v82XjoTTtLN^nW502V!QXlGUH3+gtt) z%D^9G;ECvaBKn?)zCKG#A0C%a$VThC#l}2jANvNgxwkLBx9oTW+vCzNfbADLDEg1l z1F8eLaz3OSrmiXLZ%j!yt?Ai;Lo+SuI5S&ron&ISa_4O8fy3R8wW(TPT9v53bLYV6 zi5lfHS{pm1VHk)raQ;{NDteWY4GS)`{MK ztOdl&#MLnVs615vDb>l|mb-}U;8M4Ym$|+{bxIO=6a7B`0000000000z<+oGGxRlv TV$e+|00000NkvXXu0mjf;>fJ} diff --git a/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00001.png b/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00001.png index eb20fe5a337367e38f04825bcff03509c66156af..4d5a34c990dfea7be043a92a9da984a9709a2074 100644 GIT binary patch delta 798 zcmV+(1L6Gp2Kok&B!59kL_t(|ob8-ha@;TsM441>GWS2y+$A5WV$oQd4G_}E4&GNx zg8&3BL-xoSqiLF^X_}^KZs*rw|M&a7{`h*mu%$3q8%+c3XGY)l0^ZiXItLt1bWia6 zr1Ru3iRmQg=cM}JN8#Tb3DAq=&q-&GnX5OUhE+9Tygry&Vt?S=jE+~BS;uV-=hUnK z9`Z3}vAksg_KG=4*V&5qmXTe5dO<{~8Gu9vpbPJ9TCV>%+!KUz@S#;g%@%ag^28C% zLW@j1vmAx4CU&v;5A4}n(sA-z!=YiBvPn-c4dQ&f)#`@&v2{oR`nn+1J z(KZB5hG`^|*`ROv;8(zgcj!rsp>Ws+sF=|xd=B^&@Q7pR4JSGCR(JyAjj^ehqdg6a z6s1Epd`b^-q6rUxSIUV{gH1xy2W;GAO1F^+9UB1gsDHRFUavG}xNS;eBhDqm^dhSv z2n@hQYw(0nT}b=F&feS@>aPCH^cZ}S-i1ENrpP@8m!iwNS3@V}H|)%bP;^i0h`dP2OP!bL;Dgcl4KpFM$n~4&${4vyAnB(gjAI{WRdokxc?d|Xw>ZKh$bb8)Qv!-bsnx<)* crg;i~0gSB}1}e(DeE^H)QY)C*VT$^%gF9Oy&)&$`kd}x(WQ-Utqo_Itv z(IOJhEJvZM$=xMr0_KdIPX6qaUbbeJ+SPX91eixOauLnsG9^WvPsl2S%eQVft6X_S z`hkG?IRC&n_kZxQ67&SBt}o|Kek_HDqNZt@p9fMyJ#hwH=uN$F8tapvC)9W%Ya%4^ zMB5>7FiayE%m#hS2fqR~yhBf73=M~EfQlI%g^vNB0v>S;z2PKh-U?4(yfHTQaPBh^O@KQMuYOqOY`GCSrhIAW=p<@#u9)A_*#p{*E9BvzuD8#v7m|kQy z1c3>-Xb+wc$_r^cxAVC-0%ckBrbjz4!50#{S4TGYxJ-} z4^5u-A5~sgOU9e9d8;oT*3!fblc@qVe-4}M$OL??8k*++xjd7PnRz!fdIb$BdZ8gg zkoQur2BOtYqG9h#$^DNscj?DS2;l_>JEWSv_mzpf z5F3og#{mEU006L^uZ;5R_3D3~=jlrh0{u%>z_-)9PqiFtP1myKd+aT&@tsi~R+BWc zW+xN<;dzMi;KGuT@|XC@D66!E%1!O;*+IDfDmBE8an-wj!hfvy(`Do-I012j-_U|( z9SbY^O}fun$d~f&?tMcU0omnq>cwiAChlRAsJFP=anco4!Xi(8EeB zF_nm9vfQg|EkO+@XTfyFd#6i#R;F-yg+cC0fZCr0cTfv%d{_1=5v`$i%OWO?sD-Y) zB7GW8K9Uzkm4A_EO3+`RYTL5?O-lAS0Kf;cJ`J@-p|Sy0Co0onjwL2ts6)zOZO&?a z#i>&%xe4`tlTEaG69%UUQcQK>%Uc%whpE%S#qw>xqYYjA7y3`AA4fkzd?ryPRz)fS zas>ZgbpIUDz2s4KF-)Q5+79=Y>XBlXzUwNf1SF?Daew)YixTepLswja)W`;RO;9Y8 zyk+ilI<}$lBPQE2t67xQK&`XWHq>&VwxLcdY}r@ErcULDI84IJ z&5(m9p$a|8B*^68RtPTu000000000000000000000002MZTte~!t2B%SdDN10000< LMNUMnLIPldq+|FP delta 522 zcmV+l0`>i(1fv9yB!B8jL_t(|ob8xhj>I4cfV-Q$N$-E8xywFGVvPJqh1$*R_dPic zf`TH$aR2}S003;~D>M1^di6ig^YkSLf&QZ^;OlADr?VVwZLX!wx7ce~<2y5XSWQyN znx2gJhw!xaJ5%D?nq)u7_#$#?sv_4YNI^Hm)4G@&*rhqXDY z^(Rh^O36*A@0%>5)t4~XMUY~u318mQ;18xo2NTP${f;tp?O*6Wp}rmc2=Sgol~@(2 z0LT{nd(r(kGWU{2)x^++mTNoQSE@&fUE0@GQUOSIdw=5c851Sk_lK@H1*x75o|>Ro zCV0!-XLKw><5x_UWmd5$vw@mtr)8*RLM=m`QrOb3icO8mjW|r)OXp+*rjzmhHWXLm z{ml@ACm{`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPV-0__5jB!4tXL_t(|obB3M4uUWggyExcC+vSoXD>c9AxK+NNJwY!|DH5f zQqS}jFaiJo000000001hjLgi;YoBU*&+fn#%_`fKzAy`5S(fr*SMK%g+Q5Zb0MW|8 zxB3zBn%#km>IKKK`r$YOie0%)s~^4rJcerky-nDTWdPe|_^ zZ|I#keKYt8ATuqF6U|Oq^!$k3*m)GHKOY&)M+Wne0sf27-O%mi8#z;!_V%Yw9qR+d z`<^TcKC}GH?!b`dv zk6Zv{vkh9gndMc6<}wUO9Xc(j|DNyg+>kf~aQ< ke*gdg00000007+Y3sw)mR9g3FCIA2c07*qoM6N<$f+Jg>jsO4v diff --git a/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00005.png b/tests/functional/snapshots/nanox/test_get_public_key_confirm_refused/00005.png index c80fa832578d18c8b1e4a2518b82d7f50be84ca5..d3ed6d6af1cf7ff977e87495112cca07a48ef1cb 100644 GIT binary patch delta 414 zcmV;P0b%~R1Goc_B!7QNL_t(|obB6Tl7cV{hGE?CCcXcWa+m$VY^OF*U{Ue~-{+Tt z>%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00000.png b/tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00000.png index 6212c8bfe57f68bb18b3f4a01245d360aff3d651..33eefd2c139f645e4a38e895d3a6243b5a224482 100644 GIT binary patch delta 375 zcmV--0f_#P1Cj%fB!5{+L_t(|obB3Ka)clhg<+D)PT2pF?q2d>7onIGTD_jm|2=dm zPIws<=@0+_0000000000;4)v{8CYj#X*tH|n3H!%7C;{QoMJKP6+nu99`0tMgm3Q* zEGhym7k5==miIs7RSBvs0B(BKT(SBG-4;;9S~2t+y|6jePWD{x@Ekq^$n_1lE5F){{sL3000000002|55F}p VHHLO`4o?68002ovPDHLkV1l}At}6fl delta 373 zcmV-*0gC>T1CRrdB!5>)L_t(|obB3K5`r)gMbT)v6ZXHP-isetF_lRYf#&Hw9~Oiu zbOs191ONa4000000000u%*{Ik^UN$RFU#VXlW#~CKpOg#Vln6yK#YDG?rNfhyLSdA zWr3E9yDBqF`=9=*1l1M*H?3-}Sp9=;3&>)v82XjoTTtLN^nW502V!QXlGUH3+gtt) z%D^9G;ECvaBKn?)zCKG#A0C%a$VThC#l}2jANvNgxwkLBx9oTW+vCzNfbADLDEg1l z1F8eLaz3OSrmiXLZ%j!yt?Ai;Lo+SuI5S&ron&ISa_4O8fy3R8wW(TPT9v53bLYV6 zi5lfHS{pm1VHk)raQ;{NDteWY4GS)`{MK ztOdl&#MLnVs615vDb>l|mb-}U;8M4Ym$|+{bxIO=6a7B`0000000000z<+oGGxRlv TV$e+|00000NkvXXu0mjf;>fJ} diff --git a/tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00001.png b/tests/functional/snapshots/nanox/test_get_public_key_no_chaincode_confirm_accepted/00001.png index eb20fe5a337367e38f04825bcff03509c66156af..4d5a34c990dfea7be043a92a9da984a9709a2074 100644 GIT binary patch delta 798 zcmV+(1L6Gp2Kok&B!59kL_t(|ob8-ha@;TsM441>GWS2y+$A5WV$oQd4G_}E4&GNx zg8&3BL-xoSqiLF^X_}^KZs*rw|M&a7{`h*mu%$3q8%+c3XGY)l0^ZiXItLt1bWia6 zr1Ru3iRmQg=cM}JN8#Tb3DAq=&q-&GnX5OUhE+9Tygry&Vt?S=jE+~BS;uV-=hUnK z9`Z3}vAksg_KG=4*V&5qmXTe5dO<{~8Gu9vpbPJ9TCV>%+!KUz@S#;g%@%ag^28C% zLW@j1vmAx4CU&v;5A4}n(sA-z!=YiBvPn-c4dQ&f)#`@&v2{oR`nn+1J z(KZB5hG`^|*`ROv;8(zgcj!rsp>Ws+sF=|xd=B^&@Q7pR4JSGCR(JyAjj^ehqdg6a z6s1Epd`b^-q6rUxSIUV{gH1xy2W;GAO1F^+9UB1gsDHRFUavG}xNS;eBhDqm^dhSv z2n@hQYw(0nT}b=F&feS@>aPCH^cZ}S-i1ENrpP@8m!iwNS3@V}H|)%bP;^i0h`dP2OP!bL;Dgcl4KpFM$n~4&${4vyAnB(gjAI{WRdokxc?d|Xw>ZKh$bb8)Qv!-bsnx<)* crg;i~0gSB}1}e(DeE^H)QY)C*VT$^%gF9Oy&)&$`kd}x(WQ-Utqo_Itv z(IOJhEJvZM$=xMr0_KdIPX6qaUbbeJ+SPX91eixOauLnsG9^WvPsl2S%eQVft6X_S z`hkG?IRC&n_kZxQ67&SBt}o|Kek_HDqNZt@p9fMyJ#hwH=uN$F8tapvC)9W%Ya%4^ zMB5>7FiayE%m#hS2fqR~yhBf73=M~EfQlI%g^vNB0v>S;z2PKh-U?4(yfHTQaPBh^O@KQMuYOqOY`GCSrhIAW=p<@#u9)A_*#p{*E9BvzuD8#v7m|kQy z1c3>-Xb+wc$_r^cxAVC-0%ckBrbjz4!50#{S4TGYxJ-} z4^5u-A5~sgOU9e9d8;oT*3!fblc@qVe-4}M$OL??8k*++xjd7PnRz!fdIb$BdZ8gg zkoQur2BOtYqG9h#$^DNscj?DS2;l_>JEWSv_mzpf z5F3og#{mEU006L^uZ;5R_3D3~=jlrh0{u%>z_-)9PqiFtP1myKd+aT&@tsi~R+BWc zW+xN<;dzMi;KGuT@|XC@D66!E%1!O;*+IDfDmBE8an-wj!hfvy(`Do-I012j-_U|( z9SbY^O}fun$d~f&?tMcU0omnq>cwiAChlRAsJFP=anco4!Xi(8EeB zF_nm9vfQg|EkO+@XTfyFd#6i#R;F-yg+cC0fZCr0cTfv%d{_1=5v`$i%OWO?sD-Y) zB7GW8K9Uzkm4A_EO3+`RYTL5?O-lAS0Kf;cJ`J@-p|Sy0Co0onjwL2ts6)zOZO&?a z#i>&%xe4`tlTEaG69%UUQcQK>%Uc%whpE%S#qw>xqYYjA7y3`AA4fkzd?ryPRz)fS zas>ZgbpIUDz2s4KF-)Q5+79=Y>XBlXzUwNf1SF?Daew)YixTepLswja)W`;RO;9Y8 zyk+ilI<}$lBPQE2t67xQK&`XWHq>&VwxLcdY}r@ErcULDI84IJ z&5(m9p$a|8B*^68RtPTu000000000000000000000002MZTte~!t2B%SdDN10000< LMNUMnLIPldq+|FP delta 522 zcmV+l0`>i(1fv9yB!B8jL_t(|ob8xhj>I4cfV-Q$N$-E8xywFGVvPJqh1$*R_dPic zf`TH$aR2}S003;~D>M1^di6ig^YkSLf&QZ^;OlADr?VVwZLX!wx7ce~<2y5XSWQyN znx2gJhw!xaJ5%D?nq)u7_#$#?sv_4YNI^Hm)4G@&*rhqXDY z^(Rh^O36*A@0%>5)t4~XMUY~u318mQ;18xo2NTP${f;tp?O*6Wp}rmc2=Sgol~@(2 z0LT{nd(r(kGWU{2)x^++mTNoQSE@&fUE0@GQUOSIdw=5c851Sk_lK@H1*x75o|>Ro zCV0!-XLKw><5x_UWmd5$vw@mtr)8*RLM=m`QrOb3icO8mjW|r)OXp+*rjzmhHWXLm z{ml@ACm{%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00001.png b/tests/functional/snapshots/nanox/test_sign_message_long/00001.png index 77ef42c3658d56286fbb62425d6a2a8528fe1a6d..e978fccbe33053aa3a434fa93e542b5cd92a917f 100644 GIT binary patch delta 842 zcmV-Q1GW6(2H^&fB!4JLL_t(|ob8)ka>O7AfNiHY$^DO%yYwMl$3Z}lpLMo;PrF8u zD59cittg73D2k#e()lu$zwi6`aa|Xc@^KKB4j7#e>WF4b9~3<=nRGdD0eEvQl)I#mTtvlglsP$-36h#rjaxIus-N}*zd6dqKVfl(Z zztMd*V$7)kmDmJp7^B$HdY;V`y6KZ2Y4H2UIniN}CK&-}e4I~Y4AWPvMTkmCUN{3c z0=mhJ=JOxOoc0zj$i2#-_=&GrK8DyZGvBUy(E-d+)PEj9!|08p(^xg^fN`dpk0~e( z!H{#O%w2b>uG zMMHDi0$s%)D>k%hq`}YMG=2S0#u!$lY5xZ0H~-*#s45!rPjm zH-*}%tAC(mm88*75Ls+Pf6Q0gn*KHRLXseTEDL@!fy`MxbyJ2?Lz3SC%5})2k|2X6 z@VTso+UPBVo!YqOb{zD<`C`_wbGW+?^mwPB(McDxz==Z80mCR( zSjF2dMmGZZ$f7EKxmS={P)VR-XK(jHMNt$*QGXOgHXt|((#NNn=hZ<)P{O|vW1u!l z+ItLXL~I^)(a?vzYmsvdpwVs3e^V#CD!L4;GF8l(qvOF+nAqns8oJEJq)XzU+KPn5 zmpVvVfMRC^*t2;duP*KIN8195IY4qPGT(7aLX!5tr&b?1rfBGOT|uuDF_J8Syf_pi zfJ5<#%WILUKO7AfNiHY$^DO%yYxr8j)Q<8k9D?uzjloR z@qvn_wW27Bq9}@@NaxE~{=V<$$8}v)%G;5KZaEqZvRt5WB~>vHbarbvOU* zJXLwU7<2aK0qKl1IX}koou@mX2F=}PFQs8G%w*;*;SPgJ&Owg4(9VZ3LizQH(yNytDAdcoo9pqYYiVi;G|4(*UFMK^@WD)5nT?I_6xJ zR7;>e^qe_gg{KQz);oB__#YnNsg!0S(u@);#JZsN>g-IXW>P4x0;HiTfOfQ&sj&s* zQ1XRS#peK;gnwxvrc|6gdwl*rAhd_tg0?>&n+asj@~N9Llo^uz4p6Q`9+dCZ7HXrn40dYcn%i;E2j`1f$IjvIKG5q;og3glpWZ<|kEIP}xV#pr3Y1>-m+wofBp+PZ&tcr-!JBqae+xOE|E2ul?0+fGESZa}5VYanb03gap{Bd%hfk zKo$?fHOX-R000000I-~&pnWOjx;W2MO4&{+rR(06exB!@p~=Ih*CmhfCt~~x>cHJm zZqhHV^z%cV=QgCav>X?IBgQpXUtqnVeP=A?kfSDbTQ;-q;eTSLj{v3b+=*-o+Y|4v z>Wgmo^v)8c6r-UunCzsD0G4J5v)|Hr)^%5U6^cnSs%kfG2jWwFmz)NuCm(hqqCLG1 z+|_w$D5aKQyQeWy8)qAq%qgfF_vR~Q{?Tb>DyN%_)y4%|&N7r80qm1=>>;ctvgXu7 z)?AtfX;I3e;D0#_?z!C0M)sr8YN|^EeE&XRcJ~aHADx00BTYd7005TKm3<;5>*WM% znYtI-ywQ`Y_v!?C`jZ>Li?#}CwjNX=uxzyyg}uqfmZN(jWuvR3u0MLB{cXn`7NbC` z!FD?3LQ13`?S^{hu0LI8l*}&ojOLVyYUlzfk=D4tHh=fNW;FnvrWO#a%OZoP-`89z zLV8E`b`tNa9RUMv%X-5;zLd8DmP&Q$Q7O$>k))L#@!>VFqL)T9oW0O@~qkP&MxFw@J^UjyW-w&e;JwOKuC(P2!5qH zGfLY)7k@{k(wYnE1N-V&7X&3)RB|a(^^9ZD6ytJcSDuVWwq6m`t9nYLjer!C0@rJ+ zYly0$@#Dd?H0di>8|cE(b9mFiESCmpKWVy`=m>E2{km7u9_kfGjgFn4-@Q;*b87_u zvAhj^4sV)*zLJ-n4K?zJwK)I)d>`IL#j>+Hu7C4b^E~llS_M6PC09Pbv)t{-2>p#% zErii?pG~$y6*BK@`$&*S#zJJkL8q6Ne42EsyahlK2(W6?fNi z6Mk`ppC9TtcS4$$+HvtWlDOvT3#>P^?~H{Ua;-_-mW`}?xPO@GBS7gpcOV|Hv~x=N*Ip(JTWRqe*@KzxetlG6b7DyN%Fs*MY_oMk9G0@x?#*h5$kWRp`5 z+2qnRNKGk=f`8{MxaV>|8`+=6R8w6V;QRLhv%6=|esl_2j5GxS003A@SN4fm*6jpy znYtI-ywQ`g_v!?C_>&vJi?#}CwjNX=uxzyyg}sT!+R;6cqS4h+*B?F5{ZGo-rW^v&8By@kz>I-VOH&md%yi!^DJTZl zYpZLBs-f}Y!PJ^`%hd+DaP%DBbTG@MLE2B6?je-5`|vI*mYvmcoqxxg=ZP27D(K-Wx$^nWa`=(sOu4yJ&-{QyJrRf001`d4+VLIJd$v!tN;K207*qoM6N<$f=d;b8~^|S diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00003.png b/tests/functional/snapshots/nanox/test_sign_message_long/00003.png index be34227ed9d65d547915322325cff5b7232431a5..5672d628ecf2b5cee40d619f9d24a01bffb1c48d 100644 GIT binary patch delta 745 zcmV$*xXHMWCn?>Su_*GnHG)SYV@}W5-u=$gQRfZDa7GRez#Lp8?9)sfBEbGFn?3 z{TB67TS5zI%(pf)03Ts9fTf$l>{Xg)hn`Bm1*JOg7KSzqYLiDy2eiqDO+<90w+&YY zFKtSxC)nZno;81n$P{$j?%gFN|LAm?YA{UR;k*+cF|VQQ3}9DI-y*CRvejvX%3W?> zH>GmpQn3kjZGU9{G}cND$-(~nfb8Kp>3=o_Ek;T~00011lP#en`5)b5r?UTBkef9t ze54v$ept3qx`ZhWy;hl_zm=^VZA$hM4bQI2KJz|C)f?ZB+rqAd{;NkN8HB|7qVs?d zo7ez`w8$y0bk9YOISApj){*%Su-hpcT>%=idH|L*FKfAJy6*BK;{!H-3NSf76SkP b07?7<8R#NHOPo zh8TGS*?5lw000000D$TIbk@JFEB!dnQ!06!>$*}fIktm@moA;>DcP{)*|VEZPvs@3 z8ZJ?l=c|%U?jBl~`f1{~r*cUe3v4uW?D$F!xz&`RZ4AD(N`Dl?XMi$xav@uyjMmad zzeT=Ome4{P^Q{dHz(?2&V5z1sdzI$drl-OYnv9f!0002YX0(Jd$bah|dno(A1-Y5C z!bhs1>4#+-rAwI7&?}W0`dit`(WYcC(eUiL>@)9URK4;2xGk(o=)ZbYl0itEFFFqh zv55_!NzQ!aR3NMaq-joN-f>8Y&aUw_-7Z838h9QsqJOzluFq$Omc})j`GVPuT;^DqmrQ15Zlo6fR*v5yZ~)$0@W1%S3|>FUpXP! zgU$zJ8hpP*@mj>DMjuSzrjgMHLkVc!L2pVvvo|018X5ax)}qXOA@p>BvgbO89&iYX zqurrmuYWjcl};-^rOY6SxYFZ0HfRl4)Jn;$Rfg1WVf4&Or}kSY#`cF*h)F@6>GGRb z{$MrK*OXiC)Qs$WB1~KhM000000AM}7d29U`lXdbahW`(l z>Un%0iPBn<0C|v2uSL6MqrLsWbPX)3r$Z%G>|=d}Y>93e!ZQal{l{V3Wce8#P#$h1 zLO#~)(O=)gj1E{edro2A3^+PI5@pS#^j%Fg$10lrEU$ekXL}&A^MT9~Ox*`8Ig0@R c0DwXK0bfZaLS$l!#{d8T07*qoM6N<$f?biL{AZ!ny1)mr#5mcO6A z?J7BE*l_hs{zqT1br0-CSh<$p#`29i9MFK^@L4;Ph}NWx<$sZ@?0wn(1Tez~j>P^9 zIvCrf{$M&n2QQ@*rqSEgX-A^5X>of3P===%y^7{ys)*LbfTV|-jZ2E3;?n_r@<9_3 z9O-?-)xis!lIjU`gx)jftME)g({>*&G5LpQ$W+QOk=l$kSnyefqE7%ibFNLo{7JMp zj1ZbpIS|&vtbYhz`sA%JOrHE)sx`C6v&Q%L0b56?y>e>`It-P9f*=TjXRxmXo>gO1 zJQ?af-!JL_ccfB8Z6j*iWl=QIeG{yKGE2mciF!YwHGn^tZ_Ns&gHu`!Wwv%831)hd z`MGSb3LE0A1=%-;um<-z2L2Q_`VO4sXrYqKs3@q$X@60MhZpDMBuM zHha5AREhJl?=4l)j!yvJ)zj`3MoCSr!}QKrqL*NCXg2(udSn7n-CDcK)pKAu=#^eC zT)AooU*)I25ZcxOhHUm%4L#ZV)Dm7>$%Vs3errhl7e3Tqg>35Rg9A(&Ir?BLuz63s z5mW7AE`QAI>5XsV)}Ew0pFc+IvO`J{)IPA6Kbs}`SxPURqT3?Lnn9>~4ldv^v%S)8 zwHCr#VOhwO6sLUgV@;w&!oSmKh04`5;5ALuQ;gGQ@RJFL_vJqK$ZyT91J-0qp?YeE ziOMdxs@x4Ms-ZP?!l31|_ns+zSkCvVTp=difM zsc~YLa%Q~TxiEF)``?CM&Poc>zI6+NAP8R1g$okZrr+12i&=X6D(C|Xf%z(k7sx1a zl&^>Ryb>+KNU(All@Vg6j(8W;x1kR3s^OacCzK>r5-j6)>P}Uym%`du-v=BhWf@Qh zW@rT$7mHfZnu@6{WlZtArB;_2$oao2*g7ko@p95pnsxvs(n{VUF}kA!yQa7`3&HRn zl;TrjUrD}^WASg<2e`lC3pnblv8SVO<72lI1VIqo%O6DE;yn?CMxFow002ovPDHLk FV1lFyw#EPe delta 883 zcmV-(1C0EJ2Z{%fB!5v!L_t(|ob8-hlHDK-MM+n7!v2@UUh+Xg5rl*$Fm~yDbotqU zWCj5jCn*I%5ClOG1i^8B8S|G?>P5~OyYo1ul!Ez7B1ztF@K|Whp9ub`{?c@q&Bg{e1FeH>3!Kg0*LMddt!fQ z+8NuU{$klf2P>r%qSD*bWkXJVlj1f4rVOKa`g9tLu`E&(1DqCWXgU>V& z!Jgh%T;2G>IfoIhi z5l_0h&-RNNz#Xm>QR@iXc3Bk7>Ane;fF(=FjtM)TkS2gX)vsm+)4?&V21};9;5f6q zN&Hl&7r6~_)`IMtLs)|Q90PwcD}4vfax_y(CRCKE#(!y1hKCYhfwV=b15$zL87YD< ze75w)ZkWM&FI}KCeV4YUv0Sm(?1Ap>i|PE`>TeYtbJ?=FD>N4?!teyiT@W4>aT)Ub+o|&7L^=r zuoYOnCx1@FM7x*^BYS$|Nt|vZ-8udUvC9rBMPU2DUjA$;r=O+t(&=iRnNf$ zye76+(yf-lJq>Chlan2@MfWw15()nE(4sFYQ?%}_hTLb81 zOQw2ihw#cSxQfgTDAmv!I-%2c*-}kE*}#d4nSXtocPO6!K%-s|pH33eqo`!*%t@yw z=5v^xW7IgYb2-yr?p&BU^8If^FGmxCq^E8{5Cp;Nxo|-u+VuNcbV-)pz6$!lLSVfL zq6IQc9Hq-4KChf+AtYG7j7kWxOGC5??AuTWXw^`s|1l*=kpxTFU78aW>!q+Z^!tDV zxoj*Q>cFhvVnV3}=~PTN59Jd%7P$Nb;24{$%>3n=Q**wbFP@v+wlf*=U)>d0HvQi7_T;vTupf!<6+rPg#Z*sM53LY5rO&zk(`o3ASWPFU#b* zxp`c+jw66PP7YNk@U$s4pAnZsur%8meb<(ylDE~?U`p5&ymauX z$!jC~b+Fb_mwzVs{&T?U?rF4doq{$aJjwz90Qd;@eT&w@DLLq^yC9c%9n|15Yqg-n zpwbz{h|mW;Rybn!MQrY%kqeJE=3#|1IkA<}Dom{jYTbkpcXp2eqn){KXmMcmG_|7v zf`@LNEljk5W%gJ-^So>kZXLS4mwE&&I)WI9njBoZ7=M-rVZu@==gM-XTz7&_ct6&; z?xY!HM1LDhs1g0mpbbufS?DC4AfpYILc=?MBGx^eDz{vl53kwV2?zHtX7E^igD2hF z$y(DXoTZ3Lvt*Ua(0-~44PmnTBvqAE4LE9{^om}O`?iA-ky2ZxRen&;RE+>3k$%b- zb8HghjDI-lsp-PfTYaamcQk<4=)Ukh#+Rv~d&mn|b-jWEBcLlWRt1FecC}J#p{uQa zXM+m>0001RC-HygEKJ|p(V9?KYjdl{cTiB=cIyoduuu)H9HQDG)fWS&k5=jIjY3u1~-> zw{{Qg$gWel{Aen-l(B$%1ILamC1L+9QJCdCw~7_pX8K+TT8GzDFVKf(Ah(}epO%PSOS=G8x9ndfFQ*1h*U3}1m2#)kNaAokqP>y;6 z9iI2>`7A7#plRH@EMonk=~gPHo47%}5g9heP;>^MJEv?DrW4WX(8HCFgel@s@Y2c0 zrtXdC$HiJ(U4Ihr{r7;~!&7Nry97Byyvhba5Ck7Ve{SJgI3)+Y^%P_huY(#~Wv>=g zSX4R_84>uRhYCmNxd_c&G;-nfh8$ElqZ3Cdqr%V{q1FkEnBzSIly+ppP~*VvWy+%i zl7((wEeQHRvwG}ad0w^&k1pNbOFsiPT|ulwjSeo{41e2;Fk-8ub7?t~t}9>?-j5Bg zI~fK!qVEP0>WIEG(FZ4qRp=y>AV(i;1%_9CBR0L9YL8sbm)B@>#KrxKS-ci^@MPK? ztu>v(Sc>R0OH{c`bgo74Zui*2#Zyv0Ol-x3-@{4jNYX%UB@Gt!! z!%2)&Vt=TomIuvfwOzj6(E(Po`@-)rzDy1Ep>AN^^9~NofT_gT6(Gv%)k>~~skZu^ z18xumK@bGNo#g+KSr9jEXpN}Lwdtzy9TXJZns(@bjcRD;5Y!H#zL+q5v`a@DN@KOM z%SE5z)dgLhcGU?&n_SFVOyr87^m?+Wal$Gq&2f3p0AhfP9WudC5`d;IQbW!7%S{+n3QbOjtZvZgqg}4LTvAhCDAYzyPWYq?FgW@0*5KNQCv)bzM>(HoZ6QWmPJgTYrqSzDid<9oIrzNr} zY&UGT`XAH2N%IfsY}nI0GzK4QMgYq&e%ZTpk~KXNb^$!rDju4!<)nGySkM6dou4%YC$hz9 zggBV#c2i1ME`JrDKwB8uOJ%9(s2qIwIbcKIeCXoQ6to#>3QCeBNe*J|#$%6Ab9a~` zIYNvJWzS*@B)?ER4KN(LusA+_Lx6?P-o^BYG-T6U(qMpPDQxf{AxLUC)pImr8Ma_b z)VRhS-0?WLC8mT=L7PW3>yh?rP4{O_nfz)9Z-D*BC4W{ZZIwG*HrQ6N2Jd)1@ZnNK zYbx5jDf>Gv~YO5x9 z8q8vxL#uFe!j2$123rFFJtu+_B(vxkJZh*UMI{bwBVf9Mfr8Q^CKUu?q?@VDskRy# zo|zm6&-s=YGRKk)kR(ZxSO8jM{k=^li`#|)%YR4g{d)Dor-Z!q3OdNF+gHekSvUEb z6My=Ovw}(d)%XrPk;$qO_wFcc18>mGE=G z5i_QOVKLiA?6;wt)zc?{2t(%<=Li`788BS3nVkV1Kvm^}jK_|EVXgw*RlbRh+>>H-&4mZ z5dS?%rxXN15ClOG1l##DQ~18`{NuW=R?6et_szpgEW&*2x~^6pF}*f!W3aJi1c;FFE8gXk?9d}&7rLr&F|c48DvkiK^BYaUiDGdc zAr7Xy-E5^Rmw$>kP!>k;2_p+JoX4Rcg0X7 zM~HE*>{)DqdgT3D)BQzLLw+^5H^Bbml7A?amdYiU1+i5|gEzb$c)1i& zxY*0y{XqFY^#YpD`$+BY z@p~G=BR^ORU)TWYv^MxQo}7h(P9;YhxU!>qHS$BNh(13SFNsvJvsZ0)Cr8jtNvw{R zII`tgh=0M|*gN6Yp(cF_ne~|qi=9dLLGq|_sd3#(F(2G^sG&ev9F;;1lIlz_$~;|d zb;zBDVKL62RhT(pN8la9SOWk($Ac3-Jn@dfqK2L$CBA^M5zt-1a6$axCIN_%X1X@J z+Nx`K!^Ak4=UZOL97{An5ClOm0?-=s?`<-f-+wj?SUzI!SF0a3CFH4B&`xH}zFa=c zy4ly9_|sRM4IFv6qx7jw)@Qx0wn~a?{w~<^E2a%_*C8Z&9x!RQ{!#?_H^E#G-@%# zPsq}$ho}7hkhT%}mUc}1^>j|1$mUL36@QoB>q{;^WWv1G`+wiiYY4t8K$tkOkSrmm zVXR7jROe>Hkc1GFeYwS?XUqy9$<{AfTP9i4pCmsb<5{C+%hHqRLw|~|GGGAGd9?M<&ZuMmMjEpYlr>uni?wfUxtkmdJ%< z_tL|xWmZz%Zhvy+&99mB$kI2N&8xkx4@}=J>sR+vZ+Cjn5y*L% zfFtSI%w(5wTkVTpdk~9^`p(0NWdk6~oWeFnqg}IFpDq->7OPy^pjO5z;b>-3EL^Gq=N%p@a_A(z)BLvu#0S8Fe`MToa zxD7Z^p|6V&LI@#*kk|P$(m90i{J8I1Dp^hlp>*#mJbbF|`08<{@o%Ja>O?ko(yI8o^d2v{IzVHe%2Db zu-d)!Fl(8WG=I07QhE1l<~*|WUCrjrUfy1H@bPoN3v+Yu5ko2HWuz2D2q9zv-g}Hy zNT_nlqcSu=Dx;-Bvq7Y;y1B?8_- z2??$bI)w#eKq3pW5Q#K`%rS6fLU><$S07}2#6ENoJ2dDM@l&4LYN#YSUV@Z}OO=Ra z$*d$vf`8(xIhEYk*Hw@V^c z@zsf@1CF<&*RnkHAm{+-6ABkEt(K9e=m}cCBWyLO-#rEGf1I4XR$v(zywJ-YYK`b)so`)0520)iNm0)cQqO)3`t`vS2t6bWlR>msjXl7C_ zJ=i4$`5j-=C57DadYN4Y!23cca(Qh@=Ajg^m@QU-{tp@^$~_PGYW=0kB_V_mLJ0Yt Z{0AG>C7lhK&fow5002ovPDHLkV1nBaWflMc diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00010.png b/tests/functional/snapshots/nanox/test_sign_message_long/00010.png index 745d08100000048f40d136780bd924defe4a7f50..b9ab399144a068257fd543f7c0d456c84e9b962c 100644 GIT binary patch delta 393 zcmV;40e1e228{-gBmvZsB`E=Xu}?_>eQ@YZCK$nRxZNbU1lh8r3TkAQr{J3>KuL^;9r*cGhE6Cm&O@Z)5n?~fzwkD zSV?jcZ?O*mAi^E}S6cx90RM(o*>3+B{j#^9-QLIZ9qiqRX_}=|nAEmlwvuWKkWCNY z+K`sW>nwL_-M_@4jgjjnHBrptcab*z1r4(Ul5JD{ev=5pr3fyXHrmLv{w(o+XP?;PXnYez8+Cvao0vU&9Q^cEsnfFC#q9oCPtD nEi&Hml!f;P0_Oq%09e2;aIiK#(}*1q00000NkvXXu0mjf545=% delta 391 zcmV;20eJq628#xeBmvTqB`E=Ou}?_>e_tNRvdLG`Jf5+yeVHJ}XkSvDHD^AtS!L&c z5&eg#PKNiVA-EdepA7n7C5S>RsW=&ZFci2q&LH1yu@ST7vtAW0tjD0kH(^`FEHj8H z#wic6&T=pFTpLHkcxJ62Z(6kBC`1vWm9CLR^BQM$22`)BS}gzdRON3sJXe;5f1vKO z`=#sKnhqdh(S{XHW91^;-DQRnS88w_BlTTjrq1Et1DclQ>Jd*;oToG$*7OLRo_fGa zl9PCgeE-did6c zv_xKKxl`+Y5{EWMuA9_EF^@;ub@UfB%nnGlP4)XtA`F)zxMVc_y?zV-bF-P&|k146r>*7Nx-PO09meQ!}!#Xc%9^G--CwaoCp;o@dU2n8y|w l?|90>`vZY<0RR9j;1_RoHa&N6?)d-!002ovPDHLkV1hs;x%vPA diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00012.png b/tests/functional/snapshots/nanox/test_sign_message_long/00012.png index fd105b256a0d9a051d74421becaa741ae5e025e5..c42d5832475003794062a82a897be7378883dfbe 100644 GIT binary patch delta 787 zcmV+u1MK{)2C4>-B!BTqL_t(|ob8)Qa>O7EMM)|*>H8nacgeyPil7l85bf4mq}muH zEaq>glq5-#BuSDa+0K`(*mYg^kJsx(rG#@`S6i98hGK1lk$RaoIoHpg2rH`Wd!J^AArqQw>&=w8>m@Edg+LK5?*%-zu`r+$FH|S1Kcf-9%0b435-{FQtL{=L=8#}6|I<3K-Ifm z%zme2BTtAy2s!!zg(b2MuDL#X{0@~uH1yTBKAi}x-f6fvl@VPYreAJoe znHTJ;ca4!isrAqgv&=z_bv!3os^8)eSbDe{Vv$9Nhz{2GUsD=U%YHd-GzUZ z#(9sTqPc?`%ld6CtffCd{WF2mb<{_zVI!ar zuMlh!qjDA+GXB7&IPk5R#&t;b4t*gL&bIC!c@Ee-z!}#EF3w4kB+2vn1^ygX+O7EMM)|*>H8nacgeyPihw4B7~1{cBGtwq z$;^B^DFFZg00026oG)Lo>$>hAuh)x9+0J!cWiWSyYQQ;L&QRqc(<@(gz8z)Wg0h;p z%e%^|TRHvpN0}!VY|FNGEc`gil-w;(`fhuQFD3DH#C1|35`Q_fuM$U?H3Ed5k`u`k zvft%fW(7 zL~TzmEAH-?ZB=qDL3T!Wy{w;YNCKuH`wW}3`A4RjsXD`CZ3>qQ7}|!CBY<2veT%T1 zNEUA+BvV?0Tz~%7xUfw)XA2%lUJ1!dW2xD=-97dku)Z_;JUXYK#c)#)004k>%-C0` z$L5l7?`l-!Wgz-Vc-|@eMi$W?zuqbhaJM{pgdxu+ZGBZIwW?H`Xu+tVl7SfoRJ-d* zj%b(UZ($A*@^lqfW0M0@69vn&9mS}j_9q#1;Z}W*C4Z&?Wc4k|g(@7qBU9c72#~VZ zCsQ{7xg^R}R%xQfTNb#Noypes?cUp`CI?*Qy41$qj_TV&VUQxKh_!&)w-8cGgb~!f zk=RY$6w^Qjv(QeIN=6$@C7^m|twKRYx-9RKT8G#hs8L|)HMJ4XN!TKY3bH||fRcwD z?hUX-ntyFAzme419iLASwI|B@Xm44;l$;@40WAsBf;jzlBg(n|f6lZ?;0tSj_EATk zXI!w$-YrHpO09=}nC1SUytQ+}SQH3*A0V$ty$DOFad5Po0$J}Q%L)t%z2`D%Eje}^ z96ANXVqcBdbKnfeOJ-l18w~08MyGec6_R5x?zlJf7pbQiJ`uRc+ zrEgf-J~=&fES*QgKf{=kJM*k9T{NsbX%$dV@*TM$Q>b$KN_g&QJo%;=>jqy3)(Q-3yb3 zQpyCo7|*%q+i)mB&A3;GK>fi~m8#QC73qVj0fj9ok z65ziJs-%^hO0=Ly^VqU~)e}5>XlnQRo|U)F36F!7$!H@!DmB^$;%<26<~)PUk|KOD zi;?b?#C^gCBp??eLk`>vh5Lk$ks_q$ZcnGa0_Ht=pnoWDXsigT8Ay9Jvxr4ay=gE% z8n{?KTxRPi#1mf}k=G_5vFE-%9B)oQIwS|L<&-M)P8vau986_(c+XGg`5yi_+r{%C zHPoPJCMYg;ebxA*)IQlsB=J>mWjZ!Rvng|GbWo*ZdS|2-gO1z9Sz;U;j%wxNcWJ%c zkS-T@&VNb(``%{`hej4Pzojf0rC#~+05z08pIWeWSthku>T}w48CdAP*x+XK95L` ziBlg_OIiRjQB#No=OvkL{ydx|i<$*aFb|kSX?zRY_0m4OCd9T_R)}%E7v|z3gSF4u z&MZuys&s-gKxyxy^PvFe> z+oGEpUw0?(N;N#Y1pNSKJ(BEV!vl~Y2!bGR)#WtiyK&lh?q zeZ$K3$?2hE={y?#8OD^{nP+X&m11j2a*V)2mOR1Of;hseD}Mm2l-$U+fVEln!6wRT z!&Wdy)bDg zrA)Ak@tk|UjR_^F8TaZCs6UvhQgyni!ato$N>KVPcCe^Hi&Ryr*;o^mbt$0O6R8g{ zs=QS^k}4%2Lw{h@YRu+-_IH5)VzgN_{t|XZ+K&c75Cms2Ywxjo4}<6T7lmF2-uSyE zVE!(sl2&di(Sjb$W6S)R^B!zJPuYSqmB5e)My)syWyFe^9-^|ikOR8 zjGSIcrcd~Q1mr?w$iehNF@3_vNDcyj{MAvt(0r&OVL(g( zP=lhGpt#ueRpXCR`(!7P#8rp&3)L6wf_osn7$I&K$diE(T=s+Ei1rJd!5 zbh%9DtbYWs?|tTQXk=0ITgsAA>eXBxpoY@tQx01fH}Q4CA2jX{HnF}O4jx-dU)i_* zyX;cT;wx5Cm#}ve9b5RFA&BUw6j2C*APCN6%l&EpP0_)F{U<47@J*|RvKnFac|>|l zocfqr(gKi)nnEl%FUfTC=iw?@)GTmkd#6cdL4|R-KI#z(cqxZA(_UOMDZ50P^Ca7NRoK zbH`nYS-P?o2{jXaPPtSGV;p*h&|895q?3tj zK&{s}wTKT{FrM9-jiLECzhK<;oiztzHe%|Y3-3+DHmA93s|oL#SB@(hQ@PO6oqhgZ zQIoED2jHu4B7@Y98TfoKsKZD%Q(6&|Fisf1rP{47oqrU7(9w1ut7Ks3=db|GAT11b zhYqa!G60SzuyP3~Eoy;S-zWsbv9J`c4=(7i$vmCvK^N zachlLcYnk67{Erx*Mq$E0>C(gMb#({=mn|mXz-e0{|;!*0Rd3I2UQ(yIW*Bw7pH!h zrElmzhZY;t!^3w#vy%$mR+iso0#%mW2SFu-5JCtc>SXH%kh1OGbufXl&|xe zarXc1PAAVR^tX&rIWGVXcJ8vRC_%M8rQIoM5x#X*C>G(Ka@08m5<-W+=;#3q{*sWa fgaIIg5Hg-0u%Q827_sd500000NkvXXu0mjfe4T3s delta 747 zcmVXDBg>9!h$^Mt*Uiy%^j)Qn4_!Di<_jF4V zL?9SR8Ui7N5JCtc%lUF#6Jxx8T-Q~TyiSZUH|Dlbn1_XFQsNv{E{3!7?YL%tavzm{ z0^!Z=%IiaZate=-V}*bp$2IwoB2!drN?YxcpiK;%j4f&6bAMtFQ|TH|<9>Ps&Te8Ys;+yybkQX1d5S5vp zJMK=*(v`JHsF~<<%B@Nm>&otT`C75mWbEcyA)MIn7;LP59Kja$M1v%7vEh?ECkM znsm)O0AGa@8Kid1z~_TO9Y(sD(u$abal-g5)oyj^q<;W}j<)+)B?CJ@hXr5;X<@KC zbYR_=0dPEll}qRlRGlJieMP3f3c2UoaPL0#aUV+rWd?L=_|6Z!|3viP^J;+Bd0E|OeRE^?*UXa?32Co_R?||kU5CHXiP}R|vLlX^kaq5Rz z`i8!BXhUAU1Dc&w@V2u2E)%G-gygKq5kd$dgpfDsd~oD*XPc=$dOZMxzYPtQ4UsA- zf7jZUcjR#|^)i(vK+@gOj_Wot3uxAu(xnyGsKw{^BW?YW%JDf@BIi!4@*Nn6O zZ+AL*UZH_kp=k8rA_Ulu&XU~65^W- z4L})u*g!;Qdg-`pVp3O1Bf-wc`|SBP970gj@6{_M{^(SZs?$tJzq`&RQ$o=3ne57> zR!XF(QfXtGs1RD0eA+xCvD>@UBDhsNm1>hQ0ZdR{wZ)c87dhGyvdR?ZLi${aQ_YgBWPt6mh9_kahq&RAm6U2CDOH03$hL91C(u?e!NsE3Xz_Aei`Y1$cyg~BRnGny_gt)AP9nB zH-nue_ delta 676 zcmV;V0$csV2EqoAB!3A>L_t(|ob8)Ymg^u0hI8lKon-$@axe3cQ;&myzlfTod{3zn zL{wDT9!C%aK@bE%5G?1PO)RB!J)Gw$m24-aR2p+xc$H*pkG}@zI(h|CP8#as$0l}v zN>9}vFV6F<9e0(SA4=IgJoPBD`Vs!y#L9-rd?{b$XKCIcC4UFkJ$)i8mgs#!s`)Z& z1t^oHo_A#lJN5Fb@}W5&iB8r?#p(HNGrX|Yf{d;J7P4m9w@7q0H_@ayW@Vj`5Z`2I z0LtLQ2BLbVmyWw8X6;I8B-r_QpFQ7(LkMd6oxD=wj}D1con}J%-E}sZ5`vD;WLGA& zQX)kaqK$2Wv=1)%w0TBiw|A*UaI1JKWRo%hOi)hRV#}qAo|JmanUAI!tijFZ$n{OP zrvqsPC=a!iqDRsI)&ymxYKk~wu%rQu*bd(Z3~IPT>l=G9Iskj`L|(0L?8R$S5l?}x z040N1Q}2_`0YiV1WD0X({alLInk8Au0NZ5^Ps$<=al<7mDb++$ss;m)d0l3nbt#)Y z3O*qyr8IB-f*w?==^FA%B2fq&1A{#!KEI5cmrblAPp<)phT2(@)VMu_XKcdbJEX4R z`~XTh?${110N?1En=>N9&Q`?$WgD+QUaAy@NKZY#jC6nG#dnAio)LmxObkE}1VOMH z!x;%YzuufzZNg7+dWqXVWb}lnlnTuyY=v5nq^d5*6&~{K4CzHJzK3RBQ-9@>=9Jzd zc}k>Fu#a8L`kSia-w{3IbSYdA(2lk+%)d>Am$OrVId^ z4kU9QNf|U6etW7rr7KT))1+pQaoHhWbq@%>g{j|x2SE@7-@-4r7Kp>b{X4n<0000< KMNUMnLSTaMVK_Yi diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00016.png b/tests/functional/snapshots/nanox/test_sign_message_long/00016.png index 046bed7c911955e6a2a667df7da5ea4bd4679595..98f85e5f0e2c122465409668f069d63a7fc47900 100644 GIT binary patch delta 348 zcmV-i0i*tc27v~UBmu~=C657rgxA6s?N*E>j570iTj}1Nws&!4z0`RgdeIxuxh5d) zVlnsII0^U9))EX!AckUBV+12#SD6!q^C_U)q?HmEs@v@rpp{aGy`84hlWwAtDO{&P9p zGG~*qBXO*BI)tbYw3<3k6!hw?pO6q_R7q#Djwcy`i|}SD>D8R!vueg7oLVAMgeJ<% utWFLHpDPmaK;s+$zJX;oQ2+n{zL-C_8Bd?ON|OTs0000C657rM11v8S~HCpOBiM5^S08xJ8kdc$a<;sJoKVBpmR+? z+{I$2wHDA!s#Fbtvf7TR$No$f%OeWF1d30vF-URMM+C!)MiuML4xYqzFxv vmsy=05I$EV;(^9F0DJ?>ZlVAH0DLijw%$*l=U%Z-00000NkvXXu0mjfSBj+s diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00017.png b/tests/functional/snapshots/nanox/test_sign_message_long/00017.png index db7a039a4bd171fede71181ca768d5c5a7be6319..b3d5b7ed0d00e5de22183f38be2d3d205ee2908f 100644 GIT binary patch delta 594 zcmV-Y0x|AZ5l!PH^Q;_L9#S~OS9xTBGWdvrh4(|VqlhUh)`Kh6SOnaD) zf+mc4)JDvYGa-7hjhI%Gbi!XonMnGCh~R~XQ1vEp;s*+CalEbPVjOE`Kp_1YlOj6u zR*`*;0mKh}ef5(2fp#~VY{%Bt=FQ1dC0Wg2D--O@7f^Wjk zWT&T^SceoEIn<^DrsrViHT~&NPo373=lqzqQ7-6>Uu>SUkpZSn|E=N-7U9M0G6S4R z%ICREXAft7l>`6)0020c38z0jV;~p&CmCV7o4(|Vq8>Lqd^HW0unf5Rp z2bv)BsEwE(XF~L18!@dW>4d*UGLiHN8G;ucLe-nZi61DmhvRKM7voqn0|M#K*eIeS zZxz|s7(o2s*Hk^lez000Lw;q<3R26DlF5((4we3?6M#PW%&@LzL>qMgiWee3UNr~Vr; z`!JfAl5EY7YNtQD=ys)g0=1kg+c}x$U;J9jL5B0Ap6uzxLXG&-ZmT_Jj9pR@BKC8h zkv-ko0QLl*IsM0-BkrFK-74EIp3E(m+~xlU=sW|&Ka$5%n070ESA4_irCe=2*lrO9 f000000Kmg9M8vb(`Ft8^00000NkvXXu0mjf(kdUZ diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00018.png b/tests/functional/snapshots/nanox/test_sign_message_long/00018.png index 180b120458d3e08c64ab0b092e35920ba935c757..d250a2bca16eb0f0ea49d5cc50efd6b3149517d9 100644 GIT binary patch delta 807 zcmV+?1K9k$2EGQ6B!2}-L_t(|ob8)!a)clZhHa-e@%~5RF8$%uN%KVrF<_hL$IgmC zLV&36y2nuzMNt$*Q55NXING$X>Kl0y!VvVV#tPrCSmIKv}5Kv^bt zAzQ*Oy89IT(p`zDPuf*$4b@}^(yc?i8e(b(u%O+_o|Uq*aR9mrV{T5HCf%5k*y2G(m`4tC*btNkU+U#CoX=jO`7TNQFx0N_`7-L|2Ck zp2g7cSaDo0WY7Bg*PB}`>M6+H?GU@CAj{Sc$fAyo;3#16? zN4Ib*Pn%%DJ78#|Awd)!!aglMP%KwV$*9!1;v{Rue#dON2zSDptRVhR#2{Dn(_lhf z(NCu4U?r7>R?-P_&B3E&gm*~kl*E8N*TEBB#XpD{<-_B*lC>N2UKxAnOA(TsNy7(~ zgIIyk;eP`>g#DnJs2n!eo!6DxV0{#J2R~Vdj7lflRae>^^+Br8^;1uzmL_34K*zmR z?}dD=mziZE1uI|PaTpCyL)|Y12WEdZ^CZuK%l3>T?y!Aes5(7U0dKCF5@YiMBw z?0~MEN#lhM!?Tb@Mn%?XeZ?iViBvK_x}qqGqJJogB7hy#H=_>;u4ccMvag9Q98G$2zOAuf1divjHmw(EK lXCVJWxW_Mwq9}@8_y*|0awq|Z>WlyY002ovPDHLkV1g3@hLr#S delta 805 zcmV+=1KRw)2D}E4B!2@*L_t(|ob8)!a)clZhHa-e@%~5RF8$%Glg$?)#E83jesop@ z5&}ehwcAz{MNt$*Q55O?ING$7Beb9R0mZPo|I zNIKm2{RkO4yS>7?zkqd=wzMA$e~vcLBw8t~H`G^q$tDL#S%1ZnCtZ9&oZ*rkpe&QK zkS$>s-FXWB=&nT6C+(`WhHA0{>DHlM4KcL?SkP`|&q~?ZH~`&*u{oRuG^uAzS|=R; z1i<9OCL+4-VBn60Nkb{k1iKQ~x#qi>O+nqbqf<)$(LtGN&`m4(GwQz$Wp{vbpEp{f z7qZQ%hf;}Tx_^7SDU};970=_m46=vDRtdN*e&%z)Ei2Jy)RTgeky21m6h-k!y7G~| z)r>`Wmc5N>@3^fi#7hxRL{XI$O%USNDrP4@k`UM-v0f?zV|zm-QlZkhQr`j{(b3@z z&thnJtT?V0vS)q$>&-0|^%P|9c8JwekY#I!WM|3H{C_(youwz>Ol$hcAN^?d04YLx z=@xF~Y7;DY2MldAB#5Fz*r%ljisfo48I?L$oMf%o@0cwY;ZAsy6~ymE401(34JOnT z{bXtm?xeENopgd+b8smc;T=*sB{5*lb#R4O@eg7~`EYwzvQ}f>D`O9RDMFGnY51UW z5GxQme1Cw4upd+tmBZ$`^SV+StdGL(;9u4uqteNC)s;3!eUK`2{nQhwrAgQh&~b0o zb0Ht=WoDU3!OE9+97Y4wQ1^$yf!UwUJjrw5GitgB!$s;_u#(h1^lj*<54T+5M~w#T zfUcZLG34yGhWll8B-LFpULi&S|giKgy7afg-if(G`>N-+)K%fE|=+eCoWT&9y0b5>) zxYgVcvL`^vvpe~3??7|Qk~aYk1=R7eDK$!)OLeHxuOo2ez88e~JmB;6&t{eXln>AT jn;vkFUlc`A6szzL$qaf{Ik~e_00000NkvXXu0mjfMQ?=O diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00019.png b/tests/functional/snapshots/nanox/test_sign_message_long/00019.png index 4a6e0c2c913daf39739fe0813f3b19176a2f609a..cdac56b219ddfc3a83ae490fc5c7a8588846ec61 100644 GIT binary patch delta 792 zcmV+z1Lyp;2CoK?B!BivL_t(|ob8)Qa>O7EMM)|*@%@j)U9xaBMbLl{0uT9b(bbJX zk{Qj%oe}^500000+xc>o$vK~2j^mJ0E+^+)2XjV915PC7l2gjVrZ?{Fd^^hApSq5u zpT}{WRn}ZhpK3im)OnP$)Q*K8N157X(^J@JXsq^>Bv+8qi+`m^y7($_h9x6F=_VzS zO<_A-xm17Y_Qb}f`$igT64GGmGBpBNn$gN$m1bw-4d^bqoTHYOrLmQ$+*5oPe*@H$ z4?7Xjo?chn*)eHVN-e?mM0ceq^V?=-r=V`VH!R^)S$~<8p};Qkl3(Le@jRL)QCdhTwE?%sckTl&>4`q4o}KV!q~}op0094p z(S5S9Z20q%@5$`}%rw9@bRm|~e+qJFmaKZ--Hx$870dQG&)rk`tc%o%7A=-NJdp0r z7`YWz0y8Em`%HU5<1{jAdHxoZY~2yimm(%d^k_gYnSUK5MDY zvqX%$Gi7SFSLo6{(KY}pA}Z6Lvfd_gW*}KB(ERL40}WC-84ZEGSvFdWDJ|!s2kmgS z`C8#fv}t#CZ3DcZr5UqBo-Q8&JINKXW(`ST4FR(daMP(|w82ussyF{7#wh2-eKpY0 zQal^6&VR!!7$I^eY}8E?x3yt&O8Tf`hbE57v{Fb)2HjCSc0tV{Qd0YpyHT-IO7z9) z7H%76M?kHsEL{xjed<|T!r2C3j~!yGpxCs(#2Dy(wWG(pnDy3W-!lRf>Cw{nM@7V; z%tqr5Av4?p000000Jw&b{hHgzO@#NyY{Vp<{(lS}riMDCP{oM!s%7k(oowV5jdP#y z>AFlpyL|Du)%3@q|MW?l-V!soorS}+eJO833vyPO8Q`$j5j64GR9GBg8Ns@ck3l~!lt4d^bKJhPUzrLpCx+)I2De+QI{ z54#Z2kzOY58JIMcQctiW(VY}!eOt`v64cClbxB!&bgGrAGfW<7$gd=R2})#+cRhrq zAz4{tT~yvJPk&}*DzFcE$*=KIaUNBdC_SXKT7cW*-`oehG7^1GJv-sWNbjQn0090G zz58Ti+wk`#-<#V3jC8;Wt-DwgeWKD(#@)2Rjmt={gVj7bY}i`|Kvdb+g@_gPbQ zo+)D7&g7-pp3tddqV51zL{yeP<$0UPnSo?2L+i6A4KzsUWHbc!X4z;hrnH)qUbMqm z=BxJs=CJu$Uf6K`rJNF{1V353`u6o1u#&qV)~ulj%t1^w`d|T#B%=?e5|-ZkH!(&z zFYc>>j(?`&*@&I~9A4v~`Dm)!M= zol>DMPPcGdF**ZEU1jRSz&@tl+9&%M?Ev=JAvOisru`$vK<~319rIzZc$gaMkU|wB(x;ZOUv{#Q zTQtsf!lwhb>dBT!&3jc(#h1OIJzzUiX277Geg2DDA~3MX1DSCtlnS5YHcP=gkSN`E z$8SUFa$j9a+kDwM&a5Lz30+mz&jkmga`%LO@CihWN1I(n!a05)a5_6a1EPrkFD(E7 c02d&TZxWk(kpBNM*#H0l07*qoM6N<$f|1C65C8xG diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00020.png b/tests/functional/snapshots/nanox/test_sign_message_long/00020.png index feca784b1272b2fffe1f1320e60d7571513ccec8..faf7d6a50bf27c85d7689cde17e8b2fd132def57 100644 GIT binary patch delta 807 zcmV+?1K9k%2EGQ6B!2}-L_t(|ob8)ij^rQ=MKhz>N%p@a_A(z)BLse90#$v_M=Ry< zaDW(cp|1-700000fYAyL)zOK?fms-_z2nt zs;$}DtFg0J9{c@+G4EK8%0F+0mZ#6jTE{UGvs`@Z2t#;GY=0-vh%+pC1B5YBjiiMf zarIVvp$@~WU|32q7RbF!GE;8=N%yLfcgJ|@@?Ne&$f7pln5;S$3-K!P4rqf98HmP_ z-ZtDbc*myXdV*|0V~e~TRb0%5Ahq4QTSEMi=^~ZWO-HVm7jp4sDES7EGiPiPmW^cg z(L+~uEde48FOWW73d#g=lGiF$vOL)iWJcbRYr}Iw2;MeMnUP6J+UJQ zpWH){Mt@b`O%O^|jdQdZlaW~h#mahWhgzNM5sc3wc$gr@Wkm)-+@3*|E$!+{z$G3QSxL2gYRL+vQRZyz zb_w>4x3Kl8{Y&~`(Hey;ozWPk>}sne5~>ocv1E?SqluGRqgwd7Ftuy`xYFl1KIq(2E7K5B!2`+L_t(|ob8)ilB6IIMV*e>iThs?d+86O2?Fv>Dp+;TM~9X2 zNC6YP(8mD)00000z~lT2o`VYmV<8{VF-_j?SBLsafVyo0AY+&BWWQ= zT)ov^sKYQT7?x6u1#&Nw%+wn|(!HwW-7%iJyqBvGvZ#$XCaaFcLcB`61KQw22BLAK zw+(j<-mxjUo*-M$*dh-{6&JH1NNxA-mJokrx=7`8(~;}pg62JZ+L999nuXqP8lb)GmD_cDMCU@ zV-=TW{Oj`E{vZPRYUn&(jWeYv7o9RXQ_GGWaCp>dIe+CHF`?EtDGpwIrWB!ah4Q-Z z7|{B;tw1mR8<4f_Ak48AW};A4C1XCQxw^ZqT9oE}-5TzVu#Jq?e+;6j(fSXAK3EB& z&`Oj>MjzbDZ1bjfPq;v1#$4Ip4)hPPeSA&yWS@OaMT%&JDx=0pTF7EKqo8!kp4btD zPwt^eqkpRJCJ3df#yMJy$;d2$Vr4zGL#@vB2*zg-JWLSdvLb^ZZqJ~~mUi_e;F6jp zM-7b~3?>UnFV<42y$`%Dsl|S&8rqR1Z3ZyC0qxW$Brw7qrIx36izfjo*E>mupLCyf z7XSbN0KoSm>l2pru{3ue>sl(ie28tkOuoBceScC!5l>YLVxj%KhODGoKDA_p(kOGb zcDn@o#9P?<)cz&?uxO1!mdtw}=F!AStx+xfzA&|F{y5U-fbJi! zyW?q-CEqQJE}4hi9S}HG`IbIdLh|WoZc~MvPV4o|o?-yfD|uV(FdR1h$nlZSZf&&7 kcOSslf(`%x000*83sanMGJ*$7(EtDd07*qoM6N<$g0~TXC;$Ke diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00021.png b/tests/functional/snapshots/nanox/test_sign_message_long/00021.png index 888927745fd1eafc2468026ffed1659b8bba7fa3..605971074de111861a6f24da3cb4c5d7a84d2188 100644 GIT binary patch delta 55 zcmX@gc8G0)3M1!6)z3^?o2Bpc{|)-5Y4h0o=hdD$-W-Z80_yv1iwY-Rn7rsD0}yz+ L`njxgN@xNAkGB@J delta 58 zcmX@ac9d;`3M0=()z3`2Nfzes%k95;|6Kl|NB?QKagm;4i-6OdKTNyaN;H0L_*%;V N1fH&bF6*2UngGMK7nuM6 diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00022.png b/tests/functional/snapshots/nanox/test_sign_message_long/00022.png index 4c25eca4a42f750d9bfc79a6559fba4a70b0c48e..02ca3a784ce3ddae57042fa234b1ede0745c462c 100644 GIT binary patch delta 831 zcmV-F1Hk;*2G$0UB!3-AL_t(|ob8)ia)cldMNKL@asNwVFZrN`5c)|2$~gCYq?F;& zG|=GH90vdZ00000m-7`UlTykT=Xpvgx06!R&68}->F0Tt3{t`4zXxJ{{|=PdpV~*o zp>;Z&Sjg$;3$`FFOY8CQ6DU(R*~}Ey8fvRQ<&YgD%}_S8Cx4M`Yc)$&fHF-=BAdca zy7E(fVa~)U!7!!dtW8=>CPOQLrCF`)uQa4~bwF=IDI$e?DNnH~9O6yl15gJaHW1O7 zUOO&NUg}C|Bv=nRoni*b8yO8jrr(>Nl=!35M5<0R#Zs{mok;u`%B}!*=ZtN_dLmn# zTIjD+ijA~><$t8G&nbKwWgBE~ouw`y+~PBz18$j#u|^{y=whT01ONa4{J|bY!pEUa zp48rkDgL_N>G4yL`5bg`4^1A`)AO3aQ(?(j@=*C+Qd9D+Y5x{SGIP~a!H1R6%~EXr zrZ5+4G-g=*gan_S3SFyzm&5=kHON;-@KNov(eW5PBU^o^5lC#r@ERDGe6S% z$NGK+>Su~P();Pf-G(rH${6g)$3>y7Fr17rSW3{ny%OWnQGA%X8GI1iLWCM-ham|{ z5mZe)1b@v^7fMZ)QF`E_s*za(wXOU$HBMc8^&1mJ2|98@sg0t_!^vT{+ow zrwx?(--eb}J;Tm+b!5J*ize`g)Kz&v4BtWcWSJ&KP(?6bC=WGkO7CYT&F7v}<1}k%nwE^wpT+K9 zPrb_JVT}a+so-qXS+mDNe_}6lRsfCW;qanBzip1ez5}?62?M~oqt`)Kx`Td+ep%C$ zXE^?w>KidF1m%ma&pO!}%B^SjRuY}{8m;WFbV_Y{0KE#uM4IlUJlU)86mJr5fO7I-CnDO@ z%fMZomxfYm2{wYxpqP{7LVBklGw#(-%KW2K%~XwUidL}}9Y}l|%8meb<%})DdLnC1 zJ@l6;&5g8tWq+rz&n|ozc^PDHomMvxuJM`YfF(UKR%v7kx*2H-0ssI2{*bmJ;T_Q? zhqd=$RIqLidVCjTo`VkV(Bx4)J+B!&1(um}HmcxDg35JkKEnE4nWWp$TUJDqlr=?h z^O&1Onf1neYb7qm>2+7~pRR9QiSxf zY=%`otLm*sKvPGMJgyd~N;fr2Gp(EjI(?QF|LV<5nT@t z5|kpSlz(`rGGv)jW;P{8>A*!*BeMkRTmEYboVxhxcP5B31u5F0`EEp4N&T5U7y45) zOxJ02gL9lgin@XQUp~5uM6c+!=^NK%tXHRq#CDLLRGcojD8kd zKb~5Z%fo63`cuYPsk3B{hyKJ?#*6?un}??t1^Qug4E7zsDh4zF8;;fh-5C!08TxHi zQ#+pdZ>n#^uqo)eX!@*^Eg|1}R&PB~`nc0mLItEv000000PrY&0Y5#Ucb6-~y8r+H M07*qoM6N<$f}5|59smFU diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00023.png b/tests/functional/snapshots/nanox/test_sign_message_long/00023.png index ae2ca3f2242ff7acff0dfe67286a52e5770179bb..0b7204bde519a6ec0ba2c1c68b908a6d816fa92c 100644 GIT binary patch delta 486 zcmV4Zt*kE0ZV3LuF*^inv9l$0001hAvAY2 zZ$8{@k8`KnrLE3d5K-aDXXE50o}@yTxR_x?BHHs-?5bYM9XkKZZNy8OrC1`?Lkh)6 zj1RogW{XeguZ9|E`Y4}M6Ef^elK9jCIF!sIjzL;s4@I(^{!+x9>&v%)dY+^?s4o(c z%!jUk(NSvYHI#+87m;S0VMOhFEyPCmz9cQ$Y!Re^8viagwo9A_!YyocR~vYVO4l&q>e@ zn_rqiRFZsN==T+)B{bcCqrn(rs?BUMErM+1dt-Sj*-(UcSYE#k5y9e_j58-`D zt^iFNWW!y2>S)yjvA`?e)w#jZ;HPVq@cxM0002sdztb3fan+fWaA{NE~|bU zG`YDvPmcS3ugQDd5zP%*0YtF$3!= z)Gx9&V@PPOIaZ2sZ#X0`k74BiykQ|Pj{zs)#SB~l_Kq#8M0#k}NerCo=JHhn00000 c06=H{0MmpUXYI~HNdN!<07*qoM6N<$g4y@ye*gdg delta 486 zcmVc_zH?%*sm<{2*hzuR#j^?%Yz7RC6zecussfMLl7Vx{!R)9x|6w5s# zs9$7l#*ollbF38O-f&1>9>dB3c*8>XQFiS*E{lNdPF&E=~E00000 c0D#W?0hMVT{+-;PF8}}l07*qoM6N<$f;X4$Gynhq diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00024.png b/tests/functional/snapshots/nanox/test_sign_message_long/00024.png index 91b1ce5690e4ccbfe302ab67423fd85cfd3e65b8..3b43a4119d496c41b2ce9397a05d971e23034cf1 100644 GIT binary patch delta 831 zcmV-F1Hk;-2G$0UB!3-AL_t(|ob8)QjwB%rMYBtNlf3_txJxZUg%GyC2c{(Dw`gTC z*~-)|}9IHeSedrwxEUK4A@t_+*rTD0@yt#Acx zfZ7nZ>GaQ*r~Lbmws38bwh0=P`0uUI^7J`tm5z~E%8Pp{P=A=>9hHF~j<93~fH6`N z*%Wrf)vWf1It8KicR;)N zunQ3#>22Vi!AnCa^#mJ1V??CZI)5xpO=oloQsdrbf%ON|tyE4o`&#WDQz#nXCm-MS+#e>u*Vcuxkt!Wt3GK zz^R6mNUO77d^?5(D}sYW`Y-;W8ugmC_-|}hZNxP*;(s$>N{6przFaEXk+pP44IMYX zdbU2VD7%%Ira!`RDWVO5Hyjfk*lE#4KLbVr)aj#xB(7k{rsVwChq^;QUb#{{?}HBOzuGObZbU5Hl=l@bFIqp>bqz~Y-~%b06q{@u_G z;G-^S0J=gGK5O%GtOMGk3@=hGdI}^J2%E6vx;S<*%YG{~(DFswr(*{)SO*2o0^PAo zrzNG=Mt3(9OPe(Jt}efFcfXGByc>EEXYPjX-hVYGNs=T>!C$AYcJAFKeW>&5-87uI znXnJBit$|#{l=00Qyks%s1hj^9dRRU87z)si&6{V@#zyS1So=DDUof~QYNff2IO1d zCw?N82~xx!P93oUX>STk?uL#iovKAT`n*>^0~Xiy!4f%o+sEx5L!USUTrVgI@5lm2 zU^wGfQE9WFy!RIDK8%Ng7a3Yjs-cIOuZC{h5vQb@BuSFo%`dsvhEHE88tMQ5002ov JPDHLkV1jePiZcKJ delta 836 zcmV-K1H1gz2HOUZB!41FL_t(|ob8)ilH4E+MLVh4N$-D2>?I$raZyORdH|x`(fLUA zV31^i0bi5Xt0;=1D2k#e()kl;(^|WJyx(uBlx@|I$~!4N{xHpu~^2LC@9atXDclVkIx`u75yfig#27k~qVbCjg9* zyO1qmN8Ej>|Dg^;HSfk5qqSx<$cC*l^#rgCk1BhW&Zn;Eu?x_|(knx?JFwUkuM+Qo ze)3@_B0AFh#9f1zrc&w&HiO2DNY;jUET)z-I|ZqEA1;CU2Q$o6&M?PT{ai;c1&oJ@ zZ$sH9fL%Fbi+?aKWSi3nL3635y4{q@jkDatxYt1TPh+bbVotyFJ>b+Z4ET*qLCN4b zq$rA_$fk8hy3_bB=zf>U-|+P@oO1nI)Fq3xAgU;^a{2vRQXuRagGCu- zl?L!tLn@@r**Ct7VZn;vppgEHf2dBqt}XE!&8kLRPk%=I30TtMyQeRg%64Qfol-;R z-S2){uO-UvC8p`muw9DiQ{YXTox)`5;nFI~`=wyAoavEKDp|Xc%SsHeOATTAp zpFC2&1~JK%{WO?VSN4;sJ~&CuLMKs@Tz#;WW$9H7E%Efk(cq1F*Na$qlYUCyKGoU5 zZ^BqO?0?^QEfS-oN2;en*fS;|B*{1p2FtWYC3PcSHB>4LNQ}m|Yz0efsxRYJBkRwG zCV)S6NdwT8n(((aFULBd|CHfHYDK>SNfp8_ELU9|JD6oZ6&kSopzYJK4>DK>1!jTn zIF!?x(y}p}4aL$Xz51*!w=R|c3Ez1(^g*0C8-JR;Yc7hSD7J#%PF;4MyD$3C;MKEf zxGD5w;E%N3loA0=Rv8M;if(pjS#{&06Y&HOqi} z3*y9gq_RMY$YF`QfDs_=En&;q&>5vu^+-pb_vmN9o~ z!aX~F!6&f!qo{0PQho0!*gVpd&aaVFOAS5DdNnj{M_iI>Q4~e-Z2kdQ>5Jx0Xo`dY O0000zmvv4FO#tTa3-JH| delta 35 pcmZ3*wu)`TFD52+uE~Fxq(rjJLq*s%=YC`W0#8>zmvv4FO#sMu3b_CP diff --git a/tests/functional/snapshots/nanox/test_sign_message_long/00028.png b/tests/functional/snapshots/nanox/test_sign_message_long/00028.png index f20a23ce404d836095de9f6a3febdefebf62785f..3b1448e830a1636577632b7a42f47826d2818c83 100644 GIT binary patch delta 92 zcmV-i0Hgoe2H6I%1p`!N73@9z&b4NePSF)GBK|enA@Y|8sjudgqDo2%XgB*w%}?$! ypR-_JfyrGDNO7EM4eP_;`<+oyJX=C#h@=jF!rS1%E2Hs z0%T~ravT5v00000Z09S`rj&ABoaZT(yq!{t?p`fCh}+k#^E{Y33%l~lRet{AY)kE!{ERkexyGFBmClh^$stEanZmTPpMO9QXIQcVlsQrh*%Eff z)m!a_ISsRtVJXFFP+CknQ!9X_TdM3`noozk*Sk=fw4+!ftGibni=}vz_yDxYhfPFu zrniB+CNB-8G!pDIbVh_7Cnd%0WHtqvaqn&^`A4VARD*7ct)wZxjrcZ{T>N2l7#GX|0h;t@(mRoJVGp&y&}f<#XU{z7`U z{ZntQq$$%|rSho%t*f2eGiftl4KWQ@U5a>9GVLCSKeymAMZ7;~dr{zatQ&o$_@ z=6WZroPS!Sk3tpG);G>>&oF;bT&hfGOc z>9^85YDp90RwNvDboacmsrt|AjxyEIm@H!&r1m$&Wt%>DyH}DXca}~A46FciReCap z6h2z0NS?~)m@~qp&cffwE$F9CEd3K7z z`*&+M9Dso8qWci8Gs&0~;gl_D1;72yj-oiWr!c=->FK&O{{f&o>zN*!hsOwh3GjH0 zj%mS2=B9K$QXBU{oYy6z}F&~(eXI_sB3{g^hp3M+g70000003d;1rG4E- T0i+i!00000NkvXXu0mjf+kcu7 delta 844 zcmV-S1GD_#2IB^hB!4PNL_t(|ob8-jlH4E+MV(Z3;{7j)z2w6ciqRV(+;-=lFAoNx z79hj5YmNf|00000fZO?%XwzD|F3$7RN<$V-U~^2=PEz{5p2utxcr%IFmjE#*ejnSxspSVjxmLK<$pMdAg-`w1sHRr7m6j~ zjO(|?3wIh;CBxQQ(4e-MY?fAl2wAG)U7k;;ytlhBnvA2^BWt_Y9m}P7m;3;X$wy2? ze5Q|qyCyFWr8W}cGz>;W948~i-N|YSa^p^J8TrSCWU5Iw)mGY+zm5DhR9pe#w8}k% z?Lx6R_b}3&lz&9Fs>WvFIUDgBNTwDOx7+F-a-DwXIp9;%Fwt)&1>KC6LjV8(yc_Mn zC0=|bkJ|V)5_JYJt2=PLG zcl^_CZlo#KTch%<|D&tK?Ul4yuZFs43v0#TruuQ;(ti)Cy9a>h8M43^%@)?5N{MOz zoriGO&1;{HJaIpEt2641Jq{(4=7O#O*Deu3$A*#qN}f*KhaFic?y43O(WX@)^4J86 zsPS~S7N80tq}tp^^fwV51F(bXECdR1f{ZcPN=V4Jj_y5gY`XrlyQ4}qG$+fr2D$wk;&Pil__$Y+E>D(D6HKfCcU5Z7 z1M=x>Q1UY*PvdjU6=72IO|GWEVYVL#U+sc%c3 zL{a$sZtZ~skWgK0AJTOenUf-dvL&w&w@>UCisN_+i>sB9uG{b*0LWR-_0T;$W{69G z$Is}v1|z0KYpyzLi?T*v5r4EgasNA8K22QF%NqM~bj6Ky+bUciwhTb}%RTYS(G@q+ zZAGhaeb{vpUXi6%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_sign_message_refused/00001.png b/tests/functional/snapshots/nanox/test_sign_message_refused/00001.png index 03097febb6af88aff5d10568a5740b3fe988a85c..00cba442a8eb31e49ba2746d50f2c2e278ce4040 100644 GIT binary patch delta 60 zcmX@kdX#m73S-Yk)j}qHn>yB*eOqr%?fBZhs&%3I+KnO%V9@_WJ|c7P8N*4vbs)Z{ LtDnm{r-UW|$FUYw delta 62 zcmX@gdYpBF3S-|!)j}r2Biu{RX+QY1_H5qyukEW^7pkw_D8c{+{ZHiQKR%Fru-UT% O#P@Xdb6Mw<&;$TZz!_}- diff --git a/tests/functional/snapshots/nanox/test_sign_message_refused/00004.png b/tests/functional/snapshots/nanox/test_sign_message_refused/00004.png index c9222461cdd3ea49c300c4820e3704d33b9a3838..e90cd9db37ed7e4c669da0b1abe6e4a823770f3c 100644 GIT binary patch delta 339 zcmaFM^p0tQO1-J4i(^Q|oVPclR~<4CX?>`1PUW-wrFq@_jX}kk$&Q=C{_bC{yxi%I z_H^ILLJV*qDJUp-{om@BJF6JNOIGKE|2m}8FsJzEVy*Ar3abyaMl!6N-kAS2*sK34 z^NtmF3uIQ$mkDi&x~{%H3tZ zvTc^&QHE1ba^rn`=AOG#w&}HTh3wzZyU+KlI&I{gYm>a+wq>>Q5mm+5Cfld1Y|$6? jX68ChzTpPV-0__5jB!4tXL_t(|obB3M4uUWggyExcC+vSoXD>c9AxK+NNJwY!|DH5f zQqS}jFaiJo000000001hjLgi;YoBU*&+fn#%_`fKzAy`5S(fr*SMK%g+Q5Zb0MW|8 zxB3zBn%#km>IKKK`r$YOie0%)s~^4rJcerky-nDTWdPe|_^ zZ|I#keKYt8ATuqF6U|Oq^!$k3*m)GHKOY&)M+Wne0sf27-O%mi8#z;!_V%Yw9qR+d z`<^TcKC}GH?!b`dv zk6Zv{vkh9gndMc6<}wUO9Xc(j|DNyg+>kf~aQ< ke*gdg00000007+Y3sw)mR9g3FCIA2c07*qoM6N<$f+Jg>jsO4v diff --git a/tests/functional/snapshots/nanox/test_sign_message_refused/00005.png b/tests/functional/snapshots/nanox/test_sign_message_refused/00005.png index c80fa832578d18c8b1e4a2518b82d7f50be84ca5..d3ed6d6af1cf7ff977e87495112cca07a48ef1cb 100644 GIT binary patch delta 414 zcmV;P0b%~R1Goc_B!7QNL_t(|obB6Tl7cV{hGE?CCcXcWa+m$VY^OF*U{Ue~-{+Tt z>%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_sign_message_short/00001.png b/tests/functional/snapshots/nanox/test_sign_message_short/00001.png index 03097febb6af88aff5d10568a5740b3fe988a85c..00cba442a8eb31e49ba2746d50f2c2e278ce4040 100644 GIT binary patch delta 60 zcmX@kdX#m73S-Yk)j}qHn>yB*eOqr%?fBZhs&%3I+KnO%V9@_WJ|c7P8N*4vbs)Z{ LtDnm{r-UW|$FUYw delta 62 zcmX@gdYpBF3S-|!)j}r2Biu{RX+QY1_H5qyukEW^7pkw_D8c{+{ZHiQKR%Fru-UT% O#P@Xdb6Mw<&;$TZz!_}- diff --git a/tests/functional/snapshots/nanox/test_sign_message_short/00004.png b/tests/functional/snapshots/nanox/test_sign_message_short/00004.png index c80fa832578d18c8b1e4a2518b82d7f50be84ca5..d3ed6d6af1cf7ff977e87495112cca07a48ef1cb 100644 GIT binary patch delta 414 zcmV;P0b%~R1Goc_B!7QNL_t(|obB6Tl7cV{hGE?CCcXcWa+m$VY^OF*U{Ue~-{+Tt z>%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_burn/00001.png b/tests/functional/snapshots/nanox/test_sign_transaction_burn/00001.png index d9cd2071223991e2e4bd0736b666d7b53cdad946..b4114dad0458ad3b33d1923ba2724e43b7dc1b2f 100644 GIT binary patch delta 368 zcmV-$0gwKO1B(NYB!5y#L_t(|obB0BZo?o9fMGW6Cfxr>zRMn>BFhHSro$%d|2@$Z zN@R*@ol*b*0DzArA|jG~7YV+zZ=jS?TIj>pV4wB=$-aRh5vjEvVQP(|-8yuy=uzf# z%tz^NS@L&)`6lX@N9=UNbZhUPPN9dlcC9rx`ela&IJ^`KAAj*p^2r6eq@epo@J-1( zK&NJ(+(-OgNzWvgZIOa>QhsSj_Z0O9#$@=%?mPehfLvcO(@ZKk{-XX7IVsm%=v*GP zAT!FBH17My;>4uz>EHVE&hy(CwU^qZ6cNl+OcQ1P6PAaVxdLXnAan=l9`#Ih={`0ssI2000000000000000%lraHY$`hgnofrR O00000I;DdyA%_5a9D#pXok^eG3K zQMyL7c7`9(seRU8eZBLZ;m!Vo%u3kE3%w^m^|AoqYEff3EA4F3j}I z+(vU00Nn0j-GDjn%Ek(zHg z$T^pk%W3nXbCK47<}lype-Z>PL1~$9?G^u_YmrJ&)r>e+?tfLt5~ME{aTj3#0D%AG z;x)ASmf5?t`{8m|M83YY-k;z-H6@kEdV@jl@ErW`?vs1RR$OmIoE)KL9-M#9r9y5+ z^mrK2qg>B`A-cqG4|!MHcJp*VQOizRF1$Kx54l%Um7p1zlu`Xx*SZbs(`F;(WBVbt z>%`8lM_k0h={kl?`nPFBP5L*Z4=hoIEU^w-B3=Lh0000000000000000N^rjdLOw3 Tm$efz00000NkvXXu0mjfki?Va delta 318 zcmcb^bdza>}$AVuBmn*KS=guja1qE@taFn&qLH3~6tY7bZV8ODpSrcYsf6(a&%E zYq!oTvM-UIygG#WPNv6L%Cx4t>{>B8IP zHoSR4(JE$jdt+EvXPBm3vN!J$Hhn4IW7u&-OQh3Ern7<(=u0HfFn=d=f!R*hh&tI- OAYo5eKbLh*2~7Z^K8#oZ diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_burn/00004.png b/tests/functional/snapshots/nanox/test_sign_transaction_burn/00004.png index c80fa832578d18c8b1e4a2518b82d7f50be84ca5..d3ed6d6af1cf7ff977e87495112cca07a48ef1cb 100644 GIT binary patch delta 414 zcmV;P0b%~R1Goc_B!7QNL_t(|obB6Tl7cV{hGE?CCcXcWa+m$VY^OF*U{Ue~-{+Tt z>%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00001.png b/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00001.png index c3af4be088f91545b8aeeb6ce5b39903032b01d2..5293d78851c32bdc8dbe4d6845ad952cf8c16d89 100644 GIT binary patch delta 840 zcmV-O1GoIt2HysdB!4DJL_t(|ob8-jlH4E+MV(Z3;{7j)z2w7Hl%f|xyzI$6Up+Ju z;?W4MyXU$9000000NBp2osE@J>g)TycQ!3~f_cKAfn9rJ`?IYj+Toq%al<+prIc-R zux|n^>gua~e)><#>uYP-){=<$&l3C^5z>hBV^7200000z&boN zG_4WJQzknL`mS>A#+_5qscE7rxbn2h4#$>S)xo$Q{oUBfvif!SX@m zNp3|e`|&$szMC`~;O9+1@DZs}=Tzql;Ya|dc+njEha`6)Fonh-V-A)wI=oZTCKD}G zwJYw5r4Y3w9&@^bx#lwDG(X45h#w~^`BtQr-0)e;C}QqO5yjBIWQgjeMoLtPs~j_* zdwYthv@{L@JMS_}kIrjIY6wrZ18J=+@8FDu>1=pjUAX)@K_R`|~R_6J&%r&jb8H zpPM-&kwn_+-ALmnqR9&@aW)?@Kf=KvKc54>PJiPbaP@y3=yO{+004lQ$eX=&G?FUj zV7tRdxqaFUih5rKy89?_Bi5x9GcX z;zBJ)TUYQ|2m>?EwG)0002^7=Hl~uc)@w S&dv1z0000XDBh0{)VlKn3!d+9@F90~}Cf649no^Guo zDiJ-&aR2}S00026oUfIgUDs89pXa%&)y+S+5o($76_^5mRmxRzdC8XrkJeh4DS)jyzQlk1$b;b7hA3 z^4JQ2I^ekRxEvD9E=^2VLu(NsC&-urJFFrRo%U09B&(ISiG|sthN=@Z>Yd5#7mBT$ zj17MR)ZK8#aZt^Qw4^ppmhIK#ZlRuzwxwk!JSoFS#fUhxoCl<|aOJ z0gN{gO8NFNUxdA$tl^1k@PFvtg+LF^Bx4Pxl9^t2cOH^LnSjxxXGv4cVYMXgb9#Vd zqB&wk4lL0(o3FGT!z=l(NH4hs2p%Y!rHHGdg|RvZaa7i)o+YkztohiRRNS|#uJOrX z)(9s&<5l05qVUbL4H_uEsRWv?tPtEsh#? z?2>0;XrijFVhm=;IBOk6M4sSS`Wg9QR_(^iE`+k0abt9aPxq2VAF}lyzPU{QGOk}v zFoaJ-5T?x|KJ1b`7JZu7G`1mgVH=4AyWDCXodAxG9AIq9xrVm#5$V?`f2AB96uB0} zem26ZsSMkKTqRlNUbR|NCak@WOr%q0Dv|90000000C)|*+#JXVIrw_+00000NkvXX Hu0mjfa|4yf diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00002.png b/tests/functional/snapshots/nanox/test_sign_transaction_ipfs/00002.png index a1364e7fa524a4e88cc1fd8f88590f0ab1b401c9..1207c4fca785136c96042f1fe52f8b547ee32395 100644 GIT binary patch delta 363 zcmV-x0hIoa1CIlcEq_6d!ypVmQKsrmxc`y3OBYDU;~0l@8Ze#zRtXS5CIL!Q0ssI2 zru$jlfgz<7d7E=y)sv5VuI|7E-xT*|rvXspXVJ#SOpNTYx&s%KQd)fLMb5cKx!#(I z!R@pLn6J4n{ztI!6qJ6)w~b2tpi4VVL5&&Wz2e?%IR(kYYJcBF7ytm^fBNJ$)Z8rg zvU(|I4W$%kqiH^<68-I|EG*lSO-JA0s#6+2%egRXmbre((>^#)`SlF;;i~Argw^{v zNBs`wG#%(H=s1(~LSU9mXA|1s6gOF*0T?_(_7{Ve+gl!v^~;j}Fx+w87ia(!dBmUY ze@W}KquNr9-el2%xC3BrMZVu()^}&SqOt~4oT~g3vopQ=Ro1Z{GyOd$m2B}J-tM|V zCi>GDp(gs1F$OC!3$4UDyb|FB0000000000000000001P^8&(mHm4K~FC72?002ov JPDHLkV1gk-sm=fZ delta 363 zcmV-x0hIoa1CIlcEq_t6gCGn*QTnDkVgE~FFYkjHCWR2ORUqv>UkZv$qCjZ~0002M zbdS{?7?M(wr!mG=J-OU-bq7xPrnncL5>Sz!Mahj?xU;|29XKJSRN|WtVvIS;`BW|3 zoToWJea&tAe*}()pzs>sl9l~~E_oV)3N^&O;$FBMf@ERlcYhKF008(+7cWEA^>Wx*Qy+V~2%V(8GJ6PaW8#Q*7aiF#=Ywar!`(WHP(qX%)vmE>quHMHv z@+&{#(R=L$wIfL{1nQOHXh0hr;%3?_0fXDf_GD0Md(%VPzP!>%!yWs5dnKSEclpEp zFR7eq%d^^yUSw%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00001.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00001.png index 23677d364c3721455ab44a20582b814924e31224..3dd28ca0c9a0139517d22aa910db06ae1d861904 100644 GIT binary patch delta 739 zcmV<90v!GS1^We%B!9w5L_t(|ob8)iZUZq0Mct}9@&1?Oz4XJ1g$!I6k3CaW_k1M| z1_t~jNhyR7LI@#*{3lv#t+o6|K>nOdQ_J&?eIL?0JU$)MJf0`DRv>WN|DU7UHOYr; zt<_q4dk>J5$+zU~zBN#e%m6*jc6^0Xdq6p`cU3`I3i>6w&eNOO{sat1<)rrJawcRzCb|ABXf7h(8R2D4 zEkV+6nG!uM%tozE%49ZS%-=bi5kd$dgb;)FVZ5C_oy0Q7J8-oztCgNG@F$}I+X|m3 zG@Vfr5C+H;2!C~Y8g!&?rW2UMw(v80K3wh9xqK1pcOrZ()K{(1F7IX7L{Y^CT{rGG zRj&?_F$cPP4>c}*Tkgg|0xp>u!e#|xm&Zvxrr2`0_3K@rTF@9@dPFBDX6W%ywJSX# zNh_le6fP`s*kzW%iMSY-^cY8QL|HGFo~lb}HY1fWmw&ef#PCjw1Grd>3q79l;jQL} zIA_k>0`=yUXHI~(*Lkj(N~dubR(-v#!h2e27Yk#6EpWgC*&Ry2TtOZ#9#_c~+#oah zk70zG(SI1`;7zy+y-5&c=HMtgyk9r9n1`zAu$6r4sZACSu40-CA1&1O#C<+f_Dhx< z!y2S1xqlaFV$I4O-*)~i1&jiDHNz#$HAB4lw?~nIw2{7-3<>U0i zH8nIONA8pf?_RC_TrlT}Nh^646Ogf&tfqx(K~*5shQpCehBu$|)Y(uAO0sOP&v$MU52?g&)-|G!kbBss}3 zM(_O@e*#2h@*{b>pDL7+6(E;6{h)@14K^)0y>~Ux>|Qxy4S$9LPaQaSom031SgPzR+pDzmW(Gk(vz82|tP007V#Kg_S}Dih1R;W?)pwPC4BI?jZK94p~O zGDer8;SmPNnSZmR)6yX0mC?59YUV@6bkmAsHR3x5vFBK{bkbo*;?PUh3Y|AH<f)0QD3U$yKMN?(wS)Nt{NIzM zfDsgGx@`ae0Kh*}Ypu1;j^dXMMwK+9&Ax=MysnS9hs}XASZC#>6sN*~$iK5spwwDR zDf@*T2U}|(REcb*`cYlUYN}5aiC4@HX9x%RLxf8I|Cj5~->;cAow=29t zYtBof{p#!>n17P&CXGMJYD5Bdj&I6MMa12?rykFm?a#rOWZdX<^i9o$%USfc@Dem@ zRat!knmOn0csZMaT|J!qhYd#cf8Wv*&>d)-v%EYs>MxzrOyC`xdYN2i)1; zou4AzKg7?P$ZG0iq;2<%wz6&2EWf7H33=K9P6wIMA2_Bl)QtXM%)v~oLNl=s&&2Qo p0000000000000000001KegLDLpXL^m5eNVP002ovPDHLkV1jvO+UfuR delta 451 zcmV;!0X+WM1Kk6VB!8qyL_t(|obB0La>F1DKvB}^PT2pF*h@d$@hB1q{17;qd%j!; zumZNIm6QMg0Dv!3N-3qRj^dvUMxCif8~qi2;)dSip0)HI5oeHdAA&Nc;wKL_GoaVVB2p5^b~n(|_(IWcU3z=d6acXOwCK z8(xIK6qE+Oxm3-+cSrO#@`U;Aid}$5ZNi6aVNck`LKZ-#W`CEH?EM&ehmIsAnbv~B z2z&xgL@%?y-5$E*?A`sv{?LaK007{dyzU*&dBbd#Xq+=6l_GVC>TAbHcU4wWQOR0U z>+0({?~V4O)_=iZRkB+*K2+E^6tF+kQL&|nL$2Ibw-?T~TYf@4Zgx5Px@zKbl3p54 zK}!<#KpXlbXjHn+ICl%8k%CxAX|(6y#|C$svTHVgYt z@@$~eW}AvwsoH|5(R4~=Sg04JG}ZmE=k6_;VfU~C!HkgwC`&@pa&`Es2P}aZMH><^ zwq$NCx1?}c!`YQd-3_?>y4jF6tIJCL&910R!&*L;YOAFsT;2*JAfv_U5)Nt*v{AO^ zM*!WF#XeiyHe-Bk3= z-f!;?U(xmD-fypa0CR8>>_R6AoQydrWwU#oYLt`8hc&E+Cb8__uQ8~7{fkZ;zv{3b z-<9%i-hUU%_T-m>FUM*e4l1c)lFfv}3^2^vXhP50(7r5VVq&e9vq3&t8%AaSWwH}M z>&&XfGTCE!psZA@-BnRm9?P0pJPEbx>8brXy5jpMSt$!0q`ro;3RYC0Uk~0w;kTg` z&;m;ZesE6%Hpaw_37Fpp9xvR_IgrNW=jQ55r&;sJ(6((s;UTdN zh#)F7tpNZ40001RJ3n=z#~7`(-h1#Tr+uP6%W-ek?KfTG!JO^<@GR7VQYB`6wQmux zI?*b@8ICb}@0Qi#Ppq%%(2uN@k_cckVbKtbZfTm{yJ~1@>wmqyLhX1gg$-#z3L}6S zYa_bj5~z*hXHWI16QSx1XswMga)Y`P+REtawsv;Jqf6;|mhS+1*`RApU1*Wj=d{__ ze}ZQNl{VW{#7fl`M3ts4kzt`el+tLMjYC+TLvM0D0{{R30QgQ8)zIb5FNj)+l=sn7 zL(ts9&xctS;(u2cdlqDgkxjKE-0+ztYKnaN$ zTQaAXTTr;H;bdh}X9F(2ZW7XFby=yO*%NhXSj)#6+G=SDmp?5dATo;6WjU!q&}P}1 z9|3ezmVa6Je_}Y&tjhDVRmnY;F=71$G+A#!Yz(KSwtu}RupyjXOD=8NlKqFXjod|@ zK`&BLjLR~FDtUg+HN;bcatFw}T?^Q8<7hf{ie7Z56~yT^QC9ku3vuDUTy6drx6R!g z=$ozI?w!6e)|Xqq-EIN+;7PCxJ;}nz@Ifib=5?x3PAVTSNNj7x3IKkYLG9~5blUiZ zhh!WFsDHmM{gk3od^PxTtj4+X3T47FHMi| z6uui;1g)`Dpt_SqCw*V>B2fp-mjmCVYCnA-RbPtx=IBe^dH)2{wxH!9Trm(m*c%Cs zE6O-$zS^MK*MVdzE|H&?_Z7~_&qOw)eV+9X^5^xz#sUBU000000000000000005No Y2Tqnhw^wjZx&QzG07*qoM6N<$f-jU}jsO4v diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00004.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00004.png index 0345aec8bd180b1ab52119cf02f918a810bf3121..e8bad56b645d56e822126b0a972252a587e878ca 100644 GIT binary patch delta 466 zcmV;@0WJRV1MCBkB!9C>L_t(|obB0LZp0uAKvB1vov{BUv6p^C6Cv9;5|HxKrb^B@~XbY(5 zyLIz?Qd_rbt)-MbB6eZ+K51*Ic2rY#!S)t!8{BEDM9I1X)PMD;OKpQ_i}jYO?ZS<6 zDdoa;;nuPvd|cudBqw8GBmV5F9NF&Y%bkGUraa$;VQf{hPqLH=Xt(D0h-=x!`1tZv z4aV)4ucX0j67PTuLvMF~dpsPr(>pxcRjk%E0001%crqIryj$9@-1pM>6V;&mhS96; zmQjO|Z%#>#bAP0T^@2A>`&IBTK9Z17FW9GY7=!KGuaYu%xv7YrJ1b~Hf^54FCUhk8 z)6u868&|N!$@~$y0%d%d4Ms z+_}%VOWra8JMnE5O#lK=n!07*qo IM6N<$f@SI9YybcN delta 471 zcmV;|0Vw|L1MvfpB!9R`L_t(|obB0Ba)clZfMMF{O}PJ&xJw_Lb(kasR04MTe^0wB zU004(Z#dZ;%a&@P9L74 zLBIX{5fscJ@D8{UdOiE=<)PcoS-rIaorhj>UjhIC{9BWEL!H-4eaL(@^?wl!nlBlx z>Sh@cO!{mqiGMijy{1+?`#CR-`jGQHKC&kv9`-M7V+^+6`rtQyRqR%Tjab9SEtXbYfX9b=`_M7 z?E=jtll^6kRFnP1=!2b@g?3^c-ih=A0000000000000000001CegSMCrZ0^;zfb@G N002ovPDHLkV1oJ>*FFFM diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00005.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00005.png index c279c7048c80abb5bc64f0316ee7a64ba9efbdab..83babb94d2807a00afdcf8a411a3669592ec6f5f 100644 GIT binary patch delta 733 zcmV<30wVqQ1@#4xB!9d~L_t(|ob8)ilH(u@MVYDI3Hx6XdzlYcQ$!Ntf|2ob-}8}* ziI9YN8QDpR5JCtcgpkMi6Q{bAl2Xb!gFiX)yPUc3?LO?=-|ZSNYJ=OBA0&U1ESE&| z1))v&ic@U@wy>0vb8g3-9>Pe;ls`wtO2`ZlEfKQ;oZUJ!=6?{bg-%IT;;$rT#cL>- z@>>X;0U}rnvm4jY#;6zNs;$N}bk_li+5=KE;&zc65*GBETxvu2v;7@Vy=-T6Zz3Zh zb7b)KXF+-T+`5OtYeX$UtS;XKUL*PhRqo-K{vBqruiemGTnG*w@JWFZ&nN}>3?m2z3<>^ZZ7T%b!XKITJ7b{{d3_IQa)c!X=ToC=CC=4(THS$r?3_e3J8pg5O37S6+_ zJf46u6Q8=!?D(5(dmd0q76v6%NxYJ{6|bS- z$}eH#3{b(EnBBMr8KYK|tF{``t-B7$u00@$5x0sgNWGvhF?}i7x}UA@fa;~3(XEM$ zjJ`kyUw^8?hKteZsxT1B9C+1AiUW*7`|)aSK7~qhfI_&^^THu4LR$9%Aj8 z2<(+&7}c{1^r^j-F}1T^%7YeFb)~be8|o8R+j1{Z5_N!^GISf{|^6G3dmj=l9*G8?{RxE-i7FA&pseEN+2b1pwwVp_%ySwV(*Et6Y zF{=u6sdX8ccC((g(DwQgmOT%sFOkXcAunCERLK%VNxak87sbHQpd1^LN0^)e_*k$H z4o9(*teE`!XcGH9OwNFbq_oT0I|sM3U*0Pp%~*gG{P;f RT1Ef>002ovPDHLkV1m^3XL$es diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00006.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00006.png index 6f224982ac1d12e5bbb00680c10bf7593f656ad4..0115df096770eda6103ed72bb3af63aeb6eb5380 100644 GIT binary patch delta 475 zcmV<10VMwR1N8%tB!9d~L_t(|obB0La>F1DKvCN1PT2pF*h@bcdsGR@q_!aK-1F5* zuq+;iSSS7q;?iCa){dgZYr{@|*#ThN=FPq`D|ZOVT_&pi7iOPK(vtAaI!>s-s zthx2-a&*9M5#A6??qKqARn4{mckL=WCtz4lz8s6-Fo^deFMd$}ut8J~_idYi%YnAV z$d|hPYJ2rBo#AX{JSBT3V7{_8-~OMtbH2wvSJYRsLR2X~xy)+Va`;J{o)^%I^T;os ziy#zf7jOre(O+gT)QtXO%)w6VLOXE|@5Jx|0000000000000000001Kz5&z@t~?+v RKe_+_002ovPDHLkV1l#I>g@mk delta 476 zcmV<20VDqP1NH-uB!9h0L_t(|ob8!WaswdC@%~5hF8$bvLqS;6U9`!(_ti0q zfCwus1poj50AM*^snT0(rIcE0>MoON94KX!hC_u@t@zFmdeF_5_NUTX8}3z~43$yd zw=(Zm^B0d)>6X@7t+mHgH_v*(Mx~5IDMyK#4_N8kWl^HYx_<%69%ZU@qMhc2s@*~^ z?|=7TSCiv|@m6K$&%_i|9IHI6$8U^En}YsHeabxmFDbtThvwOpEad=XYK}{s#0Fz_ zc*gQ&>CRIo@do@sb(tk>c{r8Rm)i=YYQX#6O8@`>fY0FOZfNkl9QGaK5w(2yr0|vp za{~3sv#liOsDHkbCt*LqqfxyohpXa|xN#PI*ITV7cMMkD_>9PHMRcx&%z}=Xpk{Z3S*gESnEt*it_AMNkalT;$0QS|Cb-Qs6o}58%|%wjcSD z<*&|H|JAXlm2pM39l(5ZZGQeIaIwC}pDXGo*`$;sr&Wp#XAVbV^*n(?Ik$ZIoCu*w zy8ze8cz+oKSL6M~a0WXe3+;qDyc66D0000000000000000000000000kj4+spRm)l SRwnTP0000N%#< zw!x@4izQ1CwV1j@hJ{)vwNaVKCLG~WCo}*6004k*aw3(5xH0Y=YSn zF}U`bR+Kk8w|}i#)A1?|8r>3lRG)anR`s`5lvddt>1f5(Ut?`HluZg2Jyeoirh+%; zdq%qfHzgv~%b<}6>5HU~`ZBetCOg^mu_v9KF0B>X>AYZQ%5Nj8f_*U}zz7H{0;r#9 z3T$E$ad2X?*9JAUY`bbQPbzoilh{!V4Sq6CRz91*b$?MiEEl~9tvzMQy9lG%P&T=m z=348lRM(BG!*ork>Fo2tAZ{P|5~Lo~jFJ({m_oKoGkG;9YG^i;u(p_R%}+J++)cQ4 zaJNi<4jW9`-0Ny{PaFN#ga2S#dm5@X_q5S}J@COv{>&=$N}NH450=tAyoKOujHE7F z?TF+pTz~mm;vt?eSV!n4tR9@x7K>|_tjIk;Rl@WfkNEzZa7T7U4JH|6?D4*W$?H$~ zgvtj^lETbYvPJcg$=l0D1GY6yCI+h~ZC0voQy*)M8V%Ki<=@s1YF`+B1l-QtnS*PZ zJJL2a({K-^D{P>K;|Tr>8TBQ5nbrUOj99+v_W>Zt*58P|kHO;x z00000&f)xb^pjzitb>+(DNRYo$AXL4Vc>wnzyXJW0{{R30002^KK=u40i(^xC@$Rq P015yANkvXXu0mjfhGlyz delta 781 zcmV+o1M>W+2BZd%B!BBkL_t(|ob8)ga>F1DhH0la;r>VBE`7+1t7t>)uJeBn9fyDr z5@L~?lmGw#0001Z45gG(O8hIQ{%WmQ;b!%|R|vgy-C)x=jxsrCr_Rz*{Hzl#2@bE6 zl5>8Qzf42x#7kOLIx=16M*tfJiw0&IwJ>RR$vLZrW^HB3C4Z#q6}4@o;RvfDfElYJ zwBr(}fh>=zG*w>2l06_T*tIet)r_u2VaLwY-7wB%2V5%BaJHg2GWDD~@%4v#j>+_O za2n2H$r400rY@0Tp%zMMw9c$e_*N%000000fKTJg`Hr3ZSP4Ddv#Zd=>$~iQsT9%K zdZrDXdtB4Kx__xjR9v-$p3~=^uhlME8%o9ev2^rOm2a^y8_H$`iym5&-K4DP<7CRJ zF*hYB)ytrhQ0j}Mzs54763ManGtSSI#v4|@^+Ts40;*a$5#R)b83EMEH2*a*gE&4b z*=qw!GTX75G?c=t^^@3990`?VoNReEc^g3;uw3^dw0{nkCGR2(WkcD_YMN*rQ&L?w zUIV6Ug0qF}Pry}&$(JCyt-VUrGw8TlOd#8(WfL_g>IhfsTvNn42qfE2mWI_$*gCs= zs^5nVDs3LM+1=f&-+J&L>}yX)W_Ne9{^NlUPV#S7p+{0NGJLR<9`hDLRcIuE(W;7{ z|LCi%mVY0ae4&fjb-{}yRi>lfvm*BZRRR^FR^H6eO}OtiYefkyXCJRy7&BaXhgJ^i zBP%mkv1h7bvSY|!GurSKYSJ>;JZTe?jmH_eD#z)?sx1GuKBxm>gd*Vb=gv%A(hDXWzoWGoI6dLg5}2}$ohm+4=%VG#D3MSng#hR!!)@qG6Pk@TunVPq$u{mQrB zY$^=Swyi(VP>tdruKbKQ3q*fy@!dHwSzXQS-j`V>*vyF9t9~B0{{R3 z0O#=jJNo9ZOV&Y6K9r`U<88r3>@aY^Vc>wnzySaN00000d>+4|yQa;$xL?Wu0000< LMFvhpu0mjfYD9L@ diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00008.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00008.png index cfac626850370e52d27b089efd260a5d2d9ab170..f4737fb0e69a9300f8f03208f20316890ce8cd14 100644 GIT binary patch delta 461 zcmV;;0W$vV1Lp&fB!8|+L_t(|obB0Lj>8}fK+$wGJ7NDzVlVR%HG^z0ZfcyUz2_@R zc^F8DaJLNr008(Twboke)lvNG#v^We%EbCv)b0^++8Wr?Wc*Z0G0Lot|95HYLanuw zvJdIF*m_eS?zFW;JEEz!m?xg@b*3e6fEbJzXFG|y*zxPMi+{HIaa~H$v# zsx4?63~8jh^F~M1X@B+nPAy!3n|y@#7*2eXPFH+M`~tLFv;BQ*=_fJj*(^`GS-T6P zVxU!Tz=^oq-CutmJe&CDeopW3Y61WNe6vSjTcfk3C+8!|cMlMw>PDHiedFjW(n_M1 z(aVj9bE8padVj~xk$F;{o(oSGqeude5n%_hkcT26`Q@>{2RXr{rlVWkEn>PqjP8i) zB7N-%=BkCyTYzo?c{+0AV_@$^y8TgkBL$+H6;Zt}X#u7aty7OL4f5PViUPX#(Z3FX zG8Vv}O7oZh7;*su2j6}D#qKffOPBQQ@4Af9qmE7V6-M|pOj;vJn_xJ}%zm2AR5Sa@ zSc5CE3tee4$*jRrOfLWc0000000000000000IL_t(|obB0La)U4og<;z1PQ3pmc`tonLOn;etPo!^>Hj@Z z;){^M4C-+J0001=B(q^phN#kA-FIxjYP0mj#C8y2o_!RQ z))sU$E~%xu^NxJ>H+c!4G2D13-R}65@e5FH&HnqXWbedL_hx#q!}?P= z9S55A1l)+b-2LtAA+m`d;m7VB9!&rMfdA}k>~O8m%ShQr+E>3JTHT#C<@nCmuT++# zS6Oaqjj*45I)6HCx@Y_{S)}S2IfzVA?KSW-V&sR|ko#gm{VU?UYv}TSRw% zXq}PnQo)V{vt{8o{6FCOvsITC&db2xi|qKV_D&T<#*~m=w{8KtiMG|pr>^tfLP`TW zyF69#c!Cx!K)jk3Z~qx|0mfc=_3@Y8qdT2#8QI@$8%t+K8=K5EDkq(xDAF#_OfuPD zrjly1zZh$<6T8q(og}jcQ;}W(000000000000000003Z`Uvi?D3fEIrlK=n!07*qo IM6N<$g1Z&wng9R* diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00009.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00009.png index fdb967ac893f11ef332735905342e7dbc7aad3f9..fb73722c9087149362e74ea21058e05ca44c948c 100644 GIT binary patch delta 740 zcmVQOFxTxPUc zntxWc(_l{VNK5wP8s}oY9tfx|LqtYpZ8Yc0?GpSyHrPk5irBq%$XBqxwcYX!L{) zZFcN(_D9v#-eFeBtIQrxmvcwM=$L9a-7w1;4EA|dxP8m?UfD*C6SYm+DTAsqFGbLS znfJJAT9%P*Xo_UpBMW~v_Cp?uw-)4|2UeMSe}w-odw=w>t6_U$94p4L2UwfUj2mON zg|FH-_Gqa&>VXH~W~Lh|)F6dpV0U4pebjzO<0MF%lZ=0_vZKWbTNPE+_SaOyI$!j{ zs-b~GVBeKb`=%DWn2?b% zBRNKCY{{OH9B19_B-9toFFP4ve3&*fA{UdeYIBUlR}+glqq5=8B$QzFws{ZUGzZ4x(O>$U^{00000KEk*f>TLd+y*myb;{ECk z6LNoz)O^xa1b=mRtC}$-B#E_O9`2)OH`?lflbsK&HdBfgO$us^TeaaN?3CW92c2QC z&}L_@;9x9u*E_7Gyvj_9jJhx&tTU?PbjPOPWU$Y(!iP$yx;HUNtc(21x-^$TDS`%O z-LtA;O-8n%DRRK1*)pI1kcSeg1;y8aS%%)XnCj&R5P!RxHYvxRVjO#Vwb;z*m^Lqc z)$e%EmYSv!_yk;H%e83b5UE0)q?I}FM`0OYwO`RVn52~`3-&Eq$}C0Bt#$ad)Ucax zdg0^G=l%mMmH$q{E8Y(->!n*Msi?hg;pi`F<1@BVyyR_IwNbX^n ze0fwH9hOtGvB@d~I$hMS>B^;3eN@dDN|PnbDYFw4zM9zVYIY;hBqKUE z9{En3^xZH#@3-L|y#&QcjAT~|t4|XjNHPPq6k`I@+;1vIB3jL}=deEm;!!VWj=f0w z`Vf&O3*GY08M#kNUD6~eM>QJ^$gT3*?+vH_Md=9~D+_}Cpi~0@000000000000000 c006)gzu;t7l9{?t{Qv*}07*qoM6N<$f=^p&@&Et; diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00010.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00010.png index 806c37fe976696b217faa90d27ae873777137a69..a4d615a4805d8c2b0510795610edbbb34be844dc 100644 GIT binary patch delta 481 zcmV<70UrMP1N#GzB!9w5L_t(|obB0BZo?o9fMIXiO}PJ&xXT`@MV@UO+F_Da|Myh2 z2^d41go*$F007&4l(yb`7m?OlX)lvuJm_Fdcww~FL-;IeSJbfe_)GQPlfGJOK945* zzQKjzg}$mgFnaH;wPRTwBlL;z3sWyf-HvH$a?R@GZd)Q=)qfRWhGa&oljsjSem(6% zpMHD}SGuIvM|g@4uR>u7l5s9VK0B)xrVryLHz%o{fV?Q**(2-?x3Q85(4{%Q%W26S zvO?Z?`%xW9;T7;g^t$@{qH)^J=;mQA#D98G0ssKKla;%n;pU=5kDi(=3I*Qv*K zuqT+^+tG)xM4Z-#(KqIFvv)lc%vBR#J^`b#jdrBN!z3!fc`fqoCwtKnEr_sL6V>0< zPQd)i^1F{u4f3^#Gza+JM}IjiR5$@oC2^(}y(K#VYgz~IpBGK_nE&JOsrv4ZnSUns z_mZ^<$y#Hdc7tJ($^JG$s>%Ll%)ynYLRUITGILOh^a20?0000000000000000A;=b X!7Yc5kejXV00000NkvXXu0mjfTtn|H delta 480 zcmV<60U!SR1NsAyB!9t4L_t(|obB0BZo?o9fMIXiO}PJ&xXT`*Ma(vi(_vCg|Myg_ zffz$f%0vJF0D$d2N_+3Ui%4s&^e)LT4r4GXJU80vA$%6~E5oqI@t5ko2lr~N**vQ3 z+YT3o=lZI?fzo?#t)0v29HC8wU6|uy9Q#pSCD-hj+-*z5s(*R{)R5F@$0XXz&TlVo zF*ZLxyDMG7=fiDc!>dqOf@Gcxm(9+qg=xchlg&x0Cm=4$@9YSB!!}kj0b^;7cezop zLsp18Z$GLdDSQH6h<>d8wrE`Tb2hg-(3@~2-~L$>F>%X zAiuKg0pzW5zBZBS0(*D$RORDIs-1vaNzBxu|3^>2@>!AF_eE7b^8Y)$Rp0G3`FCQw zm#oUkMOU2DZZJ(U+26)VHQC>cId~FP=t&nzW)4b`UH||9000000000000000pv*TA Wl!_$=AK+^M0000F1DglVTY@%@kFyYwLwMk5KaU_@hgzo!I) zB*d>bDTNS12qA=!?R+KKJ*akoveeGD1zk}gqO|w6`;DIRs*=SZC>i+ReyM-K=#XEFSXyU;(DZ2A4f&U z_|97E*nbPFvS6cXMS_qkk+wX=iX)eB~%7J&p z6@2FU8;NnQsMJ!OtZz`0TCM}nVZ~9qCc2RzB7$Pg?*X{}*E%rDwT03WLabzxit>e| zW$WM5TgpjG&%txIB*lSLj!*y5@!qY5KAusbcT;!;#CqXq+tGt-=oaAaKXZ4=I1*J7 zNTgTU@S67D-UPRv0WsH);^*_F1DL}{lt@%@kFyYwSdMk5KaCI}a2-&bm5 zNeB>lla@jVA%qY@$a21t?4IXYN;!@LycM*c8&cQx;_$wwTP&ih^~3Gd47y2F*>|5! z;wR6v1?=8=p2u;>NhjOjR}{f=48qH1{t8gtP^$r4+BPqB@_(vCt7qLg{(9v6qZN7U z+0??AwE|SK29`E%K_)0D*41Fm>4J@?OUfQl{`xu5;2|izq|b6)m(EQ|LI@#bF_0Rnj*?bRPzSq9 zFZ6*y`KNmkG=C_25ufD;4!ibX9oQei70c}B_*fm>jqSTG27DpUBDcV7;N+^IEv2)B zQ@DkaNUaO2Dub&e4rUUM0PDwp<`8h&vUKp4#NP=?2HFKLA!ZtkKJG zL4DDk#cSwJ0=ElxNNnV8V{q1@VjP&S)U>|3B=sd6C4Z~MEtSWszN$MU&MY~)#XCuy zOI7IdCJoX}U4q<0VKt{ryPKgag~q7ztsb8vtRZZ0N?NK*)JEn(ES!Dn`e%}EDb-((*A6z8`1;%SL56cz6syVLrM_q&ke8ykqK}BZswnAK_L599zqBq dgb+gR~5Kz}qwv~x_NzO7$fRxv)_ zkM%IWifV6Gfz$b+gAA9o1QmPAPwCXe4#^(Oa;_Yf*a7~C`+R-sjDLoU?|^Y>_TO)# z%~d;=UqyXOjVEgc{37mgiO}o#vK;H>(a+y{#{d8TAXVgU=yYe%KVy|M{eZB_aqbx_ zaz1^eFh{qe z%W551t`F83@wnK&-ihj|j!*A^>AvxPgPoUwzZU6=toxlU5M8W@>hE$pU_a4%>+x12 zm-p{YccuvWCz4H-uk^bj>o&Reo$w9*Y`N9hYnKI6`K&RG&X4u zFq2I7kC~*J>>oxSJc(84NsA=Y2dPLe0000000000000000001x<_8USlO?5jo0|Xt N002ovPDHLkV1mWM;~)S4 delta 478 zcmV<40U`eJ1NZ}wB!9n2L_t(|obA|cZo?o9fMGW6Cb|ESxXXS-MV5_?yJ0d-@AIoo z0~qs>hSmT80D$8@>Z z*`JoJ^Ho~A(tE$IYox=@O7Ds+rRq^td9!tzdYRl~6GbUm0e`A9s-H56_O|isvI$vy ze74j4uByLy6;9WO4RX7xEvWfRe#)k1@01+DEZ53mg#!@JxW8{K9r<;;{R1Gk=J@$0 zC3o$;;wG+_(s-&?zz^bebQy6km})#m8iE+5Cr06Vp-~Un6$Dh;5k{2hP7T?kRsD zn4`zhw|E~|?hoD-Ra~85XQFy!;7<&|^yoO>;oxBq??tvD@BZKvMAfN6`n~c2$S2yK zKEBn@<^7pqu&t|Am5(Q>b^zW=qPLm+Z+ZZ>_uTuxC|Bp>@-L|>lG)$wJ;4TIgH&zp z%E_WC4rvc?lT7xHnWUQRAI2CwiCySPizG7!rARLT000000000000000002Px#07*qoM6N<$f-@NK)Bpeg diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00013.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00013.png index f7ab16edfaeb9afb5e38a4da45467a75d78fe2f1..8e937c6530b656318b077abf4c7161d2a14264dc 100644 GIT binary patch delta 730 zcmV<00ww+W1^NY$EPtC@ZUZ3U2omwt?j7~5RTb28OEA5k;`V{BuJeJ_`IktZx>{uJ?#+NakWQ`@am_}M4g z#5u#1QjD>TyRwb{NtZs4#LAWxAZ8*~gL8Fj)8r5qh8BH6q<>?~j#nrQNOQ7r1qfpe ztZu&qkkdiqt-FqsU3)+XA*Hl-QOAPdHu?;g*sc57dIw}J%N1Q)$R3k{HuL!hHx^s> zj#>_v25JCtcjs!h0G2zxJwU59RS=w{Un7oeItG&MBkOv(%kZ^A&W9Cx)g z&1snN?ksiWOPp8=ehD6itE%WGj92A8cird22^5aFX+v@X{TR8Uv*mE!^|ugD~feuL1*-ad$ng z(-WYhcz?6o0j`^Hsf53*k1Ox`LNxh>fhpEBpYuwH3lh1KsM`xQ7TiFa!QOmWOF^Dx z|FQsv_J@Mk0p?ce90uqe@4pF1DL}{lt;r>VBF8%P7AxNy&80@68?<13OKnNrRl9Q4U zLI@#*5V!NSPjo3IrId3fe**1SDN|`j>BhZTx9{Z=59)-wnLkDTWAy9s#npD}6n^%J zb|Gh2O3695e%H3)pPbU?5ntJ|1G<@XyMf%@c4?{$cMIM11%IB7aXTKaFd>a(;|}N+ zYhriv5lUAV)bQ$k$KRXTp0V9kz8v3cNr`k_rBUlGAK0S29$en)QrH=goi;LFJ)uRcZ|;}&H{5^5VfP}ngrm@2e4FkED< z{%tr*t<}F7+2BbOg`Ol>WZ7UVYnFF(-vZY-zIaz&AvKvO#aQ{wlXt6@YmaZ6;Mpzeqhlqdo-_x&9qQW>|9Ro4&W*dBx0mzkg zZLlB~H=Atqf~e3{-U?*^_oyVt07~cAzm3}AMpMtj*C53!dA8kw<3CceMZCjBI6Rr3 z(&Rdy6oOj9^WanX30WbdT1L^~iB!96++`0@5wgKJDTa0Wzo)7V zU<@Uxn-Ty30I=OxXz!(zlv2()bQEV8RU40pup4mbEWRT;z0_%o`G=0!9V@?dTZ!!J zJ{Lx){eT)?P1!Far5Y&KL7v#IAvuubo8iayd#=-ivjiZs2}4Rqwv`s<*F%( zR>mlQi1^*8KYyCO^SG`4$n(N8#Hd=g@MpxbA7bxpiVZcdTdwcHo~RC#qmw!r?0Gtm zvbG;lyY@tNY6pZbK(}b@pK!N$Fs)a2E8e5)jrxb~Rz&r_*adLz?)J=mHn(X*&obyR zMt?ah6u1EX@|pko|3@ys+ANHo7pFt$hre6ryS~O4T1f{f##);Yt2c_Y8w`_7_P6Pz zn(S}J8l1!_bkZcrtU)N!3jhEB000000000000000g!u(LQG&@BMcM!W0000Sw<{y#{yez_m<{ER;PO2CNtRLoIhy@PoWwR`c6<8z)ua3K z-hytpE~meJJS_Ee@!2$scLM+b005-2c^f)=+jD+V;=_GFzn7Hs9A#3E zT3<)JdZYtR6kxbFjt4y4A1qha!=?A^yt4vPI+aWBlU{&ecgsVP8OO7AhH0la$^DPyUHXt&hYAufV7l%9J+(v; zL3AY{0ssI2003Y+A4PgwYeaM$hx3uqKGB{Nd+5#PeWq(9Hd{XJ2kGuRJt(ajysvgI z;;T-z#5ujz+Ho9w(aH7ekwi^;WVz&Lz%Y#=8=R>v{i3elE`Ky6#3E$xBx>JtHK^@V zsLFuBSqrJ{*T5Zg8Rjz#TzRQ~FDW?#h%L7)4hA`#p2DfQ^hiq%KsS-6^DK)!E;HIV z_n&3`#G>wLyhh0u#4Y9_k!hg{r8eHia|lN@000000DxaddqI;jgGZ=JmhIt&NmGq3 zh9!gAn-|FxC4WE6l9HJt)O%yak8XbeW>%>U49T)#200h8^QPmuDDq}QO@_3xuq@hm z29no3quK1Gg*segmD;Xc+Mjl3R)eW7c{MYJHXdPA)$Cujqmh($$IvW7sdG^aIx8WA z>9fL)TzB0m(KVZ}dx~*GFA27lNL^cybZ#y(+5Ph$UVq)(XQ%fmw;FmgPPt)D^kd%x z)?T#Pj2R%$oNk0ioq9m2uSZl#uk}aARTbJwjMTX~x>|hgnk}8B`%D%^M%rp~Q?q=G zQqt}89Qe6|D%#${`|ZX4K`YccM4*PZ--X_q3nwE6rR2NUzTXquxMjg2*#blw!kP)KKq>- zXU{?ol%r*>c*dF^L%pg))mAG4Em)We1i-l>a$VDl8BLVxoKsabkU5<;DWiHk;D2dx z5-Y}ezWrOPsr6IAI3DCc(NTC`V=mRzUrx!#xmgPnI2iQw7t6FU2C-L?`+i_CjNL>1 z2z7Ym)L?Kq-0V&2KV@x|JhHa_EFo`hy*dE^0000000000000000002MPQC#urFP#m SJ%7Le0000+ delta 738 zcmV<80v-MM1^NY$B!9t4L_t(|ob8%hlI$P|hB;GbC)xj!+{-*zV^Q2hgUR&N|2=in z3W%sJ2@wDQ00000kMr-4-qsosUDuWTDQI8lPbW70uzO$S8i|dT5Bo(%_<97jS0egm z_e10L*mtIMi`V}CCAyz|jY3sO{`F}fvfrQu$#XE`Fw`YUd zzJyaNKm==JY3DWY08OX4PXkweG`>@goB_nrt%{35v!GX*?s|?MX~h#TT;$8yTg92w z3)&?2pKblbWgc2!5m`;xo0~7!!%Z)xWO7a4XTAmL;MSs-`G3;L#iN@N9*aH|Rzq*jQ~5O4 z265~Jd(YYeA=wG#~5$C~l+YBDb?fGEVUul{aN4J_P&N&%t zuCnXu`H1M#89y_}exY4M)kj3X{qTz2a-9hgIK#*9LLbc}$e4qp6o)r+x#xHtO&5bd zte!$4pMPq|+l@5`jvYk&*Vb-%a@~>t9@mNk5fLl5BFXwJ}e=+Fo*OiA$zv~R3m#zrG z?qR-xDt=08h?!d4t{?wFwzK4w^!l5uhVr?q6951J000000000000000002D9Hvrpt U-=(510000007*qoM6N<$f{2@IPyhe` diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00016.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00016.png index d93355b0efd352ebfc20e98756acdde7c7579f16..ae5a99a6652822f13d1bb1e208ba942555a37e59 100644 GIT binary patch delta 456 zcmV;(0XP2o1Nj4xB!9q3L_t(|ob8!OuEQV5|b3HLt|cj+Q3vTQS?!KAI;TSWzo zCnh%~00000fbIOni7ut2lyc5-Q=HP|K37e(yp_EeGxvKjP586J; z`|j{K{zIiJN+~(#>XB-jb%9MunTAr15_KwDrE|9>iXvnMD1T#=ozjW6TPsiP6mod| zu9>cy>iTHK#tw9qTu#&$lo}?rupVEPlC3T1LyoAx0JJvcZ{bir`Y>A`0J$~y&o_z9 z#0|OGpCZ2q)hB8NyrH+;BJA-nl+(ZDs59WJmnHxJ0KgBhvKs1E7W==b;qJS^tq{m2 zx3j&@cAmbftbe3Nb!Pb>)Vt9(4S$&|jmXg7d7a`|2Ya;I zT8>VQong2w%rr?ks(d}8)m<479ssv)JT$mpL>iV8+@g1@f2Rau#VYl#6B~e`qix0U zJ=-ouG?{;O+(e03C4m8$ub|EM|2=d7)_S3JUmQ;1UMFFX@0tDG_L)CX>{+tbAw6jn yX*bYxGTz^Y<7&LW8DelJ>_T@kaFfXa92EpSpp%Xl!I7!}0000VBF8x47mTi_yFqu~GeMJKp zZ!y7>5&!@I0KjoxaiU8pDW#lq+!mKKsVIGvlCI97hI~Z`O~Phrd?=+9cdzEY>Onh4 zdEZ?g$9Jf7MJXlc+&t23vo5eHDbrBOQKBwot90(ML{Wsi0e{LEWv6taoz}}!yMxfrDU%JeaI0N7=T_;{wq}FqYtzF0g$D6e7;F+ zCLYMm@fP`)P<^7_fH(A(CBhyLQ#q>E_kLeIV*mgE03ejj-B7o=IQ~T~cdrg^lRyr+ zlkFGn;P$IJOMhyWY&Z2JJde6M+M($$i`}u6p_PXf_1sk(uMs;hVt4Z5K-=pQHRTUz zb+jE_aVx{LEUXMkIjV!bqSYfAa3TP1>v(GLxQ{gLD7by^-uyuqM9EaT-6uQ%Q%BpT z<9p`ajA$}{?AZ84ydtpySZ|`O&;MuW0Bmtwut49C@Y|1iYhNvJ|kGI5j00UQ+rlf9NDMRlZO00000NkvXXu0mjf5^LJ( diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00017.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00017.png index 28d1b845aa8aa4242c8454166521250df3d07e76..77e77835cfce04672d2b215e1dbd0f40b63e6a66 100644 GIT binary patch delta 758 zcmVKwr1w0}Qp#~0&X0inLVqr>>4)9>w_IbXMq3YiBlq-OGbp`k zW?$`|#CM)*iF0`8c^=162c3*xPs^xFTf$|11~kKHvcZ|!a(`ab_`MrJiyyV`6%8?k z9lSc0-Zo(P6vBb2>vaco{zrWF+L2pd+X}nI5A8o<40AQ~S>_47$QuTX` z;!S+}biWmFqQ0H<7cvBs^()EcIIjzY5JLRC<_wVVRM-rt{JaQ0hHi!nuo<2KB+7gD o{TgmTo8bZwLI@#*5c2o<4=dXY&1E<4E&u=k07*qoM6N<$f?x%9Qvd(} delta 753 zcmVrUIlSw-YOOTrc>H>v%$js0T=r)`H;gVDoT<&{MSqOn`=Rl~kJz?FLrkHE ztPJQTE0EfL4RnG;kG6agQ;iEhOv)ZmN)ZRVLM4>Zq>HP3AUT?z)GckZ18x)PXtgZ% zOot&8Sbw;yZ28V@8M%_O1W}8rOL$sni-RE(+l0I3<w4K!pqs1bZzlrurQ>&F3rVO^5`0vA0H;mv#taGv_ z-s!cz3#IjViPadowqY}jOdaYRJ7AblRKRe4TT*y^V)jP5?lz~vMtA%nFN*NKL{*x1~Wyt;f-4)_B8*=?v5! zKOu|r&y9xoD!6d^6sqpEI|28yS5^y%O#rSbKa0xPM z5@HEJe1CF=mAln0F@JedYd)-)av8DJ3UkFcEzrbx^pr?T=mUc$$xYQ-iEn42Ioge4 zW1-hug6HvQG^EYL`nj0)Z=)Auu=jsEdE0VZKPUJ-KwBbb+b-&NMsaM1c!s57T=u9s z{Vm=XJH4a03uoJmEnSOj`)OkR`-}bzVwx}Ib7}&Abp)3KjI}bb{&@T(>i2YNFXG3i z`>hx|>f1^GAOmc&{z`H?&g%jI002L)*#kJ(6%J!meqIEQp@)G34ud@aM0xMJPr(v& j7&rg`00000fd9uYLyZgAxoOc%00000NkvXXu0mjf$GK{~ diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00018.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00018.png index 31d8c9feb3adb901a0aa8b9f64423a5273634e67..83bdff68e28dc0f5fd4cf49b9c6b1d3b49c90506 100644 GIT binary patch delta 481 zcmV<70UrMP1N#GzB!9w5L_t(|ob8!WZUrF-MQziaxc?=&mwrrY3@GY6(4;x%>t%`x zS7b(-5&!@I0Kjp+;-)U8q?B^baZ7A@@*w;XPIi3`4dgpw($vJ<1|Lc(rMp&@?@>_O z2=%+e(|3{9^>Uv>(9HR000000Pc8pLr0%_#uG8T`f*mm?{2W{Q{{~JqQJP0RR91000000000000000000000K)hM X$cT`Tqy5`300000NkvXXu0mjf8pi39 delta 466 zcmV;@0WJRf1NsAyB!9t4L_t(|ob8xPZp0uAKxx&RaQ`E5mo89|WrKkXCQ|j@YLqd? zKb+u{000000Iu^Dr@EAqQp!2UZLwuZMcJc_?Ajda$ajR&Bz%_6hf+%E?$yFqBWPt* z^t;RB_zBgnD5d0_TSS^~HUzdLWf@96O4U}i%HUor6h+7hP=C%SKV=ZD*r-nJ7IJy} z-70;T?m}ziaiUsK+Kh#b_^Fa?8SR$E>#wN57WCGkw)kCsL=~3JEh1azPk?OA>z-TR zj(clM-rpks5oAv#ss%l;TXui@dYI}NwHo>G*--!h004mF9G-@bzV@6aYI*ldak|_Q zmXglxS521GDt|d{8fkbRb#=6VO`rJFv6YW^JB4+AtnAfYb?_Q-@*?(0U0fJ@ZBa}9 zf>l??(Uopzn6`z{6D2Qi;Jc&gS1RB}0=lE)sl(38V6hk3jYbQdDTvakZ2O$>1WW^c zYUubZqe{S>MF=5; z5JCt!&QGqnQi_ON*9CqQwBHoc{q`mf=1jo9S%yUQO?UELsz{#n-5IoTy5rQcmcl39 zq6O?sDdoB@U1GLckt?xZB*>Emlr{t0T9d(vY_s52>vJ)<(to;$;NE!G$Aq<*ip?Y=Em5yb42t6OkMr>js7 z9mlGUOh*`plz)t?njy{fN0rDE+q4Hx{lbb);6{EiLf6Rp8DjDv7L<~0sn2ELU5inP znI(b8=?JwxVRh{4GzxaXcM}XdsJnH=-c|!!o7QaXC73-!5xO4@y>;o&0KEdnBiSlI z5L+)#<;Eopf_LO3=n`ZnsoO@swdL6ryacP7>U*0Zbbm)iBizBpZ^VLCIOyt~pp<&= z4$@qNxzqz-9lKAGmB))KNd_(Fyjbv<@d(`;gS$H8y1uC*U7AT|_K)GDn%O@L$KXx4 z3cX1u$sB{N*z|VPP`y*Mf?1(heGr-ZkZ3Y|Xr`s{Gir z(_dGT7ChGbwZh(CN3Td`m61`uRTAT&ov{DBt{x1dk?$PoL00000 z00124r`BBWy|s2-SMVpJ{HBoZuQzruX9E7MGSo=jXeHleh~#O$y9IfiVn1otO8Asp zEqR5k*{Tx-dJ%v(Xs*5{&eMSr^(LA>$Kj|pow#Uo&7 ztcigfw?La?acVxW6lqkh0j;&(d+qqW2+eEseN)G6dB-AG(*aLFbnt3pHj-#Ync)1B z#kN3`z%87jatfmH(JtY`LcGYW(J~W@@PthO00000aE6c?%J*%yiqP1OaJVJDn{*Y* z)FF1L$aI8uNPoqMs#&BM{b>++Y@7VRNk4GWDY%hej8HVPeukJlh#9HGOVV>$@UF$E z8XF~s$LR>EKEZYD;WQeog6ziV_Mq<5kO}^yC+ks zfN?ullk5}@60gWfqEiqbq+%KRm8YjGc(qv849{&+(0__#BizBpCt}7dY*h7bpptxd zJ83S$TE-6Gj>VN^WqA=LNu%VP7fw9pc!c7O#$8Uou5YS>X{P&8_V4c;YWg|A4~B z5(8h^0q1l7{W$~x000000000000000004mR+@%XN$g;tZ#1OUmZ0037!f-eM^wrId3HZ}|q*nfhm?de|-LmkIG5*j5rFltbOBlrnmjy5GWA zBWP=N=V{bhl%E}qDy5X1a~ppfi5;+AfO65vc2rY#ZC;9(EPs4#=~R(#KzGHpYZ*ja zY_uxvBV_e<-PX1I=-yt@t!TR)C3p);7e{U*es}?C^!L0Kg8B+0aqy(Yd3l`)Ny6 z-AQfQ&UEjnkAKo9zocrdJnnt!=c4^+ddJU*IbYbF!p_B|>dy5;VL!y4EQ)=pu6ycx zaHdx$($P|PXP9maqdTMODv!O=tG8Cb_6g`Fkf#H74uh4~znlFYRdjM8wprD^=k`v( zG|)EDcxi0w)AU_F(#UjF~l6A&AP(O4J9=_72(m2JIs-WGNqZ9AzR z8XFL=HFC2D41-MckLiS(=pV)$yop`tO_Lxq2U`(d0000000000000000001Bn_u2p VkdB4cdKdrz002ovPDHLkV1oHX=v@E+ delta 484 zcmVly5GWA zBWSg{c^X-Z;%|phMJXlc-1gsgVmE9HP!^rEqfFV_yc91fe1EKTDv@tMx8mBh45Aeq zRi#}*s<-P_*YeT5UeQ&wZbuQ^g3`sE+lU`7!1VN?6`ug7DSs$+JDZNTums4~?4M>5 zTX&CCqQ7Wwl9%=yml2s;<|)O}B`68S^yox0dJ?Yc)T z`2${^7)L9*onhJ*Mt4T)YLva=)gu*f?*D-HaWt1!IETSX2j~vKM~cokMA=lnz0dXp zOapCajhD8!F29ln>xQ(y;}zMPfc0tGy8M@+6A&JP(OnnE=_*!orL8yrt+2DSby6)F z6_bf6X0rzv2ASv|qZ4YPe;9J`By^!CnFN^}Y=!Uw0000000000000000000000000 aY~vqH)RQI4;^oo+0000yyeB!8(%L_t(|ob8%Ra>O7EM5(FVg!>nQ6V9kj~v&e-zotC zasx7GoDv~~5JCtcA3!Okl!8||_Hix^OKx-Zb+)_eU$mw;rjDj%&e<^tdZMq0PBq{o zl~QufSNSD}w82aKA$(76UOFdtfZo*d4^x_^Fj-pUoK2ydwtu<=HyavUE5m8E%=sPA zh_$et@gAfoy%`;{-0%p8-vKG$O_c@dkmyrfqXfO)j!i&yOK#!b&P611Y!(8`@>of% z0K|Bf!y!m|DW^nl3$sx7CT)9A%u`O<(FP3;C*s54d0 zjv3w%eGkE^G`tBnk2>|_nrljW9fE78=R++AogC&%q|YfVn%QDo^Wh{~W||J{{cJtpS9M!mpju97pgWXD(Sn=)=d~WJNXOT z{Frb#vwx^9>x`P(=|VYq$W{i;9M-=J>Zy<4PG=9kI^U4`S7r04CkuTCz#Q#tDpwQo zVU{lq(ur25bn@7}@=eUhR=P(eVH89TY>YwA-( zR21s-00000008g-)LLt;{!dE%JeACnm#O-7R$SLF+opa*JBl?+DN2Q;5q)O}5tRSvr#swJHgzAeN;E{)a+9Kt5|+|~d90002MAL=i&uR~4olU|e8@qZnnBvXw5 zN{WRW=Wx8{mw)0ngd)?ay)qL+zo)MGT%Z}mIJ=HS!gSh)C~1I(V^l3ZH=YCr7v> zl&Mm7j2S1IN}AY_@G#D$VRPD)%mglNxY_u7c)XPG(CZIL@`D&Vpyfb3%Ttk%5$-36 z)qBhk>vBQwO4aJTehxA?pN{6_S&FCphHPN!(m67y@qY~94!ZrAr8%A5D049TL<>#t z?9pWPMyDfYY85%Ilj-sueYtv#)w|q6%eQmChL2B4TIahL-FebBKF0J7*=_!dL4F4R z*b99ChLJG`sU&9Tc%o)0epWItdS-1Yt#mv$cMD2BE7p9LJL3%lpEjv1@4G`V8#?@H z-k|gaE`L5LR7SYEvHFaPw&R6#@;qDFSxsd3UC_+>{^&IDl81-oGa=%Ij~40*IMcL& zY;Gszbu@i16%H>%+to=bdse=Q=-K)UN!ok3i>+jwxWPM4zcgzu;>qis4J!GgN737a z-$rijfXzi`HW$sUXWyJ^?EHge$Kh~NTu|3cOjE2bp)YySj=XoLt!LL<`kM+l<%O2H z?iL*4l2N?kA2L8;%>`YuYBt%to&f*=000000000000000008{_02b3g$>BR6&Hw-a M07*qoM6N<$f)*MG0mM@aQ+Tx(TkBQuJw zfOU8y`%6#>tWy%N5*gTYbC{F_{HaTLk;g*vF1DQskfqtb(;oqzFrVa}_%{W^8jpAvS|o$+g|eu%AXfz&3~79Qsy)z5S7=wj-?v_AMXiD73XDBKy9Zt@%~5hE?wj|!+;`b#I%3jTV)Io z1jR@x000000PjI-t+n>F7cZsYPaVQHIVO^Ku&qphEY1FzCb6q;^LmUFC0Xd!etrE8 z_=T^s`rG4SYUfnHx;)=zn*sm;0Q@^XmRM1Lkdao8Qt#dyM(U2t$bRXyi5%hb(`Zs! zvimf$up4z(w12OrBYr!~`CGRaR7d@iaPSlNZxRbGVs}>`fg?9%2ACQv~DY{o57h_pgp^RVUUUb zHaeju`kNsKPeK)Xl1Y%sK`Mk70000000000000000000000000AdPSNO{LEeDNa=Y O0000@28{-gB!ARNL_t(|ob8)ka>F1DglVTY;r>VBE`9I}Ly%ZWM0V|Tzo&!> zAwc|ip*#9(5G4(Rn9o!(k5WMT8x>c zj*e%@fQ@ti3His>#|$uyLnLoOV~FFF$Yr4xN^hf$=MXlLC)0f{Y=jU(2qFImTMb=l zhtdqlEI_o8*MC!4ZfZWxNTelpZeDpk4ZWpdIPb{QgW}4GDtN6FB-0WH6E#!Y1;O|m z!t6YV`PalwM8XM9_WoH)6y-ISdkXi5FH^|~t)yN>J~;wE_5@7z)%^t5N_^CmBdf|D z9xX)vDVkWLnL5*+9vKrb`dSTWZ&K}*CwgEUQfvUz&wmUn8>g#PcpJF3ph+;nBEIR$ zX?c?Vem8Q|&`B)3A;)w^rMC-ox_Jf29sl?MWX@?T+~{iPEHz8EnOvz_Y`kEVSi3f9>V9$!4vtYUFdNbgUmTN6*;`IcSAR{z_PwOu0+R`_%Zne z-a=PW^?&9KN^p3i)--m?ACD_y@D&^P61A2TK7sSmCaRc@PNcwzRa=i<>laOt6ycf1 zNmj&)1un-#a|$bz-NqU7s)>sp{&C8ix!l3Eq=6?B@z+(|RiQr;(?;#JBrHdp#F1DglVTY;r>VBE`9I}Ly=fXRCaB5zo&!< zS%CQ4B&85S2qA1Lk-r2yVwJq3<(1i!IRn&OE5W%eJAb0qs&@2LSC*^_P1IUP zaztI3sSPI#8@m_dI$dyraq)J6zfTj7N(x zv(&WmtZDa&@az6}pXJqGsxIK`{OY zVRkNJ{yDJ|k#K^Oy}wok33(?U1y@r73eBWmMcy2NAA10%`s#XuYb9PaWzVXzher#M zA4L;uG*d^~(;{O4MqjHA?T=Jj<%u2`hZGyY^fklE#((K*72XD}C1?^%u!wKEa$26G zzu%1YMh0GV@I3OAY>+DpxnZ6;T$7F&KdD#o;aoG|;i zfD4HERgJkfO4#pd$wPS07(9_ztwN8(=wyz;smSh){Wf$%3oPri<4SZ~i64_s;4O3{ zRZrfa1b>G&YE5IK{PDOV25+%(FHvhr;S)F?ZK8_l=tK&fShe-&wSLhQNfDl5oMc6; zSm1I@G^ema*=?LLuO4yHTaVOTu!rX)Fsv^6Xga z4kv>4^NWP3umje8+=2PO4c$}aJi~k>RLZRHS!)b7BtT+v7&G9yWzK<`bdyRL)%445 z8$*u+*qgAreW{kKudU_5ZVyi+>1@Y;hxId!(82dvC<40mj87psq48dH?_b07*qoM6N<$f*(g>n*aa+ diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00024.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00024.png index 2cee104f73f19cd2f377ce9721118371c54ec2ba..8516a02177018064bdd44fbbc7975d0a2ac819ca 100644 GIT binary patch delta 482 zcmV<80UiGS1N;M!B!9z6L_t(|obB0LZp0uAKvAaZPT2pF*h@d6BE|*>7@Jh;Jzr@C zh{G$1n-Ty30C3zZqR~=HN-5_Y(fBG6%=Kqd;dP7IWn6qYwsom@SP!C=QbyMj=i46C zRrDYkO?ml_XjChuuEST)7BF0h^F-PG`d)aXVePiynh0^Gp-)Dov4eACZ@hb zTfH9VoJF(x%#3a=9kUnzEhsJCx$g1kIXJW39}_YF#-{wZjlixdLC-eN0cf{o`+?Td zQ}4iJ)SH!ExV@vl{uZBJ$XDba&O?F8R?JQC(!J-6KCUOPmLwn=8J(8RKDK??t+Om(+rh8qqPdRW^7I zz->qCwBl0Sdjq*m{I{n&nLb}7ZUZo%HJdO0A1%!t@mm^Di8J$cMFD+AH)6M=f3+{s zZD$n5#yY#H;<9pK8+J0ie@v&V>HWhPgD0^IJ&EV=ljvRm000000000000000001D& Y4}hfD=g9N|KL7v#07*qoM6N<$f~d&q5C8xG delta 484 zcmV zA_9V@DFFZg0LOhr1TCeclyc4y!B>gKTz@9jylyeOjEir_SeJT-^&na)WppiZzU@I> zMGuk@%F9ngP_2}bbFTNVr{U;KTT8?dq4e}Lx>z^Qs1?fj34iF$xO&`nqAoU?nEDcJ z^?ICh7Gd?78QogC&0hSMptN}By2qpE;LLJ=OvnHji}LF>8g^9)+S@z_pk12n4Xvf8 z-hs)e7c0APdq;o$Eoh^m?dq?$hub){`po`O55&9%006*AkFue+iN;atvHsfqTo_e1 z%IFl(=!&a_(|;%9Bx<#3s8NJi#(VTkc0s(hFC`@ON2zhJRBNU^-CEn<6Z;=xPsThh zw-x7_^6o7UPe*s3`rAi-bVgJc$!hnOADAWn1JF$u-`BjPy#^NF+h^8e22#9a|@0+l#3Usn{+XLJxdj{eoY zL^n>i856OYB!8nxL_t(|ob8%za_t}phHdBW#QiVHz4V83GgLk$nA7&W&yUV& z6hcriVp;my)sRw9<;8mLF&+4<6c`SgKxNTYZSXk>m>(FrZ<^qb5Zomk<@2H>)Z#;+E( z@p-B>Me@%Uwm6*uZs#qEQxG+g4hatn@gmno`$QIDmz&}M00000paiEHy1W85vxFeN z)zSA+QBb@ouYX&_x2&4Yq781-b>F4Qu)(l@53yM0cDAL0FWsU@WFs1}Iby0-*K!ST zTNgGqVstxhmu=(PCd;lZt|2}v6Sf8G9Fh1oY;y*HN=`Rv&zu+uUa^R5j4wfIk7!AH zJouAp-1I=R2OwQ3G`9OeJ(mlXCloWXVfN3*PeIEn8h=5o%Wr9TA09dpJH(Qdek1Du zY$ek~aKzz>IO1;JhZ`Ab($u;dCfdsEEG@q!Z>HILe=SrV>h|ZoKRGuBadDyNn|S{y z>2slsJh;QVXQ9{PI2mJbl)LU7ghivKdVD8wJMGGr+C|FHX~^;pcWQQ%?P47N9>f+o zxq1x|sDNWo`C1Q^6n_iQagGokgjpQZquc&8f za#K*mB>P`mkCs#yRmS5}LJ?4cn89vhN8};I1GVeEyIIIDM^}-KC3ZIoo@GZ2cTk)mHnG6#xJL q00000000000000000000&+rBI4+?n(}A5%RB z$wDAuWVZ$Y00000z~g+CYaC;=)_U*BCa3=mljiSPDWdj{xSZgILaMpdQI*=cRx7^nrcIqIeHzWPMf92`zH^rR*`)-q_*FCSch_fS+M8ZFi1I|sM3u577gQjShXR(5!$W;fX`#>wwNe37e1 zq;lnInSVVgD{Chiya|v8G3Paa+TStM`h8qVQ;$>!F(=PW?@7zaB%`)w@{;;j)x(;? z6qGT^|JT=JB~_-%89pTy0VSvz>_z;DyoCBfZQXY_3&rK=Dvo3MM#U}EDI;U+%}k!X zYG~E^qRZr90ssI2 p0000000000000000001>kU#LoBwQ9uam4@t002ovPDHLkV1jsKVIBYg diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00026.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00026.png index fb49d2231b4f1787dacab86aae004fdc0a6f6b90..1450c34d204a715bb646b65d831263a400418ccd 100644 GIT binary patch delta 492 zcmVg-n2RDE~#ZFF|+P z$qA50vwxvUcIiF882vZOt9zPx*ZCcAqoMLlu-C)1p2f=}U0ZYO$^ifXK!ojRXg6x; zr>NrHPlQo%Cx4F(`}irJWKLJyNtK!gSr1d+gx!YvDSp_?`K#Q1h;BV>)w9yVQAc(^ zEcQOcKAGOQc-E8ZJ~-HykZ^Q&k54!FC`A=l0qSVc>*mY^bVJ0`raPB`e-_#LgCYt} zjKsD|7Fl;-0;U6PqlsIsyf={tsek))m)GrG^63Pu2W89F^Z#p$F-7?-LyR(Iy{yV$ zQ*0%>_1OIWOS?6X8n(XkCOLz)Fr?uiGy0F|3^k+wFy`P*oI-En9)1(U3jhEB00000 i0000000000g!u(J+2?-D_;scL0000T{)WgJai4(Bk0*1D`WzkL-`Zcz69NE zCnrE2&HjZZ*`;^?V)WlAukLB)UFUbeg@(#A!Cnv3dRp<7`$OFUe`%)z004ZDE78zy z;LuM|#k*e#qkrN~9vk`bQ{Ks(UZE#dO2(r`HJqeA3%d>VQ~b!6^M|?p7TtQ-s%NEz z-BP7l%k5O74e3)1Aw}KZ|Vr zK|uv4Orn}3^RGKI0n>rD0mZF`UYp2+)PH{L^k3d02Wci?Jzln+|NmNCLF(R@QAU}v zURGtWDYlZ`dTf6GrQMpl4O`!Klbk{O7t(N$8U5RIhMLj88FTO?PN64p4?l_F1poj5 m000000000000000!u$ffGMSZ diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00027.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00027.png index 8bc79a8c5395a1e77033767290edb4ee16a90a33..57a08b46c528dfa5d45a406ef3a3137dc73569ab 100644 GIT binary patch delta 741 zcmVQ8RjP8|Ea)N38FV`pu zK1{8(lya7zhM;xgC3d@!PF^{HmdyaxX*L^F)3CxrvqC9FHGeddl_kBx)6Mp?qy-Z! zo&n5QiHRK7K+VzfXpl+q8CI?V$A&ek5RPf1pCXC1DlO=;#sRHEbn^D*Y{Xsdle~88DXv(AyMm5A? zsm*)gA;^yGDzX|YQ3trxqsAhmm7WHp6{f$nSYBU+x)=@FBgToJ7tG3sO#B<^THrF% zzz2#2V3do25ANjtDD=%ZMurczk}>aS;wfIgzT&E4f{AYQQhV$SFaJi)ZnDCf<6a{3 z*Xj&amVbY3uej!LrF#B|*JrW`2P8jBsao2PU9Nl5eu@Q1W zFG-;O9^{~?e)(iPtvn1zq#`3=2GzT2i?sjECbsgB1L8+*Dza}qpV2Ibi>rLAcdz(7 zeJyJC`#H)-(@OblsEj!e$uGVa*Uf zd?5oOzySaN@Vz+ShCUg#6?u>C;3x4JTU+dcZUzpx8LR;y3)TRz05|{u00000fbZiM XjEoE+0^05800000NkvXXu0mjf?Brxz delta 744 zcmVJ+{-+q#-afMiJElx|2<4) z3>O1lBAw#^000000N~xJwbokWw+#8EU5YgB>G01)TdilSV;V>8iP61MN=`A&|LGPb z!H21}mQv34GZ0iJ-eUWWbaLkanl=Mir`c>!L&F*mEefR+HGj}dSGM#T&otZ5l2%MG zc?PgxB_?v*0u4tmqd_jJUt#7Ra4guP3gPgA?z%n&5_?rz(Pd5oT8HT5?akT9Kr>{5 z>yM$^gsGNo!BD)&%q58SkETRU3$;;NqcVw2ILLF}*#H0l006#+fA($p7HHQGdM|?V zHMF(MYtTQl_UCwwDLYr%TIz&0w44M;<=*PS?hZX_JWoTGDXy0B26k{#w0GD>uwaD<&vtW2(_M6A@`ctTj;m95_&ic7wRz76n-$*wC z+d_jJC=ozVHiI18$^EO)H{%2uIao?2yrYGuxO{!ZHN_MY-RPC}*co2_8#%j4fjP&$ zMCGr^41WpBf9feJL6xA=EjHi`{;fPjb1YAMQuIiEYzs1Bh9!fy`s7+PY?dMl4%i-c0Uz*(= zpQq17t$shp_-I)vUk#OO&O_>p@5R0u5Z@>5O<`EJs6QDR1A1Fo<%N50P&c22bzE%h&lu~le*8uK^Bn_C9 z)UAjdBC4)NWEwT}HHkL(3vg&z zM}NLNSVDFR%*r!ARsaA10D!mWLx0`Mv533F)~=D1lgv-O5wzz3M496GgY=@*A@Y+t zaHR`g&3SYnCx5`Co(5Y7V4mjHyNk%QBsPXhEDv2d`cXqWhz+H5hQ5iXWNyZy=U6(L z5~I>VQ_zF%HLfCN5*(52RR^4{{6$cn14RR z?l<#)&N~Hv74Zg`>|69(;?{+&a*+!F000000000000000000000DyPp8->zT-c1LH QG5`Po07*qoM6N<$f>U-1W&i*H delta 578 zcmV-I0=@m@1mpyeEq_~b#UKbk(@uBd{+Hxl`jOs@1x0)&y*=m4F^UKYD&{x<00000 z-hdcmjPY(Qe#k20sq}Xo5tqcDLI z**H5}BbN?~>|15N10J;qr<_`KtWw<_Jxp^z8k+6ZEJeR}>)yohLJwpQYIGcD@)yvd zWg7kU^56;C$G~Uz%#RfS007|a`LG|CaxB^1VQJSW>P6-!-3a<~09l#Y^M@G4Xd~nw z=ERL5bhFN*gMT;y9_DGVv=i59UVFF^nV!T(Q;nxkm17?@tb@4uM+!SupbIRoWb2WR?9mGtbi*)LbZBz07bjdLg4Tg{ggY zeMyLZRp-j=ZgbLSTo0oTD8&s=JlQGpu}BBl6U(jvO@E9_=#%M*&ezcM@WGuBh3=$cWPGp`ZQe>YbSI^aT~q$@cx@u}p~3F{-|?gpTQjMp zf-Pz@JN^yrWAG(iapGISgB;*INtW9D(d5K~98k@Y8W}O;@2-@Nbn$8)tf#$mo98Qce4Nh0000000000000000Ptpf18i(pbygXE QdjJ3c07*qoM6N<$f~Z&(j{pDw diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00029.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00029.png index da45253c2d5b1b90e793f7db55c54488c14e29f4..698193bbcb9905e3c4b696a36f84a43ff973adef 100644 GIT binary patch delta 372 zcmV-)0gL{S1CIlcB!5;(L_t(|obB0La>F1DKvB2Tov{BUX)pa?hEYLQu^S_l-t(34 z9$^C^#{mEU04(qDJy^U(o}&;GN>$WSW4Eel6PEn29_4j2^%RBGTep zKa^5xlhusB@>xP-)ENEk0|7vJ*iCZjY0%jKUdv#mx+4eBDuS@#V@Wg%J zzPF+JivM{2A#JV8PS;o0=@SFkcLL0#$ou=t{_Y%C#;h)7EOR!hvF=Q3W*IYUY{yK$ z=a)uO{D+s_X^@HjGDfJ0{$k8QBvzqF?8A`=F8}}l000000000000000@R)BDD?F#M SkvsSR0000Q1CRrdB!5>)L_t(|obB0La>F1DKvAdDov{BUv6p@@!zf5rY}ZDpz2__8 zJ;DY;whaIP0GRF-J%B@Mt@3LrC2AzM`;H#K34bZ>U8V^b$k(FJjhVQzujm1sP;2e+ zZ68W0Ez0eynYg%2dw}_v`__L65-&m9dwlz>tRHkK(-PE~A%D&l_b%lUBomvwn=k+X z!2fjfG1NRSnpyrKQnyfRb?TZGheZE`DhtcLde;dKxWh$_pXHP>Tb8+g$!qPO8t{#` zObLDo56|Nq?UA3*b>v-;UN_7XXF=0-{oA2~OWaIh6L4ffzgD;B?rjgceOc0(h9~a( zmc9*@xBT1l4{oX4X?tIKM(?%s1n8qk;9w^C<^Jv*S9I2pqRZ?JOxHcqnpwuo((UNP zYd$oR;y=9Xc7sgxr!hiJ^e1BuBC!fZVjqq~cmV(a000000000000000fXDm*e{npg TaUOX200000NkvXXu0mjf1A4Ld diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00030.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00030.png index e7b26e42693c4c40e3c05e8c9f5fb88867ccc9e1..32947b3bb52717f92b6a89c3684761116012fd40 100644 GIT binary patch delta 446 zcmV;v0YU!P1K0zQB!8btL_t(|obB3OZiFxlMp0UIC)xj!vX?#}MIk?SU;=zF_dFqL z7~@PV)x)v?0001&`?))TQjBpu2qE;&yvgs~34FW1yA$Y&F@_M**T48vI$pO$9-LpL zzm1-^15%Y!>C^dqF`Abw+r?Axum#A=Jy^;*Oll28TTszP>VJ}{b&|uRcfgdo*Oy2w zp7a7VrB*)Ph4St%Reb;e0PGOA(#d9|d#m~R?KdTjtDmL#Jdsk4o1XBo8_pa>G-r^- z2&^8HxdG|8o~AYbt1?ER#ZB_*sWCTgexjSk>5Lsv_od#q!ws+_?LnJ;$%iKoJVMiT z!?=1%JQ5(=*?(pwcF`6RhK5k2hR^H+7Qdy_)zk&)WgJ29~|} olZL(k0000000000002P8KhxD~4?z2T5&!@I07*qoM6N<$g0Cgk%m4rY delta 445 zcmV;u0Yd)R1J?tPB!8YsL_t(|obB3Oj)O1^Mp35fPO|?cWiNd|ib8&zgbDBg_dFrS zP~$X~#${Om004l~{au|v%6q>aIOl3-p5$|N0&n-dI)N(hy>l*n{gXe1<8@oa!SPl4 z+vt8fAXGV&KAeviqj<@(T|5OhTY$LSou$mfq}D*R1to1HFMpX@C)rJU2TZAZeu>oL zNiRTAXyyG~DDM7J)dv6ozyQA$P8K7Zx0;{dxG8Cz{Vd7niIlS6^n~}_aONnYIDwE(2^8? zkF4E4pO4lqw{z~-DDP9heNxX=O-3rqxzrx5kdIo5a|u4(>()TZ8@rH>Mv+;ALs4E} zOYZIHB^xw0U-TS}M?>dewR41N&oVD3`f8$0u#UUkay9{;)Jg95YU0D(ZwCwwENk%x n4SfLs00000000000Dz7ket2*_apAeR00000NkvXXu0mjfAN$k( diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00032.png b/tests/functional/snapshots/nanox/test_sign_transaction_transfer/00032.png index c80fa832578d18c8b1e4a2518b82d7f50be84ca5..d3ed6d6af1cf7ff977e87495112cca07a48ef1cb 100644 GIT binary patch delta 414 zcmV;P0b%~R1Goc_B!7QNL_t(|obB6Tl7cV{hGE?CCcXcWa+m$VY^OF*U{Ue~-{+Tt z>%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00002.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00002.png index b3f6946dbbfff01a313f38a692d477b1b20d0367..f25c827f230cef2072576df518ba0c86a0475b10 100644 GIT binary patch delta 396 zcmV;70dxMO1EvFzB!6v5L_t(|obB0Ba)clZfMMI|O}zh+a+f|ZWf&5Wtpqaqe-Aq= zi-3uuvc~}c002CRh=_>(KBd{R<$mSXkg5_Xw08IK?cKqM@${r>=XsW!{mQM)EVXw2 zscL%X;K#LfQ$D2XXv^T1hn>T1>i?=cy)0a8^%bC_oFiDBfPd!ssGHLBhVH0rtv@!s zS7!iII3^&EJ|9&pOlFB0Rx=|13sV*AV<6=oHcUZ-S|@CEl|-0E?pQhn>6ng`_*vOk z%a?Zt`bw{E!e-&+O;|*#nz~x6>wMjq11QUNHGJUy%g4mmmzTPqfLS8}03bGVU7_gGe})qm#xqDB8p`58@!<>)tiO9IlHbHEp?hzZEc40BtX+w3gi5->MRX@xmv z=#y9ph#aX!_D+$-ALB!hk|WQo{rZbt^d9X7^+?Si6a8h3P!s*d$iYs`LOXFE-ih!6 q0000000000000000001PegStyZp8a}K9B$a002ovP6b4+LSTYM=fAuF delta 394 zcmV;50d@YS1Ed3xB!6p3L_t(|obB0dZo?o9fZ?p#O>+Mu`7Zr|hL8;oYx%H}_xUlk z%!Oblq@l+F0002ojEIPceLbYxvS%lHTa#{drO{`nsAxia^^YRRsMg~h?k9vZMXt#mU9NxIe%C^C2d!B>2P}X56phb z8GVSk1;`V~6SI?XTB_?(H7OrtO6B_KsP_zemY`0pb5>m?5mu6qtzLp`PJ3FG9n5+^ z3&yY)ySfQi8!vCdBBCNySZmyT(Nsq-+ie*B;rl0#fzK`v^?dV6?P1vnwe}Biqe^LI8Cdzj7V?Ct+>9INBgH^-=+MuahE-yMlN87shD`(|2<4C zA%q%m7$N`w0Kj&SxTZ@fB61u@^La_Lx@D(XeYLr<@8?-T*YVqb-&b7I^GYfD$NM$q zH9D7-`y2baYWeXryf?^qT+^0*3hVOz_xlrYa(Y_TLW4VF_kRj-@=`PVhLf>xsysOl z`c?P(UO9buU*G_oT^}ad$|)I!br_EM7!5O+9;C}rU+#t!G|8I0%_^CX)a}`3Xln}U zV>(k3+K1@JT?*WWR{b&`ZU?P5vluZtcZb&IQtY?7sHHRPgScr5v*vfV(T)6HO9o&` zPXGY;BbryAvws!oFEu6o*QGuEL{`ZBa|{22{+mjQ<7h4V{5_jo0}vYh+IY5qta1%N z5PfcuZFwac0DZnM>+*FyVNMwOD$#Ltb1s%MUg47D$IG3ib;&AmuI_a4=p@nqY-W&& z{x*Y96aCE?gFBIh?!VUj58+ztQ$002ov JPDHLkV1hzR#UcOz delta 409 zcmV;K0cQTW1G58=B!7BIL_t(|obA|AZo?o9fMIv)O>+MuahE-yMlJ@2N|<=v|2<3{ zNnB>YVTb?#007%P;zE~FMC3S*=JS%UI`Sy2zSKNrJ9*xq?{R{!@)H_;QYl6M{r;Wu zo*@5D`;>j8wjVFuXX89Wqj%XUtlMo0{5d!?L!Biu)#FIJSAT$0mzoLKosTwDc^Q4n zM}4zhayqa?-~gPx@7CGMY3bIbZbl~4)Gc3nkS>Qj!VM*8(rErRtK_4XM?zamkj?2# zOI!z{cQ`Wwx1p6?>D?XS=*=vHG@Tp7%l)PFN|w_ramy5D&2Md^gZy7h24G1~008(q z?9qaAAmQI^e}7%t({D6NnSXBKf6zZuNpT#lZ8(BYCD#CiX1@l{_P|a^@>slKObLvm9L-wK!LIy7=lO+5c|CB$NGZI;kf6 zn=uA=q6*!K_wb!aF8}}l0000000000000005at(rauQ*ZVdcgQ00000NkvXXu0mjf D6dAu0 diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00006.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00006.png index 41036987218951429360fe85cddb772919995f2f..3dfe336808594a50f7408e5a43fc1f06bbfdd338 100644 GIT binary patch delta 406 zcmV;H0crlP1F!>-B!72FL_t(|obA|AZo?o9fMGiICb|ESxXT_;5yN0mgTZV6?_uf) zb(kRzBLn~d0ARa^UFaBN2;sV}>hqGYWn?96zM8)!hmptD?4!rO@5e6myclEo$Ll@A z-|P%KC)Z2!TdBR*XL4-sdD?~UkxRI2A1>I+&E;vD+!?!{0Dq+}RjW@~uw|(DqTDFA z3@f4RqmSV}!wJYkZx-1^X=$dlnU2XE$r+XNF`V_~4wRrty>(hWCC6*XO3=8crA$A!&_9$vU2$<7U9vuZ_r})*m}Wl(_x6vKuL&?xo?Cc(yc|tH zdA=Xk)$4S^>@f9-qvPo6T+C;_%sHu#!<}XCQm;k1y3^p+PO|^mx=AMc+cZ*5_BUe= zPNE8(#C!N8(hC3p0000000000000000GRm&RsCXQV-GM6pa1{>07*qoM6N<$f*O;@ Ad;kCd delta 405 zcmV;G0c!rR1Fr*+B!6~EL_t(|obA|AZo?o9fMGWECb|ESxXT_;5yRM^6%()hzlSL! z)M19WjFbQX0D$AZ{6goPQ%cu$b=OIj-lvoqsn*900Nn0j-GDjn%Ek(zHg z$T^pk%W3nXbCK47<}lype-Z>PL1~$9?G^u_YmrJ&)r>e+?tfLt5~ME{aTj3#0D%AG z;x)ASmf5?t`{8m|M83YY-k;z-H6@kEdV@jl@ErW`?vs1RR$OmIoE)KL9-M#9r9y5+ z^mrK2qg>B`A-cqG4|!MHcJp*VQOizRF1$Kx54l%Um7p1zlu`Xx*SZbs(`F;(WBVbt z>%`8lM_k0h={kl?`nPFBP5L*Z4=hoIEU^w-B3=Lh0000000000000000N^rjdLOw3 Tm$efz00000NkvXXu0mjfki?Va delta 318 zcmcb^bdza>}$AVuBmn*KS=guja1qE@taFn&qLH3~6tY7bZV8ODpSrcYsf6(a&%E zYq!oTvM-UIygG#WPNv6L%Cx4t>{>B8IP zHoSR4(JE$jdt+EvXPBm3vN!J$Hhn4IW7u&-OQh3Ern7<(=u0HfFn=d=f!R*hh&tI- OAYo5eKbLh*2~7Z^K8#oZ diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote/00009.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote/00009.png index c80fa832578d18c8b1e4a2518b82d7f50be84ca5..d3ed6d6af1cf7ff977e87495112cca07a48ef1cb 100644 GIT binary patch delta 414 zcmV;P0b%~R1Goc_B!7QNL_t(|obB6Tl7cV{hGE?CCcXcWa+m$VY^OF*U{Ue~-{+Tt z>%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00001.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00001.png index fea4e48177ffb1cf735542d45282718e32716096..613a80b3d26ba0f1e38eed3ee56a95d1fe49dec1 100644 GIT binary patch delta 321 zcmV-H0lxm(0^900Nn0j-GDjn%Ek(zHg z$T^pk%W3nXbCK47<}lype-Z>PL1~$9?G^u_YmrJ&)r>e+?tfLt5~ME{aTj3#0D%AG z;x)ASmf5?t`{8m|M83YY-k;z-H6@kEdV@jl@ErW`?vs1RR$OmIoE)KL9-M#9r9y5+ z^mrK2qg>B`A-cqG4|!MHcJp*VQOizRF1$Kx54l%Um7p1zlu`Xx*SZbs(`F;(WBVbt z>%`8lM_k0h={kl?`nPFBP5L*Z4=hoIEU^w-B3=Lh0000000000000000N^rjdLOw3 Tm$efz00000NkvXXu0mjfki?Va delta 318 zcmcb^bdza>}$AVuBmn*KS=guja1qE@taFn&qLH3~6tY7bZV8ODpSrcYsf6(a&%E zYq!oTvM-UIygG#WPNv6L%Cx4t>{>B8IP zHoSR4(JE$jdt+EvXPBm3vN!J$Hhn4IW7u&-OQh3Ern7<(=u0HfFn=d=f!R*hh&tI- OAYo5eKbLh*2~7Z^K8#oZ diff --git a/tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00003.png b/tests/functional/snapshots/nanox/test_sign_transaction_vote_cancel/00003.png index c80fa832578d18c8b1e4a2518b82d7f50be84ca5..d3ed6d6af1cf7ff977e87495112cca07a48ef1cb 100644 GIT binary patch delta 414 zcmV;P0b%~R1Goc_B!7QNL_t(|obB6Tl7cV{hGE?CCcXcWa+m$VY^OF*U{Ue~-{+Tt z>%=B4G`iCS00000z&CkB2XKm+)yJijz)1e>Cpv&{moEWk))xMuvv`Be@y(Thtk;0G zQBHRy$hQRD%riQG18UWe%Y5g{L@)z_k$_+%AQ*Q+!I%L!=znG#u}rt2m6^>;jc>-~ z8vQBnHDE?J6ad~S-9;>yjo}p>efu+h&1LbNw;HYB$JiN?VB}+Mz|VRp%Wd4C+dSA7 zNPW6e%EEvP){$R)+Nbrgk9=@S!NLrf*3uHHt>Qg_X%2U%8|0Ub*qnpQL)vhtCQ2z% zHPrDX-tUB!qkq2vKfKb-IDZLk=jdXs2+m*t008Lv=5rq zr|lp5Mqc}#YK^a8oBhi(eNcZ;XHKZhfYzSc9JHx(kxM{bQpP#(XOsRgOD+Mk53SC% zm#4G(%OzmXmxzl!(XRG2zuSP^8pTf&aTWfD8vppF07*qo IM6N<$f|4`P?f?J) delta 415 zcmV;Q0bu^P1Gxi`B!7TOL_t(|obB6Tl7cV{hGBNcoAmxi%3bycvz=}Or7UW`;QRbi zP$xERX(KKR000000H5S5I)F>etUfNK1V-|2-_Zelx_k*Rv$o@(I*TVbY~Nf7$a)Rf zYvpuTf_ziZ%{-z5IHC6XaW|iQnFvNeFcJ`q1O#Ih6pRsolYefu5zDj;t;}qlYJ4#+ zSL-i%uK_Enp#bnq=`Lcq95k)WsKYu*;mb-U3DevQeH1S2171Af#)S(b5wYV%-Q zAocA^DH{zg*pK|=(>|?_edL2v3N}W-vX_=nZ7-e)OtZN=T_gY5h^;wzdq@XP^@&o7 zR3Ga2F5d5im4BnZ0pGmR#W;TnZO7Wm4M5zw0Hn}afSE^-N|Q_468{%q14vqbL;dQo9~ z{aC5lUv31<{D`<&6YUbF`P&BM<|xrA2sgxkxB&nF02ly>_X7h?_u2U|dE)>8002ov JPDHLkV1fgCzxDtC diff --git a/tests/functional/test_sign_message_cmd.py b/tests/functional/test_sign_message_cmd.py index e3cd6a9a..4c1b57e9 100644 --- a/tests/functional/test_sign_message_cmd.py +++ b/tests/functional/test_sign_message_cmd.py @@ -45,7 +45,11 @@ def test_sign_message_short(firmware, backend, navigator, test_name): # test_name) response = client.get_async_response().data - assert ssa.verify(MESSAGE_SHORT.encode("ascii"), public_key, response) is True + msg_short: bytes = b"".join( + [len(MESSAGE_SHORT).to_bytes(2, byteorder="little"), bytes(MESSAGE_SHORT, "ascii")] + ) + + assert ssa.verify(msg_short, public_key, response) is True # In this tests we check the behaviour of the device when asked to sign a long message @@ -74,7 +78,11 @@ def test_sign_message_long(firmware, backend, navigator, test_name): # test_name) response = client.get_async_response().data - assert ssa.verify(MESSAGE_LONG.encode("ascii"), public_key, response) is True + msg_long: bytes = b"".join( + [len(MESSAGE_LONG).to_bytes(2, byteorder="little"), bytes(MESSAGE_LONG, "ascii")] + ) + + assert ssa.verify(msg_long, public_key, response) is True # Message signature refused test From 074c1d59464b62269aca8572d99a42e586e4e5b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=82=B4=E2=B1=A033=E2=82=B1?= Date: Thu, 17 Aug 2023 13:10:45 -0400 Subject: [PATCH 8/9] chore: update .gitignore (#6) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 2c5c7d80..b99c8b2f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,13 @@ src/glyphs.c src/glyphs.h bin/ +build/ debug/ dep/ obj/ # Unit tests and code coverage +tests/functional/snapshots-tmp/ tests/unit-tests/build/ tests/unit-tests/coverage/ tests/unit-tests/coverage.info From 1ff7f87360eeafbdfe21a8dc87e11848581c8007 Mon Sep 17 00:00:00 2001 From: sleepdefic1t Date: Thu, 17 Aug 2023 13:13:06 -0400 Subject: [PATCH 9/9] chore: bump version --- .vscode/c_cpp_properties.json | 4 ++-- CHANGELOG.md | 7 +++++++ Makefile | 2 +- doc/COMMANDS.md | 4 ++-- tests/functional/test_name_version.py | 2 +- tests/functional/test_version_cmd.py | 2 +- tests/unit-tests/CMakeLists.txt | 2 +- 7 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 9329a5f3..cc085518 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -24,11 +24,11 @@ "HAVE_USB_APDU", "USB_SEGMENT_SIZE=64", "UNUSED(x)=(void)x", - "APPVERSION=\"1.1.2\"", + "APPVERSION=\"1.1.3\"", "APPNAME=\"Solar\"", "MAJOR_VERSION=1", "MINOR_VERSION=1", - "PATCH_VERSION=2", + "PATCH_VERSION=3", "IO_SEPROXYHAL_BUFFER_SIZE_B=128", "HAVE_UX_FLOW", "DEBUG=1", diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dcafdec..eaba8d1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.3] - 2023-08-17 + +### Changed + +- Refactored deprecated throwable functions and patterns +- Updated Ragger testing library and functional tests ## [1.1.2] - 2023-08-16 @@ -72,6 +78,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Updated functional and unit tests - Refreshed documentation +[1.1.3]: https://github.com/Solar-network/ledger-app-solar/compare/1.1.2...1.1.3 [1.1.2]: https://github.com/Solar-network/ledger-app-solar/compare/1.1.1...1.1.2 [1.1.1]: https://github.com/Solar-network/ledger-app-solar/compare/1.1.0...1.1.1 [1.1.0]: https://github.com/Solar-network/ledger-app-solar/compare/1.0.0...1.1.0 diff --git a/Makefile b/Makefile index 0a7ebeb0..5cf6b16c 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ APPNAME = "Solar" # Application version APPVERSION_M = 1 APPVERSION_N = 1 -APPVERSION_P = 2 +APPVERSION_P = 3 APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" # Application source files diff --git a/doc/COMMANDS.md b/doc/COMMANDS.md index e14196f5..de8995ba 100644 --- a/doc/COMMANDS.md +++ b/doc/COMMANDS.md @@ -77,8 +77,8 @@ For the `GET_VERSION` instruction, both P1 and P2 values are not used and should ```shell => e0a2000000 -<= 0101029000 - # "1 1 2", 0x9000 +<= 0101039000 + # "1 1 3", 0x9000 ``` ## GET_PUBLIC_KEY diff --git a/tests/functional/test_name_version.py b/tests/functional/test_name_version.py index 87a5f736..ba15b497 100644 --- a/tests/functional/test_name_version.py +++ b/tests/functional/test_name_version.py @@ -14,4 +14,4 @@ def test_get_app_and_version(backend, backend_name): app_name, version = unpack_get_app_and_version_response(response.data) assert app_name == "Solar" - assert version == "1.1.2" + assert version == "1.1.3" diff --git a/tests/functional/test_version_cmd.py b/tests/functional/test_version_cmd.py index 60cec1ba..f5acb374 100644 --- a/tests/functional/test_version_cmd.py +++ b/tests/functional/test_version_cmd.py @@ -5,7 +5,7 @@ # Taken from the Makefile, to update every time the Makefile version is bumped MAJOR = 1 MINOR = 1 -PATCH = 2 +PATCH = 3 # In this test we check the behaviour of the device when asked to provide the app version def test_version(backend): diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt index 26b14e1b..73e6351b 100644 --- a/tests/unit-tests/CMakeLists.txt +++ b/tests/unit-tests/CMakeLists.txt @@ -6,7 +6,7 @@ endif() # project information project(unit_tests - VERSION 1.1.2 + VERSION 1.1.3 DESCRIPTION "Unit tests for Ledger Nano application" LANGUAGES C)