diff --git a/.github/workflows/auto-author-assign.yml b/.github/workflows/auto-author-assign.yml index a6255c9ef..82adf1738 100644 --- a/.github/workflows/auto-author-assign.yml +++ b/.github/workflows/auto-author-assign.yml @@ -1,3 +1,4 @@ +--- name: 'Auto Author Assign' on: diff --git a/.github/workflows/build-workflow.yml b/.github/workflows/build-workflow.yml deleted file mode 100644 index 1eb105d87..000000000 --- a/.github/workflows/build-workflow.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Compilation - -on: - push: - branches: - - master - pull_request: - branches: - - master - - develop - workflow_dispatch: - -jobs: - nano_release_build: - name: Build release application for NanoS, X and S+ - strategy: - matrix: - sdk: ["$NANOS_SDK", "$NANOX_SDK", "$NANOSP_SDK"] - 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: Build Ethereum - run: | - make -j BOLOS_SDK=${{ matrix.sdk }} - - - name: Build an altcoin - run: | - make clean - make -j BOLOS_SDK=${{ matrix.sdk }} CHAIN=polygon diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index d5cf7959e..b785a7ee5 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -1,39 +1,19 @@ +--- name: Tests on: + workflow_dispatch: push: - branches: - - master - pull_request: branches: - master - develop - workflow_dispatch: + pull_request: jobs: - scan-build: - name: Clang Static Analyzer - runs-on: ubuntu-latest - container: - image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest - steps: - - uses: actions/checkout@v3 - - - name: Build with Clang Static Analyzer - 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 - -# ===================================================== -# ZEMU TESTS -# ===================================================== + # ===================================================== + # ZEMU TESTS + # ===================================================== building_for_e2e_zemu_tests: name: Building binaries for E2E Zemu tests @@ -97,9 +77,9 @@ jobs: - name: Run zemu tests run: cd tests/zemu/ && yarn test -# ===================================================== -# SPECULOS TESTS -# ===================================================== + # ===================================================== + # SPECULOS TESTS + # ===================================================== building_for_e2e_speculos_tests: @@ -114,9 +94,9 @@ jobs: - name: Build testing binaries run: | mkdir tests/speculos/elfs - make clean && make -j DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOS_SDK && mv bin/app.elf tests/speculos/elfs/nanos.elf - make clean && make -j DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOX_SDK && mv bin/app.elf tests/speculos/elfs/nanox.elf - make clean && make -j DEBUG=1 NFT_TESTING_KEY=1 BOLOS_SDK=$NANOSP_SDK && mv bin/app.elf tests/speculos/elfs/nanosp.elf + make clean && make -j DEBUG=1 NFT_STAGING_KEY=1 BOLOS_SDK=$NANOS_SDK && mv bin/app.elf tests/speculos/elfs/nanos.elf + make clean && make -j DEBUG=1 NFT_STAGING_KEY=1 BOLOS_SDK=$NANOX_SDK && mv bin/app.elf tests/speculos/elfs/nanox.elf + make clean && make -j DEBUG=1 NFT_STAGING_KEY=1 BOLOS_SDK=$NANOSP_SDK && mv bin/app.elf tests/speculos/elfs/nanosp.elf - name: Upload app binaries uses: actions/upload-artifact@v3 @@ -162,16 +142,16 @@ jobs: pytest --model ${{ matrix.model }} --path ./elfs/${{ matrix.model }}.elf --display headless -# ===================================================== -# RAGGER TESTS -# ===================================================== + # ===================================================== + # RAGGER TESTS + # ===================================================== build_ragger_elfs: name: Build app for Ragger tests uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1 with: upload_app_binaries_artifact: "ragger_elfs" - flags: "DEBUG=1 CAL_CI_KEY=1 DOMAIN_NAME_TEST_KEY=1" + flags: "DEBUG=1 CAL_TEST_KEY=1 DOMAIN_NAME_TEST_KEY=1 SET_PLUGIN_TEST_KEY=1 NFT_TEST_KEY=1" jobs-ragger-tests: name: Run Ragger tests @@ -179,4 +159,43 @@ jobs: uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_ragger_tests.yml@v1 with: download_app_binaries_artifact: "ragger_elfs" - test_dir: tests/ragger + + # ===================================================== + # STATIC ANALYSIS + # ===================================================== + + # Static analysis on the main ETH chain is covered by the guidelines enforcer + scan-build: + name: Clang Static Analyzer on altcoin + runs-on: ubuntu-latest + container: + image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest + strategy: + fail-fast: false + matrix: + device: ["nanos", "nanos2", "nanox", "stax"] + + steps: + - name: Clone + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Build with Clang Static Analyzer + run: | + eval "BOLOS_SDK=\$$(echo ${{ matrix.device }} | tr [:lower:] [:upper:])_SDK" && \ + echo "BOLOS_SDK value will be: ${BOLOS_SDK}" && \ + make -j ENABLE_SDK_WERROR=1 BOLOS_SDK=${BOLOS_SDK} CHAIN=polygon scan-build + + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: scan-build + path: scan-build + + - name: Upload scan result + if: failure() + uses: actions/upload-artifact@v3 + with: + name: scan-build + path: scan-build diff --git a/.github/workflows/lint-workflow.yml b/.github/workflows/lint-workflow.yml index 7b980758e..ca32687e5 100644 --- a/.github/workflows/lint-workflow.yml +++ b/.github/workflows/lint-workflow.yml @@ -1,26 +1,26 @@ +--- name: Code style check +# 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: - - master + - master + - main + - develop pull_request: - branches: - - master - - develop jobs: - job_lint: - name: Lint - runs-on: ubuntu-latest - - steps: - - name: Clone - uses: actions/checkout@v3 - - - name: Lint - uses: DoozyX/clang-format-lint-action@v0.14 - with: - source: "./" - extensions: "h,c" - clangFormatVersion: 12.0.1 + check_linting: + name: Check linting using the reusable workflow + uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_lint.yml@v1 + with: + source: './' + extensions: 'h,c' + version: 12 diff --git a/.github/workflows/pr_on_all_plugins.yml b/.github/workflows/pr_on_all_plugins.yml new file mode 100644 index 000000000..3db1bbe03 --- /dev/null +++ b/.github/workflows/pr_on_all_plugins.yml @@ -0,0 +1,202 @@ +--- +name: Open PRs in Ethereum plugins to update SDK + +on: + workflow_dispatch: + # TODO add auto trigger once finalized + +jobs: + build-repositories-matrix: + name: Build repo matrix + runs-on: ubuntu-latest + env: + GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }} + steps: + - name: List plugin repositories + id: list-repos + run: | + # Retrieve the list of repositories from LedgerHQ organization + raw_repo_list=$(gh repo list LedgerHQ -L 2000 \ + --json name \ + --json isPrivate \ + --json isArchived \ + --jq '.[] | select(.isPrivate == false and .isArchived == false and select(.name | startswith("app-plugin-"))) | .name') + # Format the repository list as a JSON array + formatted_repo_list="[" + while IFS= read -r repo; do + formatted_repo_list+="\"$repo\", " + done < <(echo "$raw_repo_list") + formatted_repo_list=${formatted_repo_list%%, }"]" + echo "Formatted Repository List: $formatted_repo_list" + # Set output + echo "repo_list=$formatted_repo_list" >> $GITHUB_OUTPUT + outputs: + repo-matrix: ${{ steps.list-repos.outputs.repo_list }} + + + get-sdk-ref: + name: Get latest SDK reference + runs-on: ubuntu-latest + steps: + - name: Checkout SDK repository + uses: actions/checkout@v3 + with: + repository: LedgerHQ/ethereum-plugin-sdk + ref: develop + - name: Retrieve SDK reference + id: get-hash + run: | + # Get the short SHA reference of the latest commit in the SDK repository + sdk_ref=$(git rev-parse --short HEAD) + echo "SDK Reference: $sdk_ref" + # Set output + echo "sdk_ref=$sdk_ref" >> $GITHUB_OUTPUT + outputs: + sdk_ref: ${{ steps.get-hash.outputs.sdk_ref }} + + + open-issue: + name: Open SDK update summary issue + runs-on: ubuntu-latest + needs: get-sdk-ref + env: + GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }} + steps: + - name: Create 'auto' label if missing + run: | + if [[ -z $(gh label list --repo ${{ github.repository }} --search auto) ]]; then + gh label create 'auto' --repo ${{ github.repository }} --color 'b4a8d1' --description 'Automatically created' + fi + - name: Open SDK Update Issue + id: open-issue + run: | + # Create a new issue with the SDK reference in the SDK repository + issue_url=$(gh issue create \ + --repo ${{ github.repository }} \ + --label auto \ + --title "Bumping Eth plugin SDK to latest version ${{ needs.get-sdk-ref.outputs.sdk_ref }}" \ + --body "Placeholder") + echo "Issue URL: $issue_url" + # Set output + echo "issue_url=$issue_url" >> $GITHUB_OUTPUT + outputs: + issue_url: ${{ steps.open-issue.outputs.issue_url }} + + + open-prs: + name: Open pull requests + runs-on: ubuntu-latest + needs: [build-repositories-matrix, open-issue, get-sdk-ref] + strategy: + fail-fast: false + matrix: + repo: ${{ fromJSON(needs.build-repositories-matrix.outputs.repo-matrix) }} + env: + GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }} + + steps: + - name: Checkout plugin repository + uses: actions/checkout@v3 + with: + repository: LedgerHQ/${{ matrix.repo }} + submodules: recursive + ref: develop + # by default the action uses fetch-depth = 1, which creates + # shallow repositories from which we can't push + fetch-depth: 0 + # needed, else the push inside the action will use default credentials + # instead of provided ones + persist-credentials: false + + - name: Update submodule + run: | + cd ethereum-plugin-sdk/ + git checkout ${{ needs.get-sdk-ref.outputs.sdk_ref }} + + - name: Commit changes + id: commit-changes + run: | + # Set credentials for commit creation + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + # Branch name and title will be unique by design + branch_name="auto/bump_sdk_to_${{ needs.get-sdk-ref.outputs.sdk_ref }}" + title="[auto-update] Bump SDK to latest develop version ${{ needs.get-sdk-ref.outputs.sdk_ref }}" + echo "Branch Name: $branch_name" + echo "Title: $title" + git status + git commit -am "$title" + # Set output + echo "title=$title" >> $GITHUB_OUTPUT + echo "branch_name=$branch_name" >> $GITHUB_OUTPUT + + - name: Push commit + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.CI_BOT_TOKEN }} + branch: ${{ steps.commit-changes.outputs.branch_name }} + repository: LedgerHQ/${{ matrix.repo }} + force: true + + - name: Create 'auto' label if missing + run: | + if [[ -z $(gh label list --search auto) ]]; then + gh label create 'auto' --color 'b4a8d1' --description 'Automatically created' + fi + + - name: Create pull request and commment on SDK issue + run: | + # Github limits the number of possible PR being opened in a given time window. + # The limits are 20 creation per minute and 150 per hour. + # As suggested in the Github documentation, put a sleep between each POST call + # 3 seconds should be sufficient but let's sleep 4 seconds just in case. + sleep $((4 * ${{ strategy.job-index }})) + # Create the PR with a placeholder body. Will be consolidated at a later step + pr_url=$(gh pr create \ + --base 'develop' \ + --head '${{ steps.commit-changes.outputs.branch_name }}' \ + --label 'auto' \ + --title '${{ steps.commit-changes.outputs.title }}' \ + --body 'Created by a Github workflow') + echo "Pull request URL: $pr_url" + # Log the url of the PR in the issue on SDK side. We'll collect them from the issue later + gh issue comment "${{ needs.open-issue.outputs.issue_url }}" --body "OPENED $pr_url" + + + clean-issue: + name: Clean SDK update summary issue + runs-on: ubuntu-latest + needs: [get-sdk-ref, open-issue, open-prs] + env: + GITHUB_TOKEN: ${{ secrets.CI_BOT_TOKEN }} + steps: + - name: Collect all comments on the SDK issue + run: | + # Get the full text of the issue: metadata + title + rich comments + content="$(gh issue view --comments "${{ needs.open-issue.outputs.issue_url }}")" + # New header of the issue body + header="Bumping Ethereum plugin SDK to latest version ${{ needs.get-sdk-ref.outputs.sdk_ref }} for all Ethereum plugins:" + # Filter the full text of the issue to collect only the PR urls + lines="" + while IFS= read -r line; do + if [[ "$line" =~ "OPENED" ]]; then + lines+=$(echo "$line" | cut -d ' ' -f2)$'\n' + fi + done < <(echo "$content") + # Use print to resolve the '\n' chars + new_body="$(printf "$header\n$lines")" + echo "New issue body: $new_body" + # Set the consolidated body of the issue + gh issue edit "${{ needs.open-issue.outputs.issue_url }}" --body "$new_body" + + - name: Clean comments on the SDK issue + run: | + # gh api uses id instead of url + issue_id="$(basename "${{ needs.open-issue.outputs.issue_url }}")" + # Get url of all comments on the issue + comment_urls="$(gh api "repos/${{ github.repository }}/issues/${issue_id}/comments" --jq '.[].url')" + # Delete each comment using the Github REST api + while IFS= read -r url; do + echo "Deleting comment: $comment_urls" + gh api -X DELETE "$url" + done < <(echo "$comment_urls") diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-client.yml new file mode 100644 index 000000000..248c80405 --- /dev/null +++ b/.github/workflows/python-client.yml @@ -0,0 +1,80 @@ +--- +name: Python client checks, package build and deployment + +on: + workflow_dispatch: + push: + tags: + - 'client-*' + branches: + - develop + - master + paths: + - client/** + - .github/workflows/python-client.yml + pull_request: + paths: + - client/** + - .github/workflows/python-client.yml + +jobs: + lint: + name: Linting + runs-on: ubuntu-latest + steps: + - name: Clone + uses: actions/checkout@v3 + - run: pip install flake8 flake8-pyproject + - name: Flake8 lint Python code + run: (cd client && flake8 src/) + + mypy: + name: Type checking + runs-on: ubuntu-latest + steps: + - name: Clone + uses: actions/checkout@v3 + - run: pip install mypy + - name: Mypy type checking + run: (cd client && mypy src/) + + package_and_deploy: + name: Build and deploy Ethereum Client Python package + runs-on: ubuntu-latest + needs: [lint, mypy] + steps: + + - name: Clone + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Build Python package + run: | + pip install --upgrade pip build twine + cd client/ + python -m build; + python -m twine check dist/* + pip install .; + echo "TAG_VERSION=$(python -c 'from ledger_app_clients.ethereum import __version__; print(__version__)')" >> "$GITHUB_ENV" + + - name: Check version against CHANGELOG + if: startsWith(github.ref, 'refs/tags/') + run: | + CHANGELOG_VERSION=$(grep -Po '(?<=## \[)(\d+\.)+[^\]]' client/CHANGELOG.md | head -n 1) + if [ "${{ env.TAG_VERSION }}" == "${CHANGELOG_VERSION}" ]; + then + echo 'Package and CHANGELOG versions match!'; + exit 0; + else + echo "Tag '${{ env.TAG_VERSION }}' and CHANGELOG '${CHANGELOG_VERSION}' versions mismatch!"; + exit 1; + fi + + - name: Publish Python package on pypi.org + if: success() && github.event_name == 'push' + run: (cd client && python -m twine upload --verbose dist/*) + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_PUBLIC_API_TOKEN }} + TWINE_NON_INTERACTIVE: 1 diff --git a/.github/workflows/sdk-generation.yml b/.github/workflows/sdk-generation.yml index 9d26eb31a..363c89b0e 100644 --- a/.github/workflows/sdk-generation.yml +++ b/.github/workflows/sdk-generation.yml @@ -1,3 +1,4 @@ +--- name: Updating the SDK on: @@ -25,7 +26,7 @@ jobs: persist-credentials: false - name: Build new SDK - run: python tools/build_sdk.py + run: ./tools/build_sdk.sh - name: Extract branch name shell: bash diff --git a/.github/workflows/swap-ci-workflow.yml b/.github/workflows/swap-ci-workflow.yml index 3999224cf..022fe5a02 100644 --- a/.github/workflows/swap-ci-workflow.yml +++ b/.github/workflows/swap-ci-workflow.yml @@ -1,11 +1,12 @@ +--- name: Swap functional tests on: workflow_dispatch: push: branches: - - master - - develop + - master + - develop pull_request: jobs: diff --git a/.gitignore b/.gitignore index 6779287da..49c5a992e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ build/ # Python *.pyc - +__version__.py # JS tests/node_modules diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cd99025a..9b3afd163 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.10.4](https://github.com/ledgerhq/app-ethereum/compare/1.10.3...1.10.4) - 2023-03-08 + +### Added + +- Addresses in EIP-712 messages can now be displayed as a token ticker or a trusted domain name if a match is found +- Stax app now has icons of the other supported EVM chains +- (network) Bitcichain +- (network) Core +- (network) Bitrock Mainnet +- (network) Numbers Protocol +- (network) Linea +- (network) Holesky + +### Removed + +- Starkware support +- (clone) kUSD +- (clone) Tobalaba + +### Changed + +- Can now clear-sign NFT operations on other EVM chains without a clone app +- Can now swap on other EVM chains without a clone app +- Improved RAM usage +- Now shows an explicit ??? ticker when it is unknown instead of falling back to the native chain ticker + +### Fixed + +- Refusal of transactions with very large chain IDs even within specs +- Refusal of 10 character-long token tickers +- (network) Wanchain chain ID +- (network) Sepolia chain ID + ## [1.10.3](https://github.com/ledgerhq/app-ethereum/compare/1.10.2...1.10.3) - 2023-07-27 ### Added diff --git a/Makefile b/Makefile index 4715da52a..b192be047 100644 --- a/Makefile +++ b/Makefile @@ -16,13 +16,13 @@ #******************************************************************************* ifeq ($(BOLOS_SDK),) -$(error Environment variable BOLOS_SDK is not set) + $(error Environment variable BOLOS_SDK is not set) endif include $(BOLOS_SDK)/Makefile.defines DEFINES_LIB = USE_LIB_ETHEREUM -APP_LOAD_PARAMS= --curve secp256k1 $(COMMON_LOAD_PARAMS) +APP_LOAD_PARAMS = --curve secp256k1 $(COMMON_LOAD_PARAMS) # Allow the app to use path 45 for multi-sig (see BIP45). APP_LOAD_PARAMS += --path "45'" # Samsung temporary implementation for wallet ID on 0xda7aba5e/0xc1a551c5 @@ -32,29 +32,30 @@ APP_LOAD_PARAMS += --path "1517992542'/1101353413'" # Define Version # ################## -APPVERSION_M=1 -APPVERSION_N=10 -APPVERSION_P=3 -APPVERSION=$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) -APP_LOAD_FLAGS= --appFlags 0xa40 --dep Ethereum:$(APPVERSION) +APPVERSION_M = 1 +APPVERSION_N = 10 +APPVERSION_P = 4 +APPVERSION = $(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P) +APP_LOAD_FLAGS = --appFlags 0xa40 --dep Ethereum:$(APPVERSION) ########################### # Set Chain environnement # ########################### ifeq ($(CHAIN),) -CHAIN=ethereum + CHAIN = ethereum endif -SUPPORTED_CHAINS=$(shell find makefile_conf/chain/ -type f -name '*.mk'| sed 's/.*\/\(.*\).mk/\1/g' | sort) +SUPPORTED_CHAINS = $(shell find makefile_conf/chain/ -type f -name '*.mk'| sed 's/.*\/\(.*\).mk/\1/g' | sort) # Check if chain is available ifeq ($(shell test -s ./makefile_conf/chain/$(CHAIN).mk && echo -n yes), yes) -include ./makefile_conf/chain/$(CHAIN).mk + include ./makefile_conf/chain/$(CHAIN).mk else -$(error Unsupported CHAIN - use $(SUPPORTED_CHAINS)) + $(error Unsupported CHAIN - use $(SUPPORTED_CHAINS)) endif CFLAGS += -DAPPNAME=\"$(APPNAME)\" +DEFINES += CHAINID_COINNAME=\"$(TICKER)\" CHAIN_ID=$(CHAIN_ID) ######### # Other # @@ -65,15 +66,15 @@ DEFINES += $(DEFINES_LIB) #prepare hsm generation ifeq ($(TARGET_NAME),TARGET_NANOS) -ICONNAME=icons/nanos_app_$(CHAIN).gif + ICONNAME = icons/nanos_app_chain_$(CHAIN_ID).gif else ifeq ($(TARGET_NAME),TARGET_STAX) -ICONNAME=icons/stax_app_$(CHAIN).gif -DEFINES += ICONGLYPH=C_stax_$(CHAIN)_64px -DEFINES += ICONBITMAP=C_stax_$(CHAIN)_64px_bitmap -DEFINES += ICONGLYPH_SMALL=C_stax_$(CHAIN) -GLYPH_FILES += $(ICONNAME) + ICONNAME = icons/stax_app_chain_$(CHAIN_ID).gif + DEFINES += ICONGLYPH=C_stax_chain_$(CHAIN_ID)_64px + DEFINES += ICONBITMAP=C_stax_chain_$(CHAIN_ID)_64px_bitmap + DEFINES += ICONGLYPH_SMALL=C_stax_chain_$(CHAIN_ID) + GLYPH_FILES += $(ICONNAME) else -ICONNAME=icons/nanox_app_$(CHAIN).gif + ICONNAME = icons/nanox_app_chain_$(CHAIN_ID).gif endif ################ @@ -85,181 +86,207 @@ all: default # Platform # ############ -DEFINES += OS_IO_SEPROXYHAL -DEFINES += HAVE_SPRINTF HAVE_SNPRINTF_FORMAT_U -DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=4 IO_HID_EP_LENGTH=64 HAVE_USB_APDU -DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M) LEDGER_MINOR_VERSION=$(APPVERSION_N) LEDGER_PATCH_VERSION=$(APPVERSION_P) -DEFINES += BUILD_YEAR=\"$(shell date +%Y)\" +DEFINES += OS_IO_SEPROXYHAL +DEFINES += HAVE_SPRINTF HAVE_SNPRINTF_FORMAT_U +DEFINES += HAVE_IO_USB HAVE_L4_USBLIB IO_USB_MAX_ENDPOINTS=4 IO_HID_EP_LENGTH=64 HAVE_USB_APDU +DEFINES += LEDGER_MAJOR_VERSION=$(APPVERSION_M) LEDGER_MINOR_VERSION=$(APPVERSION_N) LEDGER_PATCH_VERSION=$(APPVERSION_P) +DEFINES += BUILD_YEAR=\"$(shell date +%Y)\" # U2F -DEFINES += HAVE_U2F HAVE_IO_U2F -DEFINES += U2F_PROXY_MAGIC=\"w0w\" -DEFINES += USB_SEGMENT_SIZE=64 -DEFINES += BLE_SEGMENT_SIZE=32 #max MTU, min 20 -DEFINES += UNUSED\(x\)=\(void\)x -DEFINES += APPVERSION=\"$(APPVERSION)\" +DEFINES += HAVE_U2F HAVE_IO_U2F +DEFINES += U2F_PROXY_MAGIC=\"w0w\" +DEFINES += USB_SEGMENT_SIZE=64 +DEFINES += BLE_SEGMENT_SIZE=32 #max MTU, min 20 +DEFINES += APPVERSION=\"$(APPVERSION)\" -#WEBUSB_URL = www.ledgerwallet.com -#DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=$(shell echo -n $(WEBUSB_URL) | wc -c) WEBUSB_URL=$(shell echo -n $(WEBUSB_URL) | sed -e "s/./\\\'\0\\\',/g") +#WEBUSB_URL = www.ledgerwallet.com +#DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=$(shell echo -n $(WEBUSB_URL) | wc -c) WEBUSB_URL=$(shell echo -n $(WEBUSB_URL) | sed -e "s/./\\\'\0\\\',/g") -DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL="" +DEFINES += HAVE_WEBUSB WEBUSB_URL_SIZE_B=0 WEBUSB_URL="" ifneq (,$(filter $(TARGET_NAME),TARGET_NANOX TARGET_STAX)) -DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 -DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE -SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl + DEFINES += HAVE_BLE BLE_COMMAND_TIMEOUT_MS=2000 + DEFINES += HAVE_BLE_APDU # basic ledger apdu transport over BLE + SDK_SOURCE_PATH += lib_blewbxx lib_blewbxx_impl endif ifeq ($(TARGET_NAME),TARGET_NANOS) -DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128 + DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=128 else -DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300 + DEFINES += IO_SEPROXYHAL_BUFFER_SIZE_B=300 endif ifeq ($(TARGET_NAME),TARGET_STAX) -DEFINES += NBGL_QRCODE + DEFINES += NBGL_QRCODE + SDK_SOURCE_PATH += qrcode else -DEFINES += HAVE_BAGL -DEFINES += HAVE_UX_FLOW -ifeq ($(TARGET_NAME),TARGET_NANOS) -DEFINES += HAVE_WALLET_ID_SDK -DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=32 -else -DEFINES += HAVE_GLO096 -DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=64 -DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature -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 + DEFINES += HAVE_BAGL + DEFINES += HAVE_UX_FLOW + ifeq ($(TARGET_NAME),TARGET_NANOS) + DEFINES += HAVE_WALLET_ID_SDK + DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=32 + else + DEFINES += HAVE_GLO096 + DEFINES += BAGL_WIDTH=128 BAGL_HEIGHT=64 + DEFINES += HAVE_BAGL_ELLIPSIS # long label truncation feature + 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 endif +#################### +# Enabled Features # +#################### + # Enables direct data signing without having to specify it in the settings. Useful when testing with speculos. -ALLOW_DATA:=0 +ALLOW_DATA ?= 0 ifneq ($(ALLOW_DATA),0) -DEFINES += HAVE_ALLOW_DATA + DEFINES += HAVE_ALLOW_DATA endif # Bypass the signature verification for setExternalPlugin, setPlugin, provideERC20TokenInfo and provideNFTInfo calls -BYPASS_SIGNATURES:=0 +BYPASS_SIGNATURES ?= 0 ifneq ($(BYPASS_SIGNATURES),0) -DEFINES += HAVE_BYPASS_SIGNATURES + DEFINES += HAVE_BYPASS_SIGNATURES +endif + +# Enable the SET_PLUGIN test key +SET_PLUGIN_TEST_KEY ?= 0 +ifneq ($(SET_PLUGIN_TEST_KEY),0) + DEFINES += HAVE_SET_PLUGIN_TEST_KEY endif # NFTs ifneq ($(TARGET_NAME),TARGET_NANOS) -DEFINES += HAVE_NFT_SUPPORT -# Enable the NFT testing key -NFT_TESTING_KEY:=0 -ifneq ($(NFT_TESTING_KEY),0) -DEFINES += HAVE_NFT_TESTING_KEY + DEFINES += HAVE_NFT_SUPPORT + NFT_TEST_KEY ?= 0 + ifneq ($(NFT_TEST_KEY),0) + DEFINES += HAVE_NFT_TEST_KEY + endif + NFT_STAGING_KEY ?= 0 + ifneq ($(NFT_STAGING_KEY),0) + # Key used by the staging backend + DEFINES += HAVE_NFT_STAGING_KEY + endif endif +ifneq (,$(filter $(DEFINES),HAVE_NFT_TEST_KEY)) + ifneq (, $(filter $(DEFINES),HAVE_NFT_STAGING_KEY)) + $(error Multiple alternative NFT keys set at once) + endif endif # Dynamic memory allocator ifneq ($(TARGET_NAME),TARGET_NANOS) -DEFINES += HAVE_DYN_MEM_ALLOC + DEFINES += HAVE_DYN_MEM_ALLOC endif # EIP-712 ifneq ($(TARGET_NAME),TARGET_NANOS) -DEFINES += HAVE_EIP712_FULL_SUPPORT + DEFINES += HAVE_EIP712_FULL_SUPPORT endif # CryptoAssetsList key -CAL_TEST_KEY:=0 -CAL_CI_KEY:=0 +CAL_TEST_KEY ?= 0 ifneq ($(CAL_TEST_KEY),0) -DEFINES += HAVE_CAL_TEST_KEY + # Key used in our test framework + DEFINES += HAVE_CAL_TEST_KEY +endif +CAL_STAGING_KEY ?= 0 +ifneq ($(CAL_STAGING_KEY),0) + # Key used by the staging CAL + DEFINES += HAVE_CAL_STAGING_KEY endif -ifneq ($(CAL_CI_KEY),0) -DEFINES += HAVE_CAL_CI_KEY +ifneq (,$(filter $(DEFINES),HAVE_CAL_TEST_KEY)) + ifneq (, $(filter $(DEFINES),HAVE_CAL_STAGING_KEY)) + # Can't use both the staging and testing keys + $(error Multiple alternative CAL keys set at once) + endif endif # ENS ifneq ($(TARGET_NAME),TARGET_NANOS) -DEFINES += HAVE_DOMAIN_NAME -DOMAIN_NAME_TEST_KEY:=0 -ifneq ($(DOMAIN_NAME_TEST_KEY),0) -DEFINES += HAVE_DOMAIN_NAME_TEST_KEY -endif + DEFINES += HAVE_DOMAIN_NAME + DOMAIN_NAME_TEST_KEY ?= 0 + ifneq ($(DOMAIN_NAME_TEST_KEY),0) + DEFINES += HAVE_DOMAIN_NAME_TEST_KEY + endif endif # Enabling debug PRINTF ifneq ($(DEBUG),0) -DEFINES += HAVE_STACK_OVERFLOW_CHECK -ifeq ($(TARGET_NAME),TARGET_NANOS) -DEFINES += HAVE_PRINTF PRINTF=screen_printf -else -DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf -endif + DEFINES += HAVE_STACK_OVERFLOW_CHECK + ifeq ($(TARGET_NAME),TARGET_NANOS) + DEFINES += HAVE_PRINTF PRINTF=screen_printf + else + DEFINES += HAVE_PRINTF PRINTF=mcu_usb_printf + endif else -DEFINES += PRINTF\(...\)= + DEFINES += PRINTF\(...\)= endif ifneq ($(NOCONSENT),) -DEFINES += NO_CONSENT + DEFINES += NO_CONSENT endif -#DEFINES += HAVE_TOKENS_LIST # Do not activate external ERC-20 support yet - ############## # Compiler # ############## + 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/ + $(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) + $(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) + $(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) + $(info GCCPATH is not set: arm-none-eabi-* will be used from PATH) endif -CC := $(CLANGPATH)clang - -CFLAGS += -Wno-format-invalid-specifier -Wno-format-extra-args - -AS := $(GCCPATH)arm-none-eabi-gcc - -LD := $(GCCPATH)arm-none-eabi-gcc -LDLIBS += -lm -lgcc -lc +CC := $(CLANGPATH)clang +CFLAGS += -Wno-format-invalid-specifier -Wno-format-extra-args +AS := $(GCCPATH)arm-none-eabi-gcc +LD := $(GCCPATH)arm-none-eabi-gcc +LDLIBS += -lm -lgcc -lc # import rules to compile glyphs(/pone) include $(BOLOS_SDK)/Makefile.glyphs ### variables processed by the common makefile.rules of the SDK to grab source files and include dirs -APP_SOURCE_PATH += src_common src src_features src_plugins -SDK_SOURCE_PATH += lib_stusb lib_stusb_impl lib_u2f +APP_SOURCE_PATH += src_common src src_features src_plugins +SDK_SOURCE_PATH += lib_stusb lib_stusb_impl lib_u2f ifeq ($(TARGET_NAME),TARGET_STAX) -APP_SOURCE_PATH += src_nbgl + APP_SOURCE_PATH += src_nbgl else -SDK_SOURCE_PATH += lib_ux -APP_SOURCE_PATH += src_bagl + SDK_SOURCE_PATH += lib_ux + APP_SOURCE_PATH += src_bagl endif +# Allow usage of function from lib_standard_app/crypto_helpers.c +APP_SOURCE_FILES += ${BOLOS_SDK}/lib_standard_app/crypto_helpers.c + ### initialize plugin SDK submodule if needed, rebuild it, and warn if a difference is noticed ifeq ($(CHAIN),ethereum) -ifneq ($(shell git submodule status | grep '^[-+]'),) -$(info INFO: Need to reinitialize git submodules) -$(shell git submodule update --init) -endif - -# rebuild SDK -$(shell python3 tools/build_sdk.py) - -# check if a difference is noticed (fail if it happens in CI build) -ifneq ($(shell git status | grep 'ethereum-plugin-sdk'),) -ifneq ($(JENKINS_URL),) -$(error ERROR: please update ethereum-plugin-sdk submodule first) -else -$(warning WARNING: please update ethereum-plugin-sdk submodule first) -endif -endif + ifneq ($(shell git submodule status | grep '^[-+]'),) + $(info INFO: Need to reinitialize git submodules) + $(shell git submodule update --init) + endif + + # rebuild SDK + $(shell ./tools/build_sdk.sh) + + # check if a difference is noticed (fail if it happens in CI build) + ifneq ($(shell git status | grep 'ethereum-plugin-sdk'),) + ifneq ($(JENKINS_URL),) + $(error ERROR: please update ethereum-plugin-sdk submodule first) + else + $(warning WARNING: please update ethereum-plugin-sdk submodule first) + endif + endif endif load: all @@ -279,6 +306,16 @@ test: install_tests run_tests unit-test: make -C tests/unit +ifeq ($(TARGET_NAME),TARGET_STAX) +NETWORK_ICONS_FILE = $(GEN_SRC_DIR)/net_icons.gen.c +NETWORK_ICONS_DIR = $(shell dirname "$(NETWORK_ICONS_FILE)") + +$(NETWORK_ICONS_FILE): + $(shell python3 tools/gen_networks.py "$(NETWORK_ICONS_DIR)") + +APP_SOURCE_FILES += $(NETWORK_ICONS_FILE) +endif + # import generic rules from the sdk include $(BOLOS_SDK)/Makefile.rules diff --git a/README.md b/README.md index 0293c3194..637e3d306 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Ledger Blue is not maintained anymore, but the app can still be compiled for thi This app follows the specification available in the `doc/` folder. -To compile it and load it on a device, please check out our [developer portal](https://developers.ledger.com/docs/nano-app/introduction/). +To compile it and load it on a device, please check out our [developer portal](https://developers.ledger.com/docs/device-app/introduction). ### Plugins diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 000000000..3051463d4 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,4 @@ +*egg-info +dist +*wheel +*~ diff --git a/client/CHANGELOG.md b/client/CHANGELOG.md new file mode 100644 index 000000000..094bcd627 --- /dev/null +++ b/client/CHANGELOG.md @@ -0,0 +1,53 @@ +# Changelog + +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). + +## [0.3.0] - 2024-02-13 + +### Added + +- New `provide_token_metadata` function + +### Fixed + +- Increased the delay between `autonext` callback calls for EIP-712 on Stax +- `recover_transaction` util function for non-legacy transactions + +## [0.2.1] - 2023-12-01 + +### Fixed + +- v0.2.0 version already published on pypi.org + +## [0.2.0] - 2023-12-01 + +### Added + +- New generic `sign` function that uses the Web3.py library + +### Removed + +- `sign_legacy` & `sign_1559` functions + +### Fixed + +- Now uses the proper signing key for the `SET_EXTERNAL_PLUGIN` APDU + +### Changed + +- `get_public_addr` now returns address as `bytes` instead of `str` + +## [0.1.0] - 2023-10-30 + +### Added + +- Update the ragger app client to support "set external plugin" APDU + +## [0.0.1] - 2023-07-08 + +### Added + +- Initial version diff --git a/client/MANIFEST.in b/client/MANIFEST.in new file mode 100644 index 000000000..98060d13f --- /dev/null +++ b/client/MANIFEST.in @@ -0,0 +1 @@ +include src/ledger_app_clients/ethereum/keychain/* diff --git a/client/README.md b/client/README.md new file mode 100644 index 000000000..eedef6a94 --- /dev/null +++ b/client/README.md @@ -0,0 +1,20 @@ +# Python client for the Ledger Ethereum application + +This package allows to communicate with the Ledger Ethereum application, either on a +real device, or emulated on Speculos. + +## Installation from pypi.org + +You can install the client from `pypi.org`: + + ```bash + pip install ledger_app_clients.ethereum + ``` + +## Installation from sources + +You can also install the client from this repo: + +```bash +pip install . +``` diff --git a/client/pyproject.toml b/client/pyproject.toml new file mode 100644 index 000000000..3a91961d1 --- /dev/null +++ b/client/pyproject.toml @@ -0,0 +1,51 @@ +[build-system] +requires = [ + "setuptools>=45", + "setuptools_scm[toml]>=6.2", + "wheel" +] +build-backend = "setuptools.build_meta" + +[project] +name = "ledger_app_clients.ethereum" +authors = [ + { name = "Ledger", email = "hello@ledger.fr" } +] +description = "Ledger Ethereum Python client" +readme = { file = "README.md", content-type = "text/markdown" } +# license = { file = "LICENSE" } +classifiers = [ + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Operating System :: POSIX :: Linux", + "Operating System :: Microsoft :: Windows", + "Operating System :: MacOS :: MacOS X", +] +dynamic = [ "version" ] +requires-python = ">=3.7" +dependencies = [ + "ragger[speculos]", + "web3~=6.0", +] + +[tools.setuptools] +include-package-data = true + +[tool.setuptools_scm] +version_file = "src/ledger_app_clients/ethereum/__version__.py" +local_scheme = "no-local-version" +root = "../" +git_describe_command = "git describe --dirty --tags --long --match client-*[0-9]*" +fallback_version = "0.0.0" + +[project.urls] +Home = "https://github.com/LedgerHQ/app-ethereum" + +[tool.mypy] +ignore_missing_imports = true + +[tool.flake8] +max-line-length = 120 \ No newline at end of file diff --git a/client/src/ledger_app_clients/ethereum/__init__.py b/client/src/ledger_app_clients/ethereum/__init__.py new file mode 100644 index 000000000..ce05207b0 --- /dev/null +++ b/client/src/ledger_app_clients/ethereum/__init__.py @@ -0,0 +1,4 @@ +try: + from ledger_app_clients.ethereum.__version__ import __version__ # noqa +except ImportError: + __version__ = "unknown version" # noqa diff --git a/client/src/ledger_app_clients/ethereum/client.py b/client/src/ledger_app_clients/ethereum/client.py new file mode 100644 index 000000000..aa2b27b9f --- /dev/null +++ b/client/src/ledger_app_clients/ethereum/client.py @@ -0,0 +1,255 @@ +import rlp +from enum import IntEnum +from ragger.backend import BackendInterface +from ragger.utils import RAPDU +from typing import Optional + +from .command_builder import CommandBuilder +from .eip712 import EIP712FieldType +from .keychain import sign_data, Key +from .tlv import format_tlv + +from web3 import Web3 + + +class StatusWord(IntEnum): + OK = 0x9000 + ERROR_NO_INFO = 0x6a00 + INVALID_DATA = 0x6a80 + INSUFFICIENT_MEMORY = 0x6a84 + INVALID_INS = 0x6d00 + INVALID_P1_P2 = 0x6b00 + CONDITION_NOT_SATISFIED = 0x6985 + REF_DATA_NOT_FOUND = 0x6a88 + + +class DomainNameTag(IntEnum): + STRUCTURE_TYPE = 0x01 + STRUCTURE_VERSION = 0x02 + CHALLENGE = 0x12 + SIGNER_KEY_ID = 0x13 + SIGNER_ALGO = 0x14 + SIGNATURE = 0x15 + DOMAIN_NAME = 0x20 + COIN_TYPE = 0x21 + ADDRESS = 0x22 + + +class EthAppClient: + def __init__(self, client: BackendInterface): + self._client = client + self._cmd_builder = CommandBuilder() + + def _send(self, payload: bytes): + return self._client.exchange_async_raw(payload) + + def response(self) -> Optional[RAPDU]: + return self._client.last_async_response + + def eip712_send_struct_def_struct_name(self, name: str): + return self._send(self._cmd_builder.eip712_send_struct_def_struct_name(name)) + + def eip712_send_struct_def_struct_field(self, + field_type: EIP712FieldType, + type_name: str, + type_size: int, + array_levels: list, + key_name: str): + return self._send(self._cmd_builder.eip712_send_struct_def_struct_field( + field_type, + type_name, + type_size, + array_levels, + key_name)) + + def eip712_send_struct_impl_root_struct(self, name: str): + return self._send(self._cmd_builder.eip712_send_struct_impl_root_struct(name)) + + def eip712_send_struct_impl_array(self, size: int): + return self._send(self._cmd_builder.eip712_send_struct_impl_array(size)) + + def eip712_send_struct_impl_struct_field(self, raw_value: bytes): + chunks = self._cmd_builder.eip712_send_struct_impl_struct_field(bytearray(raw_value)) + for chunk in chunks[:-1]: + with self._send(chunk): + pass + return self._send(chunks[-1]) + + def eip712_sign_new(self, bip32_path: str): + return self._send(self._cmd_builder.eip712_sign_new(bip32_path)) + + def eip712_sign_legacy(self, + bip32_path: str, + domain_hash: bytes, + message_hash: bytes): + return self._send(self._cmd_builder.eip712_sign_legacy(bip32_path, + domain_hash, + message_hash)) + + def eip712_filtering_activate(self): + return self._send(self._cmd_builder.eip712_filtering_activate()) + + def eip712_filtering_message_info(self, name: str, filters_count: int, sig: bytes): + return self._send(self._cmd_builder.eip712_filtering_message_info(name, filters_count, sig)) + + def eip712_filtering_show_field(self, name: str, sig: bytes): + return self._send(self._cmd_builder.eip712_filtering_show_field(name, sig)) + + def sign(self, + bip32_path: str, + tx_params: dict): + tx = Web3().eth.account.create().sign_transaction(tx_params).rawTransaction + prefix = bytes() + suffix = [] + if tx[0] in [0x01, 0x02]: + prefix = tx[:1] + tx = tx[len(prefix):] + else: # legacy + if "chainId" in tx_params: + suffix = [int(tx_params["chainId"]), bytes(), bytes()] + decoded = rlp.decode(tx)[:-3] # remove already computed signature + tx = prefix + rlp.encode(decoded + suffix) + chunks = self._cmd_builder.sign(bip32_path, tx, suffix) + for chunk in chunks[:-1]: + with self._send(chunk): + pass + return self._send(chunks[-1]) + + def get_challenge(self): + return self._send(self._cmd_builder.get_challenge()) + + def get_public_addr(self, + display: bool = True, + chaincode: bool = False, + bip32_path: str = "m/44'/60'/0'/0/0", + chain_id: Optional[int] = None): + return self._send(self._cmd_builder.get_public_addr(display, + chaincode, + bip32_path, + chain_id)) + + def provide_domain_name(self, challenge: int, name: str, addr: bytes): + payload = format_tlv(DomainNameTag.STRUCTURE_TYPE, 3) # TrustedDomainName + payload += format_tlv(DomainNameTag.STRUCTURE_VERSION, 1) + payload += format_tlv(DomainNameTag.SIGNER_KEY_ID, 0) # test key + payload += format_tlv(DomainNameTag.SIGNER_ALGO, 1) # secp256k1 + payload += format_tlv(DomainNameTag.CHALLENGE, challenge) + payload += format_tlv(DomainNameTag.COIN_TYPE, 0x3c) # ETH in slip-44 + payload += format_tlv(DomainNameTag.DOMAIN_NAME, name) + payload += format_tlv(DomainNameTag.ADDRESS, addr) + payload += format_tlv(DomainNameTag.SIGNATURE, + sign_data(Key.DOMAIN_NAME, payload)) + + chunks = self._cmd_builder.provide_domain_name(payload) + for chunk in chunks[:-1]: + with self._send(chunk): + pass + return self._send(chunks[-1]) + + def set_plugin(self, + plugin_name: str, + contract_addr: bytes, + selector: bytes, + chain_id: int, + type_: int = 1, + version: int = 1, + key_id: int = 2, + algo_id: int = 1, + sig: Optional[bytes] = None): + if sig is None: + # Temporarily get a command with an empty signature to extract the payload and + # compute the signature on it + tmp = self._cmd_builder.set_plugin(type_, + version, + plugin_name, + contract_addr, + selector, + chain_id, + key_id, + algo_id, + bytes()) + # skip APDU header & empty sig + sig = sign_data(Key.SET_PLUGIN, tmp[5:-1]) + return self._send(self._cmd_builder.set_plugin(type_, + version, + plugin_name, + contract_addr, + selector, + chain_id, + key_id, + algo_id, + sig)) + + def provide_nft_metadata(self, + collection: str, + addr: bytes, + chain_id: int, + type_: int = 1, + version: int = 1, + key_id: int = 1, + algo_id: int = 1, + sig: Optional[bytes] = None): + if sig is None: + # Temporarily get a command with an empty signature to extract the payload and + # compute the signature on it + tmp = self._cmd_builder.provide_nft_information(type_, + version, + collection, + addr, + chain_id, + key_id, + algo_id, + bytes()) + # skip APDU header & empty sig + sig = sign_data(Key.NFT, tmp[5:-1]) + return self._send(self._cmd_builder.provide_nft_information(type_, + version, + collection, + addr, + chain_id, + key_id, + algo_id, + sig)) + + def set_external_plugin(self, + plugin_name: str, + contract_address: bytes, + method_selelector: bytes, + sig: Optional[bytes] = None): + if sig is None: + # Temporarily get a command with an empty signature to extract the payload and + # compute the signature on it + tmp = self._cmd_builder.set_external_plugin(plugin_name, contract_address, method_selelector, bytes()) + + # skip APDU header & empty sig + sig = sign_data(Key.CAL, tmp[5:]) + return self._send(self._cmd_builder.set_external_plugin(plugin_name, contract_address, method_selelector, sig)) + + def personal_sign(self, path: str, msg: bytes): + chunks = self._cmd_builder.personal_sign(path, msg) + for chunk in chunks[:-1]: + with self._send(chunk): + pass + return self._send(chunks[-1]) + + def provide_token_metadata(self, + ticker: str, + addr: bytes, + decimals: int, + chain_id: int, + sig: Optional[bytes] = None): + if sig is None: + # Temporarily get a command with an empty signature to extract the payload and + # compute the signature on it + tmp = self._cmd_builder.provide_erc20_token_information(ticker, + addr, + decimals, + chain_id, + bytes()) + # skip APDU header & empty sig + sig = sign_data(Key.CAL, tmp[6:]) + return self._send(self._cmd_builder.provide_erc20_token_information(ticker, + addr, + decimals, + chain_id, + sig)) diff --git a/tests/ragger/app/command_builder.py b/client/src/ledger_app_clients/ethereum/command_builder.py similarity index 56% rename from tests/ragger/app/command_builder.py rename to client/src/ledger_app_clients/ethereum/command_builder.py index ae3f730f8..0ba0809bb 100644 --- a/tests/ragger/app/command_builder.py +++ b/client/src/ledger_app_clients/ethereum/command_builder.py @@ -1,17 +1,29 @@ -from enum import IntEnum, auto -from typing import Iterator, Optional -from .eip712 import EIP712FieldType -from ragger.bip import pack_derivation_path +# documentation about APDU format is available here: +# https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp.adoc + import struct +from enum import IntEnum +from typing import Optional +from ragger.bip import pack_derivation_path + +from .eip712 import EIP712FieldType + class InsType(IntEnum): + GET_PUBLIC_ADDR = 0x02 SIGN = 0x04 + PERSONAL_SIGN = 0x08 + PROVIDE_ERC20_TOKEN_INFORMATION = 0x0a + PROVIDE_NFT_INFORMATION = 0x14 + SET_PLUGIN = 0x16 EIP712_SEND_STRUCT_DEF = 0x1a EIP712_SEND_STRUCT_IMPL = 0x1c EIP712_SEND_FILTERING = 0x1e EIP712_SIGN = 0x0c GET_CHALLENGE = 0x20 PROVIDE_DOMAIN_NAME = 0x22 + EXTERNAL_PLUGIN_SETUP = 0x12 + class P1Type(IntEnum): COMPLETE_SEND = 0x00 @@ -19,6 +31,7 @@ class P1Type(IntEnum): SIGN_FIRST_CHUNK = 0x00 SIGN_SUBSQT_CHUNK = 0x80 + class P2Type(IntEnum): STRUCT_NAME = 0x00 STRUCT_FIELD = 0xff @@ -29,6 +42,7 @@ class P2Type(IntEnum): FILTERING_CONTRACT_NAME = 0x0f FILTERING_FIELD_NAME = 0xff + class CommandBuilder: _CLA: int = 0xE0 @@ -36,7 +50,7 @@ def _serialize(self, ins: InsType, p1: int, p2: int, - cdata: bytearray = bytes()) -> bytes: + cdata: bytes = bytes()) -> bytes: header = bytearray() header.append(self._CLA) @@ -62,24 +76,24 @@ def eip712_send_struct_def_struct_field(self, field_type: EIP712FieldType, type_name: str, type_size: int, - array_levels: [], + array_levels: list, key_name: str) -> bytes: data = bytearray() typedesc = 0 typedesc |= (len(array_levels) > 0) << 7 - typedesc |= (type_size != None) << 6 + typedesc |= (type_size is not None) << 6 typedesc |= field_type data.append(typedesc) if field_type == EIP712FieldType.CUSTOM: data.append(len(type_name)) data += self._string_to_bytes(type_name) - if type_size != None: + if type_size is not None: data.append(type_size) if len(array_levels) > 0: data.append(len(array_levels)) for level in array_levels: - data.append(0 if level == None else 1) - if level != None: + data.append(0 if level is None else 1) + if level is not None: data.append(level) data.append(len(key_name)) data += self._string_to_bytes(key_name) @@ -102,7 +116,7 @@ def eip712_send_struct_impl_array(self, size: int) -> bytes: P2Type.ARRAY, data) - def eip712_send_struct_impl_struct_field(self, data: bytearray) -> Iterator[bytes]: + def eip712_send_struct_impl_struct_field(self, data: bytearray) -> list[bytes]: chunks = list() # Add a 16-bit integer with the data's byte length (network byte order) data_w_length = bytearray() @@ -169,17 +183,40 @@ def eip712_filtering_show_field(self, name: str, sig: bytes) -> bytes: P2Type.FILTERING_FIELD_NAME, self._eip712_filtering_send_name(name, sig)) - def sign(self, bip32_path: str, rlp_data: bytes) -> list[bytes]: + def set_external_plugin(self, plugin_name: str, contract_address: bytes, selector: bytes, sig: bytes) -> bytes: + data = bytearray() + data.append(len(plugin_name)) + data += self._string_to_bytes(plugin_name) + data += contract_address + data += selector + data += sig + + return self._serialize(InsType.EXTERNAL_PLUGIN_SETUP, + P1Type.COMPLETE_SEND, + 0x00, + data) + + def sign(self, bip32_path: str, rlp_data: bytes, vrs: list) -> list[bytes]: apdus = list() payload = pack_derivation_path(bip32_path) payload += rlp_data p1 = P1Type.SIGN_FIRST_CHUNK while len(payload) > 0: + chunk_size = 0xff + + # TODO: Fix the app & remove this, issue #409 + if len(vrs) == 3: + if len(payload) > chunk_size: + import rlp + diff = len(rlp.encode(vrs)) - (len(payload) - chunk_size) + if diff > 0: + chunk_size -= diff + apdus.append(self._serialize(InsType.SIGN, p1, 0x00, - payload[:0xff])) - payload = payload[0xff:] + payload[:chunk_size])) + payload = payload[chunk_size:] p1 = P1Type.SIGN_SUBSQT_CHUNK return apdus @@ -188,7 +225,7 @@ def get_challenge(self) -> bytes: def provide_domain_name(self, tlv_payload: bytes) -> list[bytes]: chunks = list() - payload = struct.pack(">H", len(tlv_payload)) + payload = struct.pack(">H", len(tlv_payload)) payload += tlv_payload p1 = 1 while len(payload) > 0: @@ -199,3 +236,96 @@ def provide_domain_name(self, tlv_payload: bytes) -> list[bytes]: payload = payload[0xff:] p1 = 0 return chunks + + def get_public_addr(self, + display: bool, + chaincode: bool, + bip32_path: str, + chain_id: Optional[int]) -> bytes: + payload = pack_derivation_path(bip32_path) + if chain_id is not None: + payload += struct.pack(">Q", chain_id) + return self._serialize(InsType.GET_PUBLIC_ADDR, + int(display), + int(chaincode), + payload) + + def set_plugin(self, + type_: int, + version: int, + plugin_name: str, + contract_addr: bytes, + selector: bytes, + chain_id: int, + key_id: int, + algo_id: int, + sig: bytes) -> bytes: + payload = bytearray() + payload.append(type_) + payload.append(version) + payload.append(len(plugin_name)) + payload += plugin_name.encode() + payload += contract_addr + payload += selector + payload += struct.pack(">Q", chain_id) + payload.append(key_id) + payload.append(algo_id) + payload.append(len(sig)) + payload += sig + return self._serialize(InsType.SET_PLUGIN, 0x00, 0x00, payload) + + def provide_nft_information(self, + type_: int, + version: int, + collection_name: str, + addr: bytes, + chain_id: int, + key_id: int, + algo_id: int, + sig: bytes): + payload = bytearray() + payload.append(type_) + payload.append(version) + payload.append(len(collection_name)) + payload += collection_name.encode() + payload += addr + payload += struct.pack(">Q", chain_id) + payload.append(key_id) + payload.append(algo_id) + payload.append(len(sig)) + payload += sig + return self._serialize(InsType.PROVIDE_NFT_INFORMATION, 0x00, 0x00, payload) + + def personal_sign(self, path: str, msg: bytes): + payload = pack_derivation_path(path) + payload += struct.pack(">I", len(msg)) + payload += msg + chunks = list() + p1 = P1Type.SIGN_FIRST_CHUNK + while len(payload) > 0: + chunk_size = 0xff + chunks.append(self._serialize(InsType.PERSONAL_SIGN, + p1, + 0x00, + payload[:chunk_size])) + payload = payload[chunk_size:] + p1 = P1Type.SIGN_SUBSQT_CHUNK + return chunks + + def provide_erc20_token_information(self, + ticker: str, + addr: bytes, + decimals: int, + chain_id: int, + sig: bytes) -> bytes: + payload = bytearray() + payload.append(len(ticker)) + payload += ticker.encode() + payload += addr + payload += struct.pack(">I", decimals) + payload += struct.pack(">I", chain_id) + payload += sig + return self._serialize(InsType.PROVIDE_ERC20_TOKEN_INFORMATION, + 0x00, + 0x00, + payload) diff --git a/tests/ragger/eip712/InputData.py b/client/src/ledger_app_clients/ethereum/eip712/InputData.py similarity index 75% rename from tests/ragger/eip712/InputData.py rename to client/src/ledger_app_clients/ethereum/eip712/InputData.py index 6dd647131..a19ccf3e8 100644 --- a/tests/ragger/eip712/InputData.py +++ b/client/src/ledger_app_clients/ethereum/eip712/InputData.py @@ -1,24 +1,28 @@ -#!/usr/bin/env python3 - +import hashlib import json -import sys import re -import hashlib -from app.client import EthAppClient, EIP712FieldType -import keychain -from typing import Callable import signal +import sys +import copy +from typing import Any, Callable, Optional + +from ledger_app_clients.ethereum import keychain +from ledger_app_clients.ethereum.client import EthAppClient, EIP712FieldType + # global variables app_client: EthAppClient = None -filtering_paths = None -current_path = list() -sig_ctx = {} +filtering_paths: dict = {} +current_path: list[str] = list() +sig_ctx: dict[str, Any] = {} -autonext_handler: Callable = None +def default_handler(): + raise RuntimeError("Uninitialized handler") +autonext_handler: Callable = default_handler + # From a string typename, extract the type and all the array depth # Input = "uint8[2][][4]" | "bool" @@ -57,29 +61,34 @@ def get_typesize(typename): return (typename, typesize) - def parse_int(typesize): return (EIP712FieldType.INT, int(typesize / 8)) + def parse_uint(typesize): return (EIP712FieldType.UINT, int(typesize / 8)) + def parse_address(typesize): return (EIP712FieldType.ADDRESS, None) + def parse_bool(typesize): return (EIP712FieldType.BOOL, None) + def parse_string(typesize): return (EIP712FieldType.STRING, None) + def parse_bytes(typesize): - if typesize != None: + if typesize is not None: return (EIP712FieldType.FIX_BYTES, typesize) return (EIP712FieldType.DYN_BYTES, None) + # set functions for each type -parsing_type_functions = {}; +parsing_type_functions = {} parsing_type_functions["int"] = parse_int parsing_type_functions["uint"] = parse_uint parsing_type_functions["address"] = parse_address @@ -88,7 +97,6 @@ def parse_bytes(typesize): parsing_type_functions["bytes"] = parse_bytes - def send_struct_def_field(typename, keyname): type_enum = None @@ -110,7 +118,6 @@ def send_struct_def_field(typename, keyname): return (typename, type_enum, typesize, array_lvls) - def encode_integer(value, typesize): data = bytearray() @@ -124,9 +131,9 @@ def encode_integer(value, typesize): if value == 0: data.append(0) else: - if value < 0: # negative number, send it as unsigned + if value < 0: # negative number, send it as unsigned mask = 0 - for i in range(typesize): # make a mask as big as the typesize + for i in range(typesize): # make a mask as big as the typesize mask = (mask << 8) | 0xff value &= mask while value > 0: @@ -135,42 +142,51 @@ def encode_integer(value, typesize): data.reverse() return data + def encode_int(value, typesize): return encode_integer(value, typesize) + def encode_uint(value, typesize): return encode_integer(value, typesize) + def encode_hex_string(value, size): data = bytearray() - value = value[2:] # skip 0x + value = value[2:] # skip 0x byte_idx = 0 while byte_idx < size: data.append(int(value[(byte_idx * 2):(byte_idx * 2 + 2)], 16)) byte_idx += 1 return data + def encode_address(value, typesize): return encode_hex_string(value, 20) + def encode_bool(value, typesize): return encode_integer(value, typesize) + def encode_string(value, typesize): data = bytearray() for char in value: data.append(ord(char)) return data + def encode_bytes_fix(value, typesize): return encode_hex_string(value, typesize) + def encode_bytes_dyn(value, typesize): # length of the value string # - the length of 0x (2) # / by the length of one byte in a hex string (2) return encode_hex_string(value, int((len(value) - 2) / 2)) + # set functions for each type encoding_functions = {} encoding_functions[EIP712FieldType.INT] = encode_int @@ -182,7 +198,6 @@ def encode_bytes_dyn(value, typesize): encoding_functions[EIP712FieldType.DYN_BYTES] = encode_bytes_dyn - def send_struct_impl_field(value, field): # Something wrong happened if this triggers if isinstance(value, list) or (field["enum"] == EIP712FieldType.CUSTOM): @@ -190,7 +205,6 @@ def send_struct_impl_field(value, field): data = encoding_functions[field["enum"]](value, field["typesize"]) - if filtering_paths: path = ".".join(current_path) if path in filtering_paths.keys(): @@ -201,8 +215,7 @@ def send_struct_impl_field(value, field): disable_autonext() - -def evaluate_field(structs, data, field, lvls_left, new_level = True): +def evaluate_field(structs, data, field, lvls_left, new_level=True): array_lvls = field["array_lvls"] if new_level: @@ -217,7 +230,7 @@ def evaluate_field(structs, data, field, lvls_left, new_level = True): return False current_path.pop() idx += 1 - if array_lvls[lvls_left - 1] != None: + if array_lvls[lvls_left - 1] is not None: if array_lvls[lvls_left - 1] != idx: print("Mismatch in array size! Got %d, expected %d\n" % (idx, array_lvls[lvls_left - 1]), @@ -234,7 +247,6 @@ def evaluate_field(structs, data, field, lvls_left, new_level = True): return True - def send_struct_impl(structs, data, structname): # Check if it is a struct we don't known if structname not in structs.keys(): @@ -246,6 +258,7 @@ def send_struct_impl(structs, data, structname): return False return True + # ledgerjs doesn't actually sign anything, and instead uses already pre-computed signatures def send_filtering_message_info(display_name: str, filters_count: int): global sig_ctx @@ -264,6 +277,7 @@ def send_filtering_message_info(display_name: str, filters_count: int): enable_autonext() disable_autonext() + # ledgerjs doesn't actually sign anything, and instead uses already pre-computed signatures def send_filtering_show_field(display_name): global sig_ctx @@ -283,11 +297,6 @@ def send_filtering_show_field(display_name): with app_client.eip712_filtering_show_field(display_name, sig): pass -def read_filtering_file(domain, message, filtering_file_path): - data_json = None - with open(filtering_file_path) as data: - data_json = json.load(data) - return data_json def prepare_filtering(filtr_data, message): global filtering_paths @@ -297,12 +306,14 @@ def prepare_filtering(filtr_data, message): else: filtering_paths = {} + def handle_optional_domain_values(domain): if "chainId" not in domain.keys(): domain["chainId"] = 0 if "verifyingContract" not in domain.keys(): domain["verifyingContract"] = "0x0000000000000000000000000000000000000000" + def init_signature_context(types, domain): global sig_ctx @@ -316,7 +327,7 @@ def init_signature_context(types, domain): for i in range(8): sig_ctx["chainid"].append(chainid & (0xff << (i * 8))) sig_ctx["chainid"].reverse() - schema_str = json.dumps(types).replace(" ","") + schema_str = json.dumps(types).replace(" ", "") schema_hash = hashlib.sha224(schema_str.encode()) sig_ctx["schema_hash"] = bytearray.fromhex(schema_hash.hexdigest()) @@ -324,74 +335,74 @@ def init_signature_context(types, domain): def next_timeout(_signum: int, _frame): autonext_handler() + def enable_autonext(): - seconds = 1/4 - if app_client._client.firmware.device == 'stax': # Stax Speculos is slow - interval = seconds * 3 + if app_client._client.firmware.device == 'stax': # Stax Speculos is slow + delay = 1.5 else: - interval = seconds - signal.setitimer(signal.ITIMER_REAL, seconds, interval) + delay = 1/4 + signal.setitimer(signal.ITIMER_REAL, delay, delay) + def disable_autonext(): signal.setitimer(signal.ITIMER_REAL, 0, 0) -def process_file(aclient: EthAppClient, - input_file_path: str, - filtering_file_path = None, - autonext: Callable = None) -> bool: +def process_data(aclient: EthAppClient, + data_json: dict, + filters: Optional[dict] = None, + autonext: Optional[Callable] = None) -> bool: global sig_ctx global app_client global autonext_handler + # deepcopy because this function modifies the dict + data_json = copy.deepcopy(data_json) app_client = aclient - with open(input_file_path, "r") as data: - data_json = json.load(data) - domain_typename = "EIP712Domain" - message_typename = data_json["primaryType"] - types = data_json["types"] - domain = data_json["domain"] - message = data_json["message"] - - if autonext: - autonext_handler = autonext - signal.signal(signal.SIGALRM, next_timeout) - - if filtering_file_path: - init_signature_context(types, domain) - filtr = read_filtering_file(domain, message, filtering_file_path) - - # send types definition - for key in types.keys(): - with app_client.eip712_send_struct_def_struct_name(key): - pass - for f in types[key]: - (f["type"], f["enum"], f["typesize"], f["array_lvls"]) = \ - send_struct_def_field(f["type"], f["name"]) - - if filtering_file_path: - with app_client.eip712_filtering_activate(): - pass - prepare_filtering(filtr, message) - - # send domain implementation - with app_client.eip712_send_struct_impl_root_struct(domain_typename): - enable_autonext() - disable_autonext() - if not send_struct_impl(types, domain, domain_typename): - return False + domain_typename = "EIP712Domain" + message_typename = data_json["primaryType"] + types = data_json["types"] + domain = data_json["domain"] + message = data_json["message"] + + if autonext: + autonext_handler = autonext + signal.signal(signal.SIGALRM, next_timeout) + + if filters: + init_signature_context(types, domain) + + # send types definition + for key in types.keys(): + with app_client.eip712_send_struct_def_struct_name(key): + pass + for f in types[key]: + (f["type"], f["enum"], f["typesize"], f["array_lvls"]) = \ + send_struct_def_field(f["type"], f["name"]) - if filtering_file_path: - if filtr and "name" in filtr: - send_filtering_message_info(filtr["name"], len(filtering_paths)) - else: - send_filtering_message_info(domain["name"], len(filtering_paths)) - - # send message implementation - with app_client.eip712_send_struct_impl_root_struct(message_typename): - enable_autonext() - disable_autonext() - if not send_struct_impl(types, message, message_typename): - return False + if filters: + with app_client.eip712_filtering_activate(): + pass + prepare_filtering(filters, message) + + # send domain implementation + with app_client.eip712_send_struct_impl_root_struct(domain_typename): + enable_autonext() + disable_autonext() + if not send_struct_impl(types, domain, domain_typename): + return False + + if filters: + if filters and "name" in filters: + send_filtering_message_info(filters["name"], len(filtering_paths)) + else: + send_filtering_message_info(domain["name"], len(filtering_paths)) + + # send message implementation + with app_client.eip712_send_struct_impl_root_struct(message_typename): + enable_autonext() + disable_autonext() + if not send_struct_impl(types, message, message_typename): + return False return True diff --git a/client/src/ledger_app_clients/ethereum/eip712/__init__.py b/client/src/ledger_app_clients/ethereum/eip712/__init__.py new file mode 100644 index 000000000..172091ccf --- /dev/null +++ b/client/src/ledger_app_clients/ethereum/eip712/__init__.py @@ -0,0 +1 @@ +from .struct import EIP712FieldType # noqa diff --git a/tests/ragger/app/eip712.py b/client/src/ledger_app_clients/ethereum/eip712/struct.py similarity index 99% rename from tests/ragger/app/eip712.py rename to client/src/ledger_app_clients/ethereum/eip712/struct.py index f719c6ea8..19dbacc57 100644 --- a/tests/ragger/app/eip712.py +++ b/client/src/ledger_app_clients/ethereum/eip712/struct.py @@ -1,5 +1,6 @@ from enum import IntEnum, auto + class EIP712FieldType(IntEnum): CUSTOM = 0, INT = auto() diff --git a/tests/ragger/keychain.py b/client/src/ledger_app_clients/ethereum/keychain.py similarity index 90% rename from tests/ragger/keychain.py rename to client/src/ledger_app_clients/ethereum/keychain.py index 31914a4fb..0fc6712b1 100644 --- a/tests/ragger/keychain.py +++ b/client/src/ledger_app_clients/ethereum/keychain.py @@ -1,23 +1,29 @@ import os import hashlib -from ecdsa.util import sigencode_der from ecdsa import SigningKey +from ecdsa.util import sigencode_der from enum import Enum, auto + # Private key PEM files have to be named the same (lowercase) as their corresponding enum entries # Example: for an entry in the Enum named DEV, its PEM file must be at keychain/dev.pem class Key(Enum): CAL = auto() DOMAIN_NAME = auto() + SET_PLUGIN = auto() + NFT = auto() + _keys: dict[Key, SigningKey] = dict() + # Open the corresponding PEM file and load its key in the global dict def _init_key(key: Key): global _keys with open("%s/keychain/%s.pem" % (os.path.dirname(__file__), key.name.lower())) as pem_file: _keys[key] = SigningKey.from_pem(pem_file.read(), hashlib.sha256) - assert (key in _keys) and (_keys[key] != None) + assert (key in _keys) and (_keys[key] is not None) + # Generate a SECP256K1 signature of the given data with the given key def sign_data(key: Key, data: bytes) -> bytes: diff --git a/tests/ragger/keychain/cal.pem b/client/src/ledger_app_clients/ethereum/keychain/cal.pem similarity index 100% rename from tests/ragger/keychain/cal.pem rename to client/src/ledger_app_clients/ethereum/keychain/cal.pem diff --git a/tests/ragger/keychain/domain_name.pem b/client/src/ledger_app_clients/ethereum/keychain/domain_name.pem similarity index 100% rename from tests/ragger/keychain/domain_name.pem rename to client/src/ledger_app_clients/ethereum/keychain/domain_name.pem diff --git a/client/src/ledger_app_clients/ethereum/keychain/nft.pem b/client/src/ledger_app_clients/ethereum/keychain/nft.pem new file mode 100644 index 000000000..de6d21a29 --- /dev/null +++ b/client/src/ledger_app_clients/ethereum/keychain/nft.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQACg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIK69Gt4o0bzkOaEwUE5X2tI+Ks80FQi785Co+6woU9hioAcGBSuBBAAK +oUQDQgAEPPtfsxkF9L052dU1pAwmqrUcXX0yGbKKyUK5gPsgbPswtRzC3iEZrAOO +uw191lQXcCBKPO06eeKLMvu2cmRowA== +-----END EC PRIVATE KEY----- diff --git a/client/src/ledger_app_clients/ethereum/keychain/set_plugin.pem b/client/src/ledger_app_clients/ethereum/keychain/set_plugin.pem new file mode 100644 index 000000000..6e84a2115 --- /dev/null +++ b/client/src/ledger_app_clients/ethereum/keychain/set_plugin.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BgUrgQQACg== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEIBErwcYvqeKSOlmQ/j3xPkVcwFf+j1aiMsA+RabczvN7oAcGBSuBBAAK +oUQDQgAEwFW8Ts8FXi2FCF01Eno95nBcf4hQVc1wceh2cb8ZH+M8yPAavC8ofIGa +FIq+G1gd8bSUCvXU3DpOa2AZF3ErNw== +-----END EC PRIVATE KEY----- diff --git a/client/src/ledger_app_clients/ethereum/response_parser.py b/client/src/ledger_app_clients/ethereum/response_parser.py new file mode 100644 index 000000000..a50ae0184 --- /dev/null +++ b/client/src/ledger_app_clients/ethereum/response_parser.py @@ -0,0 +1,52 @@ +def signature(data: bytes) -> tuple[bytes, bytes, bytes]: + assert len(data) == (1 + 32 + 32) + + v = data[0:1] + data = data[1:] + r = data[0:32] + data = data[32:] + s = data[0:32] + + return v, r, s + + +def challenge(data: bytes) -> int: + assert len(data) == 4 + return int.from_bytes(data, "big") + + +def pk_addr(data: bytes, has_chaincode: bool = False): + idx = 0 + + if len(data) < (idx + 1): + return None + pk_len = data[idx] + idx += 1 + + if len(data) < (idx + pk_len): + return None + pk = data[idx:idx + pk_len] + idx += pk_len + + if len(data) < (idx + 1): + return None + addr_len = data[idx] + idx += 1 + + if len(data) < (idx + addr_len): + return None + addr = data[idx:idx + addr_len] + idx += addr_len + + if has_chaincode: + if len(data) < (idx + 32): + return None + chaincode = data[idx:idx + 32] + idx += 32 + else: + chaincode = None + + if idx != len(data): + return None + + return pk, bytes.fromhex(addr.decode()), chaincode diff --git a/tests/ragger/app/settings.py b/client/src/ledger_app_clients/ethereum/settings.py similarity index 83% rename from tests/ragger/app/settings.py rename to client/src/ledger_app_clients/ethereum/settings.py index ec6bf78b4..6bd73e91e 100644 --- a/tests/ragger/app/settings.py +++ b/client/src/ledger_app_clients/ethereum/settings.py @@ -1,7 +1,8 @@ from enum import Enum, auto -from typing import List from ragger.firmware import Firmware from ragger.navigator import Navigator, NavInsID, NavIns +from typing import Union + class SettingID(Enum): BLIND_SIGNING = auto() @@ -10,6 +11,7 @@ class SettingID(Enum): VERBOSE_EIP712 = auto() VERBOSE_ENS = auto() + def get_device_settings(device: str) -> list[SettingID]: if device == "nanos": return [ @@ -27,19 +29,22 @@ def get_device_settings(device: str) -> list[SettingID]: ] return [] + settings_per_page = 3 -def get_setting_position(device: str, setting: NavInsID) -> tuple[int, int]: - screen_height = 672 # px - header_height = 85 # px - footer_height = 124 # px + +def get_setting_position(device: str, setting: Union[NavInsID, SettingID]) -> tuple[int, int]: + screen_height = 672 # px + header_height = 85 # px + footer_height = 124 # px usable_height = screen_height - (header_height + footer_height) setting_height = usable_height // settings_per_page - index_in_page = get_device_settings(device).index(setting) % settings_per_page + index_in_page = get_device_settings(device).index(SettingID(setting)) % settings_per_page return 350, header_height + (setting_height * index_in_page) + (setting_height // 2) + def settings_toggle(fw: Firmware, nav: Navigator, to_toggle: list[SettingID]): - moves = list() + moves: list[Union[NavIns, NavInsID]] = list() settings = get_device_settings(fw.device) # Assume the app is on the home page if fw.device.startswith("nano"): @@ -49,7 +54,7 @@ def settings_toggle(fw: Firmware, nav: Navigator, to_toggle: list[SettingID]): if setting in to_toggle: moves += [NavInsID.BOTH_CLICK] moves += [NavInsID.RIGHT_CLICK] - moves += [NavInsID.BOTH_CLICK] # Back + moves += [NavInsID.BOTH_CLICK] # Back else: moves += [NavInsID.USE_CASE_HOME_SETTINGS] moves += [NavInsID.USE_CASE_SETTINGS_NEXT] diff --git a/tests/ragger/app/tlv.py b/client/src/ledger_app_clients/ethereum/tlv.py similarity index 75% rename from tests/ragger/app/tlv.py rename to client/src/ledger_app_clients/ethereum/tlv.py index 2ff4cef7b..fd5dc109e 100644 --- a/tests/ragger/app/tlv.py +++ b/client/src/ledger_app_clients/ethereum/tlv.py @@ -1,4 +1,5 @@ -from typing import Any +from typing import Union + def der_encode(value: int) -> bytes: # max() to have minimum length of 1 @@ -7,16 +8,15 @@ def der_encode(value: int) -> bytes: value_bytes = (0x80 | len(value_bytes)).to_bytes(1, 'big') + value_bytes return value_bytes -def format_tlv(tag: int, value: Any) -> bytes: + +def format_tlv(tag: int, value: Union[int, str, bytes]) -> bytes: if isinstance(value, int): # max() to have minimum length of 1 value = value.to_bytes(max(1, (value.bit_length() + 7) // 8), 'big') elif isinstance(value, str): value = value.encode() - if not isinstance(value, bytes): - print("Unhandled TLV formatting for type : %s" % (type(value))) - return None + assert isinstance(value, bytes), f"Unhandled TLV formatting for type : {type(value)}" tlv = bytearray() tlv += der_encode(tag) diff --git a/client/src/ledger_app_clients/ethereum/utils.py b/client/src/ledger_app_clients/ethereum/utils.py new file mode 100644 index 000000000..2b50fe551 --- /dev/null +++ b/client/src/ledger_app_clients/ethereum/utils.py @@ -0,0 +1,39 @@ +from eth_account import Account +from eth_account.messages import encode_defunct, encode_typed_data +import rlp + + +def get_selector_from_data(data: str) -> bytes: + raw_data = bytes.fromhex(data[2:]) + return raw_data[:4] + + +def recover_message(msg, vrs: tuple) -> bytes: + if isinstance(msg, dict): # EIP-712 + smsg = encode_typed_data(full_message=msg) + else: # EIP-191 + smsg = encode_defunct(primitive=msg) + addr = Account.recover_message(smsg, vrs) + return bytes.fromhex(addr[2:]) + + +def recover_transaction(tx_params, vrs: tuple) -> bytes: + raw_tx = Account.create().sign_transaction(tx_params).rawTransaction + prefix = bytes() + if raw_tx[0] in [0x01, 0x02]: + prefix = raw_tx[:1] + raw_tx = raw_tx[len(prefix):] + # v is returned on one byte only so it might have overflowed + # in that case, we will reconstruct it to its full value + if "chainId" in tx_params: + trunc_chain_id = tx_params["chainId"] + while trunc_chain_id.bit_length() > 32: + trunc_chain_id >>= 8 + target = tx_params["chainId"] * 2 + 35 + trunc_target = trunc_chain_id * 2 + 35 + diff = vrs[0][0] - (trunc_target & 0xff) + vrs = (target + diff, vrs[1], vrs[2]) + decoded = rlp.decode(raw_tx) + reencoded = rlp.encode(decoded[:-3] + list(vrs)) + addr = Account.recover_transaction(prefix + reencoded) + return bytes.fromhex(addr[2:]) diff --git a/doc/eth_contract_support_embedded.adoc b/doc/eth_contract_support_embedded.adoc index 67c27c0c6..36a582c98 100644 --- a/doc/eth_contract_support_embedded.adoc +++ b/doc/eth_contract_support_embedded.adoc @@ -6,24 +6,24 @@ Application version 1.3.0 - 05th of July 2020 ## 1.3.0 - Initial release -## About +## About This document described how a specific device UI for a smart contract can be added in the current version of the Ethereum application, before plugins are added ## Standard support -The applications already includes dedicated UI support for those specific contract calls : +The applications already includes dedicated UI support for those specific contract calls : * ERC 20 approve(address, uint256) - implementation in *src_features/erc20_approval* * ERC 20 transfer(address, uint256) - implementation in *src_features/signTx* ## Requirements -The following data is necessary for a specific contract support +The following data is necessary for a specific contract support * Smart contract ABI (at least for calls that are to be supported by the application) -The following data is optional for a specific contract support +The following data is optional for a specific contract support * Contract address (can be optional if supported by multiple instances) @@ -38,60 +38,11 @@ The first four bytes of the call data for a function call specifies the function The following online tool can be used to compute selectors https://emn178.github.io/online-tools/keccak_256.html -## Limitations - - * The total number of parameters of a contract call is 4 (as defined in *src/shared_context.h* for tokenContext_t.data, each parameter being encoded as an uint256). Additional parameters can be supported if not required to handle the displaying logic (see "Also handle exception that only need to process the beginning of data" in *src_features/signTx/logic_signTx.c* for CONTRACT_STARKWARE_VERIFY_ESCAPE and CONTRACT_STARKWARE_REGISTER) - - * Non fixed size types (dynamic sized byte sequences, dynamic sized strings, variable length arrays) are not directly supported - -## Sample implementation of a function call - -This example describes how to implement a specific UI for a contract call. This exemple is using Starkex token deposit - *deposit(uint256 tokenId, uint256 vaultId, uint256 quantizedAmount)* - - - * Implement the specific UI logic in a new *src_features* subdirectory - note that strings.common.maxFee will be provisioned with the maximum fee to pay for this call - -``` -See src_features/stark_contract_deposit for this example -``` - - * Compute the selector - - -``` -keccak-256("deposit(uint256,uint256,uint256)") = 00aeef8a... -``` - - * Add an entry to the contract_call_t enum of *src/shared_context.h* for this function call - -``` -CONTRACT_STARKWARE_DEPOSIT_TOKEN -``` - - * Check for the selector being called and the arguments size in *src_features/signTx/logic_signTx.c* customProcessor function - additional logic can be applied (quantumSet in this example) - -```C -if ((context->currentFieldLength == STARKWARE_DEPOSIT_TOKEN_DATA_SIZE) && - (memcmp(context->workBuffer, STARKWARE_DEPOSIT_TOKEN_ID, 4) == 0) && - quantumSet) { - contractProvisioned = CONTRACT_STARKWARE_DEPOSIT_TOKEN; -} -``` - - * Call the dedicated UI at the end of the transaction parsing in *src_features/signTx/logic_signTx.c* finalizeParsing function - -```C -if (contractProvisioned == CONTRACT_STARKWARE_DEPOSIT_TOKEN) { - ux_flow_init(0, ux_approval_starkware_deposit_flow, NULL); - return; -} -``` - ## Using ERC 20 token tickers A UI implementation might want to convert an ERC 20 token contract address to a ticker for easier validation -2 tickers can be temporarily provisioned to the application by using the PROVIDE ERC 20 TOKEN INFORMATION APDU, described in *src_features/provideErc20TokenInformation* - the UI can then iterate on the provisioned tickers to display relevant information to the user +2 tickers can be temporarily provisioned to the application by using the PROVIDE ERC 20 TOKEN INFORMATION APDU, described in *src_features/provideErc20TokenInformation* - the UI can then iterate on the provisioned tickers to display relevant information to the user The same mechanism will be extended to support well known contract addresses in the future diff --git a/doc/eth_starkware_extensions.adoc b/doc/eth_starkware_extensions.adoc deleted file mode 100644 index 48e91fd8e..000000000 --- a/doc/eth_starkware_extensions.adoc +++ /dev/null @@ -1,348 +0,0 @@ -Ethereum application : Starkware extensions -============================================ -Ledger Firmware Team -Application version 1.5.0 - 4th of October 2020 - -## 1.3.0 - - Initial release - -## 1.5.0 - - Update with Starkex v2 APIs - -## About - -This specification describes the APDU messages interface implementing the Starkware extensions for the Ethereum appilcation - -## Modified general purpose APDUs - -### GET APP CONFIGURATION - -#### Description - -This command returns specific application configuration - -It is modified to notify Stark extensions support on flag 0x04 - -#### Coding - -'Command' - -[width="80%"] -|============================================================================================================================== -| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le* -| E0 | 06 | 00 | 00 | 00 | 04 -|============================================================================================================================== - -'Input data' - -None - -'Output data' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Flags - 0x01 : arbitrary data signature enabled by user - - 0x02 : ERC 20 Token information needs to be provided externally - - 0x04 : Stark extensions are supported - - 0x08 : Stark protocol v2 is supported - | 01 -| Application major version | 01 -| Application minor version | 01 -| Application patch version | 01 -|============================================================================================================================== - - -## Additional APDUs - -Additional APDUs use the APDU CLA F0 - -### GET STARK PUBLIC KEY - -#### Description - -This command returns the public Stark key (X and Y coordinates) for the given BIP 32 path. - -The key can be optionally checked on the device before being returned - in that case, only the X coordinate is displayed, as this is what is used in the contract - -#### Coding - -'Command' - -[width="80%"] -|============================================================================================================================== -| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le* -| F0 | 02 | 00 : return address - - 01 : display address and confirm before returning - | 00 | variable | variable -|============================================================================================================================== - -'Input data' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Number of BIP 32 derivations to perform (max 10) | 1 -| First derivation index (big endian) | 4 -| ... | 4 -| Last derivation index (big endian) | 4 -|============================================================================================================================== - -'Output data' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Stark key | 65 -|============================================================================================================================== - -### SIGN STARK MESSAGE - -#### Description - -This command signs an order or a transfer on the Starkware curve. - -The contract addressed associated to the token shall have be provisioned previously with the PROVIDE ERC 20 TOKEN INFORMATION command or this command will fail. - -The quantum type for v2 messages is encoded as p1 for the PROVIDE QUANTUM command - -#### Coding - -'Command' - -[width="80%"] -|============================================================================================================================== -| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le* -| F0 | 04 | - 01 : sign a Stark Order (protocol v1, handles ETH and regular ERC 20) - - 02 : sign a Stark Transfer (protocol v1, handles ETH and regular ERC 20) - - 03 : sign a Stark Order (since protocol v2) - - 04 : sign a Stark Transfer (since protocol v2) - - 05 : sign a Stark Conditional Transfer (since protocol v2) - - | 00 | variable | variable -|============================================================================================================================== - -'Input data for a Stark Order (v1)' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Number of BIP 32 derivations to perform (max 10) | 1 -| First derivation index (big endian) | 4 -| ... | 4 -| Last derivation index (big endian) | 4 -| Contract address of the token to be sold (or 00..00 for ETH) | 20 -| Quantization of the token to be sold (big endian) | 32 -| Contract address of the token to be bought (or 00..00 for ETH) | 20 -| Quantization of the token to be bought (big endian) | 32 -| ID of the source vault (big endian encoded) | 4 -| ID of the destination vault (big endian encoded) | 4 -| Amount to be sold (big endian encoded) | 8 -| Amount to buy (big endian encoded) | 8 -| Transaction nonce (big endian encoded) | 4 -| Transaction timestamp (big endian encoded) | 4 -|============================================================================================================================== - -'Input data for a Stark Transfer (v1)' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Number of BIP 32 derivations to perform (max 10) | 1 -| First derivation index (big endian) | 4 -| ... | 4 -| Last derivation index (big endian) | 4 -| Contract address of the token to be transferred (or 00..00 for ETH) | 20 -| Quantization of the token to be transferred (big endian) | 32 -| Token target public key | 32 -| ID of the source vault (big endian encoded) | 4 -| ID of the destination vault (big endian encoded) | 4 -| Amount to be transferred (big endian encoded) | 8 -| Transaction nonce (big endian encoded) | 4 -| Transaction timestamp (big endian encoded) | 4 -|============================================================================================================================== - -'Input data for a Stark Order (v2)' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Number of BIP 32 derivations to perform (max 10) | 1 -| First derivation index (big endian) | 4 -| ... | 4 -| Last derivation index (big endian) | 4 -| Quantization type of the token to be sold | 1 -| Contract address of the token to be sold (or 00..00 for ETH) | 20 -| Quantization or Token ID of the token to be sold (big endian) | 32 -| Minting blob of the token to be sold (ignored if non mintable) | 32 -| Quantization type of the token to be bought | 1 -| Contract address of the token to be bought (or 00..00 for ETH) | 20 -| Quantization or Token ID of the token to be bought (big endian) | 32 -| Minting blob of the token to be bought (ignored if non mintable) | 32 -| ID of the source vault (big endian encoded) | 4 -| ID of the destination vault (big endian encoded) | 4 -| Amount to be sold (big endian encoded) | 8 -| Amount to buy (big endian encoded) | 8 -| Transaction nonce (big endian encoded) | 4 -| Transaction timestamp (big endian encoded) | 4 -|============================================================================================================================== - -'Input data for a Stark Transfer (v2)' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Number of BIP 32 derivations to perform (max 10) | 1 -| First derivation index (big endian) | 4 -| ... | 4 -| Last derivation index (big endian) | 4 -| Quantization type of the token to be transferred | 1 -| Contract address of the token to be transferred (or 00..00 for ETH) | 20 -| Quantization or Token ID of the token to be transferred (big endian) | 32 -| Minting blob of the token to be transferred (ignored if non mintable) | 32 -| Token target public key | 32 -| ID of the source vault (big endian encoded) | 4 -| ID of the destination vault (big endian encoded) | 4 -| Amount to be transferred (big endian encoded) | 8 -| Transaction nonce (big endian encoded) | 4 -| Transaction timestamp (big endian encoded) | 4 -|============================================================================================================================== - -'Input data for a Stark Conditional Transfer' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Number of BIP 32 derivations to perform (max 10) | 1 -| First derivation index (big endian) | 4 -| ... | 4 -| Last derivation index (big endian) | 4 -| Quantization type of the token to be transferred | 1 -| Contract address of the token to be transferred (or 00..00 for ETH) | 20 -| Quantization or Token ID of the token to be transferred (big endian) | 32 -| Minting blob of the token to be transferred (ignored if non mintable) | 32 -| Token target public key | 32 -| ID of the source vault (big endian encoded) | 4 -| ID of the destination vault (big endian encoded) | 4 -| Amount to be transferred (big endian encoded) | 8 -| Transaction nonce (big endian encoded) | 4 -| Transaction timestamp (big endian encoded) | 4 -| Conditional transfer fact (big endian) | 32 -| Conditional transfer L1 condition logic address | 20 -|============================================================================================================================== - -'Output data' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| RFU (00) | 1 -| r | 32 -| s | 32 -|============================================================================================================================== - - -### PROVIDES QUANTUM - -#### Description - -This command provides quantization data used to compute a tokenId and provide additional information to the user before signing a transaction performing a deposit or withdrawal call on a Stark powered smart contract. - -It shall be called following a PROVIDE ERC 20 TOKEN INFORMATION command called for the associated contract - -#### Coding - -'Command' - -[width="80%"] -|============================================================================================================================== -| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le* -| F0 | 08 | - 00 : legacy (protocol v1, handles ETH and regular ERC 20) - - 01 : quantum encoded for ETH (since protocol v2) - - 02 : quantum encoded for a regular ERC 20 (since protocol v2) - - 03 : quantum encoded for a regular ERC 721 (since protocol v2) - - 04 : quantum encoded for a mintable ERC 20 (since protocol v2) - - 05 : quantum encoded for a mintable ERC 721 (since protocol v2) - - | 00 | variable | variable -|============================================================================================================================== - -'Legacy Input data' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Contract address used in the next transaction | 20 -| Quantization to be used in the next transaction | 32 -|============================================================================================================================== - -'v2 Input data' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Contract address used in the next transaction (ignored for ETH) | 20 -| Quantization to be used in the next transaction (ignored for ERC 721s) | 32 -| Minting blob to be used in the next transaction (ignored for non mintable) | 32 -|============================================================================================================================== - -'Output data' - -None - -### UNSAFE SIGN - -#### Description - -This command signs an arbitrary hash on the Starkware Curve after presenting the hash to the user. It is intended for speed of execution in case an unknown Stark model is pushed and should be avoided as much as possible. - -#### Coding - -'Command' - -[width="80%"] -|============================================================================================================================== -| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le* -| F0 | 0A | - 00 - | 00 | variable | variable -|============================================================================================================================== - -'Input data' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| Number of BIP 32 derivations to perform (max 10) | 1 -| First derivation index (big endian) | 4 -| ... | 4 -| Last derivation index (big endian) | 4 -| Hash to sign | 32 -|============================================================================================================================== - -'Output data' - -[width="80%"] -|============================================================================================================================== -| *Description* | *Length* -| RFU (00) | 1 -| r | 32 -| s | 32 -|============================================================================================================================== - diff --git a/doc/ethapp.adoc b/doc/ethapp.adoc index 6997b9b1e..4e5c646e3 100644 --- a/doc/ethapp.adoc +++ b/doc/ethapp.adoc @@ -87,6 +87,7 @@ The address can be optionally checked on the device before being returned. | First derivation index (big endian) | 4 | ... | 4 | Last derivation index (big endian) | 4 +| Chain ID (big endian) (optional) | 8 |============================================================================================================================== 'Output data' @@ -527,7 +528,7 @@ The plugin names `ERC20`, `ERC721` and `ERC1155` are reserved. Additional plugin The signature is computed on -type || version || len(pluginName) || pluginName || address || selector || chainId || keyId || algorithmId || len(signature) || signature +type || version || len(pluginName) || pluginName || address || selector || chainId || keyId || algorithmId #### Coding diff --git a/doc/ethapp_plugins.adoc b/doc/ethapp_plugins.adoc index a3bdbbe27..886928a4b 100644 --- a/doc/ethapp_plugins.adoc +++ b/doc/ethapp_plugins.adoc @@ -1,315 +1,313 @@ -Ethereum application Plugins : Technical Specifications -======================================================= -Ledger Firmware Team -Specification version 1.0 - 24th of September 2020 - - -## 1.0 - - Initial release - -## About - -This specification describes the plugin interface used to display a specific UI on device for Ethereum smart contracts. - -Feel free to checkout the ParaSwap plugin to see an actual implementation. Link: https://github.com/LedgerHQ/app-ethereum/blob/named-external-plugins/doc/ethapp_plugins.asc . - -## Flow overview - -When signing an Ethereum transaction containing data, the Ethereum application looks for a plugin using .either a selector list or the contract address. - -If a plugin is found, each network serialized data field (32 bytes) is passed to the plugin along with the field offset. The plugin can decide to stop the signature process if a data field isn't expected - -After all fields have been received, the plugin can report to the Ethereum application whether the full data is accepted, and the user interface model that'll be used to display the data - -### Amount/Address user interface - -In this model, the generic (without data) transaction display is used, with the amount and destination address replaced by data provided by the plugin - -### Generic user interface - -In this model, the plugin first reports a number of screens (2 lines of text, the second line being scrollable) to be displayed - -The Ethereum application will request each screen to be displayed to the plugin and let the user browse through them. - -The first screen being displayed is always a description of the plugin being used (name and version reported by the plugin), and the last screens include the transaction fees in ETH and a confirmation prompt - -### Code flow - -The plugin interfacing logic is described in _src/eth_plugin_interface.h_ - -The plugin common dispatcher is found in _src/eth_plugin_handler.c_ - -The plugin generic UI dispatcher is found in _src/eth_plugin_ui.c_ - -Sample internal plugins are provided in _src_plugins/_ - -## Creating a plugin - -### Creating an internal plugin - -Internal plugins are triggered on specific selectors. You can modify _src/eth_plugin_internal.c_ to add your mapping. - -Other specific mappings can be also added by modifying the common dispatcher - -### Creating an external plugin - -An external plugin is a library application named after the base64 encoding of the 20 bytes smart contract address - -## Detailed flow messages - -### Generic fields - -The following generic fields are present in all messages : - - * pluginSharedRW : scratch objects and utilities available to the plugin (can be read and written) - - * pluginSharedRO : transaction data available to the plugin (can only be read) - - * pluginContext : arbitrary data blob holding the plugin context, to be set and used by the plugin - - * result : return code set by the plugin following the message processing - -### ETH_PLUGIN_INIT_CONTRACT - -[source,C] ----- - -typedef struct ethPluginInitContract_t { - - // in - - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - uint32_t pluginContextLength; - uint8_t *selector; // 4 bytes selector - uint32_t dataSize; - - char *alias; // 29 bytes alias if ETH_PLUGIN_RESULT_OK_ALIAS set - - uint8_t result; - -} ethPluginInitContract_t; - ----- - -This message is sent when the selector of the data has been parsed. The following specific fields are filled when the plugin is called : - - * pluginContextLength : length of the data field available to store the plugin context - * selector : 4 bytes selector of the data field - * dataSize : size in bytes of the data field - -The following return codes are expected, any other will abort the signing process : - - * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized - * ETH_PLUGIN_RESULT_OK_ALIAS : if a base64 encoded alias of another plugin to call is copied to the _alias_ field. In this case, the dispatcher will follow the alias chain, and the original plugin will only be called to retrieve its name when using a generic user interface - * ETH_PLUGIN_RESULT_FALLBACK : if the signing logic should fallback to the generic one - -### ETH_PLUGIN_PROVIDE_PARAMETER - -[source,C] ----- - -typedef struct ethPluginProvideParameter_t { - - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - uint8_t *parameter; // 32 bytes parameter - uint32_t parameterOffset; - - uint8_t result; - -} ethPluginProvideParameter_t; - ----- - -This message is sent when a new 32 bytes component of the data field is available. The following specific fields are filled when the plugin is called : - - * parameter : pointer to the 32 bytes parameter being parsed - * parameterOffset : offset to this parameter from the beginning of the data field (starts at 4, following the selector) - -The following return codes are expected, any other will abort the signing process : - - * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized - * ETH_PLUGIN_RESULT_FALLBACK : if the signing logic should fallback to the generic one - -There are already defined functions to extract data from a parameter: -[source,C] ----- -void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size); -void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size); - -// Get the value from the beginning of the parameter (right to left) and check if the rest of it is zero -bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value); -bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value); ----- - -### ETH_PLUGIN_FINALIZE - -[source,C] ----- - -typedef struct ethPluginFinalize_t { - - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - - uint8_t *itemLookup1; // set by the plugin if a token or an nft should be looked up - uint8_t *itemLookup2; - - uint8_t *amount; // set an uint256 pointer if uiType is UI_AMOUNT_ADDRESS - uint8_t *address; // set to the destination address if uiType is UI_AMOUNT_ADDRESS. Set to the user's address if uiType is UI_TYPE_GENERIC - - uint8_t uiType; - uint8_t numScreens; // ignored if uiType is UI_AMOUNT_ADDRESS - uint8_t result; - -} ethPluginFinalize_t; - ----- - -This message is sent when the data field has been fully parsed. The following specific fields can be filled by the plugin : - - * itemLookup1 : the pointer shall be set to a 20 bytes address to look up an ERC20 token or NFT if needed by the plugin - * itemLookup2 : the pointer shall be set to a 20 bytes address to look up an ERC20 token or NFT if needed by the plugin - * uiType : set to either ETH_UI_TYPE_AMOUNT_ADDRESS for an amount/address UI or ETH_UI_TYPE_GENERIC for a generic UI - -The following specific fields are filled by the plugin when returning an amount/address UI : - - * amount : set to a pointer to a 256 bits number - * address : set to a pointer to a 20 bytes address - -The following specific fields are filled by the plugin when returning a generic UI : - - * numScreens : number of screens handled by the plugin - -The following return codes are expected, any other will abort the signing process : - - * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized - * ETH_PLUGIN_RESULT_FALLBACK : if the signing logic should fallback to the generic one - -### ETH_PLUGIN_PROVIDE_INFO - -[source,C] ----- - -typedef struct ethPluginProvideInfo_t { - - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - - union extraInfo *item1; // set by the ETH application, to be saved by the plugin - union extraInfo *item2; - - uint8_t additionalScreens; // Used by the plugin if it needs to display additional screens based on the information received. - - uint8_t result; - -} ethPluginProvideInfo_t; - ----- - -This message is sent if an information lookup was required by the plugin when parsing a finalize message. The following specific fields are filled when the plugin is called : - - * item1 : pointer to an union matching itemLookup1, or NULL if not found - * item2 : pointer to an union matching itemLookup2, or NULL if not found - -The following return codes are expected, any other will abort the signing process : - - * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized - * ETH_PLUGIN_RESULT_FALLBACK : if the signing logic should fallback to the generic one - -### ETH_PLUGIN_QUERY_CONTRACT_ID - -[source,C] ----- - -typedef struct ethQueryContractID_t { - - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - - char *name; - uint32_t nameLength; - char *version; - uint32_t versionLength; - - uint8_t result; - -} ethQueryContractID_t; - ----- - -This message is sent after the parsing finalization and information lookups if requested if a generic UI is used. The following specific fields are provided when the plugin is called : - - * name : pointer to the name of the plugin, to be filled by the plugin - * nameLength : maximum name length - * version : pointer to the version of the plugin, to be filled by the plugin - * versionLength : maximum version length - -The following return codes are expected, any other will abort the signing process : - - * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized - -### ETH_PLUGIN_QUERY_CONTRACT_UI - -[source,C] ----- - -typedef struct ethQueryContractUI_t { - - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - union extraInfo_t *item1; - union extraInfo_t *item2; - char network_ticker[MAX_TICKER_LEN]; - uint8_t *pluginContext; - uint8_t screenIndex; - char *title; - uint32_t titleLength; - char *msg; - uint32_t msgLength; - - uint8_t result; - -} ethQueryContractUI_t; - ----- - -This message is sent when a plugin screen shall be displayed if a generic UI is used. The following specific fields are provided when the plugin is called : - - - * item1 : pointer to token / nft information - * item2 : pointer to token / nft information - * network_ticker : string that holds the network ticker - * screenIndex : index of the screen to display, starting from 0 - * title : pointer to the first line of the screen, to be filled by the plugin - * titleLength : maximum title length - * msg : pointer to the second line of the screen, to be filled by the plugin - * msgLength : maximum msg length - -The following return codes are expected, any other will abort the signing process : - - * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized - -## Caveats - -When setting a pointer from the plugin space, make sure to use an address that will be accessible from the Ethereum application (typically in the plugin RAM context, *not* on the plugin stack) - -Do not use data types that need to be aligned (such as uint32_t) in the plugin context. - -## TODOs - -Provide a sample callback mechanism for common plugin actions (amount to string, 256 bits number multiplication ...) to avoid duplicating code in the plugin space - -Provide external plugins samples - -Fully support Starkware as an independant application (APDU logic added) - -Support extra flags for the generic UI (fast confirmation on first screen, ...) - -Support extra plugin provisioning (signed list of associated smart contract addresses, ...) +Ethereum application Plugins : Technical Specifications +======================================================= +Ledger Firmware Team +Specification version 1.0 - 24th of September 2020 + + +## 1.0 + - Initial release + +## About + +This specification describes the plugin interface used to display a specific UI on device for Ethereum smart contracts. + +Feel free to checkout the ParaSwap plugin to see an actual implementation. Link: https://github.com/LedgerHQ/app-ethereum/blob/named-external-plugins/doc/ethapp_plugins.asc . + +## Flow overview + +When signing an Ethereum transaction containing data, the Ethereum application looks for a plugin using .either a selector list or the contract address. + +If a plugin is found, each network serialized data field (32 bytes) is passed to the plugin along with the field offset. The plugin can decide to stop the signature process if a data field isn't expected + +After all fields have been received, the plugin can report to the Ethereum application whether the full data is accepted, and the user interface model that'll be used to display the data + +### Amount/Address user interface + +In this model, the generic (without data) transaction display is used, with the amount and destination address replaced by data provided by the plugin + +### Generic user interface + +In this model, the plugin first reports a number of screens (2 lines of text, the second line being scrollable) to be displayed + +The Ethereum application will request each screen to be displayed to the plugin and let the user browse through them. + +The first screen being displayed is always a description of the plugin being used (name and version reported by the plugin), and the last screens include the transaction fees in ETH and a confirmation prompt + +### Code flow + +The plugin interfacing logic is described in _src/eth_plugin_interface.h_ + +The plugin common dispatcher is found in _src/eth_plugin_handler.c_ + +The plugin generic UI dispatcher is found in _src/eth_plugin_ui.c_ + +Sample internal plugins are provided in _src_plugins/_ + +## Creating a plugin + +### Creating an internal plugin + +Internal plugins are triggered on specific selectors. You can modify _src/eth_plugin_internal.c_ to add your mapping. + +Other specific mappings can be also added by modifying the common dispatcher + +### Creating an external plugin + +An external plugin is a library application named after the base64 encoding of the 20 bytes smart contract address + +## Detailed flow messages + +### Generic fields + +The following generic fields are present in all messages : + + * pluginSharedRW : scratch objects and utilities available to the plugin (can be read and written) + + * pluginSharedRO : transaction data available to the plugin (can only be read) + + * pluginContext : arbitrary data blob holding the plugin context, to be set and used by the plugin + + * result : return code set by the plugin following the message processing + +### ETH_PLUGIN_INIT_CONTRACT + +[source,C] +---- + +typedef struct ethPluginInitContract_t { + + // in + + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; + uint32_t pluginContextLength; + uint8_t *selector; // 4 bytes selector + uint32_t dataSize; + + char *alias; // 29 bytes alias if ETH_PLUGIN_RESULT_OK_ALIAS set + + uint8_t result; + +} ethPluginInitContract_t; + +---- + +This message is sent when the selector of the data has been parsed. The following specific fields are filled when the plugin is called : + + * pluginContextLength : length of the data field available to store the plugin context + * selector : 4 bytes selector of the data field + * dataSize : size in bytes of the data field + +The following return codes are expected, any other will abort the signing process : + + * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized + * ETH_PLUGIN_RESULT_OK_ALIAS : if a base64 encoded alias of another plugin to call is copied to the _alias_ field. In this case, the dispatcher will follow the alias chain, and the original plugin will only be called to retrieve its name when using a generic user interface + * ETH_PLUGIN_RESULT_FALLBACK : if the signing logic should fallback to the generic one + +### ETH_PLUGIN_PROVIDE_PARAMETER + +[source,C] +---- + +typedef struct ethPluginProvideParameter_t { + + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; + uint8_t *parameter; // 32 bytes parameter + uint32_t parameterOffset; + + uint8_t result; + +} ethPluginProvideParameter_t; + +---- + +This message is sent when a new 32 bytes component of the data field is available. The following specific fields are filled when the plugin is called : + + * parameter : pointer to the 32 bytes parameter being parsed + * parameterOffset : offset to this parameter from the beginning of the data field (starts at 4, following the selector) + +The following return codes are expected, any other will abort the signing process : + + * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized + * ETH_PLUGIN_RESULT_FALLBACK : if the signing logic should fallback to the generic one + +There are already defined functions to extract data from a parameter: +[source,C] +---- +void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size); +void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size); + +// Get the value from the beginning of the parameter (right to left) and check if the rest of it is zero +bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value); +bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value); +---- + +### ETH_PLUGIN_FINALIZE + +[source,C] +---- + +typedef struct ethPluginFinalize_t { + + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; + + uint8_t *itemLookup1; // set by the plugin if a token or an nft should be looked up + uint8_t *itemLookup2; + + uint8_t *amount; // set an uint256 pointer if uiType is UI_AMOUNT_ADDRESS + uint8_t *address; // set to the destination address if uiType is UI_AMOUNT_ADDRESS. Set to the user's address if uiType is UI_TYPE_GENERIC + + uint8_t uiType; + uint8_t numScreens; // ignored if uiType is UI_AMOUNT_ADDRESS + uint8_t result; + +} ethPluginFinalize_t; + +---- + +This message is sent when the data field has been fully parsed. The following specific fields can be filled by the plugin : + + * itemLookup1 : the pointer shall be set to a 20 bytes address to look up an ERC20 token or NFT if needed by the plugin + * itemLookup2 : the pointer shall be set to a 20 bytes address to look up an ERC20 token or NFT if needed by the plugin + * uiType : set to either ETH_UI_TYPE_AMOUNT_ADDRESS for an amount/address UI or ETH_UI_TYPE_GENERIC for a generic UI + +The following specific fields are filled by the plugin when returning an amount/address UI : + + * amount : set to a pointer to a 256 bits number + * address : set to a pointer to a 20 bytes address + +The following specific fields are filled by the plugin when returning a generic UI : + + * numScreens : number of screens handled by the plugin + +The following return codes are expected, any other will abort the signing process : + + * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized + * ETH_PLUGIN_RESULT_FALLBACK : if the signing logic should fallback to the generic one + +### ETH_PLUGIN_PROVIDE_INFO + +[source,C] +---- + +typedef struct ethPluginProvideInfo_t { + + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; + + union extraInfo *item1; // set by the ETH application, to be saved by the plugin + union extraInfo *item2; + + uint8_t additionalScreens; // Used by the plugin if it needs to display additional screens based on the information received. + + uint8_t result; + +} ethPluginProvideInfo_t; + +---- + +This message is sent if an information lookup was required by the plugin when parsing a finalize message. The following specific fields are filled when the plugin is called : + + * item1 : pointer to an union matching itemLookup1, or NULL if not found + * item2 : pointer to an union matching itemLookup2, or NULL if not found + +The following return codes are expected, any other will abort the signing process : + + * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized + * ETH_PLUGIN_RESULT_FALLBACK : if the signing logic should fallback to the generic one + +### ETH_PLUGIN_QUERY_CONTRACT_ID + +[source,C] +---- + +typedef struct ethQueryContractID_t { + + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; + + char *name; + uint32_t nameLength; + char *version; + uint32_t versionLength; + + uint8_t result; + +} ethQueryContractID_t; + +---- + +This message is sent after the parsing finalization and information lookups if requested if a generic UI is used. The following specific fields are provided when the plugin is called : + + * name : pointer to the name of the plugin, to be filled by the plugin + * nameLength : maximum name length + * version : pointer to the version of the plugin, to be filled by the plugin + * versionLength : maximum version length + +The following return codes are expected, any other will abort the signing process : + + * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized + +### ETH_PLUGIN_QUERY_CONTRACT_UI + +[source,C] +---- + +typedef struct ethQueryContractUI_t { + + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + union extraInfo_t *item1; + union extraInfo_t *item2; + char network_ticker[MAX_TICKER_LEN]; + uint8_t *pluginContext; + uint8_t screenIndex; + char *title; + uint32_t titleLength; + char *msg; + uint32_t msgLength; + + uint8_t result; + +} ethQueryContractUI_t; + +---- + +This message is sent when a plugin screen shall be displayed if a generic UI is used. The following specific fields are provided when the plugin is called : + + + * item1 : pointer to token / nft information + * item2 : pointer to token / nft information + * network_ticker : string that holds the network ticker + * screenIndex : index of the screen to display, starting from 0 + * title : pointer to the first line of the screen, to be filled by the plugin + * titleLength : maximum title length + * msg : pointer to the second line of the screen, to be filled by the plugin + * msgLength : maximum msg length + +The following return codes are expected, any other will abort the signing process : + + * ETH_PLUGIN_RESULT_OK : if the plugin can be successfully initialized + +## Caveats + +When setting a pointer from the plugin space, make sure to use an address that will be accessible from the Ethereum application (typically in the plugin RAM context, *not* on the plugin stack) + +Do not use data types that need to be aligned (such as uint32_t) in the plugin context. + +## TODOs + +Provide a sample callback mechanism for common plugin actions (amount to string, 256 bits number multiplication ...) to avoid duplicating code in the plugin space + +Provide external plugins samples + +Support extra flags for the generic UI (fast confirmation on first screen, ...) + +Support extra plugin provisioning (signed list of associated smart contract addresses, ...) diff --git a/ethereum-plugin-sdk b/ethereum-plugin-sdk index b9777e7a8..0a98664de 160000 --- a/ethereum-plugin-sdk +++ b/ethereum-plugin-sdk @@ -1 +1 @@ -Subproject commit b9777e7a81a9c33b3f8997ffa23396fa2b3f861d +Subproject commit 0a98664deba849f05a51407d8a3edb05cd83d464 diff --git a/glyphs/stax_chain_100_64px.gif b/glyphs/stax_chain_100_64px.gif new file mode 100644 index 000000000..87d0da732 Binary files /dev/null and b/glyphs/stax_chain_100_64px.gif differ diff --git a/glyphs/stax_chain_10200_64px.gif b/glyphs/stax_chain_10200_64px.gif new file mode 100644 index 000000000..87d0da732 Binary files /dev/null and b/glyphs/stax_chain_10200_64px.gif differ diff --git a/glyphs/stax_conflux_espace_64px.gif b/glyphs/stax_chain_1030_64px.gif similarity index 100% rename from glyphs/stax_conflux_espace_64px.gif rename to glyphs/stax_chain_1030_64px.gif diff --git a/glyphs/stax_chain_10507_64px.gif b/glyphs/stax_chain_10507_64px.gif new file mode 100644 index 000000000..287008fb9 Binary files /dev/null and b/glyphs/stax_chain_10507_64px.gif differ diff --git a/glyphs/stax_chain_106_64px.gif b/glyphs/stax_chain_106_64px.gif new file mode 100644 index 000000000..b3a1c0daf Binary files /dev/null and b/glyphs/stax_chain_106_64px.gif differ diff --git a/glyphs/stax_chain_1088_64px.gif b/glyphs/stax_chain_1088_64px.gif new file mode 100644 index 000000000..933d35dd1 Binary files /dev/null and b/glyphs/stax_chain_1088_64px.gif differ diff --git a/glyphs/stax_thundercore_64px.gif b/glyphs/stax_chain_108_64px.gif similarity index 100% rename from glyphs/stax_thundercore_64px.gif rename to glyphs/stax_chain_108_64px.gif diff --git a/glyphs/stax_chain_10_64px.gif b/glyphs/stax_chain_10_64px.gif new file mode 100644 index 000000000..ebd55a1e6 Binary files /dev/null and b/glyphs/stax_chain_10_64px.gif differ diff --git a/glyphs/stax_chain_1101_64px.gif b/glyphs/stax_chain_1101_64px.gif new file mode 100644 index 000000000..662cab037 Binary files /dev/null and b/glyphs/stax_chain_1101_64px.gif differ diff --git a/glyphs/stax_chain_11155111_64px.gif b/glyphs/stax_chain_11155111_64px.gif new file mode 120000 index 000000000..8ced0b781 --- /dev/null +++ b/glyphs/stax_chain_11155111_64px.gif @@ -0,0 +1 @@ +stax_chain_1_64px.gif \ No newline at end of file diff --git a/glyphs/stax_chain_1116_64px.gif b/glyphs/stax_chain_1116_64px.gif new file mode 100644 index 000000000..fbf2fae0f Binary files /dev/null and b/glyphs/stax_chain_1116_64px.gif differ diff --git a/glyphs/stax_chain_11297108109_64px.gif b/glyphs/stax_chain_11297108109_64px.gif new file mode 100644 index 000000000..2cecbfffb Binary files /dev/null and b/glyphs/stax_chain_11297108109_64px.gif differ diff --git a/glyphs/stax_moonbeam_64px.gif b/glyphs/stax_chain_1284_64px.gif similarity index 100% rename from glyphs/stax_moonbeam_64px.gif rename to glyphs/stax_chain_1284_64px.gif diff --git a/glyphs/stax_moonriver_64px.gif b/glyphs/stax_chain_1285_64px.gif similarity index 100% rename from glyphs/stax_moonriver_64px.gif rename to glyphs/stax_chain_1285_64px.gif diff --git a/glyphs/stax_ether1_64px.gif b/glyphs/stax_chain_1313114_64px.gif similarity index 100% rename from glyphs/stax_ether1_64px.gif rename to glyphs/stax_chain_1313114_64px.gif diff --git a/glyphs/stax_polygon_64px.gif b/glyphs/stax_chain_137_64px.gif similarity index 100% rename from glyphs/stax_polygon_64px.gif rename to glyphs/stax_chain_137_64px.gif diff --git a/glyphs/stax_flare_64px.gif b/glyphs/stax_chain_14_64px.gif similarity index 100% rename from glyphs/stax_flare_64px.gif rename to glyphs/stax_chain_14_64px.gif diff --git a/glyphs/stax_atheios_64px.gif b/glyphs/stax_chain_1620_64px.gif similarity index 100% rename from glyphs/stax_atheios_64px.gif rename to glyphs/stax_chain_1620_64px.gif diff --git a/glyphs/stax_flare_coston_64px.gif b/glyphs/stax_chain_16_64px.gif similarity index 100% rename from glyphs/stax_flare_coston_64px.gif rename to glyphs/stax_chain_16_64px.gif diff --git a/glyphs/stax_chain_17000_64px.gif b/glyphs/stax_chain_17000_64px.gif new file mode 120000 index 000000000..8ced0b781 --- /dev/null +++ b/glyphs/stax_chain_17000_64px.gif @@ -0,0 +1 @@ +stax_chain_1_64px.gif \ No newline at end of file diff --git a/glyphs/stax_cube_64px.gif b/glyphs/stax_chain_1818_64px.gif similarity index 100% rename from glyphs/stax_cube_64px.gif rename to glyphs/stax_chain_1818_64px.gif diff --git a/glyphs/stax_chain_1907_64px.gif b/glyphs/stax_chain_1907_64px.gif new file mode 100644 index 000000000..543f164ae Binary files /dev/null and b/glyphs/stax_chain_1907_64px.gif differ diff --git a/glyphs/stax_chain_196_64px.gif b/glyphs/stax_chain_196_64px.gif new file mode 100644 index 000000000..5368f8a43 Binary files /dev/null and b/glyphs/stax_chain_196_64px.gif differ diff --git a/glyphs/stax_ethergem_64px.gif b/glyphs/stax_chain_1987_64px.gif similarity index 100% rename from glyphs/stax_ethergem_64px.gif rename to glyphs/stax_chain_1987_64px.gif diff --git a/glyphs/stax_bttc_64px.gif b/glyphs/stax_chain_199_64px.gif similarity index 100% rename from glyphs/stax_bttc_64px.gif rename to glyphs/stax_chain_199_64px.gif diff --git a/glyphs/stax_songbird_64px.gif b/glyphs/stax_chain_19_64px.gif similarity index 100% rename from glyphs/stax_songbird_64px.gif rename to glyphs/stax_chain_19_64px.gif diff --git a/glyphs/stax_ethereum_64px.gif b/glyphs/stax_chain_1_64px.gif similarity index 100% rename from glyphs/stax_ethereum_64px.gif rename to glyphs/stax_chain_1_64px.gif diff --git a/glyphs/stax_akroma_64px.gif b/glyphs/stax_chain_200625_64px.gif similarity index 100% rename from glyphs/stax_akroma_64px.gif rename to glyphs/stax_chain_200625_64px.gif diff --git a/glyphs/stax_tecracoin_64px.gif b/glyphs/stax_chain_20531811_64px.gif similarity index 100% rename from glyphs/stax_tecracoin_64px.gif rename to glyphs/stax_chain_20531811_64px.gif diff --git a/glyphs/stax_tecratestnet_64px.gif b/glyphs/stax_chain_20531812_64px.gif similarity index 100% rename from glyphs/stax_tecratestnet_64px.gif rename to glyphs/stax_chain_20531812_64px.gif diff --git a/glyphs/stax_chain_2222_64px.gif b/glyphs/stax_chain_2222_64px.gif new file mode 100644 index 000000000..882dacd56 Binary files /dev/null and b/glyphs/stax_chain_2222_64px.gif differ diff --git a/glyphs/stax_dexon_64px.gif b/glyphs/stax_chain_237_64px.gif similarity index 100% rename from glyphs/stax_dexon_64px.gif rename to glyphs/stax_chain_237_64px.gif diff --git a/glyphs/stax_webchain_64px.gif b/glyphs/stax_chain_24484_64px.gif similarity index 100% rename from glyphs/stax_webchain_64px.gif rename to glyphs/stax_chain_24484_64px.gif diff --git a/glyphs/stax_chain_245022926_64px.gif b/glyphs/stax_chain_245022926_64px.gif new file mode 100644 index 000000000..e79f76f7e Binary files /dev/null and b/glyphs/stax_chain_245022926_64px.gif differ diff --git a/glyphs/stax_chain_245022934_64px.gif b/glyphs/stax_chain_245022934_64px.gif new file mode 100644 index 000000000..e79f76f7e Binary files /dev/null and b/glyphs/stax_chain_245022934_64px.gif differ diff --git a/glyphs/stax_artis_sigma1_64px.gif b/glyphs/stax_chain_246529_64px.gif similarity index 100% rename from glyphs/stax_artis_sigma1_64px.gif rename to glyphs/stax_chain_246529_64px.gif diff --git a/glyphs/stax_artis_tau1_64px.gif b/glyphs/stax_chain_246785_64px.gif similarity index 100% rename from glyphs/stax_artis_tau1_64px.gif rename to glyphs/stax_chain_246785_64px.gif diff --git a/glyphs/stax_energywebchain_64px.gif b/glyphs/stax_chain_246_64px.gif similarity index 100% rename from glyphs/stax_energywebchain_64px.gif rename to glyphs/stax_chain_246_64px.gif diff --git a/glyphs/stax_oasys_64px.gif b/glyphs/stax_chain_248_64px.gif similarity index 100% rename from glyphs/stax_oasys_64px.gif rename to glyphs/stax_chain_248_64px.gif diff --git a/glyphs/stax_kardiachain_64px.gif b/glyphs/stax_chain_24_64px.gif similarity index 100% rename from glyphs/stax_kardiachain_64px.gif rename to glyphs/stax_chain_24_64px.gif diff --git a/glyphs/stax_chain_250_64px.gif b/glyphs/stax_chain_250_64px.gif new file mode 100644 index 000000000..4bd472407 Binary files /dev/null and b/glyphs/stax_chain_250_64px.gif differ diff --git a/glyphs/stax_chain_25_64px.gif b/glyphs/stax_chain_25_64px.gif new file mode 100644 index 000000000..dc4db196b Binary files /dev/null and b/glyphs/stax_chain_25_64px.gif differ diff --git a/glyphs/stax_hpb_64px.gif b/glyphs/stax_chain_269_64px.gif similarity index 100% rename from glyphs/stax_hpb_64px.gif rename to glyphs/stax_chain_269_64px.gif diff --git a/glyphs/stax_chain_288_64px.gif b/glyphs/stax_chain_288_64px.gif new file mode 100644 index 000000000..a445fe973 Binary files /dev/null and b/glyphs/stax_chain_288_64px.gif differ diff --git a/glyphs/stax_reosc_64px.gif b/glyphs/stax_chain_2894_64px.gif similarity index 100% rename from glyphs/stax_reosc_64px.gif rename to glyphs/stax_chain_2894_64px.gif diff --git a/glyphs/stax_expanse_64px.gif b/glyphs/stax_chain_2_64px.gif similarity index 100% rename from glyphs/stax_expanse_64px.gif rename to glyphs/stax_chain_2_64px.gif diff --git a/glyphs/stax_rsk_64px.gif b/glyphs/stax_chain_30_64px.gif similarity index 100% rename from glyphs/stax_rsk_64px.gif rename to glyphs/stax_chain_30_64px.gif diff --git a/glyphs/stax_ethersocial_64px.gif b/glyphs/stax_chain_31102_64px.gif similarity index 100% rename from glyphs/stax_ethersocial_64px.gif rename to glyphs/stax_chain_31102_64px.gif diff --git a/glyphs/stax_pirl_64px.gif b/glyphs/stax_chain_3125659152_64px.gif similarity index 100% rename from glyphs/stax_pirl_64px.gif rename to glyphs/stax_chain_3125659152_64px.gif diff --git a/glyphs/stax_rsk_testnet_64px.gif b/glyphs/stax_chain_31_64px.gif similarity index 100% rename from glyphs/stax_rsk_testnet_64px.gif rename to glyphs/stax_chain_31_64px.gif diff --git a/glyphs/stax_chain_321_64px.gif b/glyphs/stax_chain_321_64px.gif new file mode 100644 index 000000000..2805c9ddc Binary files /dev/null and b/glyphs/stax_chain_321_64px.gif differ diff --git a/glyphs/stax_shiden_64px.gif b/glyphs/stax_chain_336_64px.gif similarity index 100% rename from glyphs/stax_shiden_64px.gif rename to glyphs/stax_chain_336_64px.gif diff --git a/glyphs/stax_chain_369_64px.gif b/glyphs/stax_chain_369_64px.gif new file mode 100644 index 000000000..2832ecbeb Binary files /dev/null and b/glyphs/stax_chain_369_64px.gif differ diff --git a/glyphs/stax_chain_39797_64px.gif b/glyphs/stax_chain_39797_64px.gif new file mode 100644 index 000000000..21a2d302a Binary files /dev/null and b/glyphs/stax_chain_39797_64px.gif differ diff --git a/glyphs/stax_ropsten_64px.gif b/glyphs/stax_chain_3_64px.gif similarity index 100% rename from glyphs/stax_ropsten_64px.gif rename to glyphs/stax_chain_3_64px.gif diff --git a/glyphs/stax_tobalaba_64px.gif b/glyphs/stax_chain_401697_64px.gif similarity index 100% rename from glyphs/stax_tobalaba_64px.gif rename to glyphs/stax_chain_401697_64px.gif diff --git a/glyphs/stax_chain_40_64px.gif b/glyphs/stax_chain_40_64px.gif new file mode 100644 index 000000000..151d58d07 Binary files /dev/null and b/glyphs/stax_chain_40_64px.gif differ diff --git a/glyphs/stax_chain_4201_64px.gif b/glyphs/stax_chain_4201_64px.gif new file mode 100644 index 000000000..f91bcb140 Binary files /dev/null and b/glyphs/stax_chain_4201_64px.gif differ diff --git a/glyphs/stax_chain_42161_64px.gif b/glyphs/stax_chain_42161_64px.gif new file mode 100644 index 000000000..8be1020d9 Binary files /dev/null and b/glyphs/stax_chain_42161_64px.gif differ diff --git a/glyphs/stax_chain_42220_64px.gif b/glyphs/stax_chain_42220_64px.gif new file mode 100644 index 000000000..2b1370cec Binary files /dev/null and b/glyphs/stax_chain_42220_64px.gif differ diff --git a/glyphs/stax_chain_42_64px.gif b/glyphs/stax_chain_42_64px.gif new file mode 100644 index 000000000..f91bcb140 Binary files /dev/null and b/glyphs/stax_chain_42_64px.gif differ diff --git a/glyphs/stax_chain_43114_64px.gif b/glyphs/stax_chain_43114_64px.gif new file mode 100644 index 000000000..3d2c01de3 Binary files /dev/null and b/glyphs/stax_chain_43114_64px.gif differ diff --git a/glyphs/stax_chain_44787_64px.gif b/glyphs/stax_chain_44787_64px.gif new file mode 100644 index 000000000..2b1370cec Binary files /dev/null and b/glyphs/stax_chain_44787_64px.gif differ diff --git a/glyphs/stax_chain_4919_64px.gif b/glyphs/stax_chain_4919_64px.gif new file mode 100644 index 000000000..6814b7456 Binary files /dev/null and b/glyphs/stax_chain_4919_64px.gif differ diff --git a/glyphs/stax_chain_4_64px.gif b/glyphs/stax_chain_4_64px.gif new file mode 100644 index 000000000..503a95f05 Binary files /dev/null and b/glyphs/stax_chain_4_64px.gif differ diff --git a/glyphs/stax_xdcnetwork_64px.gif b/glyphs/stax_chain_50_64px.gif similarity index 100% rename from glyphs/stax_xdcnetwork_64px.gif rename to glyphs/stax_chain_50_64px.gif diff --git a/glyphs/stax_apothemnetwork_64px.gif b/glyphs/stax_chain_51_64px.gif similarity index 100% rename from glyphs/stax_apothemnetwork_64px.gif rename to glyphs/stax_chain_51_64px.gif diff --git a/glyphs/stax_chain_534351_64px.gif b/glyphs/stax_chain_534351_64px.gif new file mode 100644 index 000000000..27e944552 Binary files /dev/null and b/glyphs/stax_chain_534351_64px.gif differ diff --git a/glyphs/stax_chain_534352_64px.gif b/glyphs/stax_chain_534352_64px.gif new file mode 100644 index 000000000..27e944552 Binary files /dev/null and b/glyphs/stax_chain_534352_64px.gif differ diff --git a/glyphs/stax_chain_534353_64px.gif b/glyphs/stax_chain_534353_64px.gif new file mode 100644 index 000000000..27e944552 Binary files /dev/null and b/glyphs/stax_chain_534353_64px.gif differ diff --git a/glyphs/stax_chain_534354_64px.gif b/glyphs/stax_chain_534354_64px.gif new file mode 100644 index 000000000..4b12d59e8 Binary files /dev/null and b/glyphs/stax_chain_534354_64px.gif differ diff --git a/glyphs/stax_bsc_64px.gif b/glyphs/stax_chain_56_64px.gif similarity index 100% rename from glyphs/stax_bsc_64px.gif rename to glyphs/stax_chain_56_64px.gif diff --git a/glyphs/stax_chain_57_64px.gif b/glyphs/stax_chain_57_64px.gif new file mode 100644 index 000000000..7cd5c8751 Binary files /dev/null and b/glyphs/stax_chain_57_64px.gif differ diff --git a/glyphs/stax_chain_59144_64px.gif b/glyphs/stax_chain_59144_64px.gif new file mode 100644 index 000000000..39d5a698e Binary files /dev/null and b/glyphs/stax_chain_59144_64px.gif differ diff --git a/glyphs/stax_astar_64px.gif b/glyphs/stax_chain_592_64px.gif similarity index 100% rename from glyphs/stax_astar_64px.gif rename to glyphs/stax_chain_592_64px.gif diff --git a/glyphs/stax_goerli_64px.gif b/glyphs/stax_chain_5_64px.gif similarity index 100% rename from glyphs/stax_goerli_64px.gif rename to glyphs/stax_chain_5_64px.gif diff --git a/glyphs/stax_gochain_64px.gif b/glyphs/stax_chain_60_64px.gif similarity index 100% rename from glyphs/stax_gochain_64px.gif rename to glyphs/stax_chain_60_64px.gif diff --git a/glyphs/stax_ethereum_classic_64px.gif b/glyphs/stax_chain_61_64px.gif similarity index 100% rename from glyphs/stax_ethereum_classic_64px.gif rename to glyphs/stax_chain_61_64px.gif diff --git a/glyphs/stax_chain_62320_64px.gif b/glyphs/stax_chain_62320_64px.gif new file mode 100644 index 000000000..2b1370cec Binary files /dev/null and b/glyphs/stax_chain_62320_64px.gif differ diff --git a/glyphs/stax_multivac_64px.gif b/glyphs/stax_chain_62621_64px.gif similarity index 100% rename from glyphs/stax_multivac_64px.gif rename to glyphs/stax_chain_62621_64px.gif diff --git a/glyphs/stax_ellaism_64px.gif b/glyphs/stax_chain_64_64px.gif similarity index 100% rename from glyphs/stax_ellaism_64px.gif rename to glyphs/stax_chain_64_64px.gif diff --git a/glyphs/stax_okc_64px.gif b/glyphs/stax_chain_66_64px.gif similarity index 100% rename from glyphs/stax_okc_64px.gif rename to glyphs/stax_chain_66_64px.gif diff --git a/glyphs/stax_chain_7171_64px.gif b/glyphs/stax_chain_7171_64px.gif new file mode 100644 index 000000000..3181f5a5d Binary files /dev/null and b/glyphs/stax_chain_7171_64px.gif differ diff --git a/glyphs/stax_shyft_64px.gif b/glyphs/stax_chain_7341_64px.gif similarity index 100% rename from glyphs/stax_shyft_64px.gif rename to glyphs/stax_chain_7341_64px.gif diff --git a/glyphs/stax_volta_64px.gif b/glyphs/stax_chain_73799_64px.gif similarity index 100% rename from glyphs/stax_volta_64px.gif rename to glyphs/stax_chain_73799_64px.gif diff --git a/glyphs/stax_mix_64px.gif b/glyphs/stax_chain_76_64px.gif similarity index 100% rename from glyphs/stax_mix_64px.gif rename to glyphs/stax_chain_76_64px.gif diff --git a/glyphs/stax_musicoin_64px.gif b/glyphs/stax_chain_7762959_64px.gif similarity index 100% rename from glyphs/stax_musicoin_64px.gif rename to glyphs/stax_chain_7762959_64px.gif diff --git a/glyphs/stax_wethio_64px.gif b/glyphs/stax_chain_78_64px.gif similarity index 100% rename from glyphs/stax_wethio_64px.gif rename to glyphs/stax_chain_78_64px.gif diff --git a/glyphs/stax_callisto_64px.gif b/glyphs/stax_chain_820_64px.gif similarity index 100% rename from glyphs/stax_callisto_64px.gif rename to glyphs/stax_chain_820_64px.gif diff --git a/glyphs/stax_chain_8217_64px.gif b/glyphs/stax_chain_8217_64px.gif new file mode 100644 index 000000000..787694c23 Binary files /dev/null and b/glyphs/stax_chain_8217_64px.gif differ diff --git a/glyphs/stax_meter_64px.gif b/glyphs/stax_chain_82_64px.gif similarity index 100% rename from glyphs/stax_meter_64px.gif rename to glyphs/stax_chain_82_64px.gif diff --git a/glyphs/stax_chain_8453_64px.gif b/glyphs/stax_chain_8453_64px.gif new file mode 100644 index 000000000..43c3075fe Binary files /dev/null and b/glyphs/stax_chain_8453_64px.gif differ diff --git a/glyphs/stax_id4good_64px.gif b/glyphs/stax_chain_846000_64px.gif similarity index 100% rename from glyphs/stax_id4good_64px.gif rename to glyphs/stax_chain_846000_64px.gif diff --git a/glyphs/stax_wanchain_64px.gif b/glyphs/stax_chain_888_64px.gif similarity index 100% rename from glyphs/stax_wanchain_64px.gif rename to glyphs/stax_chain_888_64px.gif diff --git a/glyphs/stax_tomochain_64px.gif b/glyphs/stax_chain_88_64px.gif similarity index 100% rename from glyphs/stax_tomochain_64px.gif rename to glyphs/stax_chain_88_64px.gif diff --git a/glyphs/stax_ubiq_64px.gif b/glyphs/stax_chain_8_64px.gif similarity index 100% rename from glyphs/stax_ubiq_64px.gif rename to glyphs/stax_chain_8_64px.gif diff --git a/glyphs/stax_chain_9001_64px.gif b/glyphs/stax_chain_9001_64px.gif new file mode 100644 index 000000000..a28246fbd Binary files /dev/null and b/glyphs/stax_chain_9001_64px.gif differ diff --git a/glyphs/stax_poa_64px.gif b/glyphs/stax_chain_99_64px.gif similarity index 100% rename from glyphs/stax_poa_64px.gif rename to glyphs/stax_chain_99_64px.gif diff --git a/glyphs/stax_kusd_64px.gif b/glyphs/stax_kusd_64px.gif deleted file mode 100644 index b18730662..000000000 Binary files a/glyphs/stax_kusd_64px.gif and /dev/null differ diff --git a/icons/nanos_app_ethereum.gif b/icons/nanos_app_chain_1.gif similarity index 100% rename from icons/nanos_app_ethereum.gif rename to icons/nanos_app_chain_1.gif diff --git a/icons/nanos_app_conflux_espace.gif b/icons/nanos_app_chain_1030.gif similarity index 100% rename from icons/nanos_app_conflux_espace.gif rename to icons/nanos_app_chain_1030.gif diff --git a/icons/nanos_app_thundercore.gif b/icons/nanos_app_chain_108.gif similarity index 100% rename from icons/nanos_app_thundercore.gif rename to icons/nanos_app_chain_108.gif diff --git a/icons/nanos_app_moonbeam.gif b/icons/nanos_app_chain_1284.gif similarity index 100% rename from icons/nanos_app_moonbeam.gif rename to icons/nanos_app_chain_1284.gif diff --git a/icons/nanos_app_moonriver.gif b/icons/nanos_app_chain_1285.gif similarity index 100% rename from icons/nanos_app_moonriver.gif rename to icons/nanos_app_chain_1285.gif diff --git a/icons/nanos_app_ether1.gif b/icons/nanos_app_chain_1313114.gif similarity index 100% rename from icons/nanos_app_ether1.gif rename to icons/nanos_app_chain_1313114.gif diff --git a/icons/nanos_app_polygon.gif b/icons/nanos_app_chain_137.gif similarity index 100% rename from icons/nanos_app_polygon.gif rename to icons/nanos_app_chain_137.gif diff --git a/icons/nanos_app_flare.gif b/icons/nanos_app_chain_14.gif similarity index 100% rename from icons/nanos_app_flare.gif rename to icons/nanos_app_chain_14.gif diff --git a/icons/nanos_app_flare_coston.gif b/icons/nanos_app_chain_16.gif similarity index 100% rename from icons/nanos_app_flare_coston.gif rename to icons/nanos_app_chain_16.gif diff --git a/icons/nanos_app_atheios.gif b/icons/nanos_app_chain_1620.gif similarity index 100% rename from icons/nanos_app_atheios.gif rename to icons/nanos_app_chain_1620.gif diff --git a/icons/nanos_app_cube.gif b/icons/nanos_app_chain_1818.gif similarity index 100% rename from icons/nanos_app_cube.gif rename to icons/nanos_app_chain_1818.gif diff --git a/icons/nanos_app_songbird.gif b/icons/nanos_app_chain_19.gif similarity index 100% rename from icons/nanos_app_songbird.gif rename to icons/nanos_app_chain_19.gif diff --git a/icons/nanos_app_ethergem.gif b/icons/nanos_app_chain_1987.gif similarity index 100% rename from icons/nanos_app_ethergem.gif rename to icons/nanos_app_chain_1987.gif diff --git a/icons/nanos_app_bttc.gif b/icons/nanos_app_chain_199.gif similarity index 100% rename from icons/nanos_app_bttc.gif rename to icons/nanos_app_chain_199.gif diff --git a/icons/nanos_app_expanse.gif b/icons/nanos_app_chain_2.gif similarity index 100% rename from icons/nanos_app_expanse.gif rename to icons/nanos_app_chain_2.gif diff --git a/icons/nanos_app_akroma.gif b/icons/nanos_app_chain_200625.gif similarity index 100% rename from icons/nanos_app_akroma.gif rename to icons/nanos_app_chain_200625.gif diff --git a/icons/nanos_app_tecracoin.gif b/icons/nanos_app_chain_20531811.gif similarity index 100% rename from icons/nanos_app_tecracoin.gif rename to icons/nanos_app_chain_20531811.gif diff --git a/icons/nanos_app_tecratestnet.gif b/icons/nanos_app_chain_20531812.gif similarity index 100% rename from icons/nanos_app_tecratestnet.gif rename to icons/nanos_app_chain_20531812.gif diff --git a/icons/nanos_app_dexon.gif b/icons/nanos_app_chain_237.gif similarity index 100% rename from icons/nanos_app_dexon.gif rename to icons/nanos_app_chain_237.gif diff --git a/icons/nanos_app_kardiachain.gif b/icons/nanos_app_chain_24.gif similarity index 100% rename from icons/nanos_app_kardiachain.gif rename to icons/nanos_app_chain_24.gif diff --git a/icons/nanos_app_webchain.gif b/icons/nanos_app_chain_24484.gif similarity index 100% rename from icons/nanos_app_webchain.gif rename to icons/nanos_app_chain_24484.gif diff --git a/icons/nanos_app_artis_sigma1.gif b/icons/nanos_app_chain_246529.gif similarity index 100% rename from icons/nanos_app_artis_sigma1.gif rename to icons/nanos_app_chain_246529.gif diff --git a/icons/nanos_app_artis_tau1.gif b/icons/nanos_app_chain_246785.gif similarity index 100% rename from icons/nanos_app_artis_tau1.gif rename to icons/nanos_app_chain_246785.gif diff --git a/icons/nanos_app_oasys.gif b/icons/nanos_app_chain_248.gif similarity index 100% rename from icons/nanos_app_oasys.gif rename to icons/nanos_app_chain_248.gif diff --git a/icons/nanos_app_hpb.gif b/icons/nanos_app_chain_269.gif similarity index 100% rename from icons/nanos_app_hpb.gif rename to icons/nanos_app_chain_269.gif diff --git a/icons/nanos_app_reosc.gif b/icons/nanos_app_chain_2894.gif similarity index 100% rename from icons/nanos_app_reosc.gif rename to icons/nanos_app_chain_2894.gif diff --git a/icons/nanos_app_goerli.gif b/icons/nanos_app_chain_3.gif similarity index 100% rename from icons/nanos_app_goerli.gif rename to icons/nanos_app_chain_3.gif diff --git a/icons/nanos_app_rsk.gif b/icons/nanos_app_chain_30.gif similarity index 100% rename from icons/nanos_app_rsk.gif rename to icons/nanos_app_chain_30.gif diff --git a/icons/nanos_app_rsk_testnet.gif b/icons/nanos_app_chain_31.gif similarity index 100% rename from icons/nanos_app_rsk_testnet.gif rename to icons/nanos_app_chain_31.gif diff --git a/icons/nanos_app_ethersocial.gif b/icons/nanos_app_chain_31102.gif similarity index 100% rename from icons/nanos_app_ethersocial.gif rename to icons/nanos_app_chain_31102.gif diff --git a/icons/nanos_app_pirl.gif b/icons/nanos_app_chain_3125659152.gif similarity index 100% rename from icons/nanos_app_pirl.gif rename to icons/nanos_app_chain_3125659152.gif diff --git a/icons/nanos_app_shiden.gif b/icons/nanos_app_chain_336.gif similarity index 100% rename from icons/nanos_app_shiden.gif rename to icons/nanos_app_chain_336.gif diff --git a/icons/nanos_app_tobalaba.gif b/icons/nanos_app_chain_401697.gif similarity index 100% rename from icons/nanos_app_tobalaba.gif rename to icons/nanos_app_chain_401697.gif diff --git a/icons/nanos_app_ropsten.gif b/icons/nanos_app_chain_5.gif similarity index 100% rename from icons/nanos_app_ropsten.gif rename to icons/nanos_app_chain_5.gif diff --git a/icons/nanos_app_apothemnetwork.gif b/icons/nanos_app_chain_50.gif similarity index 100% rename from icons/nanos_app_apothemnetwork.gif rename to icons/nanos_app_chain_50.gif diff --git a/icons/nanos_app_xdcnetwork.gif b/icons/nanos_app_chain_51.gif similarity index 100% rename from icons/nanos_app_xdcnetwork.gif rename to icons/nanos_app_chain_51.gif diff --git a/icons/nanos_app_bsc.gif b/icons/nanos_app_chain_56.gif similarity index 100% rename from icons/nanos_app_bsc.gif rename to icons/nanos_app_chain_56.gif diff --git a/icons/nanos_app_astar.gif b/icons/nanos_app_chain_592.gif similarity index 100% rename from icons/nanos_app_astar.gif rename to icons/nanos_app_chain_592.gif diff --git a/icons/nanos_app_gochain.gif b/icons/nanos_app_chain_60.gif similarity index 100% rename from icons/nanos_app_gochain.gif rename to icons/nanos_app_chain_60.gif diff --git a/icons/nanos_app_ethereum_classic.gif b/icons/nanos_app_chain_61.gif similarity index 100% rename from icons/nanos_app_ethereum_classic.gif rename to icons/nanos_app_chain_61.gif diff --git a/icons/nanos_app_multivac.gif b/icons/nanos_app_chain_62621.gif similarity index 100% rename from icons/nanos_app_multivac.gif rename to icons/nanos_app_chain_62621.gif diff --git a/icons/nanos_app_ellaism.gif b/icons/nanos_app_chain_64.gif similarity index 100% rename from icons/nanos_app_ellaism.gif rename to icons/nanos_app_chain_64.gif diff --git a/icons/nanos_app_okc.gif b/icons/nanos_app_chain_66.gif similarity index 100% rename from icons/nanos_app_okc.gif rename to icons/nanos_app_chain_66.gif diff --git a/icons/nanos_app_shyft.gif b/icons/nanos_app_chain_7341.gif similarity index 100% rename from icons/nanos_app_shyft.gif rename to icons/nanos_app_chain_7341.gif diff --git a/icons/nanos_app_volta.gif b/icons/nanos_app_chain_73799.gif similarity index 100% rename from icons/nanos_app_volta.gif rename to icons/nanos_app_chain_73799.gif diff --git a/icons/nanos_app_mix.gif b/icons/nanos_app_chain_76.gif similarity index 100% rename from icons/nanos_app_mix.gif rename to icons/nanos_app_chain_76.gif diff --git a/icons/nanos_app_musicoin.gif b/icons/nanos_app_chain_7762959.gif similarity index 100% rename from icons/nanos_app_musicoin.gif rename to icons/nanos_app_chain_7762959.gif diff --git a/icons/nanos_app_wethio.gif b/icons/nanos_app_chain_78.gif similarity index 100% rename from icons/nanos_app_wethio.gif rename to icons/nanos_app_chain_78.gif diff --git a/icons/nanos_app_ubiq.gif b/icons/nanos_app_chain_8.gif similarity index 100% rename from icons/nanos_app_ubiq.gif rename to icons/nanos_app_chain_8.gif diff --git a/icons/nanos_app_meter.gif b/icons/nanos_app_chain_82.gif similarity index 100% rename from icons/nanos_app_meter.gif rename to icons/nanos_app_chain_82.gif diff --git a/icons/nanos_app_callisto.gif b/icons/nanos_app_chain_820.gif similarity index 100% rename from icons/nanos_app_callisto.gif rename to icons/nanos_app_chain_820.gif diff --git a/icons/nanos_app_id4good.gif b/icons/nanos_app_chain_846000.gif similarity index 100% rename from icons/nanos_app_id4good.gif rename to icons/nanos_app_chain_846000.gif diff --git a/icons/nanos_app_tomochain.gif b/icons/nanos_app_chain_88.gif similarity index 100% rename from icons/nanos_app_tomochain.gif rename to icons/nanos_app_chain_88.gif diff --git a/icons/nanos_app_wanchain.gif b/icons/nanos_app_chain_888.gif similarity index 100% rename from icons/nanos_app_wanchain.gif rename to icons/nanos_app_chain_888.gif diff --git a/icons/nanos_app_poa.gif b/icons/nanos_app_chain_99.gif similarity index 100% rename from icons/nanos_app_poa.gif rename to icons/nanos_app_chain_99.gif diff --git a/icons/nanos_app_kusd.gif b/icons/nanos_app_kusd.gif deleted file mode 100644 index 8adc23bdd..000000000 Binary files a/icons/nanos_app_kusd.gif and /dev/null differ diff --git a/icons/nanox_app_ethereum.gif b/icons/nanox_app_chain_1.gif similarity index 100% rename from icons/nanox_app_ethereum.gif rename to icons/nanox_app_chain_1.gif diff --git a/icons/nanox_app_conflux_espace.gif b/icons/nanox_app_chain_1030.gif similarity index 100% rename from icons/nanox_app_conflux_espace.gif rename to icons/nanox_app_chain_1030.gif diff --git a/icons/nanox_app_thundercore.gif b/icons/nanox_app_chain_108.gif similarity index 100% rename from icons/nanox_app_thundercore.gif rename to icons/nanox_app_chain_108.gif diff --git a/icons/nanox_app_moonbeam.gif b/icons/nanox_app_chain_1284.gif similarity index 100% rename from icons/nanox_app_moonbeam.gif rename to icons/nanox_app_chain_1284.gif diff --git a/icons/nanox_app_moonriver.gif b/icons/nanox_app_chain_1285.gif similarity index 100% rename from icons/nanox_app_moonriver.gif rename to icons/nanox_app_chain_1285.gif diff --git a/icons/nanox_app_ether1.gif b/icons/nanox_app_chain_1313114.gif similarity index 100% rename from icons/nanox_app_ether1.gif rename to icons/nanox_app_chain_1313114.gif diff --git a/icons/nanox_app_polygon.gif b/icons/nanox_app_chain_137.gif similarity index 100% rename from icons/nanox_app_polygon.gif rename to icons/nanox_app_chain_137.gif diff --git a/icons/nanox_app_flare.gif b/icons/nanox_app_chain_14.gif similarity index 100% rename from icons/nanox_app_flare.gif rename to icons/nanox_app_chain_14.gif diff --git a/icons/nanox_app_flare_coston.gif b/icons/nanox_app_chain_16.gif similarity index 100% rename from icons/nanox_app_flare_coston.gif rename to icons/nanox_app_chain_16.gif diff --git a/icons/nanox_app_atheios.gif b/icons/nanox_app_chain_1620.gif similarity index 100% rename from icons/nanox_app_atheios.gif rename to icons/nanox_app_chain_1620.gif diff --git a/icons/nanox_app_cube.gif b/icons/nanox_app_chain_1818.gif similarity index 100% rename from icons/nanox_app_cube.gif rename to icons/nanox_app_chain_1818.gif diff --git a/icons/nanox_app_songbird.gif b/icons/nanox_app_chain_19.gif similarity index 100% rename from icons/nanox_app_songbird.gif rename to icons/nanox_app_chain_19.gif diff --git a/icons/nanox_app_ethergem.gif b/icons/nanox_app_chain_1987.gif similarity index 100% rename from icons/nanox_app_ethergem.gif rename to icons/nanox_app_chain_1987.gif diff --git a/icons/nanox_app_bttc.gif b/icons/nanox_app_chain_199.gif similarity index 100% rename from icons/nanox_app_bttc.gif rename to icons/nanox_app_chain_199.gif diff --git a/icons/nanox_app_expanse.gif b/icons/nanox_app_chain_2.gif similarity index 100% rename from icons/nanox_app_expanse.gif rename to icons/nanox_app_chain_2.gif diff --git a/icons/nanox_app_akroma.gif b/icons/nanox_app_chain_200625.gif similarity index 100% rename from icons/nanox_app_akroma.gif rename to icons/nanox_app_chain_200625.gif diff --git a/icons/nanox_app_tecracoin.gif b/icons/nanox_app_chain_20531811.gif similarity index 100% rename from icons/nanox_app_tecracoin.gif rename to icons/nanox_app_chain_20531811.gif diff --git a/icons/nanox_app_tecratestnet.gif b/icons/nanox_app_chain_20531812.gif similarity index 100% rename from icons/nanox_app_tecratestnet.gif rename to icons/nanox_app_chain_20531812.gif diff --git a/icons/nanox_app_dexon.gif b/icons/nanox_app_chain_237.gif similarity index 100% rename from icons/nanox_app_dexon.gif rename to icons/nanox_app_chain_237.gif diff --git a/icons/nanox_app_kardiachain.gif b/icons/nanox_app_chain_24.gif similarity index 100% rename from icons/nanox_app_kardiachain.gif rename to icons/nanox_app_chain_24.gif diff --git a/icons/nanox_app_webchain.gif b/icons/nanox_app_chain_24484.gif similarity index 100% rename from icons/nanox_app_webchain.gif rename to icons/nanox_app_chain_24484.gif diff --git a/icons/nanox_app_artis_sigma1.gif b/icons/nanox_app_chain_246529.gif similarity index 100% rename from icons/nanox_app_artis_sigma1.gif rename to icons/nanox_app_chain_246529.gif diff --git a/icons/nanox_app_artis_tau1.gif b/icons/nanox_app_chain_246785.gif similarity index 100% rename from icons/nanox_app_artis_tau1.gif rename to icons/nanox_app_chain_246785.gif diff --git a/icons/nanox_app_oasys.gif b/icons/nanox_app_chain_248.gif similarity index 100% rename from icons/nanox_app_oasys.gif rename to icons/nanox_app_chain_248.gif diff --git a/icons/nanox_app_hpb.gif b/icons/nanox_app_chain_269.gif similarity index 100% rename from icons/nanox_app_hpb.gif rename to icons/nanox_app_chain_269.gif diff --git a/icons/nanox_app_reosc.gif b/icons/nanox_app_chain_2894.gif similarity index 100% rename from icons/nanox_app_reosc.gif rename to icons/nanox_app_chain_2894.gif diff --git a/icons/nanox_app_goerli.gif b/icons/nanox_app_chain_3.gif similarity index 100% rename from icons/nanox_app_goerli.gif rename to icons/nanox_app_chain_3.gif diff --git a/icons/nanox_app_rsk.gif b/icons/nanox_app_chain_30.gif similarity index 100% rename from icons/nanox_app_rsk.gif rename to icons/nanox_app_chain_30.gif diff --git a/icons/nanox_app_rsk_testnet.gif b/icons/nanox_app_chain_31.gif similarity index 100% rename from icons/nanox_app_rsk_testnet.gif rename to icons/nanox_app_chain_31.gif diff --git a/icons/nanox_app_ethersocial.gif b/icons/nanox_app_chain_31102.gif similarity index 100% rename from icons/nanox_app_ethersocial.gif rename to icons/nanox_app_chain_31102.gif diff --git a/icons/nanox_app_pirl.gif b/icons/nanox_app_chain_3125659152.gif similarity index 100% rename from icons/nanox_app_pirl.gif rename to icons/nanox_app_chain_3125659152.gif diff --git a/icons/nanox_app_shiden.gif b/icons/nanox_app_chain_336.gif similarity index 100% rename from icons/nanox_app_shiden.gif rename to icons/nanox_app_chain_336.gif diff --git a/icons/nanox_app_ropsten.gif b/icons/nanox_app_chain_5.gif similarity index 100% rename from icons/nanox_app_ropsten.gif rename to icons/nanox_app_chain_5.gif diff --git a/icons/nanox_app_apothemnetwork.gif b/icons/nanox_app_chain_50.gif similarity index 100% rename from icons/nanox_app_apothemnetwork.gif rename to icons/nanox_app_chain_50.gif diff --git a/icons/nanox_app_xdcnetwork.gif b/icons/nanox_app_chain_51.gif similarity index 100% rename from icons/nanox_app_xdcnetwork.gif rename to icons/nanox_app_chain_51.gif diff --git a/icons/nanox_app_bsc.gif b/icons/nanox_app_chain_56.gif similarity index 100% rename from icons/nanox_app_bsc.gif rename to icons/nanox_app_chain_56.gif diff --git a/icons/nanox_app_astar.gif b/icons/nanox_app_chain_592.gif similarity index 100% rename from icons/nanox_app_astar.gif rename to icons/nanox_app_chain_592.gif diff --git a/icons/nanox_app_gochain.gif b/icons/nanox_app_chain_60.gif similarity index 100% rename from icons/nanox_app_gochain.gif rename to icons/nanox_app_chain_60.gif diff --git a/icons/nanox_app_ethereum_classic.gif b/icons/nanox_app_chain_61.gif similarity index 100% rename from icons/nanox_app_ethereum_classic.gif rename to icons/nanox_app_chain_61.gif diff --git a/icons/nanox_app_multivac.gif b/icons/nanox_app_chain_62621.gif similarity index 100% rename from icons/nanox_app_multivac.gif rename to icons/nanox_app_chain_62621.gif diff --git a/icons/nanox_app_ellaism.gif b/icons/nanox_app_chain_64.gif similarity index 100% rename from icons/nanox_app_ellaism.gif rename to icons/nanox_app_chain_64.gif diff --git a/icons/nanox_app_okc.gif b/icons/nanox_app_chain_66.gif similarity index 100% rename from icons/nanox_app_okc.gif rename to icons/nanox_app_chain_66.gif diff --git a/icons/nanox_app_shyft.gif b/icons/nanox_app_chain_7341.gif similarity index 100% rename from icons/nanox_app_shyft.gif rename to icons/nanox_app_chain_7341.gif diff --git a/icons/nanox_app_volta.gif b/icons/nanox_app_chain_73799.gif similarity index 100% rename from icons/nanox_app_volta.gif rename to icons/nanox_app_chain_73799.gif diff --git a/icons/nanox_app_mix.gif b/icons/nanox_app_chain_76.gif similarity index 100% rename from icons/nanox_app_mix.gif rename to icons/nanox_app_chain_76.gif diff --git a/icons/nanox_app_musicoin.gif b/icons/nanox_app_chain_7762959.gif similarity index 100% rename from icons/nanox_app_musicoin.gif rename to icons/nanox_app_chain_7762959.gif diff --git a/icons/nanox_app_wethio.gif b/icons/nanox_app_chain_78.gif similarity index 100% rename from icons/nanox_app_wethio.gif rename to icons/nanox_app_chain_78.gif diff --git a/icons/nanox_app_ubiq.gif b/icons/nanox_app_chain_8.gif similarity index 100% rename from icons/nanox_app_ubiq.gif rename to icons/nanox_app_chain_8.gif diff --git a/icons/nanox_app_meter.gif b/icons/nanox_app_chain_82.gif similarity index 100% rename from icons/nanox_app_meter.gif rename to icons/nanox_app_chain_82.gif diff --git a/icons/nanox_app_callisto.gif b/icons/nanox_app_chain_820.gif similarity index 100% rename from icons/nanox_app_callisto.gif rename to icons/nanox_app_chain_820.gif diff --git a/icons/nanox_app_id4good.gif b/icons/nanox_app_chain_846000.gif similarity index 100% rename from icons/nanox_app_id4good.gif rename to icons/nanox_app_chain_846000.gif diff --git a/icons/nanox_app_tomochain.gif b/icons/nanox_app_chain_88.gif similarity index 100% rename from icons/nanox_app_tomochain.gif rename to icons/nanox_app_chain_88.gif diff --git a/icons/nanox_app_wanchain.gif b/icons/nanox_app_chain_888.gif similarity index 100% rename from icons/nanox_app_wanchain.gif rename to icons/nanox_app_chain_888.gif diff --git a/icons/nanox_app_poa.gif b/icons/nanox_app_chain_99.gif similarity index 100% rename from icons/nanox_app_poa.gif rename to icons/nanox_app_chain_99.gif diff --git a/icons/nanox_app_kusd.gif b/icons/nanox_app_kusd.gif deleted file mode 100644 index 6c8d03b86..000000000 Binary files a/icons/nanox_app_kusd.gif and /dev/null differ diff --git a/icons/stax_app_ethereum.gif b/icons/stax_app_chain_1.gif similarity index 100% rename from icons/stax_app_ethereum.gif rename to icons/stax_app_chain_1.gif diff --git a/icons/stax_app_conflux_espace.gif b/icons/stax_app_chain_1030.gif similarity index 100% rename from icons/stax_app_conflux_espace.gif rename to icons/stax_app_chain_1030.gif diff --git a/icons/stax_app_thundercore.gif b/icons/stax_app_chain_108.gif similarity index 100% rename from icons/stax_app_thundercore.gif rename to icons/stax_app_chain_108.gif diff --git a/icons/stax_app_moonbeam.gif b/icons/stax_app_chain_1284.gif similarity index 100% rename from icons/stax_app_moonbeam.gif rename to icons/stax_app_chain_1284.gif diff --git a/icons/stax_app_moonriver.gif b/icons/stax_app_chain_1285.gif similarity index 100% rename from icons/stax_app_moonriver.gif rename to icons/stax_app_chain_1285.gif diff --git a/icons/stax_app_ether1.gif b/icons/stax_app_chain_1313114.gif similarity index 100% rename from icons/stax_app_ether1.gif rename to icons/stax_app_chain_1313114.gif diff --git a/icons/stax_app_polygon.gif b/icons/stax_app_chain_137.gif similarity index 100% rename from icons/stax_app_polygon.gif rename to icons/stax_app_chain_137.gif diff --git a/icons/stax_app_flare.gif b/icons/stax_app_chain_14.gif similarity index 100% rename from icons/stax_app_flare.gif rename to icons/stax_app_chain_14.gif diff --git a/icons/stax_app_flare_coston.gif b/icons/stax_app_chain_16.gif similarity index 100% rename from icons/stax_app_flare_coston.gif rename to icons/stax_app_chain_16.gif diff --git a/icons/stax_app_atheios.gif b/icons/stax_app_chain_1620.gif similarity index 100% rename from icons/stax_app_atheios.gif rename to icons/stax_app_chain_1620.gif diff --git a/icons/stax_app_cube.gif b/icons/stax_app_chain_1818.gif similarity index 100% rename from icons/stax_app_cube.gif rename to icons/stax_app_chain_1818.gif diff --git a/icons/stax_app_songbird.gif b/icons/stax_app_chain_19.gif similarity index 100% rename from icons/stax_app_songbird.gif rename to icons/stax_app_chain_19.gif diff --git a/icons/stax_app_ethergem.gif b/icons/stax_app_chain_1987.gif similarity index 100% rename from icons/stax_app_ethergem.gif rename to icons/stax_app_chain_1987.gif diff --git a/icons/stax_app_bttc.gif b/icons/stax_app_chain_199.gif similarity index 100% rename from icons/stax_app_bttc.gif rename to icons/stax_app_chain_199.gif diff --git a/icons/stax_app_expanse.gif b/icons/stax_app_chain_2.gif similarity index 100% rename from icons/stax_app_expanse.gif rename to icons/stax_app_chain_2.gif diff --git a/icons/stax_app_akroma.gif b/icons/stax_app_chain_200625.gif similarity index 100% rename from icons/stax_app_akroma.gif rename to icons/stax_app_chain_200625.gif diff --git a/icons/stax_app_tecracoin.gif b/icons/stax_app_chain_20531811.gif similarity index 100% rename from icons/stax_app_tecracoin.gif rename to icons/stax_app_chain_20531811.gif diff --git a/icons/stax_app_tecratestnet.gif b/icons/stax_app_chain_20531812.gif similarity index 100% rename from icons/stax_app_tecratestnet.gif rename to icons/stax_app_chain_20531812.gif diff --git a/icons/stax_app_dexon.gif b/icons/stax_app_chain_237.gif similarity index 100% rename from icons/stax_app_dexon.gif rename to icons/stax_app_chain_237.gif diff --git a/icons/stax_app_kardiachain.gif b/icons/stax_app_chain_24.gif similarity index 100% rename from icons/stax_app_kardiachain.gif rename to icons/stax_app_chain_24.gif diff --git a/icons/stax_app_webchain.gif b/icons/stax_app_chain_24484.gif similarity index 100% rename from icons/stax_app_webchain.gif rename to icons/stax_app_chain_24484.gif diff --git a/icons/stax_app_energywebchain.gif b/icons/stax_app_chain_246.gif similarity index 100% rename from icons/stax_app_energywebchain.gif rename to icons/stax_app_chain_246.gif diff --git a/icons/stax_app_artis_sigma1.gif b/icons/stax_app_chain_246529.gif similarity index 100% rename from icons/stax_app_artis_sigma1.gif rename to icons/stax_app_chain_246529.gif diff --git a/icons/stax_app_artis_tau1.gif b/icons/stax_app_chain_246785.gif similarity index 100% rename from icons/stax_app_artis_tau1.gif rename to icons/stax_app_chain_246785.gif diff --git a/icons/stax_app_oasys.gif b/icons/stax_app_chain_248.gif similarity index 100% rename from icons/stax_app_oasys.gif rename to icons/stax_app_chain_248.gif diff --git a/icons/stax_app_hpb.gif b/icons/stax_app_chain_269.gif similarity index 100% rename from icons/stax_app_hpb.gif rename to icons/stax_app_chain_269.gif diff --git a/icons/stax_app_reosc.gif b/icons/stax_app_chain_2894.gif similarity index 100% rename from icons/stax_app_reosc.gif rename to icons/stax_app_chain_2894.gif diff --git a/icons/stax_app_ropsten.gif b/icons/stax_app_chain_3.gif similarity index 100% rename from icons/stax_app_ropsten.gif rename to icons/stax_app_chain_3.gif diff --git a/icons/stax_app_rsk.gif b/icons/stax_app_chain_30.gif similarity index 100% rename from icons/stax_app_rsk.gif rename to icons/stax_app_chain_30.gif diff --git a/icons/stax_app_rsk_testnet.gif b/icons/stax_app_chain_31.gif similarity index 100% rename from icons/stax_app_rsk_testnet.gif rename to icons/stax_app_chain_31.gif diff --git a/icons/stax_app_ethersocial.gif b/icons/stax_app_chain_31102.gif similarity index 100% rename from icons/stax_app_ethersocial.gif rename to icons/stax_app_chain_31102.gif diff --git a/icons/stax_app_pirl.gif b/icons/stax_app_chain_3125659152.gif similarity index 100% rename from icons/stax_app_pirl.gif rename to icons/stax_app_chain_3125659152.gif diff --git a/icons/stax_app_shiden.gif b/icons/stax_app_chain_336.gif similarity index 100% rename from icons/stax_app_shiden.gif rename to icons/stax_app_chain_336.gif diff --git a/icons/stax_app_tobalaba.gif b/icons/stax_app_chain_401697.gif similarity index 100% rename from icons/stax_app_tobalaba.gif rename to icons/stax_app_chain_401697.gif diff --git a/icons/stax_app_goerli.gif b/icons/stax_app_chain_5.gif similarity index 100% rename from icons/stax_app_goerli.gif rename to icons/stax_app_chain_5.gif diff --git a/icons/stax_app_xdcnetwork.gif b/icons/stax_app_chain_50.gif similarity index 100% rename from icons/stax_app_xdcnetwork.gif rename to icons/stax_app_chain_50.gif diff --git a/icons/stax_app_apothemnetwork.gif b/icons/stax_app_chain_51.gif similarity index 100% rename from icons/stax_app_apothemnetwork.gif rename to icons/stax_app_chain_51.gif diff --git a/icons/stax_app_bsc.gif b/icons/stax_app_chain_56.gif similarity index 100% rename from icons/stax_app_bsc.gif rename to icons/stax_app_chain_56.gif diff --git a/icons/stax_app_astar.gif b/icons/stax_app_chain_592.gif similarity index 100% rename from icons/stax_app_astar.gif rename to icons/stax_app_chain_592.gif diff --git a/icons/stax_app_gochain.gif b/icons/stax_app_chain_60.gif similarity index 100% rename from icons/stax_app_gochain.gif rename to icons/stax_app_chain_60.gif diff --git a/icons/stax_app_ethereum_classic.gif b/icons/stax_app_chain_61.gif similarity index 100% rename from icons/stax_app_ethereum_classic.gif rename to icons/stax_app_chain_61.gif diff --git a/icons/stax_app_multivac.gif b/icons/stax_app_chain_62621.gif similarity index 100% rename from icons/stax_app_multivac.gif rename to icons/stax_app_chain_62621.gif diff --git a/icons/stax_app_ellaism.gif b/icons/stax_app_chain_64.gif similarity index 100% rename from icons/stax_app_ellaism.gif rename to icons/stax_app_chain_64.gif diff --git a/icons/stax_app_okc.gif b/icons/stax_app_chain_66.gif similarity index 100% rename from icons/stax_app_okc.gif rename to icons/stax_app_chain_66.gif diff --git a/icons/stax_app_shyft.gif b/icons/stax_app_chain_7341.gif similarity index 100% rename from icons/stax_app_shyft.gif rename to icons/stax_app_chain_7341.gif diff --git a/icons/stax_app_volta.gif b/icons/stax_app_chain_73799.gif similarity index 100% rename from icons/stax_app_volta.gif rename to icons/stax_app_chain_73799.gif diff --git a/icons/stax_app_mix.gif b/icons/stax_app_chain_76.gif similarity index 100% rename from icons/stax_app_mix.gif rename to icons/stax_app_chain_76.gif diff --git a/icons/stax_app_musicoin.gif b/icons/stax_app_chain_7762959.gif similarity index 100% rename from icons/stax_app_musicoin.gif rename to icons/stax_app_chain_7762959.gif diff --git a/icons/stax_app_wethio.gif b/icons/stax_app_chain_78.gif similarity index 100% rename from icons/stax_app_wethio.gif rename to icons/stax_app_chain_78.gif diff --git a/icons/stax_app_ubiq.gif b/icons/stax_app_chain_8.gif similarity index 100% rename from icons/stax_app_ubiq.gif rename to icons/stax_app_chain_8.gif diff --git a/icons/stax_app_meter.gif b/icons/stax_app_chain_82.gif similarity index 100% rename from icons/stax_app_meter.gif rename to icons/stax_app_chain_82.gif diff --git a/icons/stax_app_callisto.gif b/icons/stax_app_chain_820.gif similarity index 100% rename from icons/stax_app_callisto.gif rename to icons/stax_app_chain_820.gif diff --git a/icons/stax_app_id4good.gif b/icons/stax_app_chain_846000.gif similarity index 100% rename from icons/stax_app_id4good.gif rename to icons/stax_app_chain_846000.gif diff --git a/icons/stax_app_tomochain.gif b/icons/stax_app_chain_88.gif similarity index 100% rename from icons/stax_app_tomochain.gif rename to icons/stax_app_chain_88.gif diff --git a/icons/stax_app_wanchain.gif b/icons/stax_app_chain_888.gif similarity index 100% rename from icons/stax_app_wanchain.gif rename to icons/stax_app_chain_888.gif diff --git a/icons/stax_app_poa.gif b/icons/stax_app_chain_99.gif similarity index 100% rename from icons/stax_app_poa.gif rename to icons/stax_app_chain_99.gif diff --git a/icons/stax_app_kusd.gif b/icons/stax_app_kusd.gif deleted file mode 100644 index 18b1a1c5e..000000000 Binary files a/icons/stax_app_kusd.gif and /dev/null differ diff --git a/ledger_app.toml b/ledger_app.toml new file mode 100644 index 000000000..5c2fe3020 --- /dev/null +++ b/ledger_app.toml @@ -0,0 +1,13 @@ +[app] +build_directory = "./" +sdk = "C" +devices = ["nanos", "nanox", "nanos+", "stax"] + +[use_cases] # Coherent build options that make sense for your application +debug = "DEBUG=1" +use_test_keys = "DEBUG=1 CAL_TEST_KEY=1 DOMAIN_NAME_TEST_KEY=1 SET_PLUGIN_TEST_KEY=1 NFT_TEST_KEY=1" +cal_bypass = "DEBUG=1 BYPASS_SIGNATURES=1" + +[tests] +unit_directory = "./tests/unit" +pytest_directory = "./tests/ragger" diff --git a/makefile_conf/chain/akroma.mk b/makefile_conf/chain/akroma.mk index 27d91e109..68c935fa4 100644 --- a/makefile_conf/chain/akroma.mk +++ b/makefile_conf/chain/akroma.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/200625'" -DEFINES += CHAINID_UPCASE=\"AKA\" CHAINID_COINNAME=\"AKA\" CHAIN_KIND=CHAIN_KIND_AKROMA CHAIN_ID=200625 +TICKER = "AKA" +CHAIN_ID = 200625 APPNAME = "Akroma" \ No newline at end of file diff --git a/makefile_conf/chain/apothemnetwork.mk b/makefile_conf/chain/apothemnetwork.mk index 23816b5ab..57dc45ba5 100644 --- a/makefile_conf/chain/apothemnetwork.mk +++ b/makefile_conf/chain/apothemnetwork.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/550'" -DEFINES += CHAINID_UPCASE=\"APOTHEMNETWORK\" CHAINID_COINNAME=\"TXDC\" CHAIN_KIND=CHAIN_KIND_APOTHEMNETWORK CHAIN_ID=51 +TICKER = "TXDC" +CHAIN_ID = 51 APPNAME = "ApothemNetwork" diff --git a/makefile_conf/chain/artis_sigma1.mk b/makefile_conf/chain/artis_sigma1.mk index 2170e486c..766bd321c 100644 --- a/makefile_conf/chain/artis_sigma1.mk +++ b/makefile_conf/chain/artis_sigma1.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/246529'" -DEFINES += CHAINID_UPCASE=\"ARTISSIGMA1\" CHAINID_COINNAME=\"ATS\" CHAIN_KIND=CHAIN_KIND_ARTIS_SIGMA1 CHAIN_ID=246529 +TICKER = "ATS" +CHAIN_ID = 246529 APPNAME = "ARTIS sigma1" \ No newline at end of file diff --git a/makefile_conf/chain/artis_tau1.mk b/makefile_conf/chain/artis_tau1.mk index 3316dc2c8..dd0d981ae 100644 --- a/makefile_conf/chain/artis_tau1.mk +++ b/makefile_conf/chain/artis_tau1.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/246785'" -DEFINES += CHAINID_UPCASE=\"ARTISTAU1\" CHAINID_COINNAME=\"ATS\" CHAIN_KIND=CHAIN_KIND_ARTIS_TAU1 CHAIN_ID=246785 +TICKER = "ATS" +CHAIN_ID = 246785 APPNAME = "ARTIS tau1" \ No newline at end of file diff --git a/makefile_conf/chain/astar.mk b/makefile_conf/chain/astar.mk index 0f8bbe934..8914d3800 100644 --- a/makefile_conf/chain/astar.mk +++ b/makefile_conf/chain/astar.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/810'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"ASTAR\" CHAINID_COINNAME=\"ASTR\" CHAIN_KIND=CHAIN_KIND_ASTAR CHAIN_ID=592 -APPNAME = "Astar EVM" +TICKER = "ASTR" +CHAIN_ID = 592 +APPNAME = "Astar Polkadot EVM" diff --git a/makefile_conf/chain/atheios.mk b/makefile_conf/chain/atheios.mk index 111852dbd..e7e9ef555 100644 --- a/makefile_conf/chain/atheios.mk +++ b/makefile_conf/chain/atheios.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/1620'" -DEFINES += CHAINID_UPCASE=\"ATHEIOS\" CHAINID_COINNAME=\"ATH\" CHAIN_KIND=CHAIN_KIND_ATHEIOS CHAIN_ID=1620 +TICKER = "ATH" +CHAIN_ID = 1620 APPNAME = "Atheios" \ No newline at end of file diff --git a/makefile_conf/chain/bsc.mk b/makefile_conf/chain/bsc.mk index 7c8f00d85..dc70e0bcc 100644 --- a/makefile_conf/chain/bsc.mk +++ b/makefile_conf/chain/bsc.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"BSC\" CHAINID_COINNAME=\"BNB\" CHAIN_KIND=CHAIN_KIND_BSC CHAIN_ID=56 +TICKER = "BNB" +CHAIN_ID = 56 APPNAME = "Binance Smart Chain" \ No newline at end of file diff --git a/makefile_conf/chain/bttc.mk b/makefile_conf/chain/bttc.mk index af96c73bf..9e82b675e 100644 --- a/makefile_conf/chain/bttc.mk +++ b/makefile_conf/chain/bttc.mk @@ -1,3 +1,4 @@ -APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"BTTC\" CHAINID_COINNAME=\"BTT\" CHAIN_KIND=CHAIN_KIND_BTTC CHAIN_ID=199 +APP_LOAD_PARAMS += --path "44'/60'" +TICKER = "BTT" +CHAIN_ID = 199 APPNAME = "BTTC" \ No newline at end of file diff --git a/makefile_conf/chain/callisto.mk b/makefile_conf/chain/callisto.mk index ec068db87..1147dc9c8 100644 --- a/makefile_conf/chain/callisto.mk +++ b/makefile_conf/chain/callisto.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/820'" -DEFINES += CHAINID_UPCASE=\"CALLISTO\" CHAINID_COINNAME=\"CLO\" CHAIN_KIND=CHAIN_KIND_CALLISTO CHAIN_ID=820 +TICKER = "CLO" +CHAIN_ID = 820 APPNAME = "Callisto" \ No newline at end of file diff --git a/makefile_conf/chain/conflux_espace.mk b/makefile_conf/chain/conflux_espace.mk index ba6728944..6efc293af 100644 --- a/makefile_conf/chain/conflux_espace.mk +++ b/makefile_conf/chain/conflux_espace.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"CONFLUX\" CHAINID_COINNAME=\"CFX\" CHAIN_KIND=CHAIN_KIND_CONFLUX_ESPACE CHAIN_ID=1030 +TICKER = "CFX" +CHAIN_ID = 1030 APPNAME = "Conflux eSpace" \ No newline at end of file diff --git a/makefile_conf/chain/cube.mk b/makefile_conf/chain/cube.mk index 6eff7742f..7ac424cf6 100644 --- a/makefile_conf/chain/cube.mk +++ b/makefile_conf/chain/cube.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"CUBE\" CHAINID_COINNAME=\"CUBE\" CHAIN_KIND=CHAIN_KIND_CUBE CHAIN_ID=1818 +TICKER = "CUBE" +CHAIN_ID = 1818 APPNAME = "Cube" \ No newline at end of file diff --git a/makefile_conf/chain/dexon.mk b/makefile_conf/chain/dexon.mk index 9d9a4a5bb..c892e3533 100644 --- a/makefile_conf/chain/dexon.mk +++ b/makefile_conf/chain/dexon.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/237'" -DEFINES += CHAINID_UPCASE=\"DEXON\" CHAINID_COINNAME=\"DXN\" CHAIN_KIND=CHAIN_KIND_DEXON CHAIN_ID=237 +TICKER = "DXN" +CHAIN_ID = 237 APPNAME = "DEXON" \ No newline at end of file diff --git a/makefile_conf/chain/ellaism.mk b/makefile_conf/chain/ellaism.mk index c47ad84b0..1bd55896d 100644 --- a/makefile_conf/chain/ellaism.mk +++ b/makefile_conf/chain/ellaism.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/163'" -DEFINES += CHAINID_UPCASE=\"ELLA\" CHAINID_COINNAME=\"ELLA\" CHAIN_KIND=CHAIN_KIND_ELLAISM CHAIN_ID=64 +TICKER = "ELLA" +CHAIN_ID = 64 APPNAME = "Ellaism" \ No newline at end of file diff --git a/makefile_conf/chain/energywebchain.mk b/makefile_conf/chain/energywebchain.mk index 1024857d0..6de07e2c3 100644 --- a/makefile_conf/chain/energywebchain.mk +++ b/makefile_conf/chain/energywebchain.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/246'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"ENERGYWEBCHAIN\" CHAINID_COINNAME=\"EWT\" CHAIN_KIND=CHAIN_KIND_ENERGYWEBCHAIN CHAIN_ID=246 +TICKER = "EWT" +CHAIN_ID = 246 APPNAME = "EnergyWebChain" diff --git a/makefile_conf/chain/ether1.mk b/makefile_conf/chain/ether1.mk index 21b9a9ff0..9efc01588 100644 --- a/makefile_conf/chain/ether1.mk +++ b/makefile_conf/chain/ether1.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/1313114'" -DEFINES += CHAINID_UPCASE=\"ETHER1\" CHAINID_COINNAME=\"ETHO\" CHAIN_KIND=CHAIN_KIND_ETHER1 CHAIN_ID=1313114 +TICKER = "ETHO" +CHAIN_ID = 1313114 APPNAME = "Ether-1" \ No newline at end of file diff --git a/makefile_conf/chain/ethereum.mk b/makefile_conf/chain/ethereum.mk index 73c0c163a..993c9306d 100644 --- a/makefile_conf/chain/ethereum.mk +++ b/makefile_conf/chain/ethereum.mk @@ -1,13 +1,11 @@ # Lock the application on its standard path for 1.5. Please complain if non compliant APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"ETHEREUM\" CHAINID_COINNAME=\"ETH\" CHAIN_KIND=CHAIN_KIND_ETHEREUM CHAIN_ID=1 -# Starkware integration -APP_LOAD_PARAMS += --path "2645'/579218131'" -DEFINES += HAVE_STARKWARE -DEFINES += STARK_BIP32_PATH_0=0x80000A55 STARK_BIP32_PATH_1=0xA2862AD3 +TICKER = "ETH" +CHAIN_ID = 1 # Allow to derive ETH 2 public keys APP_LOAD_PARAMS += --path "12381/3600" --curve bls12381g1 DEFINES += HAVE_ETH2 APPNAME = "Ethereum" DEFINES_LIB= -APP_LOAD_FLAGS=--appFlags 0xa40 \ No newline at end of file +DEFINES += HAVE_BOLOS_APP_STACK_CANARY +APP_LOAD_FLAGS=--appFlags 0xa40 diff --git a/makefile_conf/chain/ethereum_classic.mk b/makefile_conf/chain/ethereum_classic.mk index 2c72c664c..ac44b6ab5 100644 --- a/makefile_conf/chain/ethereum_classic.mk +++ b/makefile_conf/chain/ethereum_classic.mk @@ -1,4 +1,5 @@ # Also allows ETC to access the ETH derivation path to recover forked assets APP_LOAD_PARAMS += --path "44'/61'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"ETC\" CHAINID_COINNAME=\"ETC\" CHAIN_KIND=CHAIN_KIND_ETHEREUM_CLASSIC CHAIN_ID=61 +TICKER = "ETC" +CHAIN_ID = 61 APPNAME = "Ethereum Classic" \ No newline at end of file diff --git a/makefile_conf/chain/ethergem.mk b/makefile_conf/chain/ethergem.mk index 6eeb421b4..6c819762b 100644 --- a/makefile_conf/chain/ethergem.mk +++ b/makefile_conf/chain/ethergem.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/1987'" -DEFINES += CHAINID_UPCASE=\"ETHERGEM\" CHAINID_COINNAME=\"EGEM\" CHAIN_KIND=CHAIN_KIND_ETHERGEM CHAIN_ID=1987 +TICKER = "EGEM" +CHAIN_ID = 1987 APPNAME = "EtherGem" \ No newline at end of file diff --git a/makefile_conf/chain/ethersocial.mk b/makefile_conf/chain/ethersocial.mk index cbba79577..bbf512c76 100644 --- a/makefile_conf/chain/ethersocial.mk +++ b/makefile_conf/chain/ethersocial.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/31102'" -DEFINES += CHAINID_UPCASE=\"ETHERSOCIAL\" CHAINID_COINNAME=\"ESN\" CHAIN_KIND=CHAIN_KIND_ETHERSOCIAL CHAIN_ID=31102 +TICKER = "ESN" +CHAIN_ID = 31102 APPNAME = "Ethersocial" \ No newline at end of file diff --git a/makefile_conf/chain/expanse.mk b/makefile_conf/chain/expanse.mk index 36226ef9a..f2ee9952e 100644 --- a/makefile_conf/chain/expanse.mk +++ b/makefile_conf/chain/expanse.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/40'" -DEFINES += CHAINID_UPCASE=\"EXPANSE\" CHAINID_COINNAME=\"EXP\" CHAIN_KIND=CHAIN_KIND_EXPANSE CHAIN_ID=2 +TICKER = "EXP" +CHAIN_ID = 2 APPNAME = "Expanse" \ No newline at end of file diff --git a/makefile_conf/chain/flare.mk b/makefile_conf/chain/flare.mk index 565b5bb71..36339eea1 100644 --- a/makefile_conf/chain/flare.mk +++ b/makefile_conf/chain/flare.mk @@ -1,5 +1,6 @@ APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"FLARE\" CHAINID_COINNAME=\"FLR\" CHAIN_KIND=CHAIN_KIND_FLARE CHAIN_ID=14 +TICKER = "FLR" +CHAIN_ID = 14 # Pending review parameters APP_LOAD_PARAMS += --tlvraw 9F:01 diff --git a/makefile_conf/chain/flare_coston.mk b/makefile_conf/chain/flare_coston.mk index f546f00a8..0d6bddf5d 100644 --- a/makefile_conf/chain/flare_coston.mk +++ b/makefile_conf/chain/flare_coston.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"FLARE\" CHAINID_COINNAME=\"FLR\" CHAIN_KIND=CHAIN_KIND_FLARE CHAIN_ID=16 +TICKER = "FLR" +CHAIN_ID = 16 APPNAME = "Flare Coston" \ No newline at end of file diff --git a/makefile_conf/chain/gochain.mk b/makefile_conf/chain/gochain.mk index eca804c6c..180b2fd67 100644 --- a/makefile_conf/chain/gochain.mk +++ b/makefile_conf/chain/gochain.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/6060'" -DEFINES += CHAINID_UPCASE=\"GOCHAIN\" CHAINID_COINNAME=\"GO\" CHAIN_KIND=CHAIN_KIND_GOCHAIN CHAIN_ID=60 +TICKER = "GO" +CHAIN_ID = 60 APPNAME = "GoChain" \ No newline at end of file diff --git a/makefile_conf/chain/goerli.mk b/makefile_conf/chain/goerli.mk index fe6bd8815..c01e6c9b8 100644 --- a/makefile_conf/chain/goerli.mk +++ b/makefile_conf/chain/goerli.mk @@ -1,14 +1,10 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"ETHEREUM\" CHAINID_COINNAME=\"ETH\" CHAIN_KIND=CHAIN_KIND_ETHEREUM CHAIN_ID=5 -# Starkware integration -APP_LOAD_PARAMS += --path "2645'/579218131'" -DEFINES += HAVE_STARKWARE -# Keep for Starkware Goerli tests -DEFINES += HAVE_TOKENS_EXTRA_LIST -DEFINES += STARK_BIP32_PATH_0=0x80000A55 STARK_BIP32_PATH_1=0xA2862AD3 +TICKER = "ETH" +CHAIN_ID = 5 # Allow to derive ETH 2 public keys APP_LOAD_PARAMS += --path "12381/3600" --curve bls12381g1 DEFINES += HAVE_ETH2 APPNAME = "Eth Goerli" DEFINES_LIB= -APP_LOAD_FLAGS=--appFlags 0xa40 \ No newline at end of file +DEFINES += HAVE_BOLOS_APP_STACK_CANARY +APP_LOAD_FLAGS=--appFlags 0xa40 diff --git a/makefile_conf/chain/hpb.mk b/makefile_conf/chain/hpb.mk index 475abf2ea..60fb3c137 100644 --- a/makefile_conf/chain/hpb.mk +++ b/makefile_conf/chain/hpb.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/269'" -DEFINES += CHAINID_UPCASE=\"HPB\" CHAINID_COINNAME=\"HPB\" CHAIN_KIND=CHAIN_KIND_HPB CHAIN_ID=269 +TICKER = "HPB" +CHAIN_ID = 269 APPNAME = "HPB" \ No newline at end of file diff --git a/makefile_conf/chain/id4good.mk b/makefile_conf/chain/id4good.mk index 57a50cb34..4abac3043 100644 --- a/makefile_conf/chain/id4good.mk +++ b/makefile_conf/chain/id4good.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/161803'" -DEFINES += CHAINID_UPCASE=\"ID4GOOD\" CHAINID_COINNAME=\"A4G\" CHAIN_KIND=CHAIN_KIND_ID4GOOD CHAIN_ID=846000 +TICKER = "A4G" +CHAIN_ID = 846000 APPNAME = "ID4Good" diff --git a/makefile_conf/chain/kardiachain.mk b/makefile_conf/chain/kardiachain.mk index bff1af84f..cc76d38d6 100644 --- a/makefile_conf/chain/kardiachain.mk +++ b/makefile_conf/chain/kardiachain.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"KARDIACHAIN\" CHAINID_COINNAME=\"KAI\" CHAIN_KIND=CHAIN_KIND_KARDIACHAIN CHAIN_ID=24 +TICKER = "KAI" +CHAIN_ID = 24 APPNAME = "KardiaChain" \ No newline at end of file diff --git a/makefile_conf/chain/kusd.mk b/makefile_conf/chain/kusd.mk deleted file mode 100644 index 38cf6cd53..000000000 --- a/makefile_conf/chain/kusd.mk +++ /dev/null @@ -1,3 +0,0 @@ -APP_LOAD_PARAMS += --path "44'/91927009'" -DEFINES += CHAINID_UPCASE=\"KUSD\" CHAINID_COINNAME=\"KUSD\" CHAIN_KIND=CHAIN_KIND_KUSD CHAIN_ID=1 -APPNAME = "kUSD" \ No newline at end of file diff --git a/makefile_conf/chain/meter.mk b/makefile_conf/chain/meter.mk index fcf2f364f..2a7412013 100644 --- a/makefile_conf/chain/meter.mk +++ b/makefile_conf/chain/meter.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"METER\" CHAINID_COINNAME=\"MTR\" CHAIN_KIND=CHAIN_KIND_METER CHAIN_ID=82 +TICKER = "MTR" +CHAIN_ID = 82 APPNAME = "Meter" \ No newline at end of file diff --git a/makefile_conf/chain/mix.mk b/makefile_conf/chain/mix.mk index 0c9264af7..c180cc90b 100644 --- a/makefile_conf/chain/mix.mk +++ b/makefile_conf/chain/mix.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/76'" -DEFINES += CHAINID_UPCASE=\"MIX\" CHAINID_COINNAME=\"MIX\" CHAIN_KIND=CHAIN_KIND_MIX CHAIN_ID=76 +TICKER = "MIX" +CHAIN_ID = 76 APPNAME = "Mix" \ No newline at end of file diff --git a/makefile_conf/chain/moonbeam.mk b/makefile_conf/chain/moonbeam.mk index c243367ea..5822f8f1f 100644 --- a/makefile_conf/chain/moonbeam.mk +++ b/makefile_conf/chain/moonbeam.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" --path "44'/1284'" -DEFINES += CHAINID_UPCASE=\"MOONBEAM\" CHAINID_COINNAME=\"GLMR\" CHAIN_KIND=CHAIN_KIND_MOONBEAM CHAIN_ID=1284 +TICKER = "GLMR" +CHAIN_ID = 1284 APPNAME = "Moonbeam" \ No newline at end of file diff --git a/makefile_conf/chain/moonriver.mk b/makefile_conf/chain/moonriver.mk index 02341311f..441371573 100644 --- a/makefile_conf/chain/moonriver.mk +++ b/makefile_conf/chain/moonriver.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" --path "44'/1285'" -DEFINES += CHAINID_UPCASE=\"MOONRIVER\" CHAINID_COINNAME=\"MOVR\" CHAIN_KIND=CHAIN_KIND_MOONRIVER CHAIN_ID=1285 +TICKER = "MOVR" +CHAIN_ID = 1285 APPNAME = "Moonriver" \ No newline at end of file diff --git a/makefile_conf/chain/multivac.mk b/makefile_conf/chain/multivac.mk index 043299b43..c5b527047 100644 --- a/makefile_conf/chain/multivac.mk +++ b/makefile_conf/chain/multivac.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"MULTIVAC\" CHAINID_COINNAME=\"MTV\" CHAIN_KIND=CHAIN_KIND_MULTIVAC CHAIN_ID=62621 +TICKER = "MTV" +CHAIN_ID = 62621 APPNAME = "MultiVAC" diff --git a/makefile_conf/chain/musicoin.mk b/makefile_conf/chain/musicoin.mk index 46ede3997..188bebb6e 100644 --- a/makefile_conf/chain/musicoin.mk +++ b/makefile_conf/chain/musicoin.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/184'" -DEFINES += CHAINID_UPCASE=\"MUSICOIN\" CHAINID_COINNAME=\"MUSIC\" CHAIN_KIND=CHAIN_KIND_MUSICOIN CHAIN_ID=7762959 +TICKER = "MUSIC" +CHAIN_ID = 7762959 APPNAME = "Musicoin" \ No newline at end of file diff --git a/makefile_conf/chain/oasys.mk b/makefile_conf/chain/oasys.mk index 0e2dc183d..7fc384faf 100644 --- a/makefile_conf/chain/oasys.mk +++ b/makefile_conf/chain/oasys.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/685'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"OASYS\" CHAINID_COINNAME=\"OAS\" CHAIN_KIND=CHAIN_KIND_OASYS CHAIN_ID=248 +TICKER = "OAS" +CHAIN_ID = 248 APPNAME = "Oasys" diff --git a/makefile_conf/chain/okc.mk b/makefile_conf/chain/okc.mk index d520276d4..6ed8042b3 100644 --- a/makefile_conf/chain/okc.mk +++ b/makefile_conf/chain/okc.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"OKC\" CHAINID_COINNAME=\"OKT\" CHAIN_KIND=CHAIN_KIND_OKC CHAIN_ID=66 +TICKER = "OKT" +CHAIN_ID = 66 APPNAME = "OKXChain" \ No newline at end of file diff --git a/makefile_conf/chain/pirl.mk b/makefile_conf/chain/pirl.mk index e4a73e497..3f30261cb 100644 --- a/makefile_conf/chain/pirl.mk +++ b/makefile_conf/chain/pirl.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/164'" -DEFINES += CHAINID_UPCASE=\"PIRL\" CHAINID_COINNAME=\"PIRL\" CHAIN_KIND=CHAIN_KIND_PIRL CHAIN_ID=3125659152 +TICKER = "PIRL" +CHAIN_ID = 3125659152 APPNAME = "Pirl" \ No newline at end of file diff --git a/makefile_conf/chain/poa.mk b/makefile_conf/chain/poa.mk index 6526b2b7d..c415c2640 100644 --- a/makefile_conf/chain/poa.mk +++ b/makefile_conf/chain/poa.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"POA\" CHAINID_COINNAME=\"POA\" CHAIN_KIND=CHAIN_KIND_POA CHAIN_ID=99 +TICKER = "POA" +CHAIN_ID = 99 APPNAME = "POA" \ No newline at end of file diff --git a/makefile_conf/chain/polygon.mk b/makefile_conf/chain/polygon.mk index c6f6e0f96..9bdf2dc60 100644 --- a/makefile_conf/chain/polygon.mk +++ b/makefile_conf/chain/polygon.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"POLYGON\" CHAINID_COINNAME=\"MATIC\" CHAIN_KIND=CHAIN_KIND_POLYGON CHAIN_ID=137 +TICKER = "MATIC" +CHAIN_ID = 137 APPNAME = "Polygon" \ No newline at end of file diff --git a/makefile_conf/chain/reosc.mk b/makefile_conf/chain/reosc.mk index 256d37fe2..9f9cedfbd 100644 --- a/makefile_conf/chain/reosc.mk +++ b/makefile_conf/chain/reosc.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/2894'" -DEFINES += CHAINID_UPCASE=\"REOSC\" CHAINID_COINNAME=\"REOSC\" CHAIN_KIND=CHAIN_KIND_REOSC CHAIN_ID=2894 +TICKER = "REOSC" +CHAIN_ID = 2894 APPNAME = "REOSC" \ No newline at end of file diff --git a/makefile_conf/chain/ropsten.mk b/makefile_conf/chain/ropsten.mk index 384d18b9e..d709186f8 100644 --- a/makefile_conf/chain/ropsten.mk +++ b/makefile_conf/chain/ropsten.mk @@ -1,14 +1,10 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"ETHEREUM\" CHAINID_COINNAME=\"ETH\" CHAIN_KIND=CHAIN_KIND_ETHEREUM CHAIN_ID=3 -# Starkware integration -APP_LOAD_PARAMS += --path "2645'/579218131'" -DEFINES += HAVE_STARKWARE -# Keep for Starkware Ropsten tests -DEFINES += HAVE_TOKENS_EXTRA_LIST -DEFINES += STARK_BIP32_PATH_0=0x80000A55 STARK_BIP32_PATH_1=0xA2862AD3 +TICKER = "ETH" +CHAIN_ID = 3 # Allow to derive ETH 2 public keys APP_LOAD_PARAMS += --path "12381/3600" --curve bls12381g1 DEFINES += HAVE_ETH2 APPNAME = "Eth Ropsten" DEFINES_LIB= -APP_LOAD_FLAGS=--appFlags 0xa40 \ No newline at end of file +DEFINES += HAVE_BOLOS_APP_STACK_CANARY +APP_LOAD_FLAGS=--appFlags 0xa40 diff --git a/makefile_conf/chain/rsk.mk b/makefile_conf/chain/rsk.mk index 33df17ba6..dad8f56fb 100644 --- a/makefile_conf/chain/rsk.mk +++ b/makefile_conf/chain/rsk.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/137'" --path "44'/00'" -DEFINES += CHAINID_UPCASE=\"RSK\" CHAINID_COINNAME=\"RBTC\" CHAIN_KIND=CHAIN_KIND_RSK CHAIN_ID=30 +TICKER = "RBTC" +CHAIN_ID = 30 APPNAME = "RSK" \ No newline at end of file diff --git a/makefile_conf/chain/rsk_testnet.mk b/makefile_conf/chain/rsk_testnet.mk index 76fe1ecd4..2142f7cdf 100644 --- a/makefile_conf/chain/rsk_testnet.mk +++ b/makefile_conf/chain/rsk_testnet.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/37310'" -DEFINES += CHAINID_UPCASE=\"RSKTESTNET\" CHAINID_COINNAME=\"RBTC\" CHAIN_KIND=CHAIN_KIND_RSK CHAIN_ID=31 +TICKER = "RBTC" +CHAIN_ID = 31 APPNAME = "RSK Test" \ No newline at end of file diff --git a/makefile_conf/chain/shiden.mk b/makefile_conf/chain/shiden.mk index 1a561f1eb..bda1c9d74 100644 --- a/makefile_conf/chain/shiden.mk +++ b/makefile_conf/chain/shiden.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/809'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"SHIDEN\" CHAINID_COINNAME=\"SDN\" CHAIN_KIND=CHAIN_KIND_SHIDEN CHAIN_ID=336 +TICKER = "SDN" +CHAIN_ID = 336 APPNAME = "Shiden EVM" diff --git a/makefile_conf/chain/shyft.mk b/makefile_conf/chain/shyft.mk index c30ec7f61..b578933a6 100644 --- a/makefile_conf/chain/shyft.mk +++ b/makefile_conf/chain/shyft.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"SHYFT\" CHAINID_COINNAME=\"SHFT\" CHAIN_KIND=CHAIN_KIND_SHYFT CHAIN_ID=7341 +TICKER = "SHFT" +CHAIN_ID = 7341 APPNAME = "Shyft" \ No newline at end of file diff --git a/makefile_conf/chain/songbird.mk b/makefile_conf/chain/songbird.mk index c2c1e7bfb..bc11a41a7 100644 --- a/makefile_conf/chain/songbird.mk +++ b/makefile_conf/chain/songbird.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"SONGBIRD\" CHAINID_COINNAME=\"SGB\" CHAIN_KIND=CHAIN_KIND_SONGBIRD CHAIN_ID=19 +TICKER = "SGB" +CHAIN_ID = 19 APPNAME = "Songbird" \ No newline at end of file diff --git a/makefile_conf/chain/tecracoin.mk b/makefile_conf/chain/tecracoin.mk index e51df374a..eabc8261f 100644 --- a/makefile_conf/chain/tecracoin.mk +++ b/makefile_conf/chain/tecracoin.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"TECRA\" CHAINID_COINNAME=\"TCR\" CHAIN_KIND=CHAIN_KIND_TECRA CHAIN_ID=20531812 +TICKER = "TCR" +CHAIN_ID = 20531812 APPNAME = "TecraCoin" \ No newline at end of file diff --git a/makefile_conf/chain/tecratestnet.mk b/makefile_conf/chain/tecratestnet.mk index 8091b8967..d97ab8198 100644 --- a/makefile_conf/chain/tecratestnet.mk +++ b/makefile_conf/chain/tecratestnet.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/554'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"TECRATESTNET\" CHAINID_COINNAME=\"TCR\" CHAIN_KIND=CHAIN_KIND_TECRA CHAIN_ID=20531811 +TICKER = "TCR" +CHAIN_ID = 20531811 APPNAME = "TecraTestnet" \ No newline at end of file diff --git a/makefile_conf/chain/thundercore.mk b/makefile_conf/chain/thundercore.mk index 7676978a4..a7a4dddd3 100644 --- a/makefile_conf/chain/thundercore.mk +++ b/makefile_conf/chain/thundercore.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/1001'" -DEFINES += CHAINID_UPCASE=\"THUNDERCORE\" CHAINID_COINNAME=\"TT\" CHAIN_KIND=CHAIN_KIND_THUNDERCORE CHAIN_ID=108 +TICKER = "TT" +CHAIN_ID = 108 APPNAME = "ThunderCore" \ No newline at end of file diff --git a/makefile_conf/chain/tobalaba.mk b/makefile_conf/chain/tobalaba.mk deleted file mode 100644 index 92aa14519..000000000 --- a/makefile_conf/chain/tobalaba.mk +++ /dev/null @@ -1,3 +0,0 @@ -APP_LOAD_PARAMS += --path "44'/401697'" -DEFINES += CHAINID_UPCASE=\"TOBALABA\" CHAINID_COINNAME=\"TOBALABA\" CHAIN_KIND=CHAIN_KIND_TOBALABA CHAIN_ID=401697 -APPNAME = "Tobalaba" \ No newline at end of file diff --git a/makefile_conf/chain/tomochain.mk b/makefile_conf/chain/tomochain.mk index b0cb90ce9..953830836 100644 --- a/makefile_conf/chain/tomochain.mk +++ b/makefile_conf/chain/tomochain.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/889'" -DEFINES += CHAINID_UPCASE=\"TOMOCHAIN\" CHAINID_COINNAME=\"TOMO\" CHAIN_KIND=CHAIN_KIND_TOMOCHAIN CHAIN_ID=88 +TICKER = "TOMO" +CHAIN_ID = 88 APPNAME = "TomoChain" \ No newline at end of file diff --git a/makefile_conf/chain/ubiq.mk b/makefile_conf/chain/ubiq.mk index fe86d7f7b..62a4ba127 100644 --- a/makefile_conf/chain/ubiq.mk +++ b/makefile_conf/chain/ubiq.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/108'" -DEFINES += CHAINID_UPCASE=\"UBIQ\" CHAINID_COINNAME=\"UBQ\" CHAIN_KIND=CHAIN_KIND_UBIQ CHAIN_ID=8 +TICKER = "UBQ" +CHAIN_ID = 8 APPNAME = "Ubiq" \ No newline at end of file diff --git a/makefile_conf/chain/volta.mk b/makefile_conf/chain/volta.mk index e30ca2d26..28f7c5610 100644 --- a/makefile_conf/chain/volta.mk +++ b/makefile_conf/chain/volta.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/73799'" --path "44'/60'" -DEFINES += CHAINID_UPCASE=\"VOLTA\" CHAINID_COINNAME=\"VOLTA\" CHAIN_KIND=CHAIN_KIND_VOLTA CHAIN_ID=73799 +TICKER = "VOLTA" +CHAIN_ID = 73799 APPNAME = "Volta" \ No newline at end of file diff --git a/makefile_conf/chain/wanchain.mk b/makefile_conf/chain/wanchain.mk index 4407e93c5..66b6d82da 100644 --- a/makefile_conf/chain/wanchain.mk +++ b/makefile_conf/chain/wanchain.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/5718350'" -DEFINES += CHAINID_UPCASE=\"WAN\" CHAINID_COINNAME=\"WAN\" CHAIN_KIND=CHAIN_KIND_WANCHAIN CHAIN_ID=1 -APPNAME = "Wanchain" \ No newline at end of file +TICKER = "WAN" +CHAIN_ID = 888 +APPNAME = "Wanchain" diff --git a/makefile_conf/chain/webchain.mk b/makefile_conf/chain/webchain.mk index f81d5b8a0..3a7da247c 100644 --- a/makefile_conf/chain/webchain.mk +++ b/makefile_conf/chain/webchain.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/227'" -DEFINES += CHAINID_UPCASE=\"WEBCHAIN\" CHAINID_COINNAME=\"WEB\" CHAIN_KIND=CHAIN_KIND_WEBCHAIN CHAIN_ID=24484 +TICKER = "WEB" +CHAIN_ID = 24484 APPNAME = "Webchain" \ No newline at end of file diff --git a/makefile_conf/chain/wethio.mk b/makefile_conf/chain/wethio.mk index 06fe6f99e..fc491dffa 100644 --- a/makefile_conf/chain/wethio.mk +++ b/makefile_conf/chain/wethio.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/77777'" -DEFINES += CHAINID_UPCASE=\"WETHIO\" CHAINID_COINNAME=\"ZYN\" CHAIN_KIND=CHAIN_KIND_WETHIO CHAIN_ID=78 +TICKER = "ZYN" +CHAIN_ID = 78 APPNAME = "Wethio" \ No newline at end of file diff --git a/makefile_conf/chain/xdcnetwork.mk b/makefile_conf/chain/xdcnetwork.mk index 4be443a45..9118483ac 100644 --- a/makefile_conf/chain/xdcnetwork.mk +++ b/makefile_conf/chain/xdcnetwork.mk @@ -1,3 +1,4 @@ APP_LOAD_PARAMS += --path "44'/60'" --path "44'/550'" -DEFINES += CHAINID_UPCASE=\"XDCNETWORK\" CHAINID_COINNAME=\"XDC\" CHAIN_KIND=CHAIN_KIND_XDCNETWORK CHAIN_ID=50 +TICKER = "XDC" +CHAIN_ID = 50 APPNAME = "XDC Network" diff --git a/src/apdu_constants.h b/src/apdu_constants.h index 7911d6b5b..07e41a300 100644 --- a/src/apdu_constants.h +++ b/src/apdu_constants.h @@ -5,8 +5,6 @@ #define APP_FLAG_DATA_ALLOWED 0x01 #define APP_FLAG_EXTERNAL_TOKEN_NEEDED 0x02 -#define APP_FLAG_STARKWARE 0x04 -#define APP_FLAG_STARKWARE_V2 0x08 #define CLA 0xE0 #define INS_GET_PUBLIC_KEY 0x02 @@ -47,26 +45,6 @@ #define APDU_RESPONSE_CONDITION_NOT_SATISFIED 0x6985 #define APDU_RESPONSE_REF_DATA_NOT_FOUND 0x6a88 -#ifdef HAVE_STARKWARE - -#define STARKWARE_CLA 0xF0 -#define STARKWARE_INS_GET_PUBLIC_KEY 0x02 -#define STARKWARE_INS_SIGN_MESSAGE 0x04 -#define STARKWARE_INS_PROVIDE_QUANTUM 0x08 -#define STARKWARE_INS_UNSAFE_SIGN 0x0A - -#define P1_STARK_ORDER 0x01 -#define P1_STARK_TRANSFER 0x02 -#define P1_STARK_ORDER_V2 0x03 -#define P1_STARK_TRANSFER_V2 0x04 -#define P1_STARK_CONDITIONAL_TRANSFER 0x05 - -#define STARK_ORDER_TYPE 0 -#define STARK_TRANSFER_TYPE 1 -#define STARK_CONDITIONAL_TRANSFER_TYPE 2 - -#endif - enum { OFFSET_CLA = 0, OFFSET_INS, OFFSET_P1, OFFSET_P2, OFFSET_LC, OFFSET_CDATA }; #define ERR_APDU_EMPTY 0x6982 @@ -151,35 +129,6 @@ void handleSetEth2WinthdrawalIndex(uint8_t p1, #endif -#ifdef HAVE_STARKWARE - -void handleStarkwareGetPublicKey(uint8_t p1, - uint8_t p2, - const uint8_t *dataBuffer, - uint8_t dataLength, - unsigned int *flags, - unsigned int *tx); -void handleStarkwareSignMessage(uint8_t p1, - uint8_t p2, - uint8_t *dataBuffer, - uint8_t dataLength, - unsigned int *flags, - unsigned int *tx); -void handleStarkwareProvideQuantum(uint8_t p1, - uint8_t p2, - const uint8_t *dataBuffer, - uint8_t dataLength, - unsigned int *flags, - unsigned int *tx); -void handleStarkwareUnsafeSign(uint8_t p1, - uint8_t p2, - const uint8_t *dataBuffer, - uint8_t dataLength, - unsigned int *flags, - unsigned int *tx); - -#endif - extern uint16_t apdu_response_code; #endif // _APDU_CONSTANTS_H_ diff --git a/src/chainConfig.h b/src/chainConfig.h index 070de4961..9c5490757 100644 --- a/src/chainConfig.h +++ b/src/chainConfig.h @@ -22,65 +22,9 @@ #include "os.h" -typedef enum chain_kind_e { - CHAIN_KIND_ETHEREUM, - CHAIN_KIND_MOONRIVER, - CHAIN_KIND_ETHEREUM_CLASSIC, - CHAIN_KIND_EXPANSE, - CHAIN_KIND_POA, - CHAIN_KIND_RSK, - CHAIN_KIND_UBIQ, - CHAIN_KIND_WANCHAIN, - CHAIN_KIND_KUSD, - CHAIN_KIND_PIRL, - CHAIN_KIND_AKROMA, - CHAIN_KIND_MUSICOIN, - CHAIN_KIND_CALLISTO, - CHAIN_KIND_ETHERSOCIAL, - CHAIN_KIND_ELLAISM, - CHAIN_KIND_ETHER1, - CHAIN_KIND_ETHERGEM, - CHAIN_KIND_ATHEIOS, - CHAIN_KIND_GOCHAIN, - CHAIN_KIND_MIX, - CHAIN_KIND_REOSC, - CHAIN_KIND_HPB, - CHAIN_KIND_TOMOCHAIN, - CHAIN_KIND_TOBALABA, - CHAIN_KIND_DEXON, - CHAIN_KIND_VOLTA, - CHAIN_KIND_ENERGYWEBCHAIN, - CHAIN_KIND_ARTIS_SIGMA1, - CHAIN_KIND_ARTIS_TAU1, - CHAIN_KIND_WEBCHAIN, - CHAIN_KIND_THUNDERCORE, - CHAIN_KIND_FLARE, - CHAIN_KIND_BSC, - CHAIN_KIND_SONGBIRD, - CHAIN_KIND_POLYGON, - CHAIN_KIND_SHYFT, - CHAIN_KIND_CONFLUX_ESPACE, - CHAIN_KIND_MOONBEAM, - CHAIN_KIND_BTTC, - CHAIN_KIND_KARDIACHAIN, - CHAIN_KIND_WETHIO, - CHAIN_KIND_OKC, - CHAIN_KIND_CUBE, - CHAIN_KIND_SHIDEN, - CHAIN_KIND_ASTAR, - CHAIN_KIND_XDCNETWORK, - CHAIN_KIND_METER, - CHAIN_KIND_MULTIVAC, - CHAIN_KIND_TECRA, - CHAIN_KIND_APOTHEMNETWORK, - CHAIN_KIND_ID4GOOD, - CHAIN_KIND_OASYS -} chain_kind_t; - typedef struct chain_config_s { char coinName[10]; // ticker uint64_t chainId; - chain_kind_t kind; } chain_config_t; #define ETHEREUM_MAINNET_CHAINID 1 diff --git a/src/common_ui.h b/src/common_ui.h index e14f57baf..97dabad7a 100644 --- a/src/common_ui.h +++ b/src/common_ui.h @@ -2,20 +2,17 @@ #define _COMMON_UI_H_ #include +#include void ui_idle(void); void ui_warning_contract_data(void); void ui_display_public_eth2(void); void ui_display_privacy_public_key(void); void ui_display_privacy_shared_secret(void); -void ui_display_public_key(void); +void ui_display_public_key(const uint64_t *chain_id); void ui_sign_712_v0(void); -void ui_display_stark_public(void); void ui_confirm_selector(void); void ui_confirm_parameter(void); -void ui_stark_limit_order(void); -void ui_stark_unsafe_sign(void); -void ui_stark_transfer(bool selfTransfer, bool conditional); // EIP-191 void ui_191_start(void); diff --git a/src_common/ethUstream.c b/src/ethUstream.c similarity index 99% rename from src_common/ethUstream.c rename to src/ethUstream.c index 81e607dc3..3273c6596 100644 --- a/src_common/ethUstream.c +++ b/src/ethUstream.c @@ -19,8 +19,8 @@ #include #include "ethUstream.h" -#include "ethUtils.h" -#include "utils.h" +#include "rlp_utils.h" +#include "common_utils.h" #define MAX_INT256 32 #define MAX_ADDRESS 20 diff --git a/src_common/ethUstream.h b/src/ethUstream.h similarity index 86% rename from src_common/ethUstream.h rename to src/ethUstream.h index ed5aea364..d14a42adc 100644 --- a/src_common/ethUstream.h +++ b/src/ethUstream.h @@ -15,14 +15,15 @@ * limitations under the License. ********************************************************************************/ -#ifndef _ETHUSTREAM_H_ -#define _ETHUSTREAM_H_ +#pragma once #include #include #include "os.h" #include "cx.h" +#include "common_utils.h" +#include "tx_content.h" struct txContext_t; @@ -35,10 +36,7 @@ typedef enum customStatus_e { typedef customStatus_e (*ustreamProcess_t)(struct txContext_t *context); -#define TX_FLAG_TYPE 0x01 -#define ADDRESS_LENGTH 20 -#define INT128_LENGTH 16 -#define INT256_LENGTH 32 +#define TX_FLAG_TYPE 0x01 // First variant of every Tx enum. #define RLP_NONE 0 @@ -114,24 +112,6 @@ typedef enum parserStatus_e { USTREAM_CONTINUE // Used internally to signify we can keep on parsing } parserStatus_e; -typedef struct txInt256_t { - uint8_t value[INT256_LENGTH]; - uint8_t length; -} txInt256_t; - -typedef struct txContent_t { - txInt256_t gasprice; // Used as MaxFeePerGas when dealing with EIP1559 transactions. - txInt256_t startgas; // Also known as `gasLimit`. - txInt256_t value; - txInt256_t nonce; - txInt256_t chainID; - uint8_t destination[ADDRESS_LENGTH]; - uint8_t destinationLength; - uint8_t v[8]; - uint8_t vLength; - bool dataPresent; -} txContent_t; - typedef struct txContext_t { uint8_t currentField; cx_sha3_t *sha3; @@ -164,5 +144,3 @@ parserStatus_e processTx(txContext_t *context, parserStatus_e continueTx(txContext_t *context); void copyTxData(txContext_t *context, uint8_t *out, uint32_t length); uint8_t readTxByte(txContext_t *context); - -#endif // _ETHUSTREAM_H_ diff --git a/src/eth_plugin_handler.c b/src/eth_plugin_handler.c index bb73e9e1f..c768c7e43 100644 --- a/src/eth_plugin_handler.c +++ b/src/eth_plugin_handler.c @@ -1,9 +1,9 @@ #include #include "eth_plugin_handler.h" #include "eth_plugin_internal.h" +#include "plugin_utils.h" #include "shared_context.h" #include "network.h" -#include "ethUtils.h" void eth_plugin_prepare_init(ethPluginInitContract_t *init, const uint8_t *selector, @@ -67,7 +67,9 @@ void eth_plugin_prepare_query_contract_UI(ethQueryContractUI_t *queryContractUI, queryContractUI->screenIndex = screenIndex; chain_id = get_tx_chain_id(); - strlcpy(queryContractUI->network_ticker, get_displayable_ticker(&chain_id), MAX_TICKER_LEN); + strlcpy(queryContractUI->network_ticker, + get_displayable_ticker(&chain_id, chainConfig), + sizeof(queryContractUI->network_ticker)); queryContractUI->title = title; queryContractUI->titleLength = titleLength; queryContractUI->msg = msg; diff --git a/src/eth_plugin_handler.h b/src/eth_plugin_handler.h index acd982dc8..dab8ea46d 100644 --- a/src/eth_plugin_handler.h +++ b/src/eth_plugin_handler.h @@ -6,6 +6,8 @@ #define NO_EXTRA_INFO(ctx, idx) \ (allzeroes(&(ctx.transactionContext.extraInfo[idx]), sizeof(extraInfo_t))) +#define NO_NFT_METADATA (NO_EXTRA_INFO(tmpCtx, 1)) + void eth_plugin_prepare_init(ethPluginInitContract_t *init, const uint8_t *selector, uint32_t dataSize); diff --git a/src/eth_plugin_interface.h b/src/eth_plugin_interface.h deleted file mode 100644 index 5bf54992a..000000000 --- a/src/eth_plugin_interface.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef _ETH_PLUGIN_INTERFACE_H_ -#define _ETH_PLUGIN_INTERFACE_H_ - -#include "os.h" -#include "cx.h" -#include "ethUstream.h" -#include "tokens.h" -#include "shared_context.h" - -// Interface version. To be updated everytime we introduce breaking changes to the plugin interface. -typedef enum { - ETH_PLUGIN_INTERFACE_VERSION_1 = 1, - ETH_PLUGIN_INTERFACE_VERSION_2 = 2, - ETH_PLUGIN_INTERFACE_VERSION_3 = 3, - ETH_PLUGIN_INTERFACE_VERSION_4 = 4, - ETH_PLUGIN_INTERFACE_VERSION_5 = 5, - ETH_PLUGIN_INTERFACE_VERSION_LATEST = 6 -} eth_plugin_interface_version_t; - -typedef enum { - - ETH_PLUGIN_INIT_CONTRACT = 0x0101, - ETH_PLUGIN_PROVIDE_PARAMETER = 0x0102, - ETH_PLUGIN_FINALIZE = 0x0103, - ETH_PLUGIN_PROVIDE_INFO = 0x0104, - ETH_PLUGIN_QUERY_CONTRACT_ID = 0x0105, - ETH_PLUGIN_QUERY_CONTRACT_UI = 0x0106, - ETH_PLUGIN_CHECK_PRESENCE = 0x01FF - -} eth_plugin_msg_t; - -typedef enum { - // Unsuccesful return values - ETH_PLUGIN_RESULT_ERROR = 0x00, - ETH_PLUGIN_RESULT_UNAVAILABLE = 0x01, - ETH_PLUGIN_RESULT_UNSUCCESSFUL = 0x02, // Used for comparison - - // Successful return values - ETH_PLUGIN_RESULT_SUCCESSFUL = 0x03, // Used for comparison - ETH_PLUGIN_RESULT_OK = 0x04, - ETH_PLUGIN_RESULT_OK_ALIAS = 0x05, - ETH_PLUGIN_RESULT_FALLBACK = 0x06 - -} eth_plugin_result_t; - -typedef enum { - - ETH_UI_TYPE_AMOUNT_ADDRESS = 0x01, - ETH_UI_TYPE_GENERIC = 0x02 - -} eth_ui_type_t; - -typedef void (*PluginCall)(int, void *); - -// Shared objects, read-write - -typedef struct ethPluginSharedRW_t { - cx_sha3_t *sha3; - -} ethPluginSharedRW_t; - -// Shared objects, read-only - -typedef struct ethPluginSharedRO_t { - txContent_t *txContent; - -} ethPluginSharedRO_t; - -// Init Contract - -typedef struct ethPluginInitContract_t { - uint8_t interfaceVersion; - uint8_t result; - - // in - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - size_t pluginContextLength; - const uint8_t *selector; // 4 bytes selector - size_t dataSize; - - char *alias; // 29 bytes alias if ETH_PLUGIN_RESULT_OK_ALIAS set - -} ethPluginInitContract_t; - -// Provide parameter - -typedef struct ethPluginProvideParameter_t { - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - const uint8_t *parameter; // 32 bytes parameter - uint32_t parameterOffset; - - uint8_t result; - -} ethPluginProvideParameter_t; - -// Finalize - -typedef struct ethPluginFinalize_t { - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - - uint8_t *tokenLookup1; // set by the plugin if a token should be looked up - uint8_t *tokenLookup2; - - const uint8_t *amount; // set an uint256 pointer if uiType is UI_AMOUNT_ADDRESS - const uint8_t *address; // set to the destination address if uiType is UI_AMOUNT_ADDRESS. Set - // to the user's address if uiType is UI_TYPE_GENERIC - - uint8_t uiType; - uint8_t numScreens; // ignored if uiType is UI_AMOUNT_ADDRESS - uint8_t result; - -} ethPluginFinalize_t; - -// If uiType is UI_AMOUNT_ADDRESS, the amount and address provided by the plugin will be used -// If tokenLookup1 is set, the amount is provided for this token - -// if uiType is UI_TYPE_GENERIC, the ETH application provides tokens if requested then prompts -// for each UI field -// The first field is forced by the ETH app to be the name + version of the plugin handling the -// request The last field is the fee amount - -// Provide token - -typedef struct ethPluginProvideInfo_t { - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - - union extraInfo_t *item1; // set by the ETH application, to be saved by the plugin - union extraInfo_t *item2; - - uint8_t additionalScreens; // Used by the plugin if it needs to display additional screens - // based on the information received from the token definitions. - - uint8_t result; - -} ethPluginProvideInfo_t; - -// Query Contract name and version - -// This is always called on the non aliased contract - -typedef struct ethQueryContractID_t { - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - uint8_t *pluginContext; - - char *name; - size_t nameLength; - char *version; - size_t versionLength; - - uint8_t result; - -} ethQueryContractID_t; - -// Query Contract UI - -typedef struct ethQueryContractUI_t { - ethPluginSharedRW_t *pluginSharedRW; - ethPluginSharedRO_t *pluginSharedRO; - union extraInfo_t *item1; - union extraInfo_t *item2; - char network_ticker[MAX_TICKER_LEN]; - uint8_t *pluginContext; - uint8_t screenIndex; - - char *title; - size_t titleLength; - char *msg; - size_t msgLength; - - uint8_t result; - -} ethQueryContractUI_t; - -#endif // _ETH_PLUGIN_INTERFACE_H_ diff --git a/src/eth_plugin_internal.c b/src/eth_plugin_internal.c index 075f2ec58..2cfe351eb 100644 --- a/src/eth_plugin_internal.c +++ b/src/eth_plugin_internal.c @@ -1,42 +1,9 @@ #include #include "eth_plugin_internal.h" -#include "ethUtils.h" // allzeroes - -bool erc20_plugin_available_check(void); +#include "plugin_utils.h" void erc20_plugin_call(int message, void* parameters); -void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) { - uint8_t copy_size = MIN(dst_size, ADDRESS_LENGTH); - memmove(dst, parameter + PARAMETER_LENGTH - copy_size, copy_size); -} - -void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) { - uint8_t copy_size = MIN(dst_size, PARAMETER_LENGTH); - memmove(dst, parameter, copy_size); -} - -bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value) { - if (allzeroes(parameter, PARAMETER_LENGTH - sizeof(uint16_t))) { - *value = U2BE(parameter, PARAMETER_LENGTH - sizeof(uint16_t)); - return true; - } - - return false; -} - -bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value) { - if (allzeroes(parameter, PARAMETER_LENGTH - sizeof(uint32_t))) { - *value = U4BE(parameter, PARAMETER_LENGTH - sizeof(uint32_t)); - return true; - } - - return false; -} - -#ifdef HAVE_STARKWARE -void starkware_plugin_call(int message, void* parameters); -#endif #ifdef HAVE_ETH2 void eth2_plugin_call(int message, void* parameters); #endif @@ -55,83 +22,15 @@ const uint8_t* const ETH2_SELECTORS[NUM_ETH2_SELECTORS] = {ETH2_DEPOSIT_SELECTOR #endif -#ifdef HAVE_STARKWARE - -static const uint8_t STARKWARE_REGISTER_ID[SELECTOR_SIZE] = {0xdd, 0x24, 0x14, 0xd4}; -static const uint8_t STARKWARE_DEPOSIT_TOKEN_ID[SELECTOR_SIZE] = {0x25, 0x05, 0xc3, 0xd9}; -static const uint8_t STARKWARE_DEPOSIT_ETH_ID[SELECTOR_SIZE] = {0x00, 0xae, 0xef, 0x8a}; -static const uint8_t STARKWARE_DEPOSIT_CANCEL_ID[SELECTOR_SIZE] = {0x7d, 0xf7, 0xdc, 0x04}; -static const uint8_t STARKWARE_DEPOSIT_RECLAIM_ID[SELECTOR_SIZE] = {0xae, 0x87, 0x38, 0x16}; -static const uint8_t STARKWARE_WITHDRAW_ID[SELECTOR_SIZE] = {0x44, 0x1a, 0x3e, 0x70}; -static const uint8_t STARKWARE_FULL_WITHDRAWAL_ID[SELECTOR_SIZE] = {0xa9, 0x33, 0x10, 0xc4}; -static const uint8_t STARKWARE_FREEZE_ID[SELECTOR_SIZE] = {0x93, 0xc1, 0xe4, 0x66}; -static const uint8_t STARKWARE_ESCAPE_ID[SELECTOR_SIZE] = {0x9e, 0x3a, 0xda, 0xc4}; -static const uint8_t STARKWARE_VERIFY_ESCAPE_ID[SELECTOR_SIZE] = {0x2d, 0xd5, 0x30, 0x06}; - -static const uint8_t STARKWARE_WITHDRAW_TO_ID[SELECTOR_SIZE] = {0x14, 0xcd, 0x70, 0xe4}; -static const uint8_t STARKWARE_DEPOSIT_NFT_ID[SELECTOR_SIZE] = {0xae, 0x1c, 0xdd, 0xe6}; -static const uint8_t STARKWARE_DEPOSIT_NFT_RECLAIM_ID[SELECTOR_SIZE] = {0xfc, 0xb0, 0x58, 0x22}; -static const uint8_t STARKWARE_WITHDRAW_AND_MINT_ID[SELECTOR_SIZE] = {0xd9, 0x14, 0x43, 0xb7}; -static const uint8_t STARKWARE_WITHDRAW_NFT_ID[SELECTOR_SIZE] = {0x01, 0x9b, 0x41, 0x7a}; -static const uint8_t STARKWARE_WITHDRAW_NFT_TO_ID[SELECTOR_SIZE] = {0xeb, 0xef, 0x0f, 0xd0}; -static const uint8_t STARKWARE_REGISTER_AND_DEPOSIT_TOKEN_ID[SELECTOR_SIZE] = {0x10, - 0x82, - 0x08, - 0xcf}; -static const uint8_t STARKWARE_REGISTER_AND_DEPOSIT_ETH_ID[SELECTOR_SIZE] = {0xa7, - 0x78, - 0xc0, - 0xc3}; -static const uint8_t STARKWARE_PROXY_DEPOSIT_TOKEN_ID[SELECTOR_SIZE] = {0xdc, 0xca, 0xd5, 0x24}; -static const uint8_t STARKWARE_PROXY_DEPOSIT_ETH_ID[SELECTOR_SIZE] = {0x6c, 0xe5, 0xd9, 0x57}; - -const uint8_t* const STARKWARE_SELECTORS[NUM_STARKWARE_SELECTORS] = { - STARKWARE_REGISTER_ID, - STARKWARE_DEPOSIT_TOKEN_ID, - STARKWARE_DEPOSIT_ETH_ID, - STARKWARE_DEPOSIT_CANCEL_ID, - STARKWARE_DEPOSIT_RECLAIM_ID, - STARKWARE_WITHDRAW_ID, - STARKWARE_FULL_WITHDRAWAL_ID, - STARKWARE_FREEZE_ID, - STARKWARE_ESCAPE_ID, - STARKWARE_VERIFY_ESCAPE_ID, - STARKWARE_WITHDRAW_TO_ID, - STARKWARE_DEPOSIT_NFT_ID, - STARKWARE_DEPOSIT_NFT_RECLAIM_ID, - STARKWARE_WITHDRAW_AND_MINT_ID, - STARKWARE_WITHDRAW_NFT_ID, - STARKWARE_WITHDRAW_NFT_TO_ID, - STARKWARE_REGISTER_AND_DEPOSIT_TOKEN_ID, - STARKWARE_REGISTER_AND_DEPOSIT_ETH_ID, - STARKWARE_PROXY_DEPOSIT_TOKEN_ID, - STARKWARE_PROXY_DEPOSIT_ETH_ID}; - -#endif - // All internal alias names start with 'minus' const internalEthPlugin_t INTERNAL_ETH_PLUGINS[] = { - {erc20_plugin_available_check, - (const uint8_t**) ERC20_SELECTORS, - NUM_ERC20_SELECTORS, - "-erc20", - erc20_plugin_call}, + {NULL, (const uint8_t**) ERC20_SELECTORS, NUM_ERC20_SELECTORS, "-erc20", erc20_plugin_call}, #ifdef HAVE_ETH2 {NULL, (const uint8_t**) ETH2_SELECTORS, NUM_ETH2_SELECTORS, "-eth2", eth2_plugin_call}, -#endif - -#ifdef HAVE_STARKWARE - - {NULL, - (const uint8_t**) STARKWARE_SELECTORS, - NUM_STARKWARE_SELECTORS, - "-strk", - starkware_plugin_call}, - #endif {NULL, NULL, 0, "", NULL}}; diff --git a/src/eth_plugin_internal.h b/src/eth_plugin_internal.h index 2d2ca0369..ea84e407d 100644 --- a/src/eth_plugin_internal.h +++ b/src/eth_plugin_internal.h @@ -1,26 +1,15 @@ -#ifndef _ETH_PLUGIN_INTERNAL_H_ -#define _ETH_PLUGIN_INTERNAL_H_ +#pragma once #include #include +#include "shared_context.h" #include "eth_plugin_interface.h" -#define SELECTOR_SIZE 4 -#define PARAMETER_LENGTH 32 - -void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size); - -void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size); - void erc721_plugin_call(int message, void* parameters); void erc1155_plugin_call(int message, void* parameters); -// Get the value from the beginning of the parameter (right to left) and check if the rest of it is -// zero -bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value); -bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value); - typedef bool (*PluginAvailableCheck)(void); +typedef void (*PluginCall)(int, void*); typedef struct internalEthPlugin_t { PluginAvailableCheck availableCheck; @@ -40,13 +29,4 @@ extern const uint8_t* const ETH2_SELECTORS[NUM_ETH2_SELECTORS]; #endif -#ifdef HAVE_STARKWARE - -#define NUM_STARKWARE_SELECTORS 20 -extern const uint8_t* const STARKWARE_SELECTORS[NUM_STARKWARE_SELECTORS]; - -#endif - extern internalEthPlugin_t const INTERNAL_ETH_PLUGINS[]; - -#endif // _ETH_PLUGIN_INTERNAL_H_ diff --git a/src/extra_tokens.c b/src/extra_tokens.c new file mode 100644 index 000000000..9faefcbd3 --- /dev/null +++ b/src/extra_tokens.c @@ -0,0 +1,61 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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. + ********************************************************************************/ + +#ifdef HAVE_TOKENS_EXTRA_LIST + +#include "extra_tokens.h" + +const tokenDefinition_t TOKENS_EXTRA[NUM_TOKENS_EXTRA] = { + + // Ropsten DeversiFi tokens + {{0x4c, 0x5f, 0x66, 0x59, 0x61, 0x97, 0xa8, 0x6f, 0xb3, 0x0a, + 0x24, 0x35, 0xe2, 0xef, 0x4d, 0xdc, 0xb3, 0x93, 0x42, 0xc9}, + "tUSDT", + 6}, + {{0x1c, 0x0f, 0x17, 0x43, 0x67, 0x40, 0xbf, 0xb9, 0x2c, 0x10, + 0x70, 0xee, 0x86, 0x32, 0x2d, 0xe8, 0x90, 0x83, 0x7c, 0x6a}, + "tUSDT", + 6}, + {{0xcd, 0x07, 0x7a, 0xbe, 0xdd, 0x83, 0x1a, 0x34, 0x43, 0xff, + 0xbe, 0x24, 0xfb, 0x76, 0x66, 0x1b, 0xbb, 0x17, 0xeb, 0x69}, + "tZRX", + 18}, + {{0x40, 0xd8, 0x97, 0x85, 0x00, 0xbf, 0x68, 0x32, 0x4a, 0x51, + 0x53, 0x3c, 0xd6, 0xa2, 0x1e, 0x3e, 0x59, 0xbe, 0x32, 0x4a}, + "tBTC", + 18}, + // Goerli DeversiFi tokens + {{0xd9, 0x97, 0xa8, 0x63, 0x46, 0xe7, 0x65, 0x18, 0xe6, 0x92, + 0x25, 0x56, 0xf3, 0x4d, 0x76, 0x61, 0x30, 0xc0, 0xbb, 0xfd}, + "tUSDT", + 6}, + {{0xc1, 0xd5, 0x79, 0xeb, 0xff, 0x7c, 0x0f, 0x6c, 0xfd, 0x9a, + 0xd5, 0xfb, 0x26, 0x7f, 0xec, 0x73, 0xbe, 0x70, 0xc8, 0xf7}, + "tBTC", + 18}, + {{0xa8, 0xf3, 0x14, 0x4f, 0xea, 0x2c, 0x37, 0x5a, 0xd0, 0x58, + 0xec, 0x12, 0x09, 0x9a, 0x5a, 0x21, 0xa2, 0x6f, 0xe9, 0x96}, + "tDVF", + 18}, + {{0x4c, 0xda, 0xbe, 0xc1, 0x2a, 0x39, 0x7f, 0xb6, 0xef, 0xaf, + 0x46, 0x13, 0xd5, 0xdf, 0xd7, 0x9b, 0x30, 0x9a, 0xe9, 0xfa}, + "tXDVF", + 18}, + +}; + +#endif diff --git a/src/extra_tokens.h b/src/extra_tokens.h new file mode 100644 index 000000000..f6b012c9a --- /dev/null +++ b/src/extra_tokens.h @@ -0,0 +1,28 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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 "asset_info.h" + +#ifdef HAVE_TOKENS_EXTRA_LIST + +#define NUM_TOKENS_EXTRA 8 + +extern tokenDefinition_t const TOKENS_EXTRA[NUM_TOKENS_EXTRA]; + +#endif diff --git a/src/handle_check_address.c b/src/handle_check_address.c index 7950f7ea9..45c8586fa 100644 --- a/src/handle_check_address.c +++ b/src/handle_check_address.c @@ -1,21 +1,20 @@ #include "handle_check_address.h" #include "os.h" #include "shared_context.h" -#include "ethUtils.h" #include "string.h" -#define ZERO(x) memset(&x, 0, sizeof(x)) +#define ZERO(x) explicit_bzero(&x, sizeof(x)) -int handle_check_address(check_address_parameters_t* params, chain_config_t* chain_config) { +void handle_check_address(check_address_parameters_t* params, chain_config_t* chain_config) { + params->result = 0; PRINTF("Params on the address %d\n", (unsigned int) params); PRINTF("Address to check %s\n", params->address_to_check); PRINTF("Inside handle_check_address\n"); if (params->address_to_check == 0) { PRINTF("Address to check == 0\n"); - return 0; + return; } - uint8_t i; const uint8_t* bip32_path_ptr = params->address_parameters; uint8_t bip32PathLength = *(bip32_path_ptr++); cx_sha3_t local_sha3; @@ -27,36 +26,56 @@ int handle_check_address(check_address_parameters_t* params, chain_config_t* cha char address[51]; } locals_union1; union group2 { - uint8_t privateKeyData[32]; + uint8_t privateKeyData[64]; cx_ecfp_public_key_t publicKey; } locals_union2; if ((bip32PathLength < 0x01) || (bip32PathLength > MAX_BIP32_PATH) || (bip32PathLength * 4 != params->address_parameters_length - 1)) { PRINTF("Invalid path\n"); - return 0; + return; } - for (i = 0; i < bip32PathLength; i++) { + for (uint8_t i = 0; i < bip32PathLength; i++) { locals_union1.bip32Path[i] = U4BE(bip32_path_ptr, 0); bip32_path_ptr += 4; } - os_perso_derive_node_bip32(CX_CURVE_256K1, - locals_union1.bip32Path, - bip32PathLength, - locals_union2.privateKeyData, - NULL); + if (os_derive_bip32_no_throw(CX_CURVE_256K1, + locals_union1.bip32Path, + bip32PathLength, + locals_union2.privateKeyData, + NULL) != CX_OK) { + ZERO(locals_union1); + ZERO(locals_union2); + return; + } + ZERO(locals_union1); - cx_ecfp_init_private_key(CX_CURVE_256K1, - locals_union2.privateKeyData, - 32, - &locals_union1.privateKey); + if (cx_ecfp_init_private_key_no_throw(CX_CURVE_256K1, + locals_union2.privateKeyData, + 32, + &locals_union1.privateKey) != CX_OK) { + ZERO(locals_union1); + ZERO(locals_union2); + return; + } ZERO(locals_union2); - cx_ecfp_generate_pair(CX_CURVE_256K1, &locals_union2.publicKey, &locals_union1.privateKey, 1); + if (cx_ecfp_generate_pair_no_throw(CX_CURVE_256K1, + &locals_union2.publicKey, + &locals_union1.privateKey, + 1) != CX_OK) { + ZERO(locals_union1); + ZERO(locals_union2); + return; + } ZERO(locals_union1); - getEthAddressStringFromKey(&locals_union2.publicKey, - locals_union1.address, - &local_sha3, - chain_config->chainId); + if (!getEthAddressStringFromKey(&locals_union2.publicKey, + locals_union1.address, + &local_sha3, + chain_config->chainId)) { + ZERO(locals_union1); + ZERO(locals_union2); + return; + } ZERO(locals_union2); uint8_t offset_0x = 0; @@ -66,8 +85,9 @@ int handle_check_address(check_address_parameters_t* params, chain_config_t* cha if (strcmp(locals_union1.address, params->address_to_check + offset_0x) != 0) { PRINTF("Addresses don't match\n"); - return 0; + } else { + PRINTF("Addresses match\n"); + params->result = 1; } - PRINTF("Addresses match\n"); - return 1; + ZERO(locals_union1); } diff --git a/src/handle_check_address.h b/src/handle_check_address.h index 4267a3035..92db829c5 100644 --- a/src/handle_check_address.h +++ b/src/handle_check_address.h @@ -4,7 +4,7 @@ #include "swap_lib_calls.h" #include "chainConfig.h" -int handle_check_address(check_address_parameters_t* check_address_params, - chain_config_t* chain_config); +void handle_check_address(check_address_parameters_t* check_address_params, + chain_config_t* chain_config); -#endif // _HANDLE_CHECK_ADDRESS_H_ \ No newline at end of file +#endif // _HANDLE_CHECK_ADDRESS_H_ diff --git a/src/handle_get_printable_amount.c b/src/handle_get_printable_amount.c index 715c85d10..5a70e881c 100644 --- a/src/handle_get_printable_amount.c +++ b/src/handle_get_printable_amount.c @@ -1,43 +1,51 @@ +#include +#include + +#include "swap_utils.h" #include "handle_get_printable_amount.h" #include "shared_context.h" -#include "ethUtils.h" -#include "utils.h" +#include "common_utils.h" #include "uint256.h" #include "string.h" -#include -#include +#include "network.h" -int handle_get_printable_amount(get_printable_amount_parameters_t* params, chain_config_t* config) { - uint8_t decimals; +void handle_get_printable_amount(get_printable_amount_parameters_t* params, + chain_config_t* config) { char ticker[MAX_TICKER_LEN]; + uint8_t decimals; + uint64_t chain_id = 0; + memset(params->printable_amount, 0, sizeof(params->printable_amount)); if (params->amount_length > 32) { PRINTF("Amount is too big, 32 bytes max but buffer has %u bytes", params->amount_length); - return 0; + return; } - // If the amount is a fee, its value is nominated in ETH even if we're doing an ERC20 swap + if (!parse_swap_config(params->coin_configuration, + params->coin_configuration_length, + ticker, + &decimals, + &chain_id)) { + PRINTF("Error while parsing config\n"); + return; + } + // If the amount is a fee, the ticker should be the chain's native currency if (params->is_fee) { - uint8_t ticker_len = strnlen(config->coinName, sizeof(config->coinName)); - memcpy(ticker, config->coinName, ticker_len); - ticker[ticker_len] = '\0'; - decimals = WEI_TO_ETHER; - } else { - // If the amount is *not* a fee, decimals and ticker are built from the given config - if (!parse_swap_config(params->coin_configuration, - params->coin_configuration_length, - ticker, - &decimals)) { - PRINTF("Error while parsing config\n"); - return 0; + // fallback mechanism in the absence of chain ID in swap config + if (chain_id == 0) { + chain_id = config->chainId; } + strlcpy(ticker, get_displayable_ticker(&chain_id, config), sizeof(ticker)); + decimals = WEI_TO_ETHER; } - amountToString(params->amount, - params->amount_length, - decimals, - ticker, - params->printable_amount, - sizeof(params->printable_amount)); - return 1; + if (!amountToString(params->amount, + params->amount_length, + decimals, + ticker, + params->printable_amount, + sizeof(params->printable_amount))) { + memset(params->printable_amount, 0, sizeof(params->printable_amount)); + } + return; } diff --git a/src/handle_get_printable_amount.h b/src/handle_get_printable_amount.h index 0bf20153b..b81729404 100644 --- a/src/handle_get_printable_amount.h +++ b/src/handle_get_printable_amount.h @@ -4,7 +4,7 @@ #include "swap_lib_calls.h" #include "chainConfig.h" -int handle_get_printable_amount(get_printable_amount_parameters_t* get_printable_amount_params, - chain_config_t* config); +void handle_get_printable_amount(get_printable_amount_parameters_t* get_printable_amount_params, + chain_config_t* config); -#endif // _HANDLE_GET_PRINTABLE_AMOUNT_H_ \ No newline at end of file +#endif // _HANDLE_GET_PRINTABLE_AMOUNT_H_ diff --git a/src/handle_swap_sign_transaction.c b/src/handle_swap_sign_transaction.c index 604b8a26c..fc7167a56 100644 --- a/src/handle_swap_sign_transaction.c +++ b/src/handle_swap_sign_transaction.c @@ -1,9 +1,11 @@ #include "os_io_seproxyhal.h" #include "os.h" #include "ux.h" +#include "swap_utils.h" #include "handle_swap_sign_transaction.h" #include "shared_context.h" -#include "utils.h" +#include "common_utils.h" +#include "network.h" #ifdef HAVE_NBGL #include "nbgl_use_case.h" #endif // HAVE_NBGL @@ -26,31 +28,42 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transacti return false; } - uint8_t decimals; char ticker[MAX_TICKER_LEN]; + uint8_t decimals; + uint64_t chain_id = 0; + if (!parse_swap_config(sign_transaction_params->coin_configuration, sign_transaction_params->coin_configuration_length, ticker, - &decimals)) { + &decimals, + &chain_id)) { PRINTF("Error while parsing config\n"); return false; } - amountToString(sign_transaction_params->amount, - sign_transaction_params->amount_length, - decimals, - ticker, - stack_data.fullAmount, - sizeof(stack_data.fullAmount)); + if (!amountToString(sign_transaction_params->amount, + sign_transaction_params->amount_length, + decimals, + ticker, + stack_data.fullAmount, + sizeof(stack_data.fullAmount))) { + return false; + } + // fallback mechanism in the absence of chain ID in swap config + if (chain_id == 0) { + chain_id = config->chainId; + } // If the amount is a fee, its value is nominated in ETH even if we're doing an ERC20 swap - strlcpy(ticker, config->coinName, MAX_TICKER_LEN); + strlcpy(ticker, get_displayable_ticker(&chain_id, config), sizeof(ticker)); decimals = WEI_TO_ETHER; - amountToString(sign_transaction_params->fee_amount, - sign_transaction_params->fee_amount_length, - decimals, - ticker, - stack_data.maxFee, - sizeof(stack_data.maxFee)); + if (!amountToString(sign_transaction_params->fee_amount, + sign_transaction_params->fee_amount_length, + decimals, + ticker, + stack_data.maxFee, + sizeof(stack_data.maxFee))) { + return false; + } // Full reset the global variables os_explicit_zero_BSS_segment(); @@ -67,15 +80,17 @@ void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_succes os_lib_end(); } -void handle_swap_sign_transaction(chain_config_t* config) { - UX_INIT(); +void __attribute__((noreturn)) handle_swap_sign_transaction(chain_config_t* config) { #ifdef HAVE_NBGL + // On Stax, display a spinner at startup + UX_INIT(); nbgl_useCaseSpinner("Signing"); #endif // HAVE_NBGL chainConfig = config; reset_app_context(); G_called_from_swap = true; + G_swap_response_ready = false; io_seproxyhal_init(); if (N_storage.initialized != 0x01) { @@ -88,10 +103,9 @@ void handle_swap_sign_transaction(chain_config_t* config) { nvm_write((void*) &N_storage, (void*) &storage, sizeof(internalStorage_t)); } + PRINTF("USB power ON/OFF\n"); USB_power(0); USB_power(1); - // ui_idle(); - PRINTF("USB power ON/OFF\n"); #ifdef HAVE_BLE // grab the current plane mode setting G_io_app.plane_mode = os_setting_get(OS_SETTING_PLANEMODE, NULL, 0); diff --git a/src/handle_swap_sign_transaction.h b/src/handle_swap_sign_transaction.h index d34a6d860..2c20f1eb5 100644 --- a/src/handle_swap_sign_transaction.h +++ b/src/handle_swap_sign_transaction.h @@ -6,6 +6,6 @@ bool copy_transaction_parameters(create_transaction_parameters_t* sign_transaction_params, chain_config_t* config); -void handle_swap_sign_transaction(chain_config_t* config); +void __attribute__((noreturn)) handle_swap_sign_transaction(chain_config_t* config); void __attribute__((noreturn)) finalize_exchange_sign_transaction(bool is_success); diff --git a/src_common/hash_bytes.c b/src/hash_bytes.c similarity index 100% rename from src_common/hash_bytes.c rename to src/hash_bytes.c diff --git a/src_common/hash_bytes.h b/src/hash_bytes.h similarity index 100% rename from src_common/hash_bytes.h rename to src/hash_bytes.h diff --git a/src/main.c b/src/main.c index 3399b8614..4f5ce6d7f 100644 --- a/src/main.c +++ b/src/main.c @@ -22,7 +22,7 @@ #include "os_io_seproxyhal.h" #include "glyphs.h" -#include "utils.h" +#include "common_utils.h" #include "swap_lib_calls.h" #include "handle_swap_sign_transaction.h" @@ -32,10 +32,6 @@ #include "challenge.h" #include "domain_name.h" -#ifdef HAVE_STARKWARE -#include "stark_crypto.h" -#endif - unsigned char G_io_seproxyhal_spi_buffer[IO_SEPROXYHAL_BUFFER_SIZE_B]; void ui_idle(void); @@ -53,10 +49,8 @@ cx_sha3_t global_sha3; uint8_t appState; uint16_t apdu_response_code; bool G_called_from_swap; +bool G_swap_response_ready; pluginType_t pluginType; -#ifdef HAVE_STARKWARE -bool quantumSet; -#endif #ifdef HAVE_ETH2 uint32_t eth2WithdrawalIndex; @@ -78,10 +72,8 @@ void reset_app_context() { // PRINTF("!!RESET_APP_CONTEXT\n"); appState = APP_STATE_IDLE; G_called_from_swap = false; + G_swap_response_ready = false; pluginType = OLD_INTERNAL; -#ifdef HAVE_STARKWARE - quantumSet = false; -#endif #ifdef HAVE_ETH2 eth2WithdrawalIndex = 0; #endif @@ -145,331 +137,6 @@ unsigned short io_exchange_al(unsigned char channel, unsigned short tx_len) { extraInfo_t *getKnownToken(uint8_t *contractAddress) { union extraInfo_t *currentItem = NULL; -#ifdef HAVE_TOKENS_LIST - uint32_t numTokens = 0; - uint32_t i; - switch (chainConfig->kind) { - case CHAIN_KIND_AKROMA: - numTokens = NUM_TOKENS_AKROMA; - break; - case CHAIN_KIND_ETHEREUM: - numTokens = NUM_TOKENS_ETHEREUM; - break; - case CHAIN_KIND_ETHEREUM_CLASSIC: - numTokens = NUM_TOKENS_ETHEREUM_CLASSIC; - break; - case CHAIN_KIND_PIRL: - numTokens = NUM_TOKENS_PIRL; - break; - case CHAIN_KIND_POA: - numTokens = NUM_TOKENS_POA; - break; - case CHAIN_KIND_ARTIS_SIGMA1: - numTokens = NUM_TOKENS_ARTIS_SIGMA1; - break; - case CHAIN_KIND_ARTIS_TAU1: - numTokens = NUM_TOKENS_ARTIS_TAU1; - break; - case CHAIN_KIND_RSK: - numTokens = NUM_TOKENS_RSK; - break; - case CHAIN_KIND_EXPANSE: - numTokens = NUM_TOKENS_EXPANSE; - break; - case CHAIN_KIND_UBIQ: - numTokens = NUM_TOKENS_UBIQ; - break; - case CHAIN_KIND_WANCHAIN: - numTokens = NUM_TOKENS_WANCHAIN; - break; - case CHAIN_KIND_KUSD: - numTokens = NUM_TOKENS_KUSD; - break; - case CHAIN_KIND_MUSICOIN: - numTokens = NUM_TOKENS_MUSICOIN; - break; - case CHAIN_KIND_CALLISTO: - numTokens = NUM_TOKENS_CALLISTO; - break; - case CHAIN_KIND_ETHERSOCIAL: - numTokens = NUM_TOKENS_ETHERSOCIAL; - break; - case CHAIN_KIND_ELLAISM: - numTokens = NUM_TOKENS_ELLAISM; - break; - case CHAIN_KIND_ETHER1: - numTokens = NUM_TOKENS_ETHER1; - break; - case CHAIN_KIND_ETHERGEM: - numTokens = NUM_TOKENS_ETHERGEM; - break; - case CHAIN_KIND_ATHEIOS: - numTokens = NUM_TOKENS_ATHEIOS; - break; - case CHAIN_KIND_GOCHAIN: - numTokens = NUM_TOKENS_GOCHAIN; - break; - case CHAIN_KIND_MIX: - numTokens = NUM_TOKENS_MIX; - break; - case CHAIN_KIND_REOSC: - numTokens = NUM_TOKENS_REOSC; - break; - case CHAIN_KIND_HPB: - numTokens = NUM_TOKENS_HPB; - break; - case CHAIN_KIND_TOMOCHAIN: - numTokens = NUM_TOKENS_TOMOCHAIN; - break; - case CHAIN_KIND_MOONRIVER: - numTokens = NUM_TOKENS_MOONRIVER; - break; - case CHAIN_KIND_TOBALABA: - numTokens = NUM_TOKENS_TOBALABA; - break; - case CHAIN_KIND_DEXON: - numTokens = NUM_TOKENS_DEXON; - break; - case CHAIN_KIND_VOLTA: - numTokens = NUM_TOKENS_VOLTA; - break; - case CHAIN_KIND_ENERGYWEBCHAIN: - numTokens = NUM_TOKENS_ENERGYWEBCHAIN; - break; - case CHAIN_KIND_WEBCHAIN: - numTokens = NUM_TOKENS_WEBCHAIN; - break; - case CHAIN_KIND_THUNDERCORE: - numTokens = NUM_TOKENS_THUNDERCORE; - break; - case CHAIN_KIND_FLARE: - numTokens = NUM_TOKENS_FLARE; - break; - case CHAIN_KIND_BSC: - numTokens = NUM_TOKENS_BSC; - break; - case CHAIN_KIND_SONGBIRD: - numTokens = NUM_TOKENS_SONGBIRD; - break; - case CHAIN_KIND_POLYGON: - numTokens = NUM_TOKENS_POLYGON; - break; - case CHAIN_KIND_SHYFT: - numTokens = NUM_TOKENS_SHYFT; - break; - case CHAIN_KIND_CONFLUX_ESPACE: - numTokens = NUM_TOKENS_CONFLUX_ESPACE; - break; - case CHAIN_KIND_MOONBEAM: - numTokens = NUM_TOKENS_MOONBEAM; - break; - case CHAIN_KIND_KARDIACHAIN: - numTokens = NUM_TOKENS_KARDIACHAIN; - break; - case CHAIN_KIND_BTTC: - numTokens = NUM_TOKENS_BTTC; - break; - case CHAIN_KIND_WETHIO: - numTokens = NUM_TOKENS_WETHIO; - break; - case CHAIN_KIND_OKC: - numTokens = NUM_TOKENS_OKC; - break; - case CHAIN_KIND_CUBE: - numTokens = NUM_TOKENS_CUBE; - break; - case CHAIN_KIND_SHIDEN: - numTokens = NUM_TOKENS_SHIDEN; - break; - case CHAIN_KIND_ASTAR: - numTokens = NUM_TOKENS_ASTAR; - break; - case CHAIN_KIND_XDCNETWORK: - numTokens = NUM_TOKENS_XDCNETWORK; - break; - case CHAIN_KIND_METER: - numTokens = NUM_TOKENS_METER; - break; - case CHAIN_KIND_MULTIVAC: - numTokens = NUM_TOKENS_MULTIVAC; - break; - case CHAIN_KIND_TECRA: - numTokens = NUM_TOKENS_TECRA; - break; - case CHAIN_KIND_APOTHEMNETWORK: - numTokens = NUM_TOKENS_APOTHEMNETWORK; - break; - case CHAIN_KIND_ID4GOOD: - numTokens = NUM_TOKENS_ID4GOOD; - break; - case CHAIN_KIND_OASYS: - numTokens = NUM_TOKENS_OASYS; - break; - } - for (i = 0; i < numTokens; i++) { - switch (chainConfig->kind) { - case CHAIN_KIND_AKROMA: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_AKROMA[i]); - break; - case CHAIN_KIND_ETHEREUM: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ETHEREUM[i]); - break; - case CHAIN_KIND_ETHEREUM_CLASSIC: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ETHEREUM_CLASSIC[i]); - break; - case CHAIN_KIND_PIRL: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_PIRL[i]); - break; - case CHAIN_KIND_POA: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_POA[i]); - break; - case CHAIN_KIND_ARTIS_SIGMA1: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ARTIS_SIGMA1[i]); - break; - case CHAIN_KIND_ARTIS_TAU1: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ARTIS_TAU1[i]); - break; - case CHAIN_KIND_RSK: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_RSK[i]); - break; - case CHAIN_KIND_EXPANSE: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_EXPANSE[i]); - break; - case CHAIN_KIND_UBIQ: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_UBIQ[i]); - break; - case CHAIN_KIND_WANCHAIN: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_WANCHAIN[i]); - break; - case CHAIN_KIND_KUSD: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_KUSD[i]); - break; - case CHAIN_KIND_MUSICOIN: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_MUSICOIN[i]); - break; - case CHAIN_KIND_CALLISTO: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_CALLISTO[i]); - break; - case CHAIN_KIND_ETHERSOCIAL: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ETHERSOCIAL[i]); - break; - case CHAIN_KIND_ELLAISM: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ELLAISM[i]); - break; - case CHAIN_KIND_ETHER1: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ETHER1[i]); - break; - case CHAIN_KIND_ETHERGEM: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ETHERGEM[i]); - break; - case CHAIN_KIND_ATHEIOS: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ATHEIOS[i]); - break; - case CHAIN_KIND_GOCHAIN: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_GOCHAIN[i]); - break; - case CHAIN_KIND_MIX: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_MIX[i]); - break; - case CHAIN_KIND_REOSC: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_REOSC[i]); - break; - case CHAIN_KIND_HPB: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_HPB[i]); - break; - case CHAIN_KIND_TOMOCHAIN: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_TOMOCHAIN[i]); - break; - case CHAIN_KIND_MOONRIVER: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_MOONRIVER[i]); - break; - case CHAIN_KIND_TOBALABA: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_TOBALABA[i]); - break; - case CHAIN_KIND_DEXON: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_DEXON[i]); - break; - case CHAIN_KIND_VOLTA: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_VOLTA[i]); - break; - case CHAIN_KIND_ENERGYWEBCHAIN: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ENERGYWEBCHAIN[i]); - break; - case CHAIN_KIND_WEBCHAIN: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_WEBCHAIN[i]); - break; - case CHAIN_KIND_THUNDERCORE: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_THUNDERCORE[i]); - break; - case CHAIN_KIND_FLARE: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_FLARE[i]); - break; - case CHAIN_KIND_BSC: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_BSC[i]); - break; - case CHAIN_KIND_SONGBIRD: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_SONGBIRD[i]); - break; - case CHAIN_KIND_POLYGON: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_POLYGON[i]); - break; - case CHAIN_KIND_SHYFT: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_SHYFT[i]); - break; - case CHAIN_KIND_CONFLUX_ESPACE: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_CONFLUX_ESPACE[i]); - break; - case CHAIN_KIND_MOONBEAM: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_MOONBEAM[i]); - break; - case CHAIN_KIND_BTTC: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_BTTC[i]); - break; - case CHAIN_KIND_KARDIACHAIN: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_KARDIACHAIN[i]); - break; - case CHAIN_KIND_WETHIO: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_WETHIO[i]); - break; - case CHAIN_KIND_OKC: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_OKC[i]); - break; - case CHAIN_KIND_CUBE: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_CUBE[i]); - break; - case CHAIN_KIND_SHIDEN: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_SHIDEN[i]); - break; - case CHAIN_KIND_ASTAR: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ASTAR[i]); - break; - case CHAIN_KIND_XDCNETWORK: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_XDCNETWORK[i]); - break; - case CHAIN_KIND_METER: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_METER[i]); - break; - case CHAIN_KIND_MULTIVAC: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_MULTIVAC[i]); - break; - case CHAIN_KIND_TECRA: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_TECRA[i]); - break; - case CHAIN_KIND_APOTHEMNETWORK: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_APOTHEMNETWORK[i]); - break; - case CHAIN_KIND_ID4GOOD: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_ID4GOOD[i]); - break; - case CHAIN_KIND_OASYS: - currentToken = (tokenDefinition_t *) PIC(&TOKENS_OASYS[i]); - break; - } - if (memcmp(currentToken->address, tmpContent.txContent.destination, ADDRESS_LENGTH) == 0) { - return currentToken; - } - } -#endif // Works for ERC-20 & NFT tokens since both structs in the union have the // contract address aligned for (uint8_t i = 0; i < MAX_ITEMS; i++) { @@ -555,52 +222,6 @@ void handleApdu(unsigned int *flags, unsigned int *tx) { #endif // HAVE_WALLET_ID_SDK -#ifdef HAVE_STARKWARE - - if (G_io_apdu_buffer[OFFSET_CLA] == STARKWARE_CLA) { - switch (G_io_apdu_buffer[OFFSET_INS]) { - case STARKWARE_INS_GET_PUBLIC_KEY: - handleStarkwareGetPublicKey(G_io_apdu_buffer[OFFSET_P1], - G_io_apdu_buffer[OFFSET_P2], - G_io_apdu_buffer + OFFSET_CDATA, - G_io_apdu_buffer[OFFSET_LC], - flags, - tx); - break; - case STARKWARE_INS_SIGN_MESSAGE: - handleStarkwareSignMessage(G_io_apdu_buffer[OFFSET_P1], - G_io_apdu_buffer[OFFSET_P2], - G_io_apdu_buffer + OFFSET_CDATA, - G_io_apdu_buffer[OFFSET_LC], - flags, - tx); - break; - case STARKWARE_INS_PROVIDE_QUANTUM: - handleStarkwareProvideQuantum(G_io_apdu_buffer[OFFSET_P1], - G_io_apdu_buffer[OFFSET_P2], - G_io_apdu_buffer + OFFSET_CDATA, - G_io_apdu_buffer[OFFSET_LC], - flags, - tx); - break; - case STARKWARE_INS_UNSAFE_SIGN: - handleStarkwareUnsafeSign(G_io_apdu_buffer[OFFSET_P1], - G_io_apdu_buffer[OFFSET_P2], - G_io_apdu_buffer + OFFSET_CDATA, - G_io_apdu_buffer[OFFSET_LC], - flags, - tx); - break; - default: - THROW(0x6D00); - break; - } - CLOSE_TRY; - return; - } - -#endif - if (G_io_apdu_buffer[OFFSET_CLA] != CLA) { THROW(0x6E00); } @@ -781,6 +402,7 @@ void handleApdu(unsigned int *flags, unsigned int *tx) { THROW(EXCEPTION_IO_RESET); } CATCH_OTHER(e) { + bool quit_now = G_called_from_swap && G_swap_response_ready; switch (e & 0xF000) { case 0x6000: // Wipe the transaction context and report the exception @@ -801,6 +423,18 @@ void handleApdu(unsigned int *flags, unsigned int *tx) { G_io_apdu_buffer[*tx] = sw >> 8; G_io_apdu_buffer[*tx + 1] = sw; *tx += 2; + + // If we are in swap mode and have validated a TX, we send it and immediately quit + if (quit_now) { + if (io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, *tx) == 0) { + // In case of success, the apdu is sent immediatly and eth exits + // Reaching this code means we encountered an error + finalize_exchange_sign_transaction(false); + } else { + PRINTF("Unrecoverable\n"); + os_sched_exit(-1); + } + } } FINALLY { } @@ -950,7 +584,6 @@ void init_coin_config(chain_config_t *coin_config) { memset(coin_config, 0, sizeof(chain_config_t)); strcpy(coin_config->coinName, CHAINID_COINNAME); coin_config->chainId = CHAIN_ID; - coin_config->kind = CHAIN_KIND; } void coin_main(libargs_t *args) { @@ -1042,122 +675,108 @@ void coin_main(libargs_t *args) { app_exit(); } -static void library_main_helper(libargs_t *args) { - check_api_level(CX_COMPAT_APILEVEL); +void library_main(libargs_t *args) { + chain_config_t coin_config; + if (args->chain_config == NULL) { + // We have been started directly by Exchange, not by a Clone. Init default chain + init_coin_config(&coin_config); + args->chain_config = &coin_config; + } + PRINTF("Inside a library \n"); switch (args->command) { case CHECK_ADDRESS: - // ensure result is zero if an exception is thrown - args->check_address->result = 0; - args->check_address->result = - handle_check_address(args->check_address, args->chain_config); + handle_check_address(args->check_address, args->chain_config); break; case SIGN_TRANSACTION: if (copy_transaction_parameters(args->create_transaction, args->chain_config)) { // never returns handle_swap_sign_transaction(args->chain_config); + } else { + // Failed to copy, non recoverable + os_sched_exit(-1); } break; case GET_PRINTABLE_AMOUNT: - // ensure result is zero if an exception is thrown (compatibility breaking, disabled - // until LL is ready) - // args->get_printable_amount->result = 0; - // args->get_printable_amount->result = handle_get_printable_amount(args->get_printable_amount, args->chain_config); break; default: break; } + os_lib_end(); } -void library_main(libargs_t *args) { - chain_config_t coin_config; - if (args->chain_config == NULL) { - init_coin_config(&coin_config); - args->chain_config = &coin_config; - } - volatile bool end = false; - /* This loop ensures that library_main_helper and os_lib_end are called - * within a try context, even if an exception is thrown */ - while (1) { - BEGIN_TRY { - TRY { - if (!end) { - library_main_helper(args); - } - os_lib_end(); - } - FINALLY { - end = true; - } - } - END_TRY; - } -} - -__attribute__((section(".boot"))) int main(int arg0) { -#ifdef USE_LIB_ETHEREUM +/* Eth clones do not actually contain any logic, they delegate everything to the ETH application. + * Start Eth in lib mode with the correct chain config + */ +__attribute__((noreturn)) void clone_main(libargs_t *args) { + PRINTF("Starting in clone_main\n"); BEGIN_TRY { TRY { unsigned int libcall_params[5]; chain_config_t local_chainConfig; init_coin_config(&local_chainConfig); - PRINTF("Hello from Eth-clone\n"); - check_api_level(CX_COMPAT_APILEVEL); - // delegate to Ethereum app/lib libcall_params[0] = (unsigned int) "Ethereum"; libcall_params[1] = 0x100; - libcall_params[2] = RUN_APPLICATION; libcall_params[3] = (unsigned int) &local_chainConfig; -#ifdef HAVE_NBGL - const char app_name[] = APPNAME; - caller_app_t capp; - nbgl_icon_details_t icon_details; - uint8_t bitmap[sizeof(ICONBITMAP)]; - - memcpy(&icon_details, &ICONGLYPH, sizeof(ICONGLYPH)); - memcpy(&bitmap, &ICONBITMAP, sizeof(bitmap)); - icon_details.bitmap = (const uint8_t *) bitmap; - capp.name = app_name; - capp.icon = &icon_details; - libcall_params[4] = (unsigned int) &capp; -#else - libcall_params[4] = NULL; -#endif // HAVE_NBGL - if (arg0) { - // call as a library - libcall_params[2] = ((unsigned int *) arg0)[1]; - libcall_params[4] = ((unsigned int *) arg0)[3]; // library arguments + // Clone called by Exchange, forward the request to Ethereum + if (args != NULL) { + if (args->id != 0x100) { + os_sched_exit(0); + } + libcall_params[2] = args->command; + libcall_params[4] = (unsigned int) args->get_printable_amount; os_lib_call((unsigned int *) &libcall_params); - ((unsigned int *) arg0)[0] = libcall_params[1]; + // Ethereum fulfilled the request and returned to us. We return to Exchange. os_lib_end(); } else { - // launch coin application - libcall_params[1] = 0x100; // use the Init call, as we won't exit + // Clone called from Dashboard, start Ethereum + libcall_params[2] = RUN_APPLICATION; +// On Stax, forward our icon to Ethereum +#ifdef HAVE_NBGL + const char app_name[] = APPNAME; + caller_app_t capp; + nbgl_icon_details_t icon_details; + uint8_t bitmap[sizeof(ICONBITMAP)]; + + memcpy(&icon_details, &ICONGLYPH, sizeof(ICONGLYPH)); + memcpy(&bitmap, &ICONBITMAP, sizeof(bitmap)); + icon_details.bitmap = (const uint8_t *) bitmap; + capp.name = app_name; + capp.icon = &icon_details; + libcall_params[4] = (unsigned int) &capp; +#else + libcall_params[4] = 0; +#endif // HAVE_NBGL os_lib_call((unsigned int *) &libcall_params); + // Ethereum should not return to us + os_sched_exit(-1); } } FINALLY { } } END_TRY; - // no return -#else + + // os_lib_call will raise if Ethereum application is not installed. Do not try to recover. + os_sched_exit(-1); +} + +int ethereum_main(libargs_t *args) { // exit critical section __asm volatile("cpsie i"); // ensure exception will work as planned os_boot(); - if (!arg0) { + if (args == NULL) { // called from dashboard as standalone eth app coin_main(NULL); return 0; } - libargs_t *args = (libargs_t *) arg0; if (args->id != 0x100) { app_exit(); return 0; @@ -1171,6 +790,13 @@ __attribute__((section(".boot"))) int main(int arg0) { // called as ethereum or altcoin library library_main(args); } -#endif return 0; } + +__attribute__((section(".boot"))) int main(int arg0) { +#ifdef USE_LIB_ETHEREUM + clone_main((libargs_t *) arg0); +#else + return ethereum_main((libargs_t *) arg0); +#endif +} diff --git a/src_common/mem.c b/src/mem.c similarity index 100% rename from src_common/mem.c rename to src/mem.c diff --git a/src_common/mem.h b/src/mem.h similarity index 100% rename from src_common/mem.h rename to src/mem.h diff --git a/src_common/mem_utils.c b/src/mem_utils.c similarity index 100% rename from src_common/mem_utils.c rename to src/mem_utils.c diff --git a/src_common/mem_utils.h b/src/mem_utils.h similarity index 100% rename from src_common/mem_utils.h rename to src/mem_utils.h diff --git a/src_common/network.c b/src/network.c similarity index 68% rename from src_common/network.c rename to src/network.c index 8c0d238a6..1563c321f 100644 --- a/src_common/network.c +++ b/src/network.c @@ -2,6 +2,8 @@ #include "os_utils.h" #include "os_pic.h" #include "network.h" +#include "shared_context.h" +#include "common_utils.h" typedef struct network_info_s { const char *name; @@ -9,6 +11,8 @@ typedef struct network_info_s { uint64_t chain_id; } network_info_t; +static const char *unknown_ticker = "???"; + // Mappping of chain ids to networks. static const network_info_t NETWORK_MAPPING[] = { {.chain_id = 1, .name = "Ethereum", .ticker = "ETH"}, @@ -53,9 +57,9 @@ static const network_info_t NETWORK_MAPPING[] = { {.chain_id = 19, .name = "Songbird", .ticker = "SGB"}, {.chain_id = 73799, .name = "Volta", .ticker = "VOLTA"}, {.chain_id = 25, .name = "Cronos", .ticker = "CRO"}, - {.chain_id = 534354, .name = "Scroll (Pre-Alpha)", .ticker = "SCR"}, - {.chain_id = 534353, .name = "Scroll (Goerli)", .ticker = "SCR"}, - {.chain_id = 534352, .name = "Scroll", .ticker = "SCR"}, + {.chain_id = 534353, .name = "Scroll Alpha", .ticker = "ETH"}, + {.chain_id = 534351, .name = "Scroll Sepolia", .ticker = "ETH"}, + {.chain_id = 534352, .name = "Scroll", .ticker = "ETH"}, {.chain_id = 321, .name = "KCC", .ticker = "KCS"}, {.chain_id = 30, .name = "Rootstock", .ticker = "RBTC"}, {.chain_id = 9001, .name = "Evmos", .ticker = "EVMOS"}, @@ -75,7 +79,13 @@ static const network_info_t NETWORK_MAPPING[] = { {.chain_id = 248, .name = "Oasys", .ticker = "OAS"}, {.chain_id = 1101, .name = "Polygon zkEVM", .ticker = "ETH"}, {.chain_id = 8453, .name = "Base", .ticker = "ETH"}, - {.chain_id = 58008, .name = "Sepolia", .ticker = "ETH"}, + {.chain_id = 1907, .name = "Bitcichain", .ticker = "BITCI"}, + {.chain_id = 1116, .name = "Core", .ticker = "CORE"}, + {.chain_id = 7171, .name = "Bitrock Mainnet", .ticker = "BROCK"}, + {.chain_id = 10507, .name = "Numbers Protocol", .ticker = "NUM"}, + {.chain_id = 59144, .name = "Linea", .ticker = "ETH"}, + {.chain_id = 11155111, .name = "Sepolia", .ticker = "ETH"}, + {.chain_id = 17000, .name = "Holesky", .ticker = "ETH"}, }; static const network_info_t *get_network_from_chain_id(const uint64_t *chain_id) { @@ -108,3 +118,48 @@ const char *get_network_ticker_from_chain_id(const uint64_t *chain_id) { bool chain_is_ethereum_compatible(const uint64_t *chain_id) { return get_network_from_chain_id(chain_id) != NULL; } + +// Returns the chain ID. Defaults to 0 if txType was not found (For TX). +uint64_t get_tx_chain_id(void) { + uint64_t chain_id = 0; + + switch (txContext.txType) { + case LEGACY: + chain_id = u64_from_BE(txContext.content->v, txContext.content->vLength); + break; + case EIP2930: + case EIP1559: + chain_id = u64_from_BE(tmpContent.txContent.chainID.value, + tmpContent.txContent.chainID.length); + break; + default: + PRINTF("Txtype `%d` not supported while generating chainID\n", txContext.txType); + break; + } + return chain_id; +} + +const char *get_displayable_ticker(const uint64_t *chain_id, const chain_config_t *chain_cfg) { + const char *ticker = get_network_ticker_from_chain_id(chain_id); + + if (ticker == NULL) { + if (*chain_id == chain_cfg->chainId) { + ticker = chain_cfg->coinName; + } else { + ticker = unknown_ticker; + } + } + return ticker; +} + +/** + * Checks wether the app can support the given chain ID + * + * - If the given chain ID is the same as the app's one + * - If both chain IDs are present in the array of Ethereum-compatible networks + */ +bool app_compatible_with_chain_id(const uint64_t *chain_id) { + return ((chainConfig->chainId == *chain_id) || + (chain_is_ethereum_compatible(&chainConfig->chainId) && + chain_is_ethereum_compatible(chain_id))); +} diff --git a/src/network.h b/src/network.h new file mode 100644 index 000000000..ee96347b5 --- /dev/null +++ b/src/network.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include "chainConfig.h" + +#define UNSUPPORTED_CHAIN_ID_MSG(id) \ + do { \ + PRINTF("Unsupported chain ID: %u (app: %u)\n", id, chainConfig->chainId); \ + } while (0) + +const char *get_network_name_from_chain_id(const uint64_t *chain_id); +const char *get_network_ticker_from_chain_id(const uint64_t *chain_id); + +bool chain_is_ethereum_compatible(const uint64_t *chain_id); +bool app_compatible_with_chain_id(const uint64_t *chain_id); + +uint64_t get_tx_chain_id(void); + +const char *get_displayable_ticker(const uint64_t *chain_id, const chain_config_t *chain_cfg); diff --git a/src/nft.h b/src/nft.h deleted file mode 100644 index 43ee5d151..000000000 --- a/src/nft.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _NFT_H_ -#define _NFT_H_ - -#include - -#define COLLECTION_NAME_MAX_LEN 70 -#define NO_NFT_METADATA (NO_EXTRA_INFO(tmpCtx, 1)) - -typedef struct nftInfo_t { - uint8_t contractAddress[ADDRESS_LENGTH]; // must be first item - char collectionName[COLLECTION_NAME_MAX_LEN + 1]; -} nftInfo_t; - -#endif // _NFT_H_ diff --git a/src_common/plugins.c b/src/plugins.c similarity index 100% rename from src_common/plugins.c rename to src/plugins.c diff --git a/src_common/plugins.h b/src/plugins.h similarity index 100% rename from src_common/plugins.h rename to src/plugins.h diff --git a/src/poorstream.c b/src/poorstream.c deleted file mode 100644 index 2dc2fa807..000000000 --- a/src/poorstream.c +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "poorstream.h" - -void poorstream_init(poorstream_t *stream, uint8_t *buffer) { - memset((void *) stream, 0, sizeof(poorstream_t)); - stream->pointer = buffer; -} - -void poorstream_flush(poorstream_t *stream) { - // PRINTF("Flush\n"); - *(stream->pointer + 0) = (stream->accumulator >> 56); - *(stream->pointer + 1) = (stream->accumulator >> 48); - *(stream->pointer + 2) = (stream->accumulator >> 40); - *(stream->pointer + 3) = (stream->accumulator >> 32); - *(stream->pointer + 4) = (stream->accumulator >> 24); - *(stream->pointer + 5) = (stream->accumulator >> 16); - *(stream->pointer + 6) = (stream->accumulator >> 8); - *(stream->pointer + 7) = (stream->accumulator >> 0); -} - -void poorstream_write_bits(poorstream_t *stream, uint64_t bits, uint32_t num_bits) { - stream->offset += num_bits; - if (stream->offset < 64) { - stream->accumulator |= (bits << (64 - stream->offset)); - // PRINTF("ACC |= << %d\n", (64 - stream->offset)); - } else { - stream->offset -= 64; - stream->mask = ((1 << (num_bits - stream->offset)) - 1); - // PRINTF("Mask %lx\n", stream->mask); - // PRINTF("Offset %d\n", stream->offset); - stream->accumulator |= ((bits >> stream->offset) & stream->mask); - poorstream_flush(stream); - stream->accumulator = 0; - stream->pointer += 8; - if (stream->offset) { - stream->mask = ((1 << stream->offset) - 1); - stream->accumulator |= ((bits & stream->mask) << (64 - stream->offset)); - } - } -} - -#endif diff --git a/src/poorstream.h b/src/poorstream.h deleted file mode 100644 index 6ac17a527..000000000 --- a/src/poorstream.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _POORSTREAM_H_ -#define _POORSTREAM_H_ - -#include -#include -#include - -#include "os.h" - -typedef struct poorstream_t { - uint8_t *pointer; - uint32_t offset; - uint64_t mask; - uint64_t accumulator; -} poorstream_t; - -void poorstream_init(poorstream_t *stream, uint8_t *buffer); -void poorstream_flush(poorstream_t *stream); -void poorstream_write_bits(poorstream_t *stream, uint64_t bits, uint32_t num_bits); - -#endif // _POORSTREAM_H_ diff --git a/src/public_keys.h b/src/public_keys.h new file mode 100644 index 000000000..d5964dbf4 --- /dev/null +++ b/src/public_keys.h @@ -0,0 +1,103 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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 + +static const uint8_t LEDGER_SIGNATURE_PUBLIC_KEY[] = { +#if defined(HAVE_CAL_TEST_KEY) + 0x04, 0x4c, 0xca, 0x8f, 0xad, 0x49, 0x6a, 0xa5, 0x04, 0x0a, 0x00, 0xa7, 0xeb, 0x2f, + 0x5c, 0xc3, 0xb8, 0x53, 0x76, 0xd8, 0x8b, 0xa1, 0x47, 0xa7, 0xd7, 0x05, 0x4a, 0x99, + 0xc6, 0x40, 0x56, 0x18, 0x87, 0xfe, 0x17, 0xa0, 0x96, 0xe3, 0x6c, 0x3b, 0x52, 0x3b, + 0x24, 0x4f, 0x3e, 0x2f, 0xf7, 0xf8, 0x40, 0xae, 0x26, 0xc4, 0xe7, 0x7a, 0xd3, 0xbc, + 0x73, 0x9a, 0xf5, 0xde, 0x6f, 0x2d, 0x77, 0xa7, 0xb6 +#elif defined(HAVE_CAL_STAGING_KEY) + // staging key 2019-01-11 03:07PM (erc20signer) + 0x04, 0x20, 0xda, 0x62, 0x00, 0x3c, 0x0c, 0xe0, 0x97, 0xe3, 0x36, 0x44, 0xa1, 0x0f, + 0xe4, 0xc3, 0x04, 0x54, 0x06, 0x9a, 0x44, 0x54, 0xf0, 0xfa, 0x9d, 0x4e, 0x84, 0xf4, + 0x50, 0x91, 0x42, 0x9b, 0x52, 0x20, 0xaf, 0x9e, 0x35, 0xc0, 0xb2, 0xd9, 0x28, 0x93, + 0x80, 0x13, 0x73, 0x07, 0xde, 0x4d, 0xd1, 0xd4, 0x18, 0x42, 0x8c, 0xf2, 0x1a, 0x93, + 0xb3, 0x35, 0x61, 0xbb, 0x09, 0xd8, 0x8f, 0xe5, 0x79 +#else + // production key 2019-01-11 03:07PM (erc20signer) + 0x04, 0x5e, 0x6c, 0x10, 0x20, 0xc1, 0x4d, 0xc4, 0x64, 0x42, 0xfe, 0x89, 0xf9, 0x7c, + 0x0b, 0x68, 0xcd, 0xb1, 0x59, 0x76, 0xdc, 0x24, 0xf2, 0x4c, 0x31, 0x6e, 0x7b, 0x30, + 0xfe, 0x4e, 0x8c, 0xc7, 0x6b, 0x14, 0x89, 0x15, 0x0c, 0x21, 0x51, 0x4e, 0xbf, 0x44, + 0x0f, 0xf5, 0xde, 0xa5, 0x39, 0x3d, 0x83, 0xde, 0x53, 0x58, 0xcd, 0x09, 0x8f, 0xce, + 0x8f, 0xd0, 0xf8, 0x1d, 0xaa, 0x94, 0x97, 0x91, 0x83 +#endif +}; + +static const uint8_t LEDGER_NFT_METADATA_PUBLIC_KEY[] = { +#if defined(HAVE_NFT_TEST_KEY) + 0x04, 0x3c, 0xfb, 0x5f, 0xb3, 0x19, 0x05, 0xf4, 0xbd, 0x39, 0xd9, 0xd5, 0x35, 0xa4, + 0x0c, 0x26, 0xaa, 0xb5, 0x1c, 0x5d, 0x7d, 0x32, 0x19, 0xb2, 0x8a, 0xc9, 0x42, 0xb9, + 0x80, 0xfb, 0x20, 0x6c, 0xfb, 0x30, 0xb5, 0x1c, 0xc2, 0xde, 0x21, 0x19, 0xac, 0x03, + 0x8e, 0xbb, 0x0d, 0x7d, 0xd6, 0x54, 0x17, 0x70, 0x20, 0x4a, 0x3c, 0xed, 0x3a, 0x79, + 0xe2, 0x8b, 0x32, 0xfb, 0xb6, 0x72, 0x64, 0x68, 0xc0 +#elif defined(HAVE_NFT_STAGING_KEY) + 0x04, 0xf5, 0x70, 0x0c, 0xa1, 0xe8, 0x74, 0x24, 0xc7, 0xc7, 0xd1, 0x19, 0xe7, 0xe3, + 0xc1, 0x89, 0xb1, 0x62, 0x50, 0x94, 0xdb, 0x6e, 0xa0, 0x40, 0x87, 0xc8, 0x30, 0x00, + 0x7d, 0x0b, 0x46, 0x9a, 0x53, 0x11, 0xee, 0x6a, 0x1a, 0xcd, 0x1d, 0xa5, 0xaa, 0xb0, + 0xf5, 0xc6, 0xdf, 0x13, 0x15, 0x8d, 0x28, 0xcc, 0x12, 0xd1, 0xdd, 0xa6, 0xec, 0xe9, + 0x46, 0xb8, 0x9d, 0x5c, 0x05, 0x49, 0x92, 0x59, 0xc4 +#else // production key + 0x04, 0x98, 0x8d, 0xa6, 0xb2, 0x46, 0xf2, 0x8e, 0x77, 0xc1, 0xba, 0xb6, 0x75, 0xcb, + 0x2a, 0x27, 0x44, 0xf7, 0xf5, 0xce, 0xc5, 0x6a, 0xe6, 0xe0, 0x32, 0x23, 0x33, 0x7b, + 0x57, 0x94, 0xcd, 0x6a, 0xe0, 0x7d, 0x48, 0xb3, 0x0d, 0xb9, 0xcc, 0xb4, 0x0f, 0x5a, + 0x02, 0xa1, 0x1a, 0x3a, 0xb9, 0x9d, 0x5f, 0x59, 0x5a, 0x3d, 0x50, 0xa0, 0xe1, 0x30, + 0x23, 0xfd, 0x0d, 0x95, 0x87, 0x92, 0xd7, 0x97, 0x01 +#endif +}; + +static const uint8_t DOMAIN_NAME_PUB_KEY[] = { +#ifdef HAVE_DOMAIN_NAME_TEST_KEY + 0x04, 0xb9, 0x1f, 0xbe, 0xc1, 0x73, 0xe3, 0xba, 0x4a, 0x71, 0x4e, 0x01, 0x4e, 0xbc, + 0x82, 0x7b, 0x6f, 0x89, 0x9a, 0x9f, 0xa7, 0xf4, 0xac, 0x76, 0x9c, 0xde, 0x28, 0x43, + 0x17, 0xa0, 0x0f, 0x4f, 0x65, 0x0f, 0x09, 0xf0, 0x9a, 0xa4, 0xff, 0x5a, 0x31, 0x76, + 0x02, 0x55, 0xfe, 0x5d, 0xfc, 0x81, 0x13, 0x29, 0xb3, 0xb5, 0x0b, 0xe9, 0x91, 0x94, + 0xfc, 0xa1, 0x16, 0x19, 0xe6, 0x5f, 0x2e, 0xdf, 0xea +#else + 0x04, 0x6a, 0x94, 0xe7, 0xa4, 0x2c, 0xd0, 0xc3, 0x3f, 0xdf, 0x44, 0x0c, 0x8e, 0x2a, + 0xb2, 0x54, 0x2c, 0xef, 0xbe, 0x5d, 0xb7, 0xaa, 0x0b, 0x93, 0xa9, 0xfc, 0x81, 0x4b, + 0x9a, 0xcf, 0xa7, 0x5e, 0xb4, 0xe5, 0x3d, 0x6f, 0x00, 0x25, 0x94, 0xbd, 0xb6, 0x05, + 0xd9, 0xb5, 0xbd, 0xa9, 0xfa, 0x4b, 0x4b, 0xf3, 0xa5, 0x49, 0x6f, 0xd3, 0x16, 0x4b, + 0xae, 0xf5, 0xaf, 0xcf, 0x90, 0xe8, 0x40, 0x88, 0x71 +#endif +}; + +// Only used for signing NFT plugins (ERC721 and ERC1155) +static const uint8_t LEDGER_NFT_SELECTOR_PUBLIC_KEY[] = { +#if defined(HAVE_SET_PLUGIN_TEST_KEY) + 0x04, 0xc0, 0x55, 0xbc, 0x4e, 0xcf, 0x05, 0x5e, 0x2d, 0x85, 0x08, 0x5d, 0x35, 0x12, + 0x7a, 0x3d, 0xe6, 0x70, 0x5c, 0x7f, 0x88, 0x50, 0x55, 0xcd, 0x70, 0x71, 0xe8, 0x76, + 0x71, 0xbf, 0x19, 0x1f, 0xe3, 0x3c, 0xc8, 0xf0, 0x1a, 0xbc, 0x2f, 0x28, 0x7c, 0x81, + 0x9a, 0x14, 0x8a, 0xbe, 0x1b, 0x58, 0x1d, 0xf1, 0xb4, 0x94, 0x0a, 0xf5, 0xd4, 0xdc, + 0x3a, 0x4e, 0x6b, 0x60, 0x19, 0x17, 0x71, 0x2b, 0x37 +#elif defined(HAVE_NFT_STAGING_KEY) + 0x04, 0xf5, 0x70, 0x0c, 0xa1, 0xe8, 0x74, 0x24, 0xc7, 0xc7, 0xd1, 0x19, 0xe7, 0xe3, + 0xc1, 0x89, 0xb1, 0x62, 0x50, 0x94, 0xdb, 0x6e, 0xa0, 0x40, 0x87, 0xc8, 0x30, 0x00, + 0x7d, 0x0b, 0x46, 0x9a, 0x53, 0x11, 0xee, 0x6a, 0x1a, 0xcd, 0x1d, 0xa5, 0xaa, 0xb0, + 0xf5, 0xc6, 0xdf, 0x13, 0x15, 0x8d, 0x28, 0xcc, 0x12, 0xd1, 0xdd, 0xa6, 0xec, 0xe9, + 0x46, 0xb8, 0x9d, 0x5c, 0x05, 0x49, 0x92, 0x59, 0xc4 +#else + 0x04, 0xd8, 0x62, 0x6e, 0x01, 0x9e, 0x55, 0x3e, 0x19, 0x69, 0x56, 0xf1, 0x17, 0x4d, + 0xcd, 0xb8, 0x9a, 0x1c, 0xda, 0xc4, 0x93, 0x90, 0x08, 0xbc, 0x79, 0x77, 0x33, 0x6d, + 0x78, 0x24, 0xee, 0xe3, 0xa2, 0x62, 0x24, 0x1a, 0x62, 0x73, 0x52, 0x3b, 0x09, 0xb8, + 0xd0, 0xce, 0x0d, 0x39, 0xe8, 0x60, 0xc9, 0x4d, 0x02, 0x53, 0x58, 0xdb, 0xdc, 0x25, + 0x92, 0xc7, 0xc6, 0x48, 0x0d, 0x39, 0xce, 0xbb, 0xa3 +#endif +}; diff --git a/src/rlp_utils.c b/src/rlp_utils.c new file mode 100644 index 000000000..b8b3a8f65 --- /dev/null +++ b/src/rlp_utils.c @@ -0,0 +1,113 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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. + ********************************************************************************/ + +/** + * @brief Utilities for an Ethereum Hardware Wallet logic + * @file ethUtils.h + * @author Ledger Firmware Team + * @version 1.0 + * @date 8th of March 2016 + */ + +#include +#include +#include + +#include "rlp_utils.h" + +bool rlpCanDecode(uint8_t *buffer, uint32_t bufferLength, bool *valid) { + if (*buffer <= 0x7f) { + } else if (*buffer <= 0xb7) { + } else if (*buffer <= 0xbf) { + if (bufferLength < (1 + (*buffer - 0xb7))) { + return false; + } + if (*buffer > 0xbb) { + *valid = false; // arbitrary 32 bits length limitation + return true; + } + } else if (*buffer <= 0xf7) { + } else { + if (bufferLength < (1 + (*buffer - 0xf7))) { + return false; + } + if (*buffer > 0xfb) { + *valid = false; // arbitrary 32 bits length limitation + return true; + } + } + *valid = true; + return true; +} + +bool rlpDecodeLength(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, bool *list) { + if (*buffer <= 0x7f) { + *offset = 0; + *fieldLength = 1; + *list = false; + } else if (*buffer <= 0xb7) { + *offset = 1; + *fieldLength = *buffer - 0x80; + *list = false; + } else if (*buffer <= 0xbf) { + *offset = 1 + (*buffer - 0xb7); + *list = false; + switch (*buffer) { + case 0xb8: + *fieldLength = *(buffer + 1); + break; + case 0xb9: + *fieldLength = (*(buffer + 1) << 8) + *(buffer + 2); + break; + case 0xba: + *fieldLength = (*(buffer + 1) << 16) + (*(buffer + 2) << 8) + *(buffer + 3); + break; + case 0xbb: + *fieldLength = (*(buffer + 1) << 24) + (*(buffer + 2) << 16) + + (*(buffer + 3) << 8) + *(buffer + 4); + break; + default: + return false; // arbitrary 32 bits length limitation + } + } else if (*buffer <= 0xf7) { + *offset = 1; + *fieldLength = *buffer - 0xc0; + *list = true; + } else { + *offset = 1 + (*buffer - 0xf7); + *list = true; + switch (*buffer) { + case 0xf8: + *fieldLength = *(buffer + 1); + break; + case 0xf9: + *fieldLength = (*(buffer + 1) << 8) + *(buffer + 2); + break; + case 0xfa: + *fieldLength = (*(buffer + 1) << 16) + (*(buffer + 2) << 8) + *(buffer + 3); + break; + case 0xfb: + *fieldLength = (*(buffer + 1) << 24) + (*(buffer + 2) << 16) + + (*(buffer + 3) << 8) + *(buffer + 4); + break; + default: + return false; // arbitrary 32 bits length limitation + } + } + + return true; +} diff --git a/src/rlp_utils.h b/src/rlp_utils.h new file mode 100644 index 000000000..7da158836 --- /dev/null +++ b/src/rlp_utils.h @@ -0,0 +1,37 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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 +#include +#include + +/** + * @brief Decode an RLP encoded field - see + * https://github.com/ethereum/wiki/wiki/RLP + * @param [in] buffer buffer containing the RLP encoded field to decode + * @param [out] fieldLength length of the RLP encoded field + * @param [out] offset offset to the beginning of the RLP encoded field from the + * buffer + * @param [out] list true if the field encodes a list, false if it encodes a + * string + * @return true if the RLP header is consistent + */ +bool rlpDecodeLength(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, bool *list); + +bool rlpCanDecode(uint8_t *buffer, uint32_t bufferLength, bool *valid); diff --git a/src/shared_context.h b/src/shared_context.h index f83320cb5..4c1591404 100644 --- a/src/shared_context.h +++ b/src/shared_context.h @@ -3,18 +3,19 @@ #include #include + +#include "os.h" +#include "cx.h" #include "ethUstream.h" -#include "tokens.h" +#include "tx_content.h" #include "chainConfig.h" -#include "nft.h" +#include "asset_info.h" #ifdef HAVE_NBGL #include "nbgl_types.h" #endif #define MAX_BIP32_PATH 10 -#define WEI_TO_ETHER 18 - #define SELECTOR_LENGTH 4 #define PLUGIN_ID_LENGTH 30 @@ -39,21 +40,6 @@ typedef struct internalStorage_t { bool initialized; } internalStorage_t; -#ifdef HAVE_STARKWARE - -typedef enum starkQuantumType_e { - - STARK_QUANTUM_LEGACY = 0x00, - STARK_QUANTUM_ETH, - STARK_QUANTUM_ERC20, - STARK_QUANTUM_ERC721, - STARK_QUANTUM_MINTABLE_ERC20, - STARK_QUANTUM_MINTABLE_ERC721 - -} starkQuantumType_e; - -#endif - typedef struct tokenContext_t { char pluginName[PLUGIN_ID_LENGTH]; @@ -77,13 +63,6 @@ typedef struct tokenContext_t { uint8_t pluginStatus; -#ifdef HAVE_STARKWARE - uint8_t quantum[32]; - uint8_t mintingBlob[32]; - uint8_t quantumIndex; - uint8_t quantumType; -#endif - } tokenContext_t; _Static_assert((offsetof(tokenContext_t, pluginContext) % 4) == 0, "Plugin context not aligned"); @@ -95,11 +74,6 @@ typedef struct publicKeyContext_t { bool getChaincode; } publicKeyContext_t; -typedef union extraInfo_t { - tokenDefinition_t token; - nftInfo_t nft; -} extraInfo_t; - typedef struct transactionContext_t { bip32_path_t bip32; uint8_t hash[INT256_LENGTH]; @@ -133,27 +107,8 @@ typedef union { char tmp[100]; } tmpContent_t; -#ifdef HAVE_STARKWARE - -typedef struct starkContext_t { - uint8_t w1[32]; - uint8_t w2[32]; - uint8_t w3[32]; - uint8_t w4[32]; - uint8_t conditional; - uint8_t transferDestination[32]; - uint8_t fact[32]; - uint8_t conditionAddress[20]; -} starkContext_t; - -#endif - typedef union { tokenContext_t tokenContext; - -#ifdef HAVE_STARKWARE - starkContext_t starkContext; -#endif } dataContext_t; typedef enum { APP_STATE_IDLE, APP_STATE_SIGNING_TX, APP_STATE_SIGNING_MESSAGE } app_state_t; @@ -162,28 +117,17 @@ typedef enum { CONTRACT_NONE, CONTRACT_ERC20, CONTRACT_ALLOWANCE, -#ifdef HAVE_STARKWARE - CONTRACT_STARKWARE_REGISTER, - CONTRACT_STARKWARE_DEPOSIT_TOKEN, - CONTRACT_STARKWARE_DEPOSIT_ETH, - CONTRACT_STARKWARE_WITHDRAW, - CONTRACT_STARKWARE_DEPOSIT_CANCEL, - CONTRACT_STARKWARE_DEPOSIT_RECLAIM, - CONTRACT_STARKWARE_FULL_WITHDRAWAL, - CONTRACT_STARKWARE_FREEZE, - CONTRACT_STARKWARE_ESCAPE, - CONTRACT_STARKWARE_VERIFY_ESCAPE -#endif } contract_call_t; -#define NETWORK_STRING_MAX_SIZE 16 +// must be able to hold in decimal up to : floor(MAX_UINT64 / 2) - 36 +#define NETWORK_STRING_MAX_SIZE 19 typedef struct txStringProperties_s { char fullAddress[43]; char fullAmount[79]; // 2^256 is 78 digits long char maxFee[50]; char nonce[8]; // 10M tx per account ought to be enough for everybody - char network_name[NETWORK_STRING_MAX_SIZE]; + char network_name[NETWORK_STRING_MAX_SIZE + 1]; } txStringProperties_t; #ifdef TARGET_NANOS @@ -214,6 +158,7 @@ extern cx_sha3_t global_sha3; extern const internalStorage_t N_storage_real; extern bool G_called_from_swap; +extern bool G_swap_response_ready; typedef enum { EXTERNAL, // External plugin, set by setExternalPlugin. @@ -224,26 +169,11 @@ typedef enum { extern pluginType_t pluginType; -typedef enum { CALLER_TYPE_CLONE, CALLER_TYPE_PLUGIN } e_caller_type; - -typedef struct caller_app_t { - const char *name; -#ifdef HAVE_NBGL - const nbgl_icon_details_t *icon; -#endif - char type; // does not have to be set by the caller app -} caller_app_t; - extern uint8_t appState; -#ifdef HAVE_STARKWARE -extern bool quantumSet; -#endif #ifdef HAVE_ETH2 extern uint32_t eth2WithdrawalIndex; #endif -extern caller_app_t *caller_app; - void reset_app_context(void); const uint8_t *parseBip32(const uint8_t *dataBuffer, uint8_t *dataLength, bip32_path_t *bip32); diff --git a/src/stark_crypto.c b/src/stark_crypto.c deleted file mode 100644 index ca738c930..000000000 --- a/src/stark_crypto.c +++ /dev/null @@ -1,91 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" -#include "stark_utils.h" -#include "utils.h" -#include "ethUtils.h" - -extraInfo_t *getKnownToken(uint8_t *contractAddress); - -static unsigned char const C_cx_Stark256_n[] = { - // n: 0x0800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xb7, 0x81, 0x12, 0x6d, 0xca, 0xe7, 0xb2, 0x32, 0x1e, 0x66, 0xa2, 0x41, 0xad, 0xc6, 0x4d, 0x2f}; - -// C_cx_secp256k1_n - (C_cx_secp256k1_n % C_cx_Stark256_n) -static unsigned char const STARK_DERIVE_BIAS[] = { - 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, - 0x38, 0xa1, 0x3b, 0x4b, 0x92, 0x0e, 0x94, 0x11, 0xae, 0x6d, 0xa5, 0xf4, 0x0b, 0x03, 0x58, 0xb1}; - -void starkDerivePrivateKey(uint32_t *bip32Path, uint32_t bip32PathLength, uint8_t *privateKeyData) { -#if 0 - // Sanity check - if (bip32Path[0] != STARK_BIP32_PATH_0) { - PRINTF("Invalid Stark derivation path %d\n", bip32Path[0]); - THROW(0x6a80); - } - os_perso_derive_node_bip32(CX_CURVE_256K1, bip32Path, bip32PathLength, privateKeyData, NULL); - PRINTF("Private key before processing %.*H\n", 32, privateKeyData); - // TODO - support additional schemes - cx_math_modm(privateKeyData, 32, C_cx_Stark256_n, 32); - PRINTF("Private key after processing %.*H\n", 32, privateKeyData); -#else - uint8_t tmp[33]; - uint8_t index = 0; - // Sanity check - if ((bip32PathLength < 2) || (bip32Path[0] != STARK_BIP32_PATH_0) || - (bip32Path[1] != STARK_BIP32_PATH_1)) { - PRINTF("Invalid Stark derivation path %d %d\n", bip32Path[0], bip32Path[1]); - THROW(0x6a80); - } - os_perso_derive_node_bip32(CX_CURVE_256K1, bip32Path, bip32PathLength, tmp, NULL); - PRINTF("Private key before processing %.*H\n", 32, tmp); - for (;;) { - tmp[32] = index; - cx_hash_sha256(tmp, 33, privateKeyData, 32); - PRINTF("Key hash %.*H\n", 32, privateKeyData); - if (cx_math_cmp(privateKeyData, STARK_DERIVE_BIAS, 32) < 0) { - cx_math_modm(privateKeyData, 32, C_cx_Stark256_n, 32); - break; - } - index++; - } - PRINTF("Key result %.*H\n", 32, privateKeyData); - -#endif -} - -void stark_get_amount_string(uint8_t *contractAddress, - uint8_t *quantum256, - uint8_t *amount64, - char *tmp100, - char *target100) { - uint256_t amountPre, quantum, amount; - uint8_t decimals; - char *ticker = chainConfig->coinName; - - PRINTF("stark_get_amount_string %.*H\n", 20, contractAddress); - - if (allzeroes(contractAddress, 20)) { - decimals = WEI_TO_ETHER; - PRINTF("stark_get_amount_string - ETH\n"); - } else { - tokenDefinition_t *token = &getKnownToken(contractAddress)->token; - if (token == NULL) { // caught earlier - THROW(0x6A80); - } - decimals = token->decimals; - ticker = (char *) token->ticker; - PRINTF("stark_get_amount_string - decimals %d ticker %s\n", decimals, ticker); - } - convertUint256BE(amount64, 8, &amountPre); - readu256BE(quantum256, &quantum); - mul256(&amountPre, &quantum, &amount); - tostring256(&amount, 10, tmp100, 100); - PRINTF("stark_get_amount_string - mul256 %s\n", tmp100); - strlcpy(target100, ticker, 100); - adjustDecimals(tmp100, strlen(tmp100), target100 + strlen(ticker), 100, decimals); - PRINTF("get_amount_string %s\n", target100); -} - -#endif // HAVE_STARK diff --git a/src/stark_crypto.h b/src/stark_crypto.h deleted file mode 100644 index 5ce1be31e..000000000 --- a/src/stark_crypto.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _STARK_CRYPTO_H_ -#define _STARK_CRYPTO_H_ - -#include -#include -#include - -#include "os.h" -#include "cx.h" - -/* EC points */ -#define FIELD_ELEMENT_SIZE (32) -#define EC_POINT_SIZE (2 * FIELD_ELEMENT_SIZE + 1) -typedef unsigned char FieldElement[FIELD_ELEMENT_SIZE]; -typedef unsigned char ECPoint[EC_POINT_SIZE]; - -void pedersen(FieldElement res, /* out */ - FieldElement a, - FieldElement b); - -#endif // _STARK_CRYPTO_H_ diff --git a/src/stark_utils.c b/src/stark_utils.c deleted file mode 100644 index a585e0360..000000000 --- a/src/stark_utils.c +++ /dev/null @@ -1,246 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "stark_crypto.h" -#include "shared_context.h" -#include "ethUtils.h" -#include "uint256.h" -#include "uint_common.h" - -#include "os_io_seproxyhal.h" - -#define SIGNATURE_MAX_LEN (72) - -static const ECPoint PEDERSEN_SHIFT[] = {{ - 0x04, - - 0x04, 0x9e, 0xe3, 0xeb, 0xa8, 0xc1, 0x60, 0x07, 0x00, 0xee, 0x1b, 0x87, 0xeb, 0x59, 0x9f, 0x16, - 0x71, 0x6b, 0x0b, 0x10, 0x22, 0x94, 0x77, 0x33, 0x55, 0x1f, 0xde, 0x40, 0x50, 0xca, 0x68, 0x04, - - 0x03, 0xca, 0x0c, 0xfe, 0x4b, 0x3b, 0xc6, 0xdd, 0xf3, 0x46, 0xd4, 0x9d, 0x06, 0xea, 0x0e, 0xd3, - 0x4e, 0x62, 0x10, 0x62, 0xc0, 0xe0, 0x56, 0xc1, 0xd0, 0x40, 0x5d, 0x26, 0x6e, 0x10, 0x26, 0x8a, -}}; - -static const ECPoint PEDERSEN_POINTS[4] = { - { - 0x04, - - 0x02, 0x34, 0x28, 0x7d, 0xcb, 0xaf, 0xfe, 0x7f, 0x96, 0x9c, 0x74, - 0x86, 0x55, 0xfc, 0xa9, 0xe5, 0x8f, 0xa8, 0x12, 0x0b, 0x6d, 0x56, - 0xeb, 0x0c, 0x10, 0x80, 0xd1, 0x79, 0x57, 0xeb, 0xe4, 0x7b, - - 0x03, 0xb0, 0x56, 0xf1, 0x00, 0xf9, 0x6f, 0xb2, 0x1e, 0x88, 0x95, - 0x27, 0xd4, 0x1f, 0x4e, 0x39, 0x94, 0x01, 0x35, 0xdd, 0x7a, 0x6c, - 0x94, 0xcc, 0x6e, 0xd0, 0x26, 0x8e, 0xe8, 0x9e, 0x56, 0x15, - }, - { - 0x04, - - 0x04, 0xfa, 0x56, 0xf3, 0x76, 0xc8, 0x3d, 0xb3, 0x3f, 0x9d, 0xab, - 0x26, 0x56, 0x55, 0x8f, 0x33, 0x99, 0x09, 0x9e, 0xc1, 0xde, 0x5e, - 0x30, 0x18, 0xb7, 0xa6, 0x93, 0x2d, 0xba, 0x8a, 0xa3, 0x78, - - 0x03, 0xfa, 0x09, 0x84, 0xc9, 0x31, 0xc9, 0xe3, 0x81, 0x13, 0xe0, - 0xc0, 0xe4, 0x7e, 0x44, 0x01, 0x56, 0x27, 0x61, 0xf9, 0x2a, 0x7a, - 0x23, 0xb4, 0x51, 0x68, 0xf4, 0xe8, 0x0f, 0xf5, 0xb5, 0x4d, - }, - { - 0x04, - - 0x04, 0xba, 0x4c, 0xc1, 0x66, 0xbe, 0x8d, 0xec, 0x76, 0x49, 0x10, - 0xf7, 0x5b, 0x45, 0xf7, 0x4b, 0x40, 0xc6, 0x90, 0xc7, 0x47, 0x09, - 0xe9, 0x0f, 0x3a, 0xa3, 0x72, 0xf0, 0xbd, 0x2d, 0x69, 0x97, - - 0x00, 0x40, 0x30, 0x1c, 0xf5, 0xc1, 0x75, 0x1f, 0x4b, 0x97, 0x1e, - 0x46, 0xc4, 0xed, 0xe8, 0x5f, 0xca, 0xc5, 0xc5, 0x9a, 0x5c, 0xe5, - 0xae, 0x7c, 0x48, 0x15, 0x1f, 0x27, 0xb2, 0x4b, 0x21, 0x9c, - }, - { - 0x04, - - 0x05, 0x43, 0x02, 0xdc, 0xb0, 0xe6, 0xcc, 0x1c, 0x6e, 0x44, 0xcc, - 0xa8, 0xf6, 0x1a, 0x63, 0xbb, 0x2c, 0xa6, 0x50, 0x48, 0xd5, 0x3f, - 0xb3, 0x25, 0xd3, 0x6f, 0xf1, 0x2c, 0x49, 0xa5, 0x82, 0x02, - - 0x01, 0xb7, 0x7b, 0x3e, 0x37, 0xd1, 0x35, 0x04, 0xb3, 0x48, 0x04, - 0x62, 0x68, 0xd8, 0xae, 0x25, 0xce, 0x98, 0xad, 0x78, 0x3c, 0x25, - 0x56, 0x1a, 0x87, 0x9d, 0xcc, 0x77, 0xe9, 0x9c, 0x24, 0x26, - }}; - -void accum_ec_mul(ECPoint *hash, uint8_t *buf, int len, int pedersen_idx) { - ECPoint tmp; - if (!allzeroes(buf, len)) { - uint8_t pad[32]; - memcpy(tmp, PEDERSEN_POINTS[pedersen_idx], sizeof(ECPoint)); - io_seproxyhal_io_heartbeat(); - memset(pad, 0, sizeof(pad)); - memmove(pad + 32 - len, buf, len); - cx_ecfp_scalar_mult(CX_CURVE_Stark256, tmp, sizeof(ECPoint), pad, sizeof(pad)); - io_seproxyhal_io_heartbeat(); - cx_ecfp_add_point(CX_CURVE_Stark256, *hash, *hash, tmp, sizeof(ECPoint)); - } -} - -void pedersen(FieldElement res, /* out */ - FieldElement a, - FieldElement b) { - ECPoint hash; - - memcpy(hash, PEDERSEN_SHIFT, sizeof(hash)); - - accum_ec_mul(&hash, a, 1, 1); - accum_ec_mul(&hash, a + 1, FIELD_ELEMENT_SIZE - 1, 0); - accum_ec_mul(&hash, b, 1, 3); - accum_ec_mul(&hash, b + 1, FIELD_ELEMENT_SIZE - 1, 2); - - memcpy(res, hash + 1, FIELD_ELEMENT_SIZE); -} - -void shift_stark_hash(FieldElement hash) { - uint256_t hash256, final_hash256; - readu256BE(hash, &hash256); - uint32_t bits_count = bits256(&hash256); - if (bits_count < 248) { - return; - } else if (bits_count >= 248 && bits_count % 8 >= 1 && bits_count % 8 <= 4) { - shiftl256(&hash256, 4, &final_hash256); - write_u64_be(hash, UPPER(UPPER_P((&final_hash256)))); - write_u64_be(hash + 8, LOWER(UPPER_P((&final_hash256)))); - write_u64_be(hash + 16, UPPER(LOWER_P((&final_hash256)))); - write_u64_be(hash + 24, LOWER(LOWER_P((&final_hash256)))); - return; - } else { - THROW(0x6A80); - } -} - -int stark_sign(uint8_t *signature, /* out */ - uint8_t *privateKeyData, - FieldElement token1, - FieldElement token2, - FieldElement msg, - FieldElement condition) { - unsigned int info = 0; - FieldElement hash; - cx_ecfp_private_key_t privateKey; - PRINTF("Stark sign msg w1 %.*H\n", 32, token1); - PRINTF("Stark sign msg w2 %.*H\n", 32, token2); - PRINTF("Stark sign w3 %.*H\n", 32, msg); - if (condition != NULL) { - PRINTF("Stark sign w4 %.*H\n", 32, condition); - } - pedersen(hash, token1, token2); - PRINTF("Pedersen hash 1 %.*H\n", 32, hash); - if (condition != NULL) { - pedersen(hash, hash, condition); - PRINTF("Pedersen hash condition %.*H\n", 32, hash); - } - pedersen(hash, hash, msg); - PRINTF("Pedersen hash 2 %.*H\n", 32, hash); - shift_stark_hash(hash); - cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey); - io_seproxyhal_io_heartbeat(); - int signatureLength = cx_ecdsa_sign(&privateKey, - CX_RND_RFC6979 | CX_LAST, - CX_SHA256, - hash, - sizeof(hash), - signature, - SIGNATURE_MAX_LEN, - &info); - PRINTF("Stark signature %.*H\n", signatureLength, signature); - return signatureLength; -} - -// ERC20Token(address) -static const uint8_t ERC20_SELECTOR[] = {0xf4, 0x72, 0x61, 0xb0}; -// ETH() -static const uint8_t ETH_SELECTOR[] = {0x83, 0x22, 0xff, 0xf2}; -// ERC721Token(address, uint256) -static const uint8_t ERC721_SELECTOR[] = {0x02, 0x57, 0x17, 0x92}; -// MintableERC20Token(address) -static const uint8_t MINTABLE_ERC20_SELECTOR[] = {0x68, 0x64, 0x6e, 0x2d}; -// MintableERC721Token(address,uint256) -static const uint8_t MINTABLE_ERC721_SELECTOR[] = {0xb8, 0xb8, 0x66, 0x72}; -static const char NFT_ASSET_ID_PREFIX[] = {'N', 'F', 'T', ':', 0}; -static const char MINTABLE_ASSET_ID_PREFIX[] = {'M', 'I', 'N', 'T', 'A', 'B', 'L', 'E', ':', 0}; - -void compute_token_id(cx_sha3_t *sha3, - uint8_t *contractAddress, - uint8_t quantumType, - uint8_t *quantum, - uint8_t *mintingBlob, - bool assetTypeOnly, - uint8_t *output) { - uint8_t tmp[36]; - cx_keccak_init(sha3, 256); - if ((contractAddress != NULL) && (!allzeroes(contractAddress, 20))) { - const uint8_t *selector = NULL; - switch (quantumType) { - case STARK_QUANTUM_ERC20: - case STARK_QUANTUM_LEGACY: - selector = ERC20_SELECTOR; - break; - case STARK_QUANTUM_ERC721: - selector = ERC721_SELECTOR; - break; - case STARK_QUANTUM_MINTABLE_ERC20: - selector = MINTABLE_ERC20_SELECTOR; - break; - case STARK_QUANTUM_MINTABLE_ERC721: - selector = MINTABLE_ERC721_SELECTOR; - break; - default: - PRINTF("Unsupported quantum type %d\n", quantumType); - return; - } - PRINTF("compute_token_id for %.*H\n", 20, contractAddress); - memset(tmp, 0, sizeof(tmp)); - memmove(tmp, selector, 4); - memmove(tmp + 16, contractAddress, 20); - cx_hash((cx_hash_t *) sha3, 0, tmp, sizeof(tmp), NULL, 0); - } else { - PRINTF("compute_token_id for ETH\n"); - cx_hash((cx_hash_t *) sha3, 0, ETH_SELECTOR, sizeof(ETH_SELECTOR), NULL, 0); - } - if ((quantumType == STARK_QUANTUM_ERC721) || (quantumType == STARK_QUANTUM_MINTABLE_ERC721)) { - memset(tmp, 0, 32); - tmp[31] = 1; - PRINTF("compute_token_id quantum %.*H\n", 32, tmp); - cx_hash((cx_hash_t *) sha3, CX_LAST, tmp, 32, output, 32); - } else { - PRINTF("compute_token_id quantum %.*H\n", 32, quantum); - cx_hash((cx_hash_t *) sha3, CX_LAST, quantum, 32, output, 32); - } - if (!assetTypeOnly && - ((quantumType != STARK_QUANTUM_LEGACY) && (quantumType != STARK_QUANTUM_ETH) && - (quantumType != STARK_QUANTUM_ERC20))) { - const char *prefix = NULL; - output[0] &= 0x03; - cx_keccak_init(sha3, 256); - switch (quantumType) { - case STARK_QUANTUM_ERC721: - prefix = NFT_ASSET_ID_PREFIX; - break; - case STARK_QUANTUM_MINTABLE_ERC20: - case STARK_QUANTUM_MINTABLE_ERC721: - prefix = MINTABLE_ASSET_ID_PREFIX; - break; - default: - PRINTF("Unsupported non default quantum type %d\n", quantumType); - return; - } - cx_hash((cx_hash_t *) sha3, 0, (const uint8_t *) prefix, strlen(prefix), NULL, 0); - cx_hash((cx_hash_t *) sha3, 0, output, 32, NULL, 0); - cx_hash((cx_hash_t *) sha3, CX_LAST, mintingBlob, 32, output, 32); - } - if (!assetTypeOnly && ((quantumType == STARK_QUANTUM_MINTABLE_ERC20) || - (quantumType == STARK_QUANTUM_MINTABLE_ERC721))) { - output[0] = 0x04; - output[1] = 0x00; - } else { - output[0] &= 0x03; - } - PRINTF("compute_token_id computed token %.*H\n", 32, output); -} - -#endif // HAVE_STARK diff --git a/src/stark_utils.h b/src/stark_utils.h deleted file mode 100644 index 9ba69a2b9..000000000 --- a/src/stark_utils.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _STARK_UTILS_H_ -#define _STARK_UTILS_H_ - -#include -#include -#include - -#include "os.h" -#include "cx.h" -#include "stark_crypto.h" - -void compute_token_id(cx_sha3_t *sha3, - uint8_t *contractAddress, - uint8_t quantumType, - uint8_t *quantum, - uint8_t *mintingBlob, - bool assetTypeOnly, - uint8_t *output); - -void starkDerivePrivateKey(uint32_t *bip32Path, uint32_t bip32PathLength, uint8_t *privateKeyData); - -void stark_get_amount_string(uint8_t *contractAddress, - uint8_t *quantum256, - uint8_t *amount64, - char *tmp100, - char *target100); - -int stark_sign(uint8_t *signature, /* out */ - uint8_t *privateKeyData, - FieldElement token1, - FieldElement token2, - FieldElement msg, - FieldElement condition); - -#endif // _STARK_UTILS_H_ diff --git a/src/swap_lib_calls.h b/src/swap_lib_calls.h index 287034707..c4675e303 100644 --- a/src/swap_lib_calls.h +++ b/src/swap_lib_calls.h @@ -10,6 +10,7 @@ #include "chainConfig.h" #include "shared_context.h" #include "stdint.h" +#include "caller_api.h" #define RUN_APPLICATION 1 diff --git a/src/swap_utils.c b/src/swap_utils.c new file mode 100644 index 000000000..8a5db8691 --- /dev/null +++ b/src/swap_utils.c @@ -0,0 +1,59 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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 +#include + +#include "asset_info.h" +#include "swap_utils.h" + +bool parse_swap_config(const uint8_t *config, + uint8_t config_len, + char *ticker, + uint8_t *decimals, + uint64_t *chain_id) { + uint8_t ticker_len, offset = 0; + + if (config_len == 0) { + return false; + } + ticker_len = config[offset]; + offset += sizeof(ticker_len); + if ((ticker_len == 0) || (ticker_len > (MAX_TICKER_LEN - 2)) || + ((config_len - offset) < (ticker_len))) { + return false; + } + memcpy(ticker, config + offset, ticker_len); + offset += ticker_len; + ticker[ticker_len] = '\0'; + + if ((config_len - offset) < 1) { + return false; + } + *decimals = config[offset]; + offset += sizeof(*decimals); + + // the chain ID was adder later to the CAL swap subconfig + // so it is optional for retro-compatibility (as it might not be present) + if ((config_len - offset) >= sizeof(*chain_id)) { + PRINTF("Chain ID from the swap subconfig = 0x%.*h\n", sizeof(*chain_id), &config[offset]); + *chain_id = u64_from_BE(config + offset, sizeof(*chain_id)); + offset += sizeof(*chain_id); + } + return true; +} diff --git a/src/swap_utils.h b/src/swap_utils.h new file mode 100644 index 000000000..76ca90e56 --- /dev/null +++ b/src/swap_utils.h @@ -0,0 +1,26 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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 parse_swap_config(const uint8_t* config, + uint8_t config_len, + char* ticker, + uint8_t* decimals, + uint64_t* chain_id); diff --git a/src/tokens.c b/src/tokens.c deleted file mode 100644 index a513758bd..000000000 --- a/src/tokens.c +++ /dev/null @@ -1,227 +0,0 @@ -/******************************************************************************* - * Ledger Ethereum App - * (c) 2016-2019 Ledger - * - * 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. - ********************************************************************************/ - -#ifdef HAVE_TOKENS_EXTRA_LIST - -#include "tokens.h" - -const tokenDefinition_t TOKENS_EXTRA[NUM_TOKENS_EXTRA] = { - - // Ropsten DeversiFi tokens - {{0x4c, 0x5f, 0x66, 0x59, 0x61, 0x97, 0xa8, 0x6f, 0xb3, 0x0a, - 0x24, 0x35, 0xe2, 0xef, 0x4d, 0xdc, 0xb3, 0x93, 0x42, 0xc9}, - "tUSDT", - 6}, - {{0x1c, 0x0f, 0x17, 0x43, 0x67, 0x40, 0xbf, 0xb9, 0x2c, 0x10, - 0x70, 0xee, 0x86, 0x32, 0x2d, 0xe8, 0x90, 0x83, 0x7c, 0x6a}, - "tUSDT", - 6}, - {{0xcd, 0x07, 0x7a, 0xbe, 0xdd, 0x83, 0x1a, 0x34, 0x43, 0xff, - 0xbe, 0x24, 0xfb, 0x76, 0x66, 0x1b, 0xbb, 0x17, 0xeb, 0x69}, - "tZRX", - 18}, - {{0x40, 0xd8, 0x97, 0x85, 0x00, 0xbf, 0x68, 0x32, 0x4a, 0x51, - 0x53, 0x3c, 0xd6, 0xa2, 0x1e, 0x3e, 0x59, 0xbe, 0x32, 0x4a}, - "tBTC", - 18}, - // Goerli DeversiFi tokens - {{0xd9, 0x97, 0xa8, 0x63, 0x46, 0xe7, 0x65, 0x18, 0xe6, 0x92, - 0x25, 0x56, 0xf3, 0x4d, 0x76, 0x61, 0x30, 0xc0, 0xbb, 0xfd}, - "tUSDT", - 6}, - {{0xc1, 0xd5, 0x79, 0xeb, 0xff, 0x7c, 0x0f, 0x6c, 0xfd, 0x9a, - 0xd5, 0xfb, 0x26, 0x7f, 0xec, 0x73, 0xbe, 0x70, 0xc8, 0xf7}, - "tBTC", - 18}, - {{0xa8, 0xf3, 0x14, 0x4f, 0xea, 0x2c, 0x37, 0x5a, 0xd0, 0x58, - 0xec, 0x12, 0x09, 0x9a, 0x5a, 0x21, 0xa2, 0x6f, 0xe9, 0x96}, - "tDVF", - 18}, - {{0x4c, 0xda, 0xbe, 0xc1, 0x2a, 0x39, 0x7f, 0xb6, 0xef, 0xaf, - 0x46, 0x13, 0xd5, 0xdf, 0xd7, 0x9b, 0x30, 0x9a, 0xe9, 0xfa}, - "tXDVF", - 18}, - -}; - -#endif - -#ifdef HAVE_TOKENS_LIST - -#include "tokens.h" - -// Example of custom tokens (not actually used by the main ethereum app). -// Format of a token is: `{address, ticker, decimals}`. -const tokenDefinition_t const TOKENS_ETHEREUM[NUM_TOKENS_ETHEREUM] = { - {{0xdb, 0x25, 0xf2, 0x11, 0xab, 0x05, 0xb1, 0xc9, 0x7d, 0x59, - 0x55, 0x16, 0xf4, 0x57, 0x94, 0x52, 0x8a, 0x80, 0x7a, 0xd8}, - "EURS", - 2}, - {{0xa7, 0x44, 0x76, 0x44, 0x31, 0x19, 0xA9, 0x42, 0xdE, 0x49, - 0x85, 0x90, 0xFe, 0x1f, 0x24, 0x54, 0xd7, 0xD4, 0xaC, 0x0d}, - "GNT", - 18}, -}; - -const tokenDefinition_t const TOKENS_AKROMA[NUM_TOKENS_AKROMA] = {}; - -const tokenDefinition_t const TOKENS_ELLAISM[NUM_TOKENS_ELLAISM] = { - {{0x99, 0x1e, 0x7f, 0xe4, 0xb0, 0x5f, 0x2b, 0x3d, 0xb1, 0xd7, - 0x88, 0xe7, 0x05, 0x96, 0x3f, 0x5d, 0x64, 0x7b, 0x00, 0x44}, - "MINING", - 18}, -}; - -const tokenDefinition_t const TOKENS_ETHEREUM_CLASSIC[NUM_TOKENS_ETHEREUM_CLASSIC] = { - {{0x6F, 0x6D, 0xEb, 0x5d, 0xb0, 0xC4, 0x99, 0x4A, 0x82, 0x83, - 0xA0, 0x1D, 0x6C, 0xFe, 0xEB, 0x27, 0xFc, 0x3b, 0xBe, 0x9C}, - "Smart", - 0}, - {{0x08, 0x5f, 0xb4, 0xf2, 0x40, 0x31, 0xea, 0xed, 0xbc, 0x2b, - 0x61, 0x1a, 0xa5, 0x28, 0xf2, 0x23, 0x43, 0xeb, 0x52, 0xdb}, - "BEC", - 8}, - {{0x5a, 0xce, 0x17, 0xf8, 0x7c, 0x73, 0x91, 0xe5, 0x79, 0x2a, - 0x76, 0x83, 0x06, 0x9a, 0x80, 0x25, 0xb8, 0x3b, 0xbd, 0x85}, - "PLAY", - 0}, - {{0x6A, 0xDa, 0x6F, 0x48, 0xC8, 0x15, 0x68, 0x95, 0x02, 0xC4, - 0x3e, 0xC1, 0xa5, 0x9F, 0x1b, 0x5D, 0xD3, 0xC0, 0x4E, 0x1F}, - "UNV", - 18}, -}; - -const tokenDefinition_t const TOKENS_ETHERSOCIAL[NUM_TOKENS_ETHERSOCIAL] = {}; - -const tokenDefinition_t const TOKENS_ETHER1[NUM_TOKENS_ETHER1] = {}; - -const tokenDefinition_t const TOKENS_PIRL[NUM_TOKENS_PIRL] = {}; - -const tokenDefinition_t const TOKENS_POA[NUM_TOKENS_POA] = {}; - -const tokenDefinition_t const TOKENS_RSK[NUM_TOKENS_RSK] = {}; - -const tokenDefinition_t const TOKENS_UBIQ[NUM_TOKENS_UBIQ] = { - {{0xd2, 0x45, 0x20, 0x7c, 0xfb, 0xf6, 0xeb, 0x6f, 0x34, 0x97, - 0x0d, 0xb2, 0xa8, 0x07, 0xab, 0x1d, 0x17, 0x8f, 0xde, 0x6c}, - "APX", - 8}, - {{0xff, 0x3b, 0xf0, 0x57, 0xad, 0xf3, 0xb0, 0xe0, 0x15, 0xb6, - 0x46, 0x53, 0x31, 0xa6, 0x23, 0x6e, 0x55, 0x68, 0x82, 0x74}, - "BEER", - 0}, - {{0x08, 0x53, 0x3d, 0x6a, 0x06, 0xce, 0x36, 0x52, 0x98, 0xb1, - 0x2e, 0xf9, 0x2e, 0xb4, 0x07, 0xcb, 0xa8, 0xaa, 0x82, 0x73}, - "CEFS", - 8}, - {{0x94, 0xad, 0x7e, 0x41, 0xc1, 0xd4, 0x40, 0x22, 0xc4, 0xf4, - 0x7c, 0xb1, 0xba, 0x01, 0x9f, 0xd1, 0xa0, 0x22, 0xc5, 0x36}, - "DOT", - 8}, - {{0x4b, 0x48, 0x99, 0xa1, 0x0f, 0x3e, 0x50, 0x7d, 0xb2, 0x07, - 0xb0, 0xee, 0x24, 0x26, 0x02, 0x9e, 0xfa, 0x16, 0x8a, 0x67}, - "QWARK", - 8}, - {{0x5e, 0x17, 0x15, 0xbb, 0x79, 0x80, 0x5b, 0xd6, 0x72, 0x72, - 0x97, 0x60, 0xb3, 0xf7, 0xf3, 0x4d, 0x6f, 0x48, 0x50, 0x98}, - "RICKS", - 8}, -}; - -const tokenDefinition_t const TOKENS_EXPANSE[NUM_TOKENS_EXPANSE] = {}; - -const tokenDefinition_t const TOKENS_WANCHAIN[NUM_TOKENS_WANCHAIN] = {}; - -const tokenDefinition_t const TOKENS_KUSD[NUM_TOKENS_KUSD] = {}; - -const tokenDefinition_t const TOKENS_MUSICOIN[NUM_TOKENS_MUSICOIN] = {}; - -const tokenDefinition_t const TOKENS_CALLISTO[NUM_TOKENS_CALLISTO] = {}; - -const tokenDefinition_t const TOKENS_ETHERGEM[NUM_TOKENS_ETHERGEM] = {}; - -const tokenDefinition_t const TOKENS_ATHEIOS[NUM_TOKENS_ATHEIOS] = {}; - -const tokenDefinition_t const TOKENS_GOCHAIN[NUM_TOKENS_GOCHAIN] = {}; - -const tokenDefinition_t const TOKENS_MIX[NUM_TOKENS_MIX] = {}; - -const tokenDefinition_t const TOKENS_REOSC[NUM_TOKENS_REOSC] = {}; - -const tokenDefinition_t const TOKENS_HPB[NUM_TOKENS_HPB] = {}; - -const tokenDefinition_t const TOKENS_TOMOCHAIN[NUM_TOKENS_TOMOCHAIN] = {}; - -const tokenDefinition_t const TOKENS_TOBALABA[NUM_TOKENS_TOBALABA] = {}; - -const tokenDefinition_t const TOKENS_DEXON[NUM_TOKENS_DEXON] = {}; - -const tokenDefinition_t const TOKENS_VOLTA[NUM_TOKENS_VOLTA] = {}; - -const tokenDefinition_t const TOKENS_ENERGYWEBCHAIN[NUM_TOKENS_ENERGYWEBCHAIN] = {}; - -const tokenDefinition_t const TOKENS_ARTIS_SIGMA1[NUM_TOKENS_ARTIS_SIGMA1] = {}; - -const tokenDefinition_t const TOKENS_ARTIS_TAU1[NUM_TOKENS_ARTIS_TAU1] = {}; - -const tokenDefinition_t const TOKENS_WEBCHAIN[NUM_TOKENS_WEBCHAIN] = {}; - -const tokenDefinition_t const TOKENS_THUNDERCORE[NUM_TOKENS_THUNDERCORE] = {}; - -const tokenDefinition_t const TOKENS_FLARE[NUM_TOKENS_FLARE] = {}; - -const tokenDefinition_t const TOKENS_BSC[NUM_TOKENS_BSC] = {}; - -const tokenDefinition_t const TOKENS_SONGBIRD[NUM_TOKENS_SONGBIRD] = {}; - -const tokenDefinition_t const TOKENS_MOONRIVER[NUM_TOKENS_MOONRIVER] = {}; - -const tokenDefinition_t const TOKENS_POLYGON[NUM_TOKENS_POLYGON] = {}; - -const tokenDefinition_t const TOKENS_SHYFT[NUM_TOKENS_SHYFT] = {}; - -const tokenDefinition_t const TOKENS_CONFLUX_ESPACE[NUM_TOKENS_CONFLUX_ESPACE] = {}; - -const tokenDefinition_t const TOKENS_MOONBEAM[NUM_TOKENS_MOONBEAM] = {}; - -const tokenDefinition_t const TOKENS_BTTC[NUM_TOKENS_BTTC] = {}; - -const tokenDefinition_t const TOKENS_KARDIACHAIN[NUM_TOKENS_KARDIACHAIN] = {}; - -const tokenDefinition_t const TOKENS_WETHIO[NUM_TOKENS_WETHIO] = {}; - -const tokenDefinition_t const TOKENS_OKC[NUM_TOKENS_OKC] = {}; - -const tokenDefinition_t const TOKENS_CUBE[NUM_TOKENS_CUBE] = {}; - -const tokenDefinition_t const TOKENS_ASTAR[NUM_TOKENS_ASTAR] = {}; - -const tokenDefinition_t const TOKENS_SHIDEN[NUM_TOKENS_SHIDEN] = {}; - -const tokenDefinition_t const TOKENS_XDCNETWORK[NUM_TOKENS_XDCNETWORK] = {}; - -const tokenDefinition_t const TOKENS_METER[NUM_TOKENS_METER] = {}; - -const tokenDefinition_t const TOKENS_MULTIVAC[NUM_TOKENS_MULTIVAC] = {}; - -const tokenDefinition_t const TOKENS_TECRA[NUM_TOKENS_TECRA] = {}; - -const tokenDefinition_t const TOKENS_APOTHEMNETWORK[NUM_TOKENS_APOTHEMNETWORK] = {}; - -const tokenDefinition_t const TOKENS_OASYS[NUM_TOKENS_OASYS] = {}; - -#endif diff --git a/src/tokens.h b/src/tokens.h deleted file mode 100644 index 1a261c3b8..000000000 --- a/src/tokens.h +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * Ledger Ethereum App - * (c) 2016-2019 Ledger - * - * 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. - ********************************************************************************/ - -#ifndef _TOKENS_H_ -#define _TOKENS_H_ - -#include -#include "ethUstream.h" - -#define MAX_TICKER_LEN 11 // 10 characters + '\0' -#define MAX_ITEMS 2 - -typedef struct tokenDefinition_t { - uint8_t address[ADDRESS_LENGTH]; // must be first item -#ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR - uint8_t contractName[ADDRESS_LENGTH]; -#endif - char ticker[MAX_TICKER_LEN]; - uint8_t decimals; -} tokenDefinition_t; - -#ifdef HAVE_TOKENS_EXTRA_LIST - -#define NUM_TOKENS_EXTRA 8 - -extern tokenDefinition_t const TOKENS_EXTRA[NUM_TOKENS_EXTRA]; - -#endif - -#ifndef HAVE_TOKENS_LIST - -#if defined(HAVE_CAL_TEST_KEY) && defined(HAVE_CAL_CI_KEY) -#error "CAL key contradiction, two alternative keys selected at once" -#endif - -static const uint8_t LEDGER_SIGNATURE_PUBLIC_KEY[] = { -#if defined(HAVE_CAL_TEST_KEY) - // test key 2019-01-11 03:07PM (erc20signer) - 0x04, 0x20, 0xda, 0x62, 0x00, 0x3c, 0x0c, 0xe0, 0x97, 0xe3, 0x36, 0x44, 0xa1, 0x0f, - 0xe4, 0xc3, 0x04, 0x54, 0x06, 0x9a, 0x44, 0x54, 0xf0, 0xfa, 0x9d, 0x4e, 0x84, 0xf4, - 0x50, 0x91, 0x42, 0x9b, 0x52, 0x20, 0xaf, 0x9e, 0x35, 0xc0, 0xb2, 0xd9, 0x28, 0x93, - 0x80, 0x13, 0x73, 0x07, 0xde, 0x4d, 0xd1, 0xd4, 0x18, 0x42, 0x8c, 0xf2, 0x1a, 0x93, - 0xb3, 0x35, 0x61, 0xbb, 0x09, 0xd8, 0x8f, 0xe5, 0x79 -#elif defined(HAVE_CAL_CI_KEY) - 0x04, 0x4c, 0xca, 0x8f, 0xad, 0x49, 0x6a, 0xa5, 0x04, 0x0a, 0x00, 0xa7, 0xeb, 0x2f, - 0x5c, 0xc3, 0xb8, 0x53, 0x76, 0xd8, 0x8b, 0xa1, 0x47, 0xa7, 0xd7, 0x05, 0x4a, 0x99, - 0xc6, 0x40, 0x56, 0x18, 0x87, 0xfe, 0x17, 0xa0, 0x96, 0xe3, 0x6c, 0x3b, 0x52, 0x3b, - 0x24, 0x4f, 0x3e, 0x2f, 0xf7, 0xf8, 0x40, 0xae, 0x26, 0xc4, 0xe7, 0x7a, 0xd3, 0xbc, - 0x73, 0x9a, 0xf5, 0xde, 0x6f, 0x2d, 0x77, 0xa7, 0xb6 -#else - // production key 2019-01-11 03:07PM (erc20signer) - 0x04, 0x5e, 0x6c, 0x10, 0x20, 0xc1, 0x4d, 0xc4, 0x64, 0x42, 0xfe, 0x89, 0xf9, 0x7c, - 0x0b, 0x68, 0xcd, 0xb1, 0x59, 0x76, 0xdc, 0x24, 0xf2, 0x4c, 0x31, 0x6e, 0x7b, 0x30, - 0xfe, 0x4e, 0x8c, 0xc7, 0x6b, 0x14, 0x89, 0x15, 0x0c, 0x21, 0x51, 0x4e, 0xbf, 0x44, - 0x0f, 0xf5, 0xde, 0xa5, 0x39, 0x3d, 0x83, 0xde, 0x53, 0x58, 0xcd, 0x09, 0x8f, 0xce, - 0x8f, 0xd0, 0xf8, 0x1d, 0xaa, 0x94, 0x97, 0x91, 0x83 -#endif -}; - -#else - -// These defines need to follow tokens.c - -#define NUM_TOKENS_AKROMA 0 -#define NUM_TOKENS_ELLAISM 1 -#define NUM_TOKENS_ETHEREUM 2 -#define NUM_TOKENS_ETHEREUM_CLASSIC 4 -#define NUM_TOKENS_ETHERSOCIAL 0 -#define NUM_TOKENS_ETHER1 0 -#define NUM_TOKENS_PIRL 0 -#define NUM_TOKENS_POA 0 -#define NUM_TOKENS_RSK 0 -#define NUM_TOKENS_UBIQ 6 -#define NUM_TOKENS_EXPANSE 0 -#define NUM_TOKENS_WANCHAIN 0 -#define NUM_TOKENS_KUSD 0 -#define NUM_TOKENS_MUSICOIN 0 -#define NUM_TOKENS_CALLISTO 0 -#define NUM_TOKENS_ETHERGEM 0 -#define NUM_TOKENS_ATHEIOS 0 -#define NUM_TOKENS_GOCHAIN 0 -#define NUM_TOKENS_MIX 0 -#define NUM_TOKENS_REOSC 0 -#define NUM_TOKENS_HPB 0 -#define NUM_TOKENS_TOMOCHAIN 0 -#define NUM_TOKENS_TOBALABA 0 -#define NUM_TOKENS_DEXON 0 -#define NUM_TOKENS_VOLTA 0 -#define NUM_TOKENS_ENERGYWEBCHAIN 0 -#define NUM_TOKENS_ARTIS_SIGMA1 0 -#define NUM_TOKENS_ARTIS_TAU1 0 -#define NUM_TOKENS_WEBCHAIN 0 -#define NUM_TOKENS_THUNDERCORE 0 -#define NUM_TOKENS_FLARE 0 -#define NUM_TOKENS_BSC 0 -#define NUM_TOKENS_SONGBIRD 0 -#define NUM_TOKENS_MOONRIVER 0 -#define NUM_TOKENS_POLYGON 0 -#define NUM_TOKENS_SHYFT 0 -#define NUM_TOKENS_CONFLUX_ESPACE 0 -#define NUM_TOKENS_MOONBEAM 0 -#define NUM_TOKENS_BTTC 0 -#define NUM_TOKENS_KARDIACHAIN 0 -#define NUM_TOKENS_WETHIO 0 -#define NUM_TOKENS_OKC 0 -#define NUM_TOKENS_CUBE 0 -#define NUM_TOKENS_ASTAR 0 -#define NUM_TOKENS_SHIDEN 0 -#define NUM_TOKENS_XDCNETWORK 0 -#define NUM_TOKENS_METER 0 -#define NUM_TOKENS_MULTIVAC 0 -#define NUM_TOKENS_TECRA 0 -#define NUM_TOKENS_APOTHEMNETWORK 0 -#define NUM_TOKENS_OASYS 0 - -extern tokenDefinition_t const TOKENS_AKROMA[NUM_TOKENS_AKROMA]; -extern tokenDefinition_t const TOKENS_ELLAISM[NUM_TOKENS_ELLAISM]; -extern tokenDefinition_t const TOKENS_ETHEREUM[NUM_TOKENS_ETHEREUM]; -extern tokenDefinition_t const TOKENS_ETHEREUM_CLASSIC[NUM_TOKENS_ETHEREUM_CLASSIC]; -extern tokenDefinition_t const TOKENS_ETHERSOCIAL[NUM_TOKENS_ETHERSOCIAL]; -extern tokenDefinition_t const TOKENS_ETHER1[NUM_TOKENS_ETHER1]; -extern tokenDefinition_t const TOKENS_PIRL[NUM_TOKENS_PIRL]; -extern tokenDefinition_t const TOKENS_POA[NUM_TOKENS_POA]; -extern tokenDefinition_t const TOKENS_RSK[NUM_TOKENS_RSK]; -extern tokenDefinition_t const TOKENS_UBIQ[NUM_TOKENS_UBIQ]; -extern tokenDefinition_t const TOKENS_EXPANSE[NUM_TOKENS_EXPANSE]; -extern tokenDefinition_t const TOKENS_WANCHAIN[NUM_TOKENS_WANCHAIN]; -extern tokenDefinition_t const TOKENS_KUSD[NUM_TOKENS_KUSD]; -extern tokenDefinition_t const TOKENS_MUSICOIN[NUM_TOKENS_MUSICOIN]; -extern tokenDefinition_t const TOKENS_CALLISTO[NUM_TOKENS_CALLISTO]; -extern tokenDefinition_t const TOKENS_ETHERGEM[NUM_TOKENS_ETHERGEM]; -extern tokenDefinition_t const TOKENS_ATHEIOS[NUM_TOKENS_ATHEIOS]; -extern tokenDefinition_t const TOKENS_GOCHAIN[NUM_TOKENS_GOCHAIN]; -extern tokenDefinition_t const TOKENS_MIX[NUM_TOKENS_MIX]; -extern tokenDefinition_t const TOKENS_REOSC[NUM_TOKENS_REOSC]; -extern tokenDefinition_t const TOKENS_HPB[NUM_TOKENS_HPB]; -extern tokenDefinition_t const TOKENS_TOMOCHAIN[NUM_TOKENS_TOMOCHAIN]; -extern tokenDefinition_t const TOKENS_TOBALABA[NUM_TOKENS_TOBALABA]; -extern tokenDefinition_t const TOKENS_DEXON[NUM_TOKENS_DEXON]; -extern tokenDefinition_t const TOKENS_VOLTA[NUM_TOKENS_VOLTA]; -extern tokenDefinition_t const TOKENS_ENERGYWEBCHAIN[NUM_TOKENS_ENERGYWEBCHAIN]; -extern tokenDefinition_t const TOKENS_ARTIS_SIGMA1[NUM_TOKENS_ARTIS_SIGMA1]; -extern tokenDefinition_t const TOKENS_ARTIS_TAU1[NUM_TOKENS_ARTIS_TAU1]; -extern tokenDefinition_t const TOKENS_WEBCHAIN[NUM_TOKENS_WEBCHAIN]; -extern tokenDefinition_t const TOKENS_THUNDERCORE[NUM_TOKENS_THUNDERCORE]; -extern tokenDefinition_t const TOKENS_FLARE[NUM_TOKENS_FLARE]; -extern tokenDefinition_t const TOKENS_BSC[NUM_TOKENS_BSC]; -extern tokenDefinition_t const TOKENS_SONGBIRD[NUM_TOKENS_SONGBIRD]; -extern tokenDefinition_t const TOKENS_MOONRIVER[NUM_TOKENS_MOONRIVER]; -extern tokenDefinition_t const TOKENS_POLYGON[NUM_TOKENS_POLYGON]; -extern tokenDefinition_t const TOKENS_SHYFT[NUM_TOKENS_SHYFT]; -extern tokenDefinition_t const TOKENS_CONFLUX_ESPACE[NUM_TOKENS_CONFLUX_ESPACE]; -extern tokenDefinition_t const TOKENS_MOONBEAM[NUM_TOKENS_MOONBEAM]; -extern tokenDefinition_t const TOKENS_BTTC[NUM_TOKENS_BTTC]; -extern tokenDefinition_t const TOKENS_KARDIACHAIN[NUM_TOKENS_KARDIACHAIN]; -extern tokenDefinition_t const TOKENS_WETHIO[NUM_TOKENS_WETHIO]; -extern tokenDefinition_t const TOKENS_CUBE[NUM_TOKENS_CUBE]; -extern tokenDefinition_t const TOKENS_ASTAR[NUM_TOKENS_ASTAR]; -extern tokenDefinition_t const TOKENS_SHIDEN[NUM_TOKENS_SHIDEN]; -extern tokenDefinition_t const TOKENS_XDCNETWORK[NUM_TOKENS_XDCNETWORK]; -extern tokenDefinition_t const TOKENS_METER[NUM_TOKENS_METER]; -extern tokenDefinition_t const TOKENS_MULTIVAC[NUM_TOKENS_MULTIVAC]; -extern tokenDefinition_t const TOKENS_TECRA[NUM_TOKENS_TECRA]; -extern tokenDefinition_t const TOKENS_APOTHEMNETWORK[NUM_TOKENS_APOTHEMNETWORK]; -extern tokenDefinition_t const TOKENS_OASYS[NUM_TOKENS_OASYS]; - -#endif /* HAVE_TOKENS_LIST */ - -#endif // _TOKENS_H_ diff --git a/src/ui_callbacks.h b/src/ui_callbacks.h index 041f7173e..306340076 100644 --- a/src/ui_callbacks.h +++ b/src/ui_callbacks.h @@ -21,9 +21,6 @@ unsigned int io_seproxyhal_touch_data_cancel(const bagl_element_t *e); unsigned int io_seproxyhal_touch_eth2_address_ok(const bagl_element_t *e); unsigned int io_seproxyhal_touch_privacy_ok(const bagl_element_t *e); unsigned int io_seproxyhal_touch_privacy_cancel(const bagl_element_t *e); -unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(const bagl_element_t *e); -unsigned int io_seproxyhal_touch_stark_pubkey_ok(const bagl_element_t *e); -unsigned int io_seproxyhal_touch_stark_ok(const bagl_element_t *e); void ui_warning_contract_data(void); diff --git a/src_common/uint128.c b/src/uint128.c similarity index 93% rename from src_common/uint128.c rename to src/uint128.c index 0663a24e0..b720e35c1 100644 --- a/src_common/uint128.c +++ b/src/uint128.c @@ -21,7 +21,7 @@ #include #include "uint128.h" #include "uint_common.h" -#include "ethUtils.h" // HEXDIGITS +#include "common_utils.h" // HEXDIGITS void readu128BE(const uint8_t *const buffer, uint128_t *const target) { UPPER_P(target) = readUint64BE(buffer); @@ -290,3 +290,21 @@ bool tostring128_signed(const uint128_t *const number, } return tostring128(number, base, out, out_length); // positive value } + +void convertUint64BEto128(const uint8_t *const data, uint32_t length, uint128_t *const target) { + uint8_t tmp[INT128_LENGTH]; + int64_t value; + + value = u64_from_BE(data, length); + memset(tmp, ((value < 0) ? 0xff : 0), sizeof(tmp) - length); + memmove(tmp + sizeof(tmp) - length, data, length); + readu128BE(tmp, target); +} + +void convertUint128BE(const uint8_t *const data, uint32_t length, uint128_t *const target) { + uint8_t tmp[INT128_LENGTH]; + + memset(tmp, 0, sizeof(tmp) - length); + memmove(tmp + sizeof(tmp) - length, data, length); + readu128BE(tmp, target); +} diff --git a/src_common/uint128.h b/src/uint128.h similarity index 93% rename from src_common/uint128.h rename to src/uint128.h index e1166c20b..b857089c3 100644 --- a/src_common/uint128.h +++ b/src/uint128.h @@ -56,5 +56,7 @@ bool tostring128_signed(const uint128_t *const number, uint32_t base, char *const out, uint32_t out_length); +void convertUint64BEto128(const uint8_t *const data, uint32_t length, uint128_t *const target); +void convertUint128BE(const uint8_t *const data, uint32_t length, uint128_t *const target); #endif // _UINT128_H_ diff --git a/src_common/uint256.c b/src/uint256.c similarity index 97% rename from src_common/uint256.c rename to src/uint256.c index 78511249a..8829c906d 100644 --- a/src_common/uint256.c +++ b/src/uint256.c @@ -21,8 +21,7 @@ #include #include "uint256.h" #include "uint_common.h" -#include "ethUstream.h" // INT256_LENGTH -#include "ethUtils.h" // HEXDIGITS +#include "common_utils.h" // INT256_LENGTH void readu256BE(const uint8_t *const buffer, uint256_t *const target) { readu128BE(buffer, &UPPER_P(target)); @@ -290,3 +289,11 @@ bool tostring256_signed(const uint256_t *const number, } return tostring256(number, base, out, out_length); // positive value } + +void convertUint256BE(const uint8_t *const data, uint32_t length, uint256_t *const target) { + uint8_t tmp[INT256_LENGTH]; + + memset(tmp, 0, sizeof(tmp) - length); + memmove(tmp + sizeof(tmp) - length, data, length); + readu256BE(tmp, target); +} diff --git a/src_common/uint256.h b/src/uint256.h similarity index 96% rename from src_common/uint256.h rename to src/uint256.h index 97b8cfb1f..4addf7f78 100644 --- a/src_common/uint256.h +++ b/src/uint256.h @@ -57,5 +57,6 @@ bool tostring256_signed(const uint256_t *const number, uint32_t base, char *const out, uint32_t out_length); +void convertUint256BE(const uint8_t *const data, uint32_t length, uint256_t *const target); #endif // _UINT256_H_ diff --git a/src_common/uint_common.c b/src/uint_common.c similarity index 100% rename from src_common/uint_common.c rename to src/uint_common.c diff --git a/src_common/uint_common.h b/src/uint_common.h similarity index 100% rename from src_common/uint_common.h rename to src/uint_common.h diff --git a/src/utils.c b/src/utils.c deleted file mode 100644 index 2c553b4a8..000000000 --- a/src/utils.c +++ /dev/null @@ -1,168 +0,0 @@ -/******************************************************************************* - * Ledger Ethereum App - * (c) 2016-2019 Ledger - * - * 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 - -#include "ethUstream.h" -#include "ethUtils.h" -#include "uint128.h" -#include "uint256.h" -#include "tokens.h" -#include "utils.h" - -void array_hexstr(char *strbuf, const void *bin, unsigned int len) { - while (len--) { - *strbuf++ = HEXDIGITS[((*((char *) bin)) >> 4) & 0xF]; - *strbuf++ = HEXDIGITS[(*((char *) bin)) & 0xF]; - bin = (const void *) ((unsigned int) bin + 1); - } - *strbuf = 0; // EOS -} - -void convertUint64BEto128(const uint8_t *const data, uint32_t length, uint128_t *const target) { - uint8_t tmp[INT128_LENGTH]; - int64_t value; - - value = u64_from_BE(data, length); - memset(tmp, ((value < 0) ? 0xff : 0), sizeof(tmp) - length); - memmove(tmp + sizeof(tmp) - length, data, length); - readu128BE(tmp, target); -} - -void convertUint128BE(const uint8_t *const data, uint32_t length, uint128_t *const target) { - uint8_t tmp[INT128_LENGTH]; - - memset(tmp, 0, sizeof(tmp) - length); - memmove(tmp + sizeof(tmp) - length, data, length); - readu128BE(tmp, target); -} - -void convertUint256BE(const uint8_t *const data, uint32_t length, uint256_t *const target) { - uint8_t tmp[INT256_LENGTH]; - - memset(tmp, 0, sizeof(tmp) - length); - memmove(tmp + sizeof(tmp) - length, data, length); - readu256BE(tmp, target); -} - -uint64_t u64_from_BE(const uint8_t *in, uint8_t size) { - uint8_t i = 0; - uint64_t res = 0; - - while (i < size && i < sizeof(res)) { - res <<= 8; - res |= in[i]; - i++; - } - - return res; -} - -bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len) { - if (value_len > INT256_LENGTH) { - // value len is bigger than INT256_LENGTH ?! - return false; - } - - uint16_t n[16] = {0}; - // Copy and right-align the number - memcpy((uint8_t *) n + INT256_LENGTH - value_len, value, value_len); - - // Special case when value is 0 - if (allzeroes(n, INT256_LENGTH)) { - if (out_len < 2) { - // Not enough space to hold "0" and \0. - return false; - } - strlcpy(out, "0", out_len); - return true; - } - - uint16_t *p = n; - for (int i = 0; i < 16; i++) { - n[i] = __builtin_bswap16(*p++); - } - int pos = out_len; - while (!allzeroes(n, sizeof(n))) { - if (pos == 0) { - return false; - } - pos -= 1; - unsigned int carry = 0; - for (int i = 0; i < 16; i++) { - int rem = ((carry << 16) | n[i]) % 10; - n[i] = ((carry << 16) | n[i]) / 10; - carry = rem; - } - out[pos] = '0' + carry; - } - memmove(out, out + pos, out_len - pos); - out[out_len - pos] = 0; - return true; -} - -void amountToString(const uint8_t *amount, - uint8_t amount_size, - uint8_t decimals, - const char *ticker, - char *out_buffer, - size_t out_buffer_size) { - char tmp_buffer[100] = {0}; - - if (uint256_to_decimal(amount, amount_size, tmp_buffer, sizeof(tmp_buffer)) == false) { - THROW(EXCEPTION_OVERFLOW); - } - - uint8_t amount_len = strnlen(tmp_buffer, sizeof(tmp_buffer)); - uint8_t ticker_len = strnlen(ticker, MAX_TICKER_LEN); - - memcpy(out_buffer, ticker, MIN(out_buffer_size, ticker_len)); - if (ticker_len > 0) { - out_buffer[ticker_len++] = ' '; - } - - if (adjustDecimals(tmp_buffer, - amount_len, - out_buffer + ticker_len, - out_buffer_size - ticker_len - 1, - decimals) == false) { - THROW(EXCEPTION_OVERFLOW); - } - - out_buffer[out_buffer_size - 1] = '\0'; -} - -bool parse_swap_config(const uint8_t *config, uint8_t config_len, char *ticker, uint8_t *decimals) { - uint8_t ticker_len, offset = 0; - if (config_len == 0) { - return false; - } - ticker_len = config[offset++]; - if (ticker_len == 0 || ticker_len > MAX_TICKER_LEN - 2 || config_len - offset < ticker_len) { - return false; - } - memcpy(ticker, config + offset, ticker_len); - offset += ticker_len; - ticker[ticker_len] = '\0'; - - if (config_len - offset < 1) { - return false; - } - *decimals = config[offset]; - return true; -} diff --git a/src/utils.h b/src/utils.h deleted file mode 100644 index 504c1b139..000000000 --- a/src/utils.h +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Ledger Ethereum App - * (c) 2016-2019 Ledger - * - * 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. - ********************************************************************************/ - -#ifndef _UTILS_H_ -#define _UTILS_H_ - -#include - -#include "uint256.h" - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) - -void array_hexstr(char* strbuf, const void* bin, unsigned int len); - -void convertUint128BE(const uint8_t* const data, uint32_t length, uint128_t* const target); -void convertUint256BE(const uint8_t* const data, uint32_t length, uint256_t* const target); -void convertUint64BEto128(const uint8_t* const data, uint32_t length, uint128_t* const target); - -uint64_t u64_from_BE(const uint8_t* in, uint8_t size); - -bool uint256_to_decimal(const uint8_t* value, size_t value_len, char* out, size_t out_len); - -void amountToString(const uint8_t* amount, - uint8_t amount_len, - uint8_t decimals, - const char* ticker, - char* out_buffer, - size_t out_buffer_size); - -bool parse_swap_config(const uint8_t* config, uint8_t config_len, char* ticker, uint8_t* decimals); - -#endif // _UTILS_H_ diff --git a/src_bagl/common_ui.c b/src_bagl/common_ui.c index e1449f0b3..dc6450496 100644 --- a/src_bagl/common_ui.c +++ b/src_bagl/common_ui.c @@ -28,7 +28,8 @@ void ui_display_privacy_shared_secret(void) { ux_flow_init(0, ux_display_privacy_shared_secret_flow, NULL); } -void ui_display_public_key(void) { +void ui_display_public_key(const uint64_t *chain_id) { + (void) chain_id; ux_flow_init(0, ux_display_public_flow, NULL); } @@ -36,32 +37,6 @@ void ui_sign_712_v0(void) { ux_flow_init(0, ux_sign_712_v0_flow, NULL); } -#ifdef HAVE_STARKWARE -void ui_display_stark_public(void) { - ux_flow_init(0, ux_display_stark_public_flow, NULL); -} -void ui_stark_limit_order(void) { - ux_flow_init(0, ux_stark_limit_order_flow, NULL); -} - -void ui_stark_unsafe_sign(void) { - ux_flow_init(0, ux_stark_unsafe_sign_flow, NULL); -} - -void ui_stark_transfer(bool selfTransfer, bool conditional) { - if (selfTransfer) { - ux_flow_init( - 0, - (conditional ? ux_stark_self_transfer_conditional_flow : ux_stark_self_transfer_flow), - NULL); - } else { - ux_flow_init(0, - (conditional ? ux_stark_transfer_conditional_flow : ux_stark_transfer_flow), - NULL); - } -} -#endif // HAVE_STARKWARE - void ui_confirm_selector(void) { ux_flow_init(0, ux_confirm_selector_flow, NULL); } diff --git a/src_bagl/ui_domain_name.c b/src_bagl/ui_domain_name.c index 599133d2f..31215469d 100644 --- a/src_bagl/ui_domain_name.c +++ b/src_bagl/ui_domain_name.c @@ -1,6 +1,6 @@ #ifdef HAVE_DOMAIN_NAME -#include "ux.h" +#include "ui_domain_name.h" #include "domain_name.h" ////////////////////////////////////////////////////////////////////// diff --git a/src_bagl/ui_flow.c b/src_bagl/ui_flow.c index a98ce6bdc..17f7eed99 100644 --- a/src_bagl/ui_flow.c +++ b/src_bagl/ui_flow.c @@ -1,7 +1,7 @@ #include "shared_context.h" #include "ui_callbacks.h" #include "common_ui.h" -#include "utils.h" +#include "common_utils.h" #define ENABLED_STR "Enabled" #define DISABLED_STR "Disabled" diff --git a/src_bagl/ui_flow.h b/src_bagl/ui_flow.h index 184036b67..ae2590d90 100644 --- a/src_bagl/ui_flow.h +++ b/src_bagl/ui_flow.h @@ -30,34 +30,4 @@ extern const ux_flow_step_t* const ux_display_privacy_shared_secret_flow[]; extern const ux_flow_step_t* ux_approval_tx_flow[15]; -#ifdef HAVE_STARKWARE - -extern const ux_flow_step_t* const ux_display_stark_public_flow[]; - -extern const ux_flow_step_t* const ux_stark_limit_order_flow[]; - -extern const ux_flow_step_t* const ux_stark_transfer_flow[]; - -extern const ux_flow_step_t* const ux_stark_self_transfer_flow[]; - -extern const ux_flow_step_t* const ux_stark_transfer_conditional_flow[]; - -extern const ux_flow_step_t* const ux_stark_self_transfer_conditional_flow[]; - -extern const ux_flow_step_t* const ux_approval_starkware_register_flow[]; - -extern const ux_flow_step_t* const ux_approval_starkware_deposit_flow[]; - -extern const ux_flow_step_t* const ux_approval_starkware_withdraw_flow[]; - -extern const ux_flow_step_t* const ux_approval_starkware_verify_vault_id_flow[]; - -extern const ux_flow_step_t* const ux_approval_starkware_escape_flow[]; - -extern const ux_flow_step_t* const ux_approval_starkware_verify_escape_flow[]; - -extern const ux_flow_step_t* const ux_stark_unsafe_sign_flow[]; - -#endif - #endif // _UI_FLOW_H_ diff --git a/src_bagl/ui_flow_signMessage712_v0.c b/src_bagl/ui_flow_signMessage712_v0.c index 230852e81..9cdda7051 100644 --- a/src_bagl/ui_flow_signMessage712_v0.c +++ b/src_bagl/ui_flow_signMessage712_v0.c @@ -1,7 +1,6 @@ #include "shared_context.h" #include "ui_callbacks.h" #include "common_712.h" -#include "ethUtils.h" void prepare_domain_hash_v0() { snprintf(strings.tmp.tmp, diff --git a/src_bagl/ui_flow_signTx.c b/src_bagl/ui_flow_signTx.c index 5d8e7b394..eabdf9001 100644 --- a/src_bagl/ui_flow_signTx.c +++ b/src_bagl/ui_flow_signTx.c @@ -1,13 +1,12 @@ #include "shared_context.h" #include "ui_callbacks.h" #include "chainConfig.h" -#include "utils.h" +#include "common_utils.h" #include "feature_signTx.h" #include "network.h" #include "eth_plugin_handler.h" #include "ui_plugin.h" #include "common_ui.h" -#include "ethUtils.h" #include "plugins.h" #include "domain_name.h" #include "ui_domain_name.h" @@ -158,6 +157,7 @@ UX_STEP_NOCB( .title = "Max Fees", .text = strings.common.maxFee, }); + UX_STEP_NOCB( ux_approval_network_step, bnnn_paging, @@ -240,7 +240,7 @@ void ux_approve_tx(bool fromPlugin) { } uint64_t chain_id = get_tx_chain_id(); - if (chainConfig->chainId == ETHEREUM_MAINNET_CHAINID && chain_id != chainConfig->chainId) { + if ((chainConfig->chainId == ETHEREUM_MAINNET_CHAINID) && (chain_id != chainConfig->chainId)) { ux_approval_tx_flow[step++] = &ux_approval_network_step; } diff --git a/src_bagl/ui_flow_stark_getPublicKey.c b/src_bagl/ui_flow_stark_getPublicKey.c deleted file mode 100644 index 958874fc2..000000000 --- a/src_bagl/ui_flow_stark_getPublicKey.c +++ /dev/null @@ -1,46 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" -#include "ui_callbacks.h" - -// clang-format off -UX_STEP_NOCB( - ux_display_stark_public_flow_1_step, - pnn, - { - &C_icon_eye, - "Verify", - "Stark key", - }); -UX_STEP_NOCB( - ux_display_stark_public_flow_2_step, - bnnn_paging, - { - .title = "Stark Key", - .text = strings.tmp.tmp, - }); -UX_STEP_CB( - ux_display_stark_public_flow_3_step, - pb, - io_seproxyhal_touch_stark_pubkey_ok(NULL), - { - &C_icon_validate_14, - "Approve", - }); -UX_STEP_CB( - ux_display_stark_public_flow_4_step, - pb, - io_seproxyhal_touch_address_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); -// clang-format on - -UX_FLOW(ux_display_stark_public_flow, - &ux_display_stark_public_flow_1_step, - &ux_display_stark_public_flow_2_step, - &ux_display_stark_public_flow_3_step, - &ux_display_stark_public_flow_4_step); - -#endif diff --git a/src_bagl/ui_flow_stark_sign.c b/src_bagl/ui_flow_stark_sign.c deleted file mode 100644 index 548e8808f..000000000 --- a/src_bagl/ui_flow_stark_sign.c +++ /dev/null @@ -1,228 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" -#include "ui_callbacks.h" -#include "ethUtils.h" -#include "starkDisplayUtils.h" - -// clang-format off -UX_STEP_NOCB(ux_stark_limit_order_1_step, - pnn, - { - &C_icon_eye, - "Review", - "transaction", - }); - -UX_STEP_NOCB(ux_stark_limit_order_2_step, - bnnn_paging, - { - .title = "Limit", - .text = "Order" - }); - -UX_STEP_NOCB(ux_stark_limit_order_3_step, - bnnn_paging, - { - .title = "Trading", - .text = "Pair" - }); - -UX_STEP_NOCB(ux_stark_limit_order_4_step, - bnnn_paging, - { - .title = "Sell", - .text = strings.common.fullAmount - }); - -UX_STEP_NOCB(ux_stark_limit_order_5_step, - bnnn_paging, - { - .title = "Buy", - .text = strings.common.maxFee - }); - -UX_STEP_NOCB(ux_stark_limit_order_6_step, - bnnn_paging, - { - .title = "Token Account", - .text = strings.common.fullAddress - }); - -UX_STEP_CB( - ux_stark_limit_order_7_step, - pbb, - io_seproxyhal_touch_stark_ok(NULL), - { - &C_icon_validate_14, - "Accept", - "and send", - }); -UX_STEP_CB( - ux_stark_limit_order_8_step, - pb, - io_seproxyhal_touch_tx_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); -// clang-format on - -UX_FLOW(ux_stark_limit_order_flow, - &ux_stark_limit_order_1_step, - &ux_stark_limit_order_2_step, - &ux_stark_limit_order_3_step, - &ux_stark_limit_order_4_step, - &ux_stark_limit_order_5_step, - &ux_stark_limit_order_6_step, - &ux_stark_limit_order_7_step, - &ux_stark_limit_order_8_step); - -////////////////////////////////////////////////////////////////////// -// clang-format off -UX_STEP_NOCB(ux_stark_transfer_1_step, - pnn, - { - &C_icon_eye, - "Review", - "transaction", - }); - -UX_STEP_NOCB(ux_stark_transfer_2_step, - bnnn_paging, - { - .title = "Transfer", - .text = " " - }); - -UX_STEP_NOCB(ux_stark_self_transfer_2_step, - bnnn_paging, - { - .title = "Self", - .text = "Transfer" - }); - -UX_STEP_NOCB(ux_stark_conditional_transfer_2_step, - bnnn_paging, - { - .title = "Conditional", - .text = "Transfer" - }); - -UX_STEP_NOCB(ux_stark_self_conditional_transfer_2_step, - bnnn_paging, - { - .title = "Conditional", - .text = "Self Transfer" - }); - -UX_STEP_NOCB(ux_stark_transfer_3_step, - bnnn_paging, - { - .title = "Amount", - .text = tmpContent.tmp - }); - -UX_STEP_NOCB(ux_stark_transfer_4_step, - bnnn_paging, - { - .title = "Master Account", - .text = strings.tmp.tmp - }); - -UX_STEP_NOCB(ux_stark_transfer_5_step, - bnnn_paging, - { - .title = "Token Account", - .text = strings.tmp.tmp2 - }); - -UX_STEP_CB( - ux_stark_transfer_6_step, - pbb, - io_seproxyhal_touch_stark_ok(NULL), - { - &C_icon_validate_14, - "Accept", - "and send", - }); -UX_STEP_CB( - ux_stark_transfer_7_step, - pb, - io_seproxyhal_touch_tx_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); - -UX_STEP_NOCB_INIT( - ux_stark_conditional_transfer_4_step, - bnnn_paging, - stark_sign_display_master_account(), - { - .title = "Master Account", - .text = strings.tmp.tmp - }); - -UX_STEP_NOCB_INIT( - ux_stark_conditional_transfer_8_step, - bnnn_paging, - getEthDisplayableAddress(dataContext.starkContext.conditionAddress, - strings.tmp.tmp, - sizeof(strings.tmp.tmp), - &global_sha3, - chainConfig->chainId), - { - .title = "Cond. Address", - .text = strings.tmp.tmp - }); - -UX_STEP_NOCB_INIT( - ux_stark_conditional_transfer_9_step, - bnnn_paging, - stark_sign_display_condition_fact(), - { - .title = "Cond. Fact", - .text = strings.tmp.tmp - }); -// clang-format on - -UX_FLOW(ux_stark_transfer_flow, - &ux_stark_transfer_1_step, - &ux_stark_transfer_2_step, - &ux_stark_transfer_3_step, - &ux_stark_transfer_4_step, - &ux_stark_transfer_5_step, - &ux_stark_transfer_6_step, - &ux_stark_transfer_7_step); - -UX_FLOW(ux_stark_self_transfer_flow, - &ux_stark_transfer_1_step, - &ux_stark_self_transfer_2_step, - &ux_stark_transfer_3_step, - &ux_stark_transfer_5_step, - &ux_stark_transfer_6_step, - &ux_stark_transfer_7_step); - -UX_FLOW(ux_stark_transfer_conditional_flow, - &ux_stark_transfer_1_step, - &ux_stark_conditional_transfer_2_step, - &ux_stark_transfer_3_step, - &ux_stark_conditional_transfer_4_step, - &ux_stark_transfer_5_step, - &ux_stark_conditional_transfer_8_step, - &ux_stark_conditional_transfer_9_step, - &ux_stark_transfer_6_step, - &ux_stark_transfer_7_step); - -UX_FLOW(ux_stark_self_transfer_conditional_flow, - &ux_stark_transfer_1_step, - &ux_stark_self_conditional_transfer_2_step, - &ux_stark_transfer_3_step, - &ux_stark_transfer_5_step, - &ux_stark_conditional_transfer_8_step, - &ux_stark_conditional_transfer_9_step, - &ux_stark_transfer_6_step, - &ux_stark_transfer_7_step); - -#endif diff --git a/src_bagl/ui_flow_stark_unsafe_sign.c b/src_bagl/ui_flow_stark_unsafe_sign.c deleted file mode 100644 index 1c080582e..000000000 --- a/src_bagl/ui_flow_stark_unsafe_sign.c +++ /dev/null @@ -1,70 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" -#include "ui_callbacks.h" - -unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(const bagl_element_t *e); - -void stark_unsafe_sign_display_account() { - snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.w1); -} - -void stark_unsafe_sign_display_hash() { - snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.w2); -} - -// clang-format off -UX_STEP_NOCB(ux_stark_unsafe_sign_1_step, - pnn, - { - &C_icon_warning, - "StarkNet", - "Blind Sign", - }); - -UX_STEP_NOCB_INIT( - ux_stark_unsafe_sign_2_step, - bnnn_paging, - stark_unsafe_sign_display_account(), - { - .title = "From Account", - .text = strings.tmp.tmp - }); - -UX_STEP_NOCB_INIT( - ux_stark_unsafe_sign_3_step, - bnnn_paging, - stark_unsafe_sign_display_hash(), - { - .title = "Tx Hash", - .text = strings.tmp.tmp - }); - - -UX_STEP_CB( - ux_stark_unsafe_sign_4_step, - pbb, - io_seproxyhal_touch_stark_unsafe_sign_ok(NULL), - { - &C_icon_validate_14, - "Accept", - "and send", - }); -UX_STEP_CB( - ux_stark_unsafe_sign_5_step, - pb, - io_seproxyhal_touch_tx_cancel(NULL), - { - &C_icon_crossmark, - "Reject", - }); -// clang-format on - -UX_FLOW(ux_stark_unsafe_sign_flow, - &ux_stark_unsafe_sign_1_step, - &ux_stark_unsafe_sign_2_step, - &ux_stark_unsafe_sign_3_step, - &ux_stark_unsafe_sign_4_step, - &ux_stark_unsafe_sign_5_step); - -#endif diff --git a/src_common/asset_info.h b/src_common/asset_info.h new file mode 100644 index 000000000..a2ce39332 --- /dev/null +++ b/src_common/asset_info.h @@ -0,0 +1,51 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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 +#include "common_utils.h" + +// NFT + +#define COLLECTION_NAME_MAX_LEN 70 + +typedef struct nftInfo_t { + uint8_t contractAddress[ADDRESS_LENGTH]; // must be first item + char collectionName[COLLECTION_NAME_MAX_LEN + 1]; +} nftInfo_t; + +// TOKENS + +#define MAX_TICKER_LEN 11 // 10 characters + '\0' +#define MAX_ITEMS 2 + +typedef struct tokenDefinition_t { + uint8_t address[ADDRESS_LENGTH]; // must be first item +#ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR + uint8_t contractName[ADDRESS_LENGTH]; +#endif + char ticker[MAX_TICKER_LEN]; + uint8_t decimals; +} tokenDefinition_t; + +// UNION + +typedef union extraInfo_t { + tokenDefinition_t token; + nftInfo_t nft; +} extraInfo_t; diff --git a/src_common/caller_api.h b/src_common/caller_api.h new file mode 100644 index 000000000..7f769bee9 --- /dev/null +++ b/src_common/caller_api.h @@ -0,0 +1,34 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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 + +#ifdef HAVE_NBGL +#include "ux.h" +#endif + +typedef enum { CALLER_TYPE_CLONE, CALLER_TYPE_PLUGIN } e_caller_type; + +typedef struct caller_app_t { + const char *name; +#ifdef HAVE_NBGL + const nbgl_icon_details_t *icon; +#endif + char type; // does not have to be set by the caller app +} caller_app_t; + +extern caller_app_t *caller_app; diff --git a/src_common/ethUtils.c b/src_common/common_utils.c similarity index 55% rename from src_common/ethUtils.c rename to src_common/common_utils.c index e66e0d2e5..84a424ea0 100644 --- a/src_common/ethUtils.c +++ b/src_common/common_utils.c @@ -15,132 +15,41 @@ * limitations under the License. ********************************************************************************/ -/** - * @brief Utilities for an Ethereum Hardware Wallet logic - * @file ethUtils.h - * @author Ledger Firmware Team - * @version 1.0 - * @date 8th of March 2016 - */ - -#include #include #include -#include "shared_context.h" -#include "utils.h" -#include "ethUtils.h" -#include "chainConfig.h" -#include "ethUstream.h" -#include "network.h" - -bool rlpCanDecode(uint8_t *buffer, uint32_t bufferLength, bool *valid) { - if (*buffer <= 0x7f) { - } else if (*buffer <= 0xb7) { - } else if (*buffer <= 0xbf) { - if (bufferLength < (1 + (*buffer - 0xb7))) { - return false; - } - if (*buffer > 0xbb) { - *valid = false; // arbitrary 32 bits length limitation - return true; - } - } else if (*buffer <= 0xf7) { - } else { - if (bufferLength < (1 + (*buffer - 0xf7))) { - return false; - } - if (*buffer > 0xfb) { - *valid = false; // arbitrary 32 bits length limitation - return true; - } - } - *valid = true; - return true; -} +#include "asset_info.h" +#include "common_utils.h" -bool rlpDecodeLength(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, bool *list) { - if (*buffer <= 0x7f) { - *offset = 0; - *fieldLength = 1; - *list = false; - } else if (*buffer <= 0xb7) { - *offset = 1; - *fieldLength = *buffer - 0x80; - *list = false; - } else if (*buffer <= 0xbf) { - *offset = 1 + (*buffer - 0xb7); - *list = false; - switch (*buffer) { - case 0xb8: - *fieldLength = *(buffer + 1); - break; - case 0xb9: - *fieldLength = (*(buffer + 1) << 8) + *(buffer + 2); - break; - case 0xba: - *fieldLength = (*(buffer + 1) << 16) + (*(buffer + 2) << 8) + *(buffer + 3); - break; - case 0xbb: - *fieldLength = (*(buffer + 1) << 24) + (*(buffer + 2) << 16) + - (*(buffer + 3) << 8) + *(buffer + 4); - break; - default: - return false; // arbitrary 32 bits length limitation - } - } else if (*buffer <= 0xf7) { - *offset = 1; - *fieldLength = *buffer - 0xc0; - *list = true; - } else { - *offset = 1 + (*buffer - 0xf7); - *list = true; - switch (*buffer) { - case 0xf8: - *fieldLength = *(buffer + 1); - break; - case 0xf9: - *fieldLength = (*(buffer + 1) << 8) + *(buffer + 2); - break; - case 0xfa: - *fieldLength = (*(buffer + 1) << 16) + (*(buffer + 2) << 8) + *(buffer + 3); - break; - case 0xfb: - *fieldLength = (*(buffer + 1) << 24) + (*(buffer + 2) << 16) + - (*(buffer + 3) << 8) + *(buffer + 4); - break; - default: - return false; // arbitrary 32 bits length limitation - } +void array_hexstr(char *strbuf, const void *bin, unsigned int len) { + while (len--) { + *strbuf++ = HEXDIGITS[((*((char *) bin)) >> 4) & 0xF]; + *strbuf++ = HEXDIGITS[(*((char *) bin)) & 0xF]; + bin = (const void *) ((unsigned int) bin + 1); } - - return true; + *strbuf = 0; // EOS } -void getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3_t *sha3Context) { - uint8_t hashAddress[INT256_LENGTH]; - cx_keccak_init(sha3Context, 256); - cx_hash((cx_hash_t *) sha3Context, CX_LAST, publicKey->W + 1, 64, hashAddress, 32); - memmove(out, hashAddress + 12, 20); -} +uint64_t u64_from_BE(const uint8_t *in, uint8_t size) { + uint8_t i = 0; + uint64_t res = 0; -void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey, - char *out, - cx_sha3_t *sha3Context, - uint64_t chainId) { - uint8_t hashAddress[INT256_LENGTH]; - cx_keccak_init(sha3Context, 256); - cx_hash((cx_hash_t *) sha3Context, CX_LAST, publicKey->W + 1, 64, hashAddress, 32); - getEthAddressStringFromBinary(hashAddress + 12, out, sha3Context, chainId); + while (i < size && i < sizeof(res)) { + res <<= 8; + res |= in[i]; + i++; + } + + return res; } -void u64_to_string(uint64_t src, char *dst, uint8_t dst_size) { +bool u64_to_string(uint64_t src, char *dst, uint8_t dst_size) { // Copy the numbers in ASCII format. uint8_t i = 0; do { // Checking `i + 1` to make sure we have enough space for '\0'. if (i + 1 >= dst_size) { - THROW(0x6502); + return false; } dst[i] = src % 10 + '0'; src /= 10; @@ -160,82 +69,50 @@ void u64_to_string(uint64_t src, char *dst, uint8_t dst_size) { i--; j++; } + return true; } -void getEthAddressStringFromBinary(uint8_t *address, - char *out, - cx_sha3_t *sha3Context, - uint64_t chainId) { - // save some precious stack space - union locals_union { - uint8_t hashChecksum[INT256_LENGTH]; - uint8_t tmp[51]; - } locals_union; - - uint8_t i; - bool eip1191 = false; - uint32_t offset = 0; - switch (chainId) { - case 30: - case 31: - eip1191 = true; - break; +bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len) { + if (value_len > INT256_LENGTH) { + // value len is bigger than INT256_LENGTH ?! + return false; } - if (eip1191) { - u64_to_string(chainId, (char *) locals_union.tmp, sizeof(locals_union.tmp)); - offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp)); - strlcat((char *) locals_union.tmp + offset, "0x", sizeof(locals_union.tmp) - offset); - offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp)); + + uint16_t n[16] = {0}; + // Copy and right-align the number + memcpy((uint8_t *) n + INT256_LENGTH - value_len, value, value_len); + + // Special case when value is 0 + if (allzeroes(n, INT256_LENGTH)) { + if (out_len < 2) { + // Not enough space to hold "0" and \0. + return false; + } + strlcpy(out, "0", out_len); + return true; } - for (i = 0; i < 20; i++) { - uint8_t digit = address[i]; - locals_union.tmp[offset + 2 * i] = HEXDIGITS[(digit >> 4) & 0x0f]; - locals_union.tmp[offset + 2 * i + 1] = HEXDIGITS[digit & 0x0f]; + + uint16_t *p = n; + for (int i = 0; i < 16; i++) { + n[i] = __builtin_bswap16(*p++); } - cx_keccak_init(sha3Context, 256); - cx_hash((cx_hash_t *) sha3Context, - CX_LAST, - locals_union.tmp, - offset + 40, - locals_union.hashChecksum, - 32); - for (i = 0; i < 40; i++) { - uint8_t digit = address[i / 2]; - if ((i % 2) == 0) { - digit = (digit >> 4) & 0x0f; - } else { - digit = digit & 0x0f; + int pos = out_len; + while (!allzeroes(n, sizeof(n))) { + if (pos == 0) { + return false; } - if (digit < 10) { - out[i] = HEXDIGITS[digit]; - } else { - int v = (locals_union.hashChecksum[i / 2] >> (4 * (1 - i % 2))) & 0x0f; - if (v >= 8) { - out[i] = HEXDIGITS[digit] - 'a' + 'A'; - } else { - out[i] = HEXDIGITS[digit]; - } + pos -= 1; + unsigned int carry = 0; + for (int i = 0; i < 16; i++) { + int rem = ((carry << 16) | n[i]) % 10; + n[i] = ((carry << 16) | n[i]) / 10; + carry = rem; } + out[pos] = '0' + carry; } - out[40] = '\0'; -} - -/* Fills the `out` buffer with the lowercase string representation of the pubkey passed in as binary -format by `in`. (eg: uint8_t*:0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB -> -char*:"0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB\0" ) -`sha3` context doesn't have have to be initialized prior to call.*/ -void getEthDisplayableAddress(uint8_t *in, - char *out, - size_t out_len, - cx_sha3_t *sha3, - uint64_t chainId) { - if (out_len < 43) { - strlcpy(out, "ERROR", out_len); - return; - } - out[0] = '0'; - out[1] = 'x'; - getEthAddressStringFromBinary(in, out + 2, sha3, chainId); + memmove(out, out + pos, out_len - pos); + out[out_len - pos] = 0; + return true; } bool adjustDecimals(const char *src, @@ -305,31 +182,170 @@ bool adjustDecimals(const char *src, return true; } -// Returns the chain ID. Defaults to 0 if txType was not found (For TX). -uint64_t get_tx_chain_id(void) { - uint64_t chain_id = 0; +bool amountToString(const uint8_t *amount, + uint8_t amount_size, + uint8_t decimals, + const char *ticker, + char *out_buffer, + size_t out_buffer_size) { + char tmp_buffer[100] = {0}; - switch (txContext.txType) { - case LEGACY: - chain_id = u64_from_BE(txContext.content->v, txContext.content->vLength); - break; - case EIP2930: - case EIP1559: - chain_id = u64_from_BE(tmpContent.txContent.chainID.value, - tmpContent.txContent.chainID.length); - break; - default: - PRINTF("Txtype `%d` not supported while generating chainID\n", txContext.txType); - break; + if (uint256_to_decimal(amount, amount_size, tmp_buffer, sizeof(tmp_buffer)) == false) { + return false; + } + + uint8_t amount_len = strnlen(tmp_buffer, sizeof(tmp_buffer)); + uint8_t ticker_len = strnlen(ticker, MAX_TICKER_LEN); + + memcpy(out_buffer, ticker, MIN(out_buffer_size, ticker_len)); + if (ticker_len > 0) { + out_buffer[ticker_len++] = ' '; } - return chain_id; + + if (adjustDecimals(tmp_buffer, + amount_len, + out_buffer + ticker_len, + out_buffer_size - ticker_len - 1, + decimals) == false) { + return false; + } + + out_buffer[out_buffer_size - 1] = '\0'; + return true; +} + +bool getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3_t *sha3Context) { + uint8_t hashAddress[INT256_LENGTH]; + + if (cx_keccak_init_no_throw(sha3Context, 256) != CX_OK) { + return false; + } + + if (cx_hash_no_throw((cx_hash_t *) sha3Context, + CX_LAST, + publicKey->W + 1, + 64, + hashAddress, + 32) != CX_OK) { + return false; + } + + memmove(out, hashAddress + 12, 20); + return true; } -const char *get_displayable_ticker(const uint64_t *chain_id) { - const char *ticker = get_network_ticker_from_chain_id(chain_id); +bool getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey, + char *out, + cx_sha3_t *sha3Context, + uint64_t chainId) { + uint8_t hashAddress[INT256_LENGTH]; + + if (cx_keccak_init_no_throw(sha3Context, 256) != CX_OK) { + return false; + } + + if (cx_hash_no_throw((cx_hash_t *) sha3Context, + CX_LAST, + publicKey->W + 1, + 64, + hashAddress, + 32) != CX_OK) { + return false; + } + + if (!getEthAddressStringFromBinary(hashAddress + 12, out, sha3Context, chainId)) { + return false; + } + + return true; +} + +bool getEthAddressStringFromBinary(uint8_t *address, + char *out, + cx_sha3_t *sha3Context, + uint64_t chainId) { + // save some precious stack space + union locals_union { + uint8_t hashChecksum[INT256_LENGTH]; + uint8_t tmp[51]; + } locals_union; + + uint8_t i; + bool eip1191 = false; + uint32_t offset = 0; + switch (chainId) { + case 30: + case 31: + eip1191 = true; + break; + } + if (eip1191) { + if (!u64_to_string(chainId, (char *) locals_union.tmp, sizeof(locals_union.tmp))) { + return false; + } + offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp)); + strlcat((char *) locals_union.tmp + offset, "0x", sizeof(locals_union.tmp) - offset); + offset = strnlen((char *) locals_union.tmp, sizeof(locals_union.tmp)); + } + for (i = 0; i < 20; i++) { + uint8_t digit = address[i]; + locals_union.tmp[offset + 2 * i] = HEXDIGITS[(digit >> 4) & 0x0f]; + locals_union.tmp[offset + 2 * i + 1] = HEXDIGITS[digit & 0x0f]; + } + if (cx_keccak_init_no_throw(sha3Context, 256) != CX_OK) { + return false; + } + + if (cx_hash_no_throw((cx_hash_t *) sha3Context, + CX_LAST, + locals_union.tmp, + offset + 40, + locals_union.hashChecksum, + 32) != CX_OK) { + return false; + } + for (i = 0; i < 40; i++) { + uint8_t digit = address[i / 2]; + if ((i % 2) == 0) { + digit = (digit >> 4) & 0x0f; + } else { + digit = digit & 0x0f; + } + if (digit < 10) { + out[i] = HEXDIGITS[digit]; + } else { + int v = (locals_union.hashChecksum[i / 2] >> (4 * (1 - i % 2))) & 0x0f; + if (v >= 8) { + out[i] = HEXDIGITS[digit] - 'a' + 'A'; + } else { + out[i] = HEXDIGITS[digit]; + } + } + } + out[40] = '\0'; + + return true; +} - if (ticker == NULL) { - ticker = chainConfig->coinName; +/* Fills the `out` buffer with the lowercase string representation of the pubkey passed in as binary +format by `in`. (eg: uint8_t*:0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB -> +char*:"0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB\0" ) +`sha3` context doesn't have have to be initialized prior to call.*/ +bool getEthDisplayableAddress(uint8_t *in, + char *out, + size_t out_len, + cx_sha3_t *sha3, + uint64_t chainId) { + if (out_len < 43) { + strlcpy(out, "ERROR", out_len); + return false; } - return ticker; + out[0] = '0'; + out[1] = 'x'; + if (!getEthAddressStringFromBinary(in, out + 2, sha3, chainId)) { + strlcpy(out, "ERROR", out_len); + return false; + } + + return true; } diff --git a/src_common/ethUtils.h b/src_common/common_utils.h similarity index 65% rename from src_common/ethUtils.h rename to src_common/common_utils.h index 870253351..fd198d95f 100644 --- a/src_common/ethUtils.h +++ b/src_common/common_utils.h @@ -15,57 +15,65 @@ * limitations under the License. ********************************************************************************/ -#ifndef _ETHUTILS_H_ -#define _ETHUTILS_H_ +#pragma once +#include #include +#include "os.h" #include "cx.h" -#include "chainConfig.h" + +#define WEI_TO_ETHER 18 + +#define ADDRESS_LENGTH 20 +#define INT128_LENGTH 16 +#define INT256_LENGTH 32 #define KECCAK256_HASH_BYTESIZE 32 -/** - * @brief Decode an RLP encoded field - see - * https://github.com/ethereum/wiki/wiki/RLP - * @param [in] buffer buffer containing the RLP encoded field to decode - * @param [out] fieldLength length of the RLP encoded field - * @param [out] offset offset to the beginning of the RLP encoded field from the - * buffer - * @param [out] list true if the field encodes a list, false if it encodes a - * string - * @return true if the RLP header is consistent - */ -bool rlpDecodeLength(uint8_t *buffer, uint32_t *fieldLength, uint32_t *offset, bool *list); +static const char HEXDIGITS[] = "0123456789abcdef"; + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +void array_hexstr(char *strbuf, const void *bin, unsigned int len); + +uint64_t u64_from_BE(const uint8_t *in, uint8_t size); + +bool u64_to_string(uint64_t src, char *dst, uint8_t dst_size); -bool rlpCanDecode(uint8_t *buffer, uint32_t bufferLength, bool *valid); +bool uint256_to_decimal(const uint8_t *value, size_t value_len, char *out, size_t out_len); + +bool amountToString(const uint8_t *amount, + uint8_t amount_len, + uint8_t decimals, + const char *ticker, + char *out_buffer, + size_t out_buffer_size); + +bool adjustDecimals(const char *src, + size_t srcLength, + char *target, + size_t targetLength, + uint8_t decimals); -void getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3_t *sha3Context); +bool getEthAddressFromKey(cx_ecfp_public_key_t *publicKey, uint8_t *out, cx_sha3_t *sha3Context); -void getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey, +bool getEthAddressStringFromKey(cx_ecfp_public_key_t *publicKey, char *out, cx_sha3_t *sha3Context, uint64_t chainId); -void u64_to_string(uint64_t src, char *dst, uint8_t dst_size); - -void getEthAddressStringFromBinary(uint8_t *address, +bool getEthAddressStringFromBinary(uint8_t *address, char *out, cx_sha3_t *sha3Context, uint64_t chainId); -void getEthDisplayableAddress(uint8_t *in, +bool getEthDisplayableAddress(uint8_t *in, char *out, size_t out_len, cx_sha3_t *sha3, uint64_t chainId); -bool adjustDecimals(const char *src, - size_t srcLength, - char *target, - size_t targetLength, - uint8_t decimals); - static __attribute__((no_instrument_function)) inline int allzeroes(const void *buf, size_t n) { uint8_t *p = (uint8_t *) buf; for (size_t i = 0; i < n; ++i) { @@ -83,11 +91,3 @@ static __attribute__((no_instrument_function)) inline int ismaxint(uint8_t *buf, } return 1; } - -uint64_t get_tx_chain_id(void); - -const char *get_displayable_ticker(const uint64_t *chain_id); - -static const char HEXDIGITS[] = "0123456789abcdef"; - -#endif // _ETHUTILS_H_ diff --git a/src_common/eth_plugin_interface.h b/src_common/eth_plugin_interface.h new file mode 100644 index 000000000..98218368a --- /dev/null +++ b/src_common/eth_plugin_interface.h @@ -0,0 +1,224 @@ +// clang-format off + +#pragma once + +#include "os.h" +#include "cx.h" + +// Include other header compatible with plugins +#include "asset_info.h" +#include "caller_api.h" +#include "common_utils.h" +#include "plugin_utils.h" +#include "tx_content.h" + +/************************************************************************************************* + * Comments provided in this file are quick reminders on the usage of the plugin interface * + * Reading the real plugin documentation is GREATLY recommended. * + * You can find the latest version here: * + * https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/ethapp_plugins.adoc * + *************************************************************************************************/ + +// Interface version. Will be updated every time a breaking change in the interface is introduced. +typedef enum eth_plugin_interface_version_e { + ETH_PLUGIN_INTERFACE_VERSION_1 = 1, + ETH_PLUGIN_INTERFACE_VERSION_2 = 2, + ETH_PLUGIN_INTERFACE_VERSION_3 = 3, + ETH_PLUGIN_INTERFACE_VERSION_4 = 4, + ETH_PLUGIN_INTERFACE_VERSION_5 = 5, + ETH_PLUGIN_INTERFACE_VERSION_LATEST = 6, +} eth_plugin_interface_version_t; + + +// Codes for the different requests Ethereum can send to the plugin +// The dispatch is handled by the SDK itself, the plugin code does not have to handle it +typedef enum eth_plugin_msg_e { + // Codes for actions the Ethereum app can ask the plugin to perform + ETH_PLUGIN_INIT_CONTRACT = 0x0101, + ETH_PLUGIN_PROVIDE_PARAMETER = 0x0102, + ETH_PLUGIN_FINALIZE = 0x0103, + ETH_PLUGIN_PROVIDE_INFO = 0x0104, + ETH_PLUGIN_QUERY_CONTRACT_ID = 0x0105, + ETH_PLUGIN_QUERY_CONTRACT_UI = 0x0106, + + // Special request: the Ethereum app is checking if we are installed on the device + ETH_PLUGIN_CHECK_PRESENCE = 0x01FF, +} eth_plugin_msg_t; + + +// Reply codes when responding to the Ethereum application +typedef enum eth_plugin_result_e { + // Unsuccessful return values + ETH_PLUGIN_RESULT_ERROR = 0x00, + ETH_PLUGIN_RESULT_UNAVAILABLE = 0x01, + ETH_PLUGIN_RESULT_UNSUCCESSFUL = 0x02, // Used for comparison + + // Successful return values + ETH_PLUGIN_RESULT_SUCCESSFUL = 0x03, // Used for comparison + ETH_PLUGIN_RESULT_OK = 0x04, + ETH_PLUGIN_RESULT_OK_ALIAS = 0x05, + ETH_PLUGIN_RESULT_FALLBACK = 0x06, +} eth_plugin_result_t; + + +// Format of UI the Ethereum application has to use for this plugin +typedef enum eth_ui_type_e { + // If uiType is UI_AMOUNT_ADDRESS, Ethereum will use the amount/address UI + // the amount and address provided by the plugin will be used + // If tokenLookup1 is set, the amount is provided for this token + ETH_UI_TYPE_AMOUNT_ADDRESS = 0x01, + + // If uiType is UI_TYPE_GENERIC, Ethereum will use the dedicated ETH plugin UI + // the ETH application provides tokens if requested then prompts for each UI field + // The first field is forced by the ETH app to be the name + version of the plugin handling the + // request. The last field is the fee amount + ETH_UI_TYPE_GENERIC = 0x02, +} eth_ui_type_t; + + +// Scratch objects and utilities available to the plugin READ-WRITE +typedef struct ethPluginSharedRW_s { + cx_sha3_t *sha3; +} ethPluginSharedRW_t; + + +// Transaction data available to the plugin READ-ONLY +typedef struct ethPluginSharedRO_s { + txContent_t *txContent; +} ethPluginSharedRO_t; + + +// Plugin-only memory allocated by the Ethereum application and used by the plugin. +#define PLUGIN_CONTEXT_SIZE (5 * INT256_LENGTH) +// It is recommended to cast the raw uin8_t array to a structure meaningfull for your plugin +// Helper to check that the actual plugin context structure is not bigger than the allocated memory +#define ASSERT_SIZEOF_PLUGIN_CONTEXT(s) \ + _Static_assert(sizeof(s) <= PLUGIN_CONTEXT_SIZE, "Plugin context structure is too big.") + + +/* + * HANDLERS AND PARAMETERS + * Parameters associated with the requests the Ethereum application can ask the plugin to perform + * The plugin SDK will automatically call the relevant handler for the received code, so the plugin + * has to define each of the handler functions declared below. + */ + + +// Init Contract + +typedef struct ethPluginInitContract_s { + eth_plugin_interface_version_t interfaceVersion; + eth_plugin_result_t result; + + // in + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; + size_t pluginContextLength; + const uint8_t *selector; // 4 bytes selector + size_t dataSize; + + char *alias; // 29 bytes alias if ETH_PLUGIN_RESULT_OK_ALIAS set + +} ethPluginInitContract_t; +// void handle_init_contract(ethPluginInitContract_t *parameters); + + +// Provide parameter + +typedef struct ethPluginProvideParameter_s { + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE + const uint8_t *parameter; // 32 bytes parameter + uint32_t parameterOffset; + + eth_plugin_result_t result; + +} ethPluginProvideParameter_t; +// void handle_provide_parameter(ethPluginProvideParameter_t *parameters); + + +// Finalize + +typedef struct ethPluginFinalize_s { + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE + + uint8_t *tokenLookup1; // set by the plugin if a token should be looked up + uint8_t *tokenLookup2; + + const uint8_t *amount; // set an uint256 pointer if uiType is UI_AMOUNT_ADDRESS + const uint8_t *address; // set to the destination address if uiType is UI_AMOUNT_ADDRESS. Set + // to the user's address if uiType is UI_TYPE_GENERIC + + eth_ui_type_t uiType; + uint8_t numScreens; // ignored if uiType is UI_AMOUNT_ADDRESS + eth_plugin_result_t result; + +} ethPluginFinalize_t; +// void handle_finalize(ethPluginFinalize_t *parameters); + + +// Provide token + +typedef struct ethPluginProvideInfo_s { + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE + + union extraInfo_t *item1; // set by the ETH application, to be saved by the plugin + union extraInfo_t *item2; + + uint8_t additionalScreens; // Used by the plugin if it needs to display additional screens + // based on the information received from the token definitions. + + eth_plugin_result_t result; + +} ethPluginProvideInfo_t; +// void handle_provide_token(ethPluginProvideInfo_t *parameters); + + +// Query Contract name and version + +// This is always called on the non aliased contract + +typedef struct ethQueryContractID_s { + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE + + char *name; + size_t nameLength; + char *version; + size_t versionLength; + + eth_plugin_result_t result; + +} ethQueryContractID_t; +// void handle_query_contract_id(ethQueryContractID_t *parameters); + + +// Query Contract UI + +typedef struct ethQueryContractUI_s { + ethPluginSharedRW_t *pluginSharedRW; + ethPluginSharedRO_t *pluginSharedRO; + union extraInfo_t *item1; + union extraInfo_t *item2; + char network_ticker[MAX_TICKER_LEN]; + uint8_t *pluginContext; // PLUGIN_CONTEXT_SIZE + uint8_t screenIndex; + + char *title; + size_t titleLength; + char *msg; + size_t msgLength; + + eth_plugin_result_t result; + +} ethQueryContractUI_t; +// void handle_query_contract_ui(ethQueryContractUI_t *parameters); + +// clang-format on diff --git a/src_common/network.h b/src_common/network.h deleted file mode 100644 index 8361bcb9a..000000000 --- a/src_common/network.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _NETWORK_H_ -#define _NETWORK_H_ - -#include -#include - -const char *get_network_name_from_chain_id(const uint64_t *chain_id); -const char *get_network_ticker_from_chain_id(const uint64_t *chain_id); - -bool chain_is_ethereum_compatible(const uint64_t *chain_id); - -#endif // _NETWORK_H_ diff --git a/src_common/plugin_utils.c b/src_common/plugin_utils.c new file mode 100644 index 000000000..5216fdb0b --- /dev/null +++ b/src_common/plugin_utils.c @@ -0,0 +1,42 @@ +#include + +#include "common_utils.h" +#include "plugin_utils.h" + +void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) { + uint8_t copy_size = MIN(dst_size, ADDRESS_LENGTH); + memmove(dst, parameter + PARAMETER_LENGTH - copy_size, copy_size); +} + +void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size) { + uint8_t copy_size = MIN(dst_size, PARAMETER_LENGTH); + memmove(dst, parameter, copy_size); +} + +bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value) { + if (allzeroes(parameter, PARAMETER_LENGTH - sizeof(uint16_t))) { + *value = U2BE(parameter, PARAMETER_LENGTH - sizeof(uint16_t)); + return true; + } + + return false; +} + +bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value) { + if (allzeroes(parameter, PARAMETER_LENGTH - sizeof(uint32_t))) { + *value = U4BE(parameter, PARAMETER_LENGTH - sizeof(uint32_t)); + return true; + } + + return false; +} + +bool find_selector(uint32_t selector, const uint32_t* array, size_t size, size_t* idx) { + for (size_t i = 0; i < size; ++i) { + if (selector == array[i]) { + if (idx != NULL) *idx = i; + return true; + } + } + return false; +} diff --git a/src_common/plugin_utils.h b/src_common/plugin_utils.h new file mode 100644 index 000000000..b37da7abc --- /dev/null +++ b/src_common/plugin_utils.h @@ -0,0 +1,37 @@ +/***************************************************************************** + * Ledger + * (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. + *****************************************************************************/ + +#pragma once + +#include +#include + +#include "eth_plugin_interface.h" + +#define SELECTOR_SIZE 4 +#define PARAMETER_LENGTH 32 + +void copy_address(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size); + +void copy_parameter(uint8_t* dst, const uint8_t* parameter, uint8_t dst_size); + +// Get the value from the beginning of the parameter (right to left) and check if the rest of it is +// zero +bool U2BE_from_parameter(const uint8_t* parameter, uint16_t* value); +bool U4BE_from_parameter(const uint8_t* parameter, uint32_t* value); + +bool find_selector(uint32_t selector, const uint32_t* array, size_t size, size_t* idx); diff --git a/src_common/starkDisplayUtils.c b/src_common/starkDisplayUtils.c deleted file mode 100644 index a59ae9927..000000000 --- a/src_common/starkDisplayUtils.c +++ /dev/null @@ -1,17 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" - -void stark_sign_display_master_account() { - snprintf(strings.tmp.tmp, - sizeof(strings.tmp.tmp), - "0x%.*H", - 32, - dataContext.starkContext.transferDestination); -} - -void stark_sign_display_condition_fact() { - snprintf(strings.tmp.tmp, sizeof(strings.tmp.tmp), "0x%.*H", 32, dataContext.starkContext.fact); -} - -#endif \ No newline at end of file diff --git a/src_common/starkDisplayUtils.h b/src_common/starkDisplayUtils.h deleted file mode 100644 index 48399b82d..000000000 --- a/src_common/starkDisplayUtils.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifdef HAVE_STARKWARE - -void stark_sign_display_master_account(); -void stark_sign_display_condition_fact(); - -#endif \ No newline at end of file diff --git a/src_common/tx_content.h b/src_common/tx_content.h new file mode 100644 index 000000000..ffb0afcf8 --- /dev/null +++ b/src_common/tx_content.h @@ -0,0 +1,43 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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 +#include + +#include "os.h" +#include "cx.h" +#include "common_utils.h" + +typedef struct txInt256_t { + uint8_t value[INT256_LENGTH]; + uint8_t length; +} txInt256_t; + +typedef struct txContent_t { + txInt256_t gasprice; // Used as MaxFeePerGas when dealing with EIP1559 transactions. + txInt256_t startgas; // Also known as `gasLimit`. + txInt256_t value; + txInt256_t nonce; + txInt256_t chainID; + uint8_t destination[ADDRESS_LENGTH]; + uint8_t destinationLength; + uint8_t v[8]; + uint8_t vLength; + bool dataPresent; +} txContent_t; diff --git a/src_features/getAppConfiguration/cmd_getAppConfiguration.c b/src_features/getAppConfiguration/cmd_getAppConfiguration.c index 39489b73c..c882b115b 100644 --- a/src_features/getAppConfiguration/cmd_getAppConfiguration.c +++ b/src_features/getAppConfiguration/cmd_getAppConfiguration.c @@ -13,13 +13,7 @@ void handleGetAppConfiguration(uint8_t p1, UNUSED(dataLength); UNUSED(flags); G_io_apdu_buffer[0] = (N_storage.dataAllowed ? APP_FLAG_DATA_ALLOWED : 0x00); -#ifndef HAVE_TOKENS_LIST G_io_apdu_buffer[0] |= APP_FLAG_EXTERNAL_TOKEN_NEEDED; -#endif -#ifdef HAVE_STARKWARE - G_io_apdu_buffer[0] |= APP_FLAG_STARKWARE; - G_io_apdu_buffer[0] |= APP_FLAG_STARKWARE_V2; -#endif G_io_apdu_buffer[1] = LEDGER_MAJOR_VERSION; G_io_apdu_buffer[2] = LEDGER_MINOR_VERSION; G_io_apdu_buffer[3] = LEDGER_PATCH_VERSION; diff --git a/src_features/getPublicKey/cmd_getPublicKey.c b/src_features/getPublicKey/cmd_getPublicKey.c index bc8bac6ce..c30addcb6 100644 --- a/src_features/getPublicKey/cmd_getPublicKey.c +++ b/src_features/getPublicKey/cmd_getPublicKey.c @@ -1,8 +1,7 @@ #include "shared_context.h" #include "apdu_constants.h" - +#include "common_utils.h" #include "feature_getPublicKey.h" -#include "ethUtils.h" #include "common_ui.h" #include "os_io_seproxyhal.h" @@ -21,16 +20,18 @@ void handleGetPublicKey(uint8_t p1, } if ((p1 != P1_CONFIRM) && (p1 != P1_NON_CONFIRM)) { - THROW(0x6B00); + PRINTF("Error: Unexpected P1 (%u)!\n", p1); + THROW(APDU_RESPONSE_INVALID_P1_P2); } if ((p2 != P2_CHAINCODE) && (p2 != P2_NO_CHAINCODE)) { - THROW(0x6B00); + PRINTF("Error: Unexpected P2 (%u)!\n", p2); + THROW(APDU_RESPONSE_INVALID_P1_P2); } dataBuffer = parseBip32(dataBuffer, &dataLength, &bip32); if (dataBuffer == NULL) { - THROW(0x6a80); + THROW(APDU_RESPONSE_INVALID_DATA); } tmpCtx.publicKeyContext.getChaincode = (p2 == P2_CHAINCODE); @@ -47,16 +48,32 @@ void handleGetPublicKey(uint8_t p1, explicit_bzero(&privateKey, sizeof(privateKey)); explicit_bzero(privateKeyData, sizeof(privateKeyData)); io_seproxyhal_io_heartbeat(); - getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey, - tmpCtx.publicKeyContext.address, - &global_sha3, - chainConfig->chainId); + if (!getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey, + tmpCtx.publicKeyContext.address, + &global_sha3, + chainConfig->chainId)) { + THROW(CX_INVALID_PARAMETER); + } + + uint64_t chain_id = chainConfig->chainId; + if (dataLength >= sizeof(chain_id)) { + chain_id = u64_from_BE(dataBuffer, sizeof(chain_id)); + dataLength -= sizeof(chain_id); + dataBuffer += sizeof(chain_id); + } + + (void) dataBuffer; // to prevent dead increment warning + if (dataLength > 0) { + PRINTF("Error: Leftover unwanted data (%u bytes long)!\n", dataLength); + THROW(APDU_RESPONSE_INVALID_DATA); + } + #ifndef NO_CONSENT if (p1 == P1_NON_CONFIRM) #endif // NO_CONSENT { *tx = set_result_get_publicKey(); - THROW(0x9000); + THROW(APDU_RESPONSE_OK); } #ifndef NO_CONSENT else { @@ -65,7 +82,8 @@ void handleGetPublicKey(uint8_t p1, "0x%.*s", 40, tmpCtx.publicKeyContext.address); - ui_display_public_key(); + // don't unnecessarily pass the current app's chain ID + ui_display_public_key(chainConfig->chainId == chain_id ? NULL : &chain_id); *flags |= IO_ASYNCH_REPLY; } diff --git a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c index 5cb95527c..c1f036947 100644 --- a/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c +++ b/src_features/performPrivacyOperation/cmd_performPrivacyOperation.c @@ -1,6 +1,5 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "ethUtils.h" #include "feature_performPrivacyOperation.h" #include "common_ui.h" @@ -62,10 +61,12 @@ void handlePerformPrivacyOperation(uint8_t p1, (tmpCtx.publicKeyContext.getChaincode ? tmpCtx.publicKeyContext.chainCode : NULL)); cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey); cx_ecfp_generate_pair(CX_CURVE_256K1, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1); - getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey, - tmpCtx.publicKeyContext.address, - &global_sha3, - chainConfig->chainId); + if (!getEthAddressStringFromKey(&tmpCtx.publicKeyContext.publicKey, + tmpCtx.publicKeyContext.address, + &global_sha3, + chainConfig->chainId)) { + THROW(CX_INVALID_PARAMETER); + } if (p2 == P2_PUBLIC_ENCRYPTION_KEY) { decodeScalar(privateKeyData, privateKeyDataSwapped); cx_ecfp_init_private_key(CX_CURVE_Curve25519, privateKeyDataSwapped, 32, &privateKey); diff --git a/src_features/provideDomainName/cmd_provide_domain_name.c b/src_features/provideDomainName/cmd_provide_domain_name.c index e1d14a49c..3ec5b39d4 100644 --- a/src_features/provideDomainName/cmd_provide_domain_name.c +++ b/src_features/provideDomainName/cmd_provide_domain_name.c @@ -4,29 +4,14 @@ #include #include #include -#include "utils.h" // ARRAY_SIZE +#include "common_utils.h" // ARRAY_SIZE #include "apdu_constants.h" #include "domain_name.h" #include "challenge.h" #include "mem.h" #include "hash_bytes.h" #include "network.h" - -static const uint8_t DOMAIN_NAME_PUB_KEY[] = { -#ifdef HAVE_DOMAIN_NAME_TEST_KEY - 0x04, 0xb9, 0x1f, 0xbe, 0xc1, 0x73, 0xe3, 0xba, 0x4a, 0x71, 0x4e, 0x01, 0x4e, 0xbc, - 0x82, 0x7b, 0x6f, 0x89, 0x9a, 0x9f, 0xa7, 0xf4, 0xac, 0x76, 0x9c, 0xde, 0x28, 0x43, - 0x17, 0xa0, 0x0f, 0x4f, 0x65, 0x0f, 0x09, 0xf0, 0x9a, 0xa4, 0xff, 0x5a, 0x31, 0x76, - 0x02, 0x55, 0xfe, 0x5d, 0xfc, 0x81, 0x13, 0x29, 0xb3, 0xb5, 0x0b, 0xe9, 0x91, 0x94, - 0xfc, 0xa1, 0x16, 0x19, 0xe6, 0x5f, 0x2e, 0xdf, 0xea -#else - 0x04, 0x6a, 0x94, 0xe7, 0xa4, 0x2c, 0xd0, 0xc3, 0x3f, 0xdf, 0x44, 0x0c, 0x8e, 0x2a, - 0xb2, 0x54, 0x2c, 0xef, 0xbe, 0x5d, 0xb7, 0xaa, 0x0b, 0x93, 0xa9, 0xfc, 0x81, 0x4b, - 0x9a, 0xcf, 0xa7, 0x5e, 0xb4, 0xe5, 0x3d, 0x6f, 0x00, 0x25, 0x94, 0xbd, 0xb6, 0x05, - 0xd9, 0xb5, 0xbd, 0xa9, 0xfa, 0x4b, 0x4b, 0xf3, 0xa5, 0x49, 0x6f, 0xd3, 0x16, 0x4b, - 0xae, 0xf5, 0xaf, 0xcf, 0x90, 0xe8, 0x40, 0x88, 0x71 -#endif -}; +#include "public_keys.h" #define P1_FIRST_CHUNK 0x01 #define P1_FOLLOWING_CHUNK 0x00 @@ -205,10 +190,13 @@ static bool handle_challenge(const s_tlv_data *data, s_domain_name_info *domain_name_info, s_sig_ctx *sig_ctx) { uint32_t value; - (void) domain_name_info; (void) sig_ctx; - return get_uint_from_data(data, &value) && (value == get_challenge()); + + if (!get_uint_from_data(data, &value)) { + return false; + } + return (value == get_challenge()); } /** @@ -223,8 +211,8 @@ static bool handle_sign_key_id(const s_tlv_data *data, s_domain_name_info *domain_name_info, s_sig_ctx *sig_ctx) { uint32_t value; - (void) domain_name_info; + if (!get_uint_from_data(data, &value) || (value > UINT8_MAX)) { return false; } @@ -247,7 +235,10 @@ static bool handle_sign_algo(const s_tlv_data *data, (void) domain_name_info; (void) sig_ctx; - return get_uint_from_data(data, &value) && (value == ALGO_SECP256K1); + if (!get_uint_from_data(data, &value)) { + return false; + } + return (value == ALGO_SECP256K1); } /** @@ -338,7 +329,10 @@ static bool handle_coin_type(const s_tlv_data *data, (void) domain_name_info; (void) sig_ctx; - return get_uint_from_data(data, &value) && (value == SLIP_44_ETHEREUM); + if (!get_uint_from_data(data, &value)) { + return false; + } + return (value == SLIP_44_ETHEREUM); } /** diff --git a/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c b/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c index 496c54ada..00665ad7c 100644 --- a/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c +++ b/src_features/provideErc20TokenInformation/cmd_provideTokenInfo.c @@ -1,8 +1,10 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "tokens.h" +#include "public_keys.h" #include "common_ui.h" #include "os_io_seproxyhal.h" +#include "extra_tokens.h" +#include "network.h" #ifdef HAVE_CONTRACT_NAME_IN_DESCRIPTOR @@ -111,7 +113,7 @@ void handleProvideErc20TokenInformation(uint8_t p1, UNUSED(tx); uint32_t offset = 0; uint8_t tickerLength; - uint32_t chainId; + uint64_t chain_id; uint8_t hash[INT256_LENGTH]; cx_ecfp_public_key_t tokenKey; @@ -127,7 +129,7 @@ void handleProvideErc20TokenInformation(uint8_t p1, } tickerLength = workBuffer[offset++]; dataLength--; - if ((tickerLength + 1) >= sizeof(token->ticker)) { + if ((tickerLength + 1) > sizeof(token->ticker)) { THROW(0x6A80); } if (dataLength < tickerLength + 20 + 4 + 4) { @@ -141,12 +143,13 @@ void handleProvideErc20TokenInformation(uint8_t p1, memmove(token->address, workBuffer + offset, 20); offset += 20; dataLength -= 20; + // TODO: Handle 64-bit long chain IDs token->decimals = U4BE(workBuffer, offset); offset += 4; dataLength -= 4; - chainId = U4BE(workBuffer, offset); - if ((chainConfig->chainId != ETHEREUM_MAINNET_CHAINID) && (chainConfig->chainId != chainId)) { - PRINTF("ChainId token mismatch: %d vs %d\n", chainConfig->chainId, chainId); + chain_id = U4BE(workBuffer, offset); + if (!app_compatible_with_chain_id(&chain_id)) { + UNSUPPORTED_CHAIN_ID_MSG(chain_id); THROW(0x6A80); } offset += 4; diff --git a/src_features/provideNFTInformation/cmd_provideNFTInfo.c b/src_features/provideNFTInformation/cmd_provideNFTInfo.c index 303009540..e59c77b6f 100644 --- a/src_features/provideNFTInformation/cmd_provideNFTInfo.c +++ b/src_features/provideNFTInformation/cmd_provideNFTInfo.c @@ -2,10 +2,12 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "tokens.h" -#include "utils.h" +#include "asset_info.h" +#include "common_utils.h" #include "common_ui.h" #include "os_io_seproxyhal.h" +#include "network.h" +#include "public_keys.h" #define TYPE_SIZE 1 #define VERSION_SIZE 1 @@ -19,8 +21,8 @@ #define MIN_DER_SIG_SIZE 67 #define MAX_DER_SIG_SIZE 72 -#define TEST_NFT_METADATA_KEY 0 -#define PROD_NFT_METADATA_KEY 1 +#define STAGING_NFT_METADATA_KEY 0 +#define PROD_NFT_METADATA_KEY 1 #define ALGORITHM_ID_1 1 @@ -28,22 +30,6 @@ #define VERSION_1 1 -static const uint8_t LEDGER_NFT_METADATA_PUBLIC_KEY[] = { -#ifdef HAVE_NFT_TESTING_KEY - 0x04, 0xf5, 0x70, 0x0c, 0xa1, 0xe8, 0x74, 0x24, 0xc7, 0xc7, 0xd1, 0x19, 0xe7, 0xe3, - 0xc1, 0x89, 0xb1, 0x62, 0x50, 0x94, 0xdb, 0x6e, 0xa0, 0x40, 0x87, 0xc8, 0x30, 0x00, - 0x7d, 0x0b, 0x46, 0x9a, 0x53, 0x11, 0xee, 0x6a, 0x1a, 0xcd, 0x1d, 0xa5, 0xaa, 0xb0, - 0xf5, 0xc6, 0xdf, 0x13, 0x15, 0x8d, 0x28, 0xcc, 0x12, 0xd1, 0xdd, 0xa6, 0xec, 0xe9, - 0x46, 0xb8, 0x9d, 0x5c, 0x05, 0x49, 0x92, 0x59, 0xc4 -#else - 0x04, 0x98, 0x8d, 0xa6, 0xb2, 0x46, 0xf2, 0x8e, 0x77, 0xc1, 0xba, 0xb6, 0x75, 0xcb, - 0x2a, 0x27, 0x44, 0xf7, 0xf5, 0xce, 0xc5, 0x6a, 0xe6, 0xe0, 0x32, 0x23, 0x33, 0x7b, - 0x57, 0x94, 0xcd, 0x6a, 0xe0, 0x7d, 0x48, 0xb3, 0x0d, 0xb9, 0xcc, 0xb4, 0x0f, 0x5a, - 0x02, 0xa1, 0x1a, 0x3a, 0xb9, 0x9d, 0x5f, 0x59, 0x5a, 0x3d, 0x50, 0xa0, 0xe1, 0x30, - 0x23, 0xfd, 0x0d, 0x95, 0x87, 0x92, 0xd7, 0x97, 0x01 -#endif -}; - typedef bool verificationAlgo(const cx_ecfp_public_key_t *, int, cx_md_t, @@ -140,13 +126,13 @@ void handleProvideNFTInformation(uint8_t p1, PRINTF("Address: %.*H\n", ADDRESS_LENGTH, workBuffer + offset); offset += ADDRESS_LENGTH; - uint64_t chainId = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE); + uint64_t chain_id = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE); // this prints raw data, so to have a more meaningful print, display // the buffer before the endianness swap - PRINTF("ChainID: %.*H\n", sizeof(chainId), (workBuffer + offset)); - if ((chainConfig->chainId != 0) && (chainConfig->chainId != chainId)) { - PRINTF("Chain ID token mismatch\n"); - THROW(0x6A80); + PRINTF("ChainID: %.*H\n", sizeof(chain_id), (workBuffer + offset)); + if (!app_compatible_with_chain_id(&chain_id)) { + UNSUPPORTED_CHAIN_ID_MSG(chain_id); + THROW(APDU_RESPONSE_INVALID_DATA); } offset += CHAIN_ID_SIZE; @@ -156,8 +142,8 @@ void handleProvideNFTInformation(uint8_t p1, PRINTF("KeyID: %d\n", keyId); switch (keyId) { -#ifdef HAVE_NFT_TESTING_KEY - case TEST_NFT_METADATA_KEY: +#ifdef HAVE_NFT_STAGING_KEY + case STAGING_NFT_METADATA_KEY: #endif case PROD_NFT_METADATA_KEY: rawKey = (uint8_t *) LEDGER_NFT_METADATA_PUBLIC_KEY; diff --git a/src_features/setExternalPlugin/cmd_setExternalPlugin.c b/src_features/setExternalPlugin/cmd_setExternalPlugin.c index 4a9435600..13d1faf00 100644 --- a/src_features/setExternalPlugin/cmd_setExternalPlugin.c +++ b/src_features/setExternalPlugin/cmd_setExternalPlugin.c @@ -1,8 +1,9 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "tokens.h" +#include "public_keys.h" #include "eth_plugin_interface.h" #include "eth_plugin_internal.h" +#include "plugin_utils.h" #include "common_ui.h" #include "os_io_seproxyhal.h" @@ -48,7 +49,9 @@ void handleSetExternalPlugin(uint8_t p1, workBuffer + payload_size, dataLength - payload_size)) { #ifndef HAVE_BYPASS_SIGNATURES - PRINTF("Invalid plugin signature %.*H\n", payload_size, workBuffer); + PRINTF("Invalid plugin signature %.*H\n", + dataLength - payload_size, + workBuffer + payload_size); THROW(0x6A80); #endif } diff --git a/src_features/setPlugin/cmd_setPlugin.c b/src_features/setPlugin/cmd_setPlugin.c index 8cdb8066d..d4eb522c4 100644 --- a/src_features/setPlugin/cmd_setPlugin.c +++ b/src_features/setPlugin/cmd_setPlugin.c @@ -1,11 +1,14 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "tokens.h" +#include "asset_info.h" #include "eth_plugin_interface.h" #include "eth_plugin_internal.h" -#include "utils.h" +#include "plugin_utils.h" +#include "common_utils.h" #include "common_ui.h" #include "os_io_seproxyhal.h" +#include "network.h" +#include "public_keys.h" // Supported internal plugins #define ERC721_STR "ERC721" @@ -44,23 +47,6 @@ typedef enum AlgorithmID { ECC_SECG_P256K1__ECDSA_SHA_256 = 0x01, } AlgorithmID; -// Only used for signing NFT plugins (ERC721 and ERC1155) -static const uint8_t LEDGER_NFT_SELECTOR_PUBLIC_KEY[] = { -#ifdef HAVE_NFT_TESTING_KEY - 0x04, 0xf5, 0x70, 0x0c, 0xa1, 0xe8, 0x74, 0x24, 0xc7, 0xc7, 0xd1, 0x19, 0xe7, 0xe3, - 0xc1, 0x89, 0xb1, 0x62, 0x50, 0x94, 0xdb, 0x6e, 0xa0, 0x40, 0x87, 0xc8, 0x30, 0x00, - 0x7d, 0x0b, 0x46, 0x9a, 0x53, 0x11, 0xee, 0x6a, 0x1a, 0xcd, 0x1d, 0xa5, 0xaa, 0xb0, - 0xf5, 0xc6, 0xdf, 0x13, 0x15, 0x8d, 0x28, 0xcc, 0x12, 0xd1, 0xdd, 0xa6, 0xec, 0xe9, - 0x46, 0xb8, 0x9d, 0x5c, 0x05, 0x49, 0x92, 0x59, 0xc4 -#else - 0x04, 0xd8, 0x62, 0x6e, 0x01, 0x9e, 0x55, 0x3e, 0x19, 0x69, 0x56, 0xf1, 0x17, 0x4d, - 0xcd, 0xb8, 0x9a, 0x1c, 0xda, 0xc4, 0x93, 0x90, 0x08, 0xbc, 0x79, 0x77, 0x33, 0x6d, - 0x78, 0x24, 0xee, 0xe3, 0xa2, 0x62, 0x24, 0x1a, 0x62, 0x73, 0x52, 0x3b, 0x09, 0xb8, - 0xd0, 0xce, 0x0d, 0x39, 0xe8, 0x60, 0xc9, 0x4d, 0x02, 0x53, 0x58, 0xdb, 0xdc, 0x25, - 0x92, 0xc7, 0xc6, 0x48, 0x0d, 0x39, 0xce, 0xbb, 0xa3 -#endif -}; - // Verification function used to verify the signature typedef bool verificationAlgo(const cx_ecfp_public_key_t *, int, @@ -169,13 +155,13 @@ void handleSetPlugin(uint8_t p1, PRINTF("Selector: %.*H\n", SELECTOR_SIZE, tokenContext->methodSelector); offset += SELECTOR_SIZE; - uint64_t chainId = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE); + uint64_t chain_id = u64_from_BE(workBuffer + offset, CHAIN_ID_SIZE); // this prints raw data, so to have a more meaningful print, display // the buffer before the endianness swap - PRINTF("ChainID: %.*H\n", sizeof(chainId), (workBuffer + offset)); - if ((chainConfig->chainId != 0) && (chainConfig->chainId != chainId)) { - PRINTF("Chain ID token mismatch\n"); - THROW(0x6A80); + PRINTF("ChainID: %.*H\n", sizeof(chain_id), (workBuffer + offset)); + if (!app_compatible_with_chain_id(&chain_id)) { + UNSUPPORTED_CHAIN_ID_MSG(chain_id); + THROW(APDU_RESPONSE_INVALID_DATA); } offset += CHAIN_ID_SIZE; @@ -185,7 +171,7 @@ void handleSetPlugin(uint8_t p1, PRINTF("KeyID: %d\n", keyId); switch (keyId) { -#ifdef HAVE_NFT_TESTING_KEY +#ifdef HAVE_NFT_STAGING_KEY case TEST_PLUGIN_KEY: #endif case PROD_PLUGIN_KEY: diff --git a/src_features/signMessageEIP712/commands_712.c b/src_features/signMessageEIP712/commands_712.c index a1cc45f9a..8a21dc365 100644 --- a/src_features/signMessageEIP712/commands_712.c +++ b/src_features/signMessageEIP712/commands_712.c @@ -13,7 +13,6 @@ #include "schema_hash.h" #include "filtering.h" #include "common_712.h" -#include "ethUtils.h" // allzeroes #include "common_ui.h" // ui_idle /** diff --git a/src_features/signMessageEIP712/field_hash.c b/src_features/signMessageEIP712/field_hash.c index cc57dae1c..af89be879 100644 --- a/src_features/signMessageEIP712/field_hash.c +++ b/src_features/signMessageEIP712/field_hash.c @@ -8,9 +8,8 @@ #include "mem_utils.h" #include "shared_context.h" #include "ui_logic.h" -#include "ethUtils.h" // KECCAK256_HASH_BYTESIZE #include "context_712.h" // contract_addr -#include "utils.h" // u64_from_BE +#include "common_utils.h" // u64_from_BE #include "apdu_constants.h" // APDU response codes #include "typed_data.h" #include "commands_712.h" diff --git a/src_features/signMessageEIP712/filtering.c b/src_features/signMessageEIP712/filtering.c index 1ba40dccc..ff45a6eb9 100644 --- a/src_features/signMessageEIP712/filtering.c +++ b/src_features/signMessageEIP712/filtering.c @@ -4,6 +4,7 @@ #include "hash_bytes.h" #include "ethUstream.h" // INT256_LENGTH #include "apdu_constants.h" // APDU return codes +#include "public_keys.h" #include "context_712.h" #include "commands_712.h" #include "typed_data.h" diff --git a/src_features/signMessageEIP712/path.c b/src_features/signMessageEIP712/path.c index 621d11dc5..3c823c9ce 100644 --- a/src_features/signMessageEIP712/path.c +++ b/src_features/signMessageEIP712/path.c @@ -8,7 +8,6 @@ #include "commands_712.h" #include "type_hash.h" #include "shared_context.h" -#include "ethUtils.h" #include "mem_utils.h" #include "ui_logic.h" #include "apdu_constants.h" // APDU response codes diff --git a/src_features/signMessageEIP712/sol_typenames.c b/src_features/signMessageEIP712/sol_typenames.c index bf78f2639..6163e7fa9 100644 --- a/src_features/signMessageEIP712/sol_typenames.c +++ b/src_features/signMessageEIP712/sol_typenames.c @@ -7,7 +7,7 @@ #include "os_pic.h" #include "apdu_constants.h" // APDU response codes #include "typed_data.h" -#include "utils.h" // ARRAY_SIZE +#include "common_utils.h" // ARRAY_SIZE // Bit indicating they are more types associated to this typename #define TYPENAME_MORE_TYPE (1 << 7) diff --git a/src_features/signMessageEIP712/type_hash.c b/src_features/signMessageEIP712/type_hash.c index 1e8da4b24..7b9515f86 100644 --- a/src_features/signMessageEIP712/type_hash.c +++ b/src_features/signMessageEIP712/type_hash.c @@ -7,7 +7,6 @@ #include "mem_utils.h" #include "type_hash.h" #include "shared_context.h" -#include "ethUtils.h" // KECCAK256_HASH_BYTESIZE #include "format_hash_field_type.h" #include "hash_bytes.h" #include "apdu_constants.h" // APDU response codes diff --git a/src_features/signMessageEIP712/ui_logic.c b/src_features/signMessageEIP712/ui_logic.c index e6f7b6a64..5a169e9bc 100644 --- a/src_features/signMessageEIP712/ui_logic.c +++ b/src_features/signMessageEIP712/ui_logic.c @@ -7,8 +7,7 @@ #include "mem_utils.h" #include "os_io.h" #include "shared_context.h" -#include "ethUtils.h" // getEthDisplayableAddress -#include "utils.h" // uint256_to_decimal +#include "common_utils.h" // uint256_to_decimal #include "common_712.h" #include "context_712.h" // eip712_context_deinit #include "uint256.h" // tostring256 && tostring256_signed @@ -17,6 +16,7 @@ #include "typed_data.h" #include "commands_712.h" #include "common_ui.h" +#include "domain_name.h" static t_ui_context *ui_ctx = NULL; @@ -185,6 +185,46 @@ static void ui_712_format_str(const uint8_t *const data, uint8_t length) { } } +/** + * Find a substitute token ticker for a given address + * + * @param[in] addr the given address + * @return the ticker name if found, \ref NULL otherwise + */ +static const char *get_address_token_ticker(const uint8_t *addr) { + tokenDefinition_t *token; + + // Loop over the received token informations + for (uint8_t token_idx = 0; token_idx < MAX_ITEMS; ++token_idx) { + if (tmpCtx.transactionContext.tokenSet[token_idx] == 1) { + token = &tmpCtx.transactionContext.extraInfo[token_idx].token; + if (memcmp(token->address, addr, ADDRESS_LENGTH) == 0) { + return token->ticker; + } + } + } + return NULL; +} + +/** + * Find a substitute (token ticker or domain name) for a given address + * + * @param[in] addr the given address + * @return the substitute if found, \ref NULL otherwise + */ +static const char *get_address_substitute(const uint8_t *addr) { + const char *str = NULL; + + str = get_address_token_ticker(addr); + if (str == NULL) { + if (has_domain_name(&eip712_context->chain_id, addr)) { + // No handling of the verbose domains setting + str = g_domain_name; + } + } + return str; +} + /** * Format a given data as a string representation of an address * @@ -197,12 +237,21 @@ static bool ui_712_format_addr(const uint8_t *const data, uint8_t length) { apdu_response_code = APDU_RESPONSE_INVALID_DATA; return false; } + if (ui_712_field_shown()) { - getEthDisplayableAddress((uint8_t *) data, - strings.tmp.tmp, - sizeof(strings.tmp.tmp), - &global_sha3, - chainConfig->chainId); + const char *sub; + + if (!N_storage.verbose_eip712 && ((sub = get_address_substitute(data)) != NULL)) { + ui_712_set_value(sub, strlen(sub)); + } else { + if (!getEthDisplayableAddress((uint8_t *) data, + strings.tmp.tmp, + sizeof(strings.tmp.tmp), + &global_sha3, + chainConfig->chainId)) { + THROW(APDU_RESPONSE_ERROR_NO_INFO); + } + } } return true; } diff --git a/src_features/signMessageEIP712_v0/cmd_signMessage712.c b/src_features/signMessageEIP712_v0/cmd_signMessage712.c index deaab84f5..058495e76 100644 --- a/src_features/signMessageEIP712_v0/cmd_signMessage712.c +++ b/src_features/signMessageEIP712_v0/cmd_signMessage712.c @@ -1,9 +1,8 @@ #include "shared_context.h" #include "apdu_constants.h" -#include "utils.h" +#include "common_utils.h" #include "common_ui.h" #include "common_712.h" -#include "ethUtils.h" void handleSignEIP712Message_v0(uint8_t p1, uint8_t p2, diff --git a/src_features/signTx/cmd_signTx.c b/src_features/signTx/cmd_signTx.c index d42631b7c..0eb1d1c43 100644 --- a/src_features/signTx/cmd_signTx.c +++ b/src_features/signTx/cmd_signTx.c @@ -72,7 +72,7 @@ void handleSign(uint8_t p1, txResult = processTx(&txContext, workBuffer, dataLength, - (chainConfig->kind == CHAIN_KIND_WANCHAIN ? TX_FLAG_TYPE : 0)); + (chainConfig->chainId == 888 ? TX_FLAG_TYPE : 0)); // Wanchain exception switch (txResult) { case USTREAM_SUSPENDED: break; diff --git a/src_features/signTx/logic_signTx.c b/src_features/signTx/logic_signTx.c index a107439f5..bdacd7684 100644 --- a/src_features/signTx/logic_signTx.c +++ b/src_features/signTx/logic_signTx.c @@ -1,15 +1,13 @@ +#include #include "shared_context.h" -#include "utils.h" +#include "common_utils.h" #include "feature_signTx.h" -#ifdef HAVE_STARKWARE -#include "stark_utils.h" -#endif +#include "uint256.h" #include "eth_plugin_handler.h" #include "network.h" -#include "ethUtils.h" #include "common_ui.h" #include "ui_callbacks.h" -#include +#include "apdu_constants.h" #define ERR_SILENT_MODE_CHECK_FAILED 0x6001 @@ -189,7 +187,9 @@ static void address_to_string(uint8_t *in, cx_sha3_t *sha3, uint64_t chainId) { if (in_len != 0) { - getEthDisplayableAddress(in, out, out_len, sha3, chainId); + if (!getEthDisplayableAddress(in, out, out_len, sha3, chainId)) { + THROW(APDU_RESPONSE_ERROR_NO_INFO); + } } else { strlcpy(out, "Contract", out_len); } @@ -197,7 +197,7 @@ static void address_to_string(uint8_t *in, static void raw_fee_to_string(uint256_t *rawFee, char *displayBuffer, uint32_t displayBufferSize) { uint64_t chain_id = get_tx_chain_id(); - const char *feeTicker = get_displayable_ticker(&chain_id); + const char *feeTicker = get_displayable_ticker(&chain_id, chainConfig); uint8_t tickerOffset = 0; uint32_t i; @@ -266,9 +266,12 @@ static void nonce_to_string(const txInt256_t *nonce, char *out, size_t out_size) static void get_network_as_string(char *out, size_t out_size) { uint64_t chain_id = get_tx_chain_id(); const char *name = get_network_name_from_chain_id(&chain_id); + if (name == NULL) { // No network name found so simply copy the chain ID as the network name. - u64_to_string(chain_id, out, out_size); + if (!u64_to_string(chain_id, out, out_size)) { + THROW(0x6502); + } } else { // Network name found, simply copy it. strlcpy(out, name, out_size); @@ -293,7 +296,9 @@ static void get_public_key(uint8_t *out, uint8_t outLength) { cx_ecfp_generate_pair(CX_CURVE_256K1, &publicKey, &privateKey, 1); explicit_bzero(&privateKey, sizeof(privateKey)); explicit_bzero(privateKeyData, sizeof(privateKeyData)); - getEthAddressFromKey(&publicKey, out, &global_sha3); + if (!getEthAddressFromKey(&publicKey, out, &global_sha3)) { + THROW(CX_INVALID_PARAMETER); + } } /* Local implmentation of strncasecmp, workaround of the segfaulting base implem @@ -311,13 +316,12 @@ static int strcasecmp_workaround(const char *str1, const char *str2) { return 0; } -void finalizeParsing(bool direct) { +__attribute__((noinline)) static bool finalize_parsing_helper(bool direct, bool *use_standard_UI) { char displayBuffer[50]; uint8_t decimals = WEI_TO_ETHER; uint64_t chain_id = get_tx_chain_id(); - const char *ticker = get_displayable_ticker(&chain_id); + const char *ticker = get_displayable_ticker(&chain_id, chainConfig); ethPluginFinalize_t pluginFinalize; - bool use_standard_UI = true; // Verify the chain if (chainConfig->chainId != ETHEREUM_MAINNET_CHAINID) { @@ -328,7 +332,7 @@ void finalizeParsing(bool direct) { reset_app_context(); reportFinalizeError(direct); if (!direct) { - return; + return false; } } } @@ -352,7 +356,7 @@ void finalizeParsing(bool direct) { PRINTF("Plugin finalize call failed\n"); reportFinalizeError(direct); if (!direct) { - return; + return false; } } // Lookup tokens if requested @@ -378,7 +382,7 @@ void finalizeParsing(bool direct) { PRINTF("Plugin provide token call failed\n"); reportFinalizeError(direct); if (!direct) { - return; + return false; } } pluginFinalize.result = pluginProvideInfo.result; @@ -388,7 +392,7 @@ void finalizeParsing(bool direct) { switch (pluginFinalize.uiType) { case ETH_UI_TYPE_GENERIC: // Use the dedicated ETH plugin UI - use_standard_UI = false; + *use_standard_UI = false; tmpContent.txContent.dataPresent = false; // Add the number of screens + the number of additional screens to get the total // number of screens needed. @@ -397,13 +401,13 @@ void finalizeParsing(bool direct) { break; case ETH_UI_TYPE_AMOUNT_ADDRESS: // Use the standard ETH UI as this plugin uses the amount/address UI - use_standard_UI = true; + *use_standard_UI = true; tmpContent.txContent.dataPresent = false; if ((pluginFinalize.amount == NULL) || (pluginFinalize.address == NULL)) { PRINTF("Incorrect amount/address set by plugin\n"); reportFinalizeError(direct); if (!direct) { - return; + return false; } } memmove(tmpContent.txContent.value.value, pluginFinalize.amount, 32); @@ -419,14 +423,23 @@ void finalizeParsing(bool direct) { PRINTF("ui type %d not supported\n", pluginFinalize.uiType); reportFinalizeError(direct); if (!direct) { - return; + return false; } } } } + if (G_called_from_swap) { + if (G_swap_response_ready) { + // Unreachable given current return to exchange mechanism. Safeguard against regression + PRINTF("FATAL: safety against double sign triggered\n"); + os_sched_exit(-1); + } + G_swap_response_ready = true; + } + // User has just validated a swap but ETH received apdus about a non standard plugin / contract - if (G_called_from_swap && !use_standard_UI) { + if (G_called_from_swap && !*use_standard_UI) { PRINTF("ERR_SILENT_MODE_CHECK_FAILED, G_called_from_swap\n"); THROW(ERR_SILENT_MODE_CHECK_FAILED); } @@ -435,12 +448,12 @@ void finalizeParsing(bool direct) { reportFinalizeError(direct); ui_warning_contract_data(); if (!direct) { - return; + return false; } } // Prepare destination address and amount to display - if (use_standard_UI) { + if (*use_standard_UI) { // Format the address in a temporary buffer, if in swap case compare it with validated // address, else commit it address_to_string(tmpContent.txContent.destination, @@ -462,16 +475,22 @@ void finalizeParsing(bool direct) { // Format the amount in a temporary buffer, if in swap case compare it with validated // amount, else commit it - amountToString(tmpContent.txContent.value.value, - tmpContent.txContent.value.length, - decimals, - ticker, - displayBuffer, - sizeof(displayBuffer)); + if (!amountToString(tmpContent.txContent.value.value, + tmpContent.txContent.value.length, + decimals, + ticker, + displayBuffer, + sizeof(displayBuffer))) { + PRINTF("OVERFLOW, amount to string failed\n"); + THROW(EXCEPTION_OVERFLOW); + } + if (G_called_from_swap) { // Ensure the values are the same that the ones that have been previously validated if (strcmp(strings.common.fullAmount, displayBuffer) != 0) { PRINTF("ERR_SILENT_MODE_CHECK_FAILED, amount check failed\n"); + PRINTF("Expected %s\n", strings.common.fullAmount); + PRINTF("Received %s\n", displayBuffer); THROW(ERR_SILENT_MODE_CHECK_FAILED); } } else { @@ -490,6 +509,8 @@ void finalizeParsing(bool direct) { // Ensure the values are the same that the ones that have been previously validated if (strcmp(strings.common.maxFee, displayBuffer) != 0) { PRINTF("ERR_SILENT_MODE_CHECK_FAILED, fees check failed\n"); + PRINTF("Expected %s\n", strings.common.maxFee); + PRINTF("Received %s\n", displayBuffer); THROW(ERR_SILENT_MODE_CHECK_FAILED); } } else { @@ -504,14 +525,21 @@ void finalizeParsing(bool direct) { sizeof(strings.common.nonce)); PRINTF("Nonce: %s\n", strings.common.nonce); - // Prepare chainID field + // Prepare network field get_network_as_string(strings.common.network_name, sizeof(strings.common.network_name)); PRINTF("Network: %s\n", strings.common.network_name); + return true; +} +void finalizeParsing(bool direct) { + bool use_standard_UI = true; bool no_consent_check; - // If called from swap, the user as already validated a standard transaction - // We have already checked the fields of this transaction above + if (!finalize_parsing_helper(direct, &use_standard_UI)) { + return; + } + // If called from swap, the user has already validated a standard transaction + // And we have already checked the fields of this transaction above no_consent_check = G_called_from_swap && use_standard_UI; #ifdef NO_CONSENT diff --git a/src_features/signTx/ui_common_signTx.c b/src_features/signTx/ui_common_signTx.c index e57bb2125..96eee2fe2 100644 --- a/src_features/signTx/ui_common_signTx.c +++ b/src_features/signTx/ui_common_signTx.c @@ -1,34 +1,26 @@ +#include "lib_standard_app/crypto_helpers.h" #include "os_io_seproxyhal.h" #include "shared_context.h" -#include "utils.h" +#include "common_utils.h" #include "common_ui.h" #include "handle_swap_sign_transaction.h" unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_element_t *e) { - uint8_t privateKeyData[INT256_LENGTH]; - uint8_t signature[100]; - cx_ecfp_private_key_t privateKey; - uint32_t tx = 0; + uint32_t info = 0; int err; - io_seproxyhal_io_heartbeat(); - os_perso_derive_node_bip32(CX_CURVE_256K1, - tmpCtx.transactionContext.bip32.path, - tmpCtx.transactionContext.bip32.length, - privateKeyData, - NULL); - cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey); - explicit_bzero(privateKeyData, sizeof(privateKeyData)); - unsigned int info = 0; - io_seproxyhal_io_heartbeat(); - cx_ecdsa_sign(&privateKey, - CX_RND_RFC6979 | CX_LAST, - CX_SHA256, - tmpCtx.transactionContext.hash, - sizeof(tmpCtx.transactionContext.hash), - signature, - sizeof(signature), - &info); - explicit_bzero(&privateKey, sizeof(privateKey)); + if (bip32_derive_ecdsa_sign_rs_hash_256(CX_CURVE_256K1, + tmpCtx.transactionContext.bip32.path, + tmpCtx.transactionContext.bip32.length, + CX_RND_RFC6979 | CX_LAST, + CX_SHA256, + tmpCtx.transactionContext.hash, + sizeof(tmpCtx.transactionContext.hash), + G_io_apdu_buffer + 1, + G_io_apdu_buffer + 1 + 32, + &info) != CX_OK) { + THROW(0x6F00); + } + if (txContext.txType == EIP1559 || txContext.txType == EIP2930) { if (info & CX_ECCINFO_PARITY_ODD) { G_io_apdu_buffer[0] = 1; @@ -57,13 +49,13 @@ unsigned int io_seproxyhal_touch_tx_ok(__attribute__((unused)) const bagl_elemen G_io_apdu_buffer[0] += 2; } } - format_signature_out(signature); - tx = 65; - G_io_apdu_buffer[tx++] = 0x90; - G_io_apdu_buffer[tx++] = 0x00; + + // Write status code at parity_byte + r + s + G_io_apdu_buffer[1 + 64] = 0x90; + G_io_apdu_buffer[1 + 64 + 1] = 0x00; // Send back the response, do not restart the event loop - err = io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx); + err = io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, 1 + 64 + 2); if (G_called_from_swap) { PRINTF("G_called_from_swap\n"); diff --git a/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c b/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c deleted file mode 100644 index 760318828..000000000 --- a/src_features/stark_getPublicKey/cmd_stark_getPublicKey.c +++ /dev/null @@ -1,66 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" -#include "apdu_constants.h" -#include "stark_utils.h" -#include "feature_stark_getPublicKey.h" -#include "common_ui.h" -#include "os_io_seproxyhal.h" - -void handleStarkwareGetPublicKey(uint8_t p1, - uint8_t p2, - const uint8_t *dataBuffer, - uint8_t dataLength, - unsigned int *flags, - unsigned int *tx) { - bip32_path_t bip32; - cx_ecfp_private_key_t privateKey; - uint8_t privateKeyData[32]; - - reset_app_context(); - - if ((p1 != P1_CONFIRM) && (p1 != P1_NON_CONFIRM)) { - THROW(0x6B00); - } - - if (p2 != 0) { - THROW(0x6B00); - } - - dataBuffer = parseBip32(dataBuffer, &dataLength, &bip32); - - if (dataBuffer == NULL) { - THROW(0x6a80); - } - - io_seproxyhal_io_heartbeat(); - starkDerivePrivateKey(bip32.path, bip32.length, privateKeyData); - cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey); - io_seproxyhal_io_heartbeat(); - cx_ecfp_generate_pair(CX_CURVE_Stark256, &tmpCtx.publicKeyContext.publicKey, &privateKey, 1); - explicit_bzero(&privateKey, sizeof(privateKey)); - explicit_bzero(privateKeyData, sizeof(privateKeyData)); - io_seproxyhal_io_heartbeat(); -#ifndef NO_CONSENT - if (p1 == P1_NON_CONFIRM) -#endif // NO_CONSENT - { - *tx = set_result_get_stark_publicKey(); - THROW(0x9000); - } -#ifndef NO_CONSENT - else { - // prepare for a UI based reply - snprintf(strings.tmp.tmp, - sizeof(strings.tmp.tmp), - "0x%.*H", - 32, - tmpCtx.publicKeyContext.publicKey.W + 1); - ui_display_stark_public(); - - *flags |= IO_ASYNCH_REPLY; - } -#endif // NO_CONSENT -} - -#endif diff --git a/src_features/stark_getPublicKey/feature_stark_getPublicKey.h b/src_features/stark_getPublicKey/feature_stark_getPublicKey.h deleted file mode 100644 index 4859722c4..000000000 --- a/src_features/stark_getPublicKey/feature_stark_getPublicKey.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _STARK_GET_PUB_KEY_H_ -#define _STARK_GET_PUB_KEY_H_ - -#include "shared_context.h" - -uint32_t set_result_get_stark_publicKey(void); - -#endif // _STARK_GET_PUB_KEY_H_ diff --git a/src_features/stark_getPublicKey/logic_stark_getPublicKey.c b/src_features/stark_getPublicKey/logic_stark_getPublicKey.c deleted file mode 100644 index 9338cc470..000000000 --- a/src_features/stark_getPublicKey/logic_stark_getPublicKey.c +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include -#include "shared_context.h" -#include "feature_stark_getPublicKey.h" - -uint32_t set_result_get_stark_publicKey() { - uint32_t tx = 0; - memmove(G_io_apdu_buffer + tx, tmpCtx.publicKeyContext.publicKey.W, 65); - tx += 65; - return tx; -} - -#endif // HAVE_STARKWARE diff --git a/src_features/stark_getPublicKey/ui_common_stark_getPublicKey.c b/src_features/stark_getPublicKey/ui_common_stark_getPublicKey.c deleted file mode 100644 index 31b97144f..000000000 --- a/src_features/stark_getPublicKey/ui_common_stark_getPublicKey.c +++ /dev/null @@ -1,19 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" -#include "common_ui.h" -#include "feature_stark_getPublicKey.h" - -unsigned int io_seproxyhal_touch_stark_pubkey_ok(__attribute__((unused)) const bagl_element_t *e) { - uint32_t tx = set_result_get_stark_publicKey(); - G_io_apdu_buffer[tx++] = 0x90; - G_io_apdu_buffer[tx++] = 0x00; - reset_app_context(); - // Send back the response, do not restart the event loop - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx); - // Display back the original UX - ui_idle(); - return 0; // do not redraw the widget -} - -#endif diff --git a/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c b/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c deleted file mode 100644 index 1755c9307..000000000 --- a/src_features/stark_provideQuantum/cmd_stark_provideQuantum.c +++ /dev/null @@ -1,65 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" -#include "apdu_constants.h" -#include "ethUtils.h" -#include "common_ui.h" - -void handleStarkwareProvideQuantum(uint8_t p1, - __attribute__((unused)) uint8_t p2, - const uint8_t *dataBuffer, - uint8_t dataLength, - __attribute__((unused)) unsigned int *flags, - __attribute__((unused)) unsigned int *tx) { - size_t i = 0; - uint8_t expectedDataSize = 20 + 32; - uint8_t addressZero = 0; - tokenDefinition_t *currentToken = NULL; - if (appState != APP_STATE_IDLE) { - reset_app_context(); - } - switch (p1) { - case STARK_QUANTUM_LEGACY: - break; - case STARK_QUANTUM_ETH: - case STARK_QUANTUM_ERC20: - case STARK_QUANTUM_ERC721: - case STARK_QUANTUM_MINTABLE_ERC20: - case STARK_QUANTUM_MINTABLE_ERC721: - expectedDataSize += 32; - break; - default: - THROW(0x6B00); - } - if (dataLength != expectedDataSize) { - THROW(0x6700); - } - if (p1 == STARK_QUANTUM_LEGACY) { - addressZero = allzeroes((void *) dataBuffer, 20); - } - if ((p1 != STARK_QUANTUM_ETH) && !addressZero) { - for (i = 0; i < MAX_ITEMS; i++) { - currentToken = &tmpCtx.transactionContext.extraInfo[i].token; - if (tmpCtx.transactionContext.tokenSet[i] && - (memcmp(currentToken->address, dataBuffer, 20) == 0)) { - break; - } - } - if (i == MAX_ITEMS) { - PRINTF("Associated token not found\n"); - THROW(0x6A80); - } - } else { - i = MAX_ITEMS; - } - memmove(dataContext.tokenContext.quantum, dataBuffer + 20, 32); - if (p1 != STARK_QUANTUM_LEGACY) { - memmove(dataContext.tokenContext.mintingBlob, dataBuffer + 20 + 32, 32); - } - dataContext.tokenContext.quantumIndex = i; - dataContext.tokenContext.quantumType = p1; - quantumSet = true; - THROW(0x9000); -} - -#endif diff --git a/src_features/stark_sign/cmd_stark_sign.c b/src_features/stark_sign/cmd_stark_sign.c deleted file mode 100644 index 311d9d701..000000000 --- a/src_features/stark_sign/cmd_stark_sign.c +++ /dev/null @@ -1,260 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" -#include "apdu_constants.h" -#include "stark_utils.h" -#include "poorstream.h" -#include "ethUtils.h" -#include "common_ui.h" -#include "os_io_seproxyhal.h" - -#define U8BE(buf, off) \ - (uint64_t)((((uint64_t) U4BE(buf, off)) << 32) | (((uint64_t) U4BE(buf, off + 4)) & 0xFFFFFFFF)) -#define TMP_OFFSET 140 - -void handleStarkwareSignMessage(uint8_t p1, - uint8_t p2, - uint8_t *dataBuffer, - uint8_t dataLength, - unsigned int *flags, - __attribute__((unused)) unsigned int *tx) { - uint8_t privateKeyData[INT256_LENGTH]; - uint32_t i; - uint8_t bip32PathLength; - uint8_t offset = 1; - cx_ecfp_private_key_t privateKey; - poorstream_t bitstream; - bool selfTransfer = false; - uint8_t order = 1; - uint8_t protocol = 2; - uint8_t preOffset, postOffset; - uint8_t zeroTest; - - // Initial checks - if (appState != APP_STATE_IDLE) { - reset_app_context(); - } - - if (dataLength < 1) { - PRINTF("Invalid data\n"); - THROW(0x6a80); - } - - bip32PathLength = *(dataBuffer); - - if ((bip32PathLength < 0x01) || (bip32PathLength > MAX_BIP32_PATH)) { - PRINTF("Invalid path\n"); - THROW(0x6a80); - } - switch (p1) { - case P1_STARK_ORDER: - protocol = 1; - break; - case P1_STARK_TRANSFER: - protocol = 1; - order = 0; - break; - case P1_STARK_ORDER_V2: - break; - case P1_STARK_TRANSFER_V2: - case P1_STARK_CONDITIONAL_TRANSFER: - order = 0; - break; - default: - THROW(0x6B00); - } - postOffset = (protocol == 2 ? 1 + 32 : 0); - preOffset = (protocol == 2 ? 1 : 0); - if (order) { - if (dataLength != (20 + 32 + 20 + 32 + 4 + 4 + 8 + 8 + 4 + 4 + 1 + 4 * bip32PathLength + - 2 * postOffset)) { - THROW(0x6700); - } - } else { - if (dataLength != (20 + 32 + 32 + 4 + 4 + 8 + 4 + 4 + 1 + 4 * bip32PathLength + postOffset + - (p1 == P1_STARK_CONDITIONAL_TRANSFER ? 32 + 20 : 0))) { - THROW(0x6700); - } - } - if (p2 != 0) { - THROW(0x6B00); - } - tmpCtx.transactionContext.bip32.length = bip32PathLength; - for (i = 0; i < bip32PathLength; i++) { - tmpCtx.transactionContext.bip32.path[i] = U4BE(dataBuffer, offset); - PRINTF("Storing path %d %d\n", i, tmpCtx.transactionContext.bip32.path[i]); - offset += 4; - } - // Discard the path to use part of dataBuffer as a temporary buffer - memmove(dataBuffer, dataBuffer + offset, dataLength - offset); - dataContext.starkContext.conditional = (p1 == P1_STARK_CONDITIONAL_TRANSFER); - if (dataContext.starkContext.conditional) { - memmove(dataContext.starkContext.fact, - dataBuffer + 20 + 32 + postOffset + 32 + 4 + 4 + 8 + 4 + 4, - 32); - memmove(dataContext.starkContext.conditionAddress, - dataBuffer + 20 + 32 + postOffset + 32 + 4 + 4 + 8 + 4 + 4 + 32, - 20); - PRINTF("Fact %.*H\n", 32, dataContext.starkContext.fact); - PRINTF("Address %.*H\n", 20, dataContext.starkContext.conditionAddress); - } - - zeroTest = allzeroes(dataBuffer + preOffset, 20); - if (zeroTest && (protocol == 2) && (dataBuffer[0] != STARK_QUANTUM_ETH)) { - PRINTF("stark - unexpected quantum descriptor type for null first address %d\n", - dataBuffer[0]); - THROW(0x6A80); - } - if (!zeroTest && getKnownToken(dataBuffer + preOffset) == NULL) { - PRINTF("stark - cannot process unknown token %.*H", 20, dataBuffer + preOffset); - THROW(0x6A80); - } - if (order) { - zeroTest = allzeroes(dataBuffer + 20 + 32 + postOffset + preOffset, 20); - if (zeroTest && (protocol == 2) && (dataBuffer[1 + 20 + 32 + 32] != STARK_QUANTUM_ETH)) { - PRINTF("stark - unexpected quantum descriptor type for null second address %d\n", - dataBuffer[1 + 20 + 32 + 32]); - THROW(0x6A80); - } - if (!zeroTest && getKnownToken(dataBuffer + 20 + 32 + postOffset + preOffset) == NULL) { - PRINTF("stark - cannot process unknown token %.*H", - 20, - dataBuffer + 20 + 32 + postOffset + preOffset); - THROW(0x6A80); - } - } - // Prepare the Stark parameters - io_seproxyhal_io_heartbeat(); - compute_token_id(&global_sha3, - dataBuffer + preOffset, - (protocol == 2 ? dataBuffer[0] : STARK_QUANTUM_LEGACY), - dataBuffer + preOffset + 20, - (protocol == 2 ? dataBuffer + 1 + 20 + 32 : NULL), - false, - dataContext.starkContext.w1); - if (order) { - io_seproxyhal_io_heartbeat(); - compute_token_id(&global_sha3, - dataBuffer + 20 + 32 + postOffset + preOffset, - (protocol == 2 ? dataBuffer[1 + 20 + 32 + 32] : STARK_QUANTUM_LEGACY), - dataBuffer + 20 + 32 + postOffset + preOffset + 20, - (protocol == 2 ? dataBuffer + 1 + 20 + 32 + 32 + 1 + 20 + 32 : NULL), - false, - dataContext.starkContext.w2); - offset = 20 + 32 + postOffset + 20 + 32 + postOffset; - } else { - memmove(dataContext.starkContext.w2, dataBuffer + 20 + 32 + postOffset, 32); - offset = 20 + 32 + postOffset + 32; - } - - poorstream_init(&bitstream, dataContext.starkContext.w3); - poorstream_write_bits(&bitstream, 0, 11); // padding - poorstream_write_bits(&bitstream, - (p1 == P1_STARK_CONDITIONAL_TRANSFER ? STARK_CONDITIONAL_TRANSFER_TYPE - : order ? STARK_ORDER_TYPE - : STARK_TRANSFER_TYPE), - 4); - poorstream_write_bits(&bitstream, U4BE(dataBuffer, offset), 31); - poorstream_write_bits(&bitstream, U4BE(dataBuffer, offset + 4), 31); - poorstream_write_bits(&bitstream, U8BE(dataBuffer, offset + 4 + 4), 63); - if (order) { - poorstream_write_bits(&bitstream, U8BE(dataBuffer, offset + 4 + 4 + 8), 63); - offset += 4 + 4 + 8 + 8; - } else { - poorstream_write_bits(&bitstream, 0, 63); - offset += 4 + 4 + 8; - } - poorstream_write_bits(&bitstream, U4BE(dataBuffer, offset), 31); - poorstream_write_bits(&bitstream, U4BE(dataBuffer, offset + 4), 22); - - PRINTF("stark w1 %.*H\n", 32, dataContext.starkContext.w1); - PRINTF("stark w2 %.*H\n", 32, dataContext.starkContext.w2); - PRINTF("stark w3 %.*H\n", 32, dataContext.starkContext.w3); - - if (dataContext.starkContext.conditional) { - cx_keccak_init(&global_sha3, 256); - cx_hash((cx_hash_t *) &global_sha3, - 0, - dataContext.starkContext.conditionAddress, - 20, - NULL, - 0); - cx_hash((cx_hash_t *) &global_sha3, - CX_LAST, - dataContext.starkContext.fact, - 32, - dataContext.starkContext.w4, - 32); - dataContext.starkContext.w4[0] &= 0x03; - PRINTF("stark w4 %.*H\n", 32, dataContext.starkContext.w4); - } - // Prepare the UI - if (order) { - io_seproxyhal_io_heartbeat(); - // amount to sell - stark_get_amount_string(dataBuffer + preOffset, - dataBuffer + preOffset + 20, - dataBuffer + 20 + 32 + postOffset + 20 + 32 + postOffset + 4 + 4, - (char *) (dataBuffer + TMP_OFFSET), - strings.common.fullAmount); - io_seproxyhal_io_heartbeat(); - // amount to buy - stark_get_amount_string( - dataBuffer + 20 + 32 + postOffset + preOffset, - dataBuffer + 20 + 32 + postOffset + preOffset + 20, - dataBuffer + 20 + 32 + postOffset + 20 + 32 + postOffset + 4 + 4 + 8, - (char *) (dataBuffer + TMP_OFFSET), - strings.common.maxFee); - // src vault ID - snprintf(strings.common.fullAddress, - sizeof(strings.common.fullAddress), - "%d", - U4BE(dataBuffer, 20 + 32 + postOffset + 20 + 32 + postOffset)); - } else { - cx_ecfp_public_key_t publicKey; - // Check if the transfer is a self transfer - io_seproxyhal_io_heartbeat(); - starkDerivePrivateKey(tmpCtx.transactionContext.bip32.path, - bip32PathLength, - privateKeyData); - cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey); - io_seproxyhal_io_heartbeat(); - cx_ecfp_generate_pair(CX_CURVE_Stark256, &publicKey, &privateKey, 1); - explicit_bzero(&privateKey, sizeof(privateKey)); - explicit_bzero(privateKeyData, sizeof(privateKeyData)); - io_seproxyhal_io_heartbeat(); - selfTransfer = (memcmp(publicKey.W + 1, dataBuffer + 20 + 32 + postOffset, 32) == 0); - PRINTF("self transfer %d\n", selfTransfer); - io_seproxyhal_io_heartbeat(); - // amount to transfer - stark_get_amount_string(dataBuffer + preOffset, - dataBuffer + preOffset + 20, - dataBuffer + 20 + 32 + postOffset + 32 + 4 + 4, - (char *) (dataBuffer + TMP_OFFSET), - tmpContent.tmp); - // dest vault ID - snprintf(strings.tmp.tmp2, - sizeof(strings.tmp.tmp2), - "%d", - U4BE(dataBuffer, 20 + 32 + postOffset + 32 + 4)); - if (!selfTransfer) { - memmove(dataContext.starkContext.transferDestination, - dataBuffer + 20 + 32 + postOffset, - 32); - snprintf(strings.tmp.tmp, - sizeof(strings.tmp.tmp), - "0x%.*H", - 32, - dataBuffer + 20 + 32 + postOffset); - } - } - if (order) { - ui_stark_limit_order(); - } else { - ui_stark_transfer(selfTransfer, dataContext.starkContext.conditional); - } - - *flags |= IO_ASYNCH_REPLY; -} - -#endif diff --git a/src_features/stark_sign/ui_common_stark_sign.c b/src_features/stark_sign/ui_common_stark_sign.c deleted file mode 100644 index a45f7f918..000000000 --- a/src_features/stark_sign/ui_common_stark_sign.c +++ /dev/null @@ -1,36 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "os_io_seproxyhal.h" -#include "shared_context.h" -#include "stark_utils.h" -#include "common_ui.h" - -unsigned int io_seproxyhal_touch_stark_ok(__attribute__((unused)) const bagl_element_t *e) { - uint8_t privateKeyData[32]; - uint8_t signature[72]; - uint32_t tx = 0; - io_seproxyhal_io_heartbeat(); - starkDerivePrivateKey(tmpCtx.transactionContext.bip32.path, - tmpCtx.transactionContext.bip32.length, - privateKeyData); - io_seproxyhal_io_heartbeat(); - stark_sign(signature, - privateKeyData, - dataContext.starkContext.w1, - dataContext.starkContext.w2, - dataContext.starkContext.w3, - (dataContext.starkContext.conditional ? dataContext.starkContext.w4 : NULL)); - G_io_apdu_buffer[0] = 0; - format_signature_out(signature); - tx = 65; - G_io_apdu_buffer[tx++] = 0x90; - G_io_apdu_buffer[tx++] = 0x00; - reset_app_context(); - // Send back the response, do not restart the event loop - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx); - // Display back the original UX - ui_idle(); - return 0; // do not redraw the widget -} - -#endif // HAVE_STARKWARE diff --git a/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c b/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c deleted file mode 100644 index 314fb22e4..000000000 --- a/src_features/stark_unsafe_sign/cmd_stark_unsafe_sign.c +++ /dev/null @@ -1,55 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "shared_context.h" -#include "apdu_constants.h" -#include "stark_utils.h" -#include "common_ui.h" -#include "os_io_seproxyhal.h" - -void handleStarkwareUnsafeSign(uint8_t p1, - uint8_t p2, - const uint8_t *dataBuffer, - uint8_t dataLength, - unsigned int *flags, - __attribute__((unused)) unsigned int *tx) { - uint8_t privateKeyData[INT256_LENGTH]; - cx_ecfp_public_key_t publicKey; - cx_ecfp_private_key_t privateKey; - - // Initial checks - if (appState != APP_STATE_IDLE) { - reset_app_context(); - } - - if ((p1 != 0) || (p2 != 0)) { - THROW(0x6B00); - } - - dataBuffer = parseBip32(dataBuffer, &dataLength, &tmpCtx.transactionContext.bip32); - - if (dataBuffer == NULL) { - THROW(0x6a80); - } - - if (dataLength != 32) { - THROW(0x6700); - } - - memmove(dataContext.starkContext.w2, dataBuffer, 32); - io_seproxyhal_io_heartbeat(); - starkDerivePrivateKey(tmpCtx.transactionContext.bip32.path, - tmpCtx.transactionContext.bip32.length, - privateKeyData); - cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey); - io_seproxyhal_io_heartbeat(); - cx_ecfp_generate_pair(CX_CURVE_Stark256, &publicKey, &privateKey, 1); - explicit_bzero(&privateKey, sizeof(privateKey)); - explicit_bzero(privateKeyData, sizeof(privateKeyData)); - io_seproxyhal_io_heartbeat(); - memmove(dataContext.starkContext.w1, publicKey.W + 1, 32); - ui_stark_unsafe_sign(); - - *flags |= IO_ASYNCH_REPLY; -} - -#endif diff --git a/src_features/stark_unsafe_sign/ui_common_stark_unsafe_sign.c b/src_features/stark_unsafe_sign/ui_common_stark_unsafe_sign.c deleted file mode 100644 index 4774627b8..000000000 --- a/src_features/stark_unsafe_sign/ui_common_stark_unsafe_sign.c +++ /dev/null @@ -1,42 +0,0 @@ -#ifdef HAVE_STARKWARE - -#include "os_io_seproxyhal.h" -#include "shared_context.h" -#include "stark_utils.h" -#include "common_ui.h" - -unsigned int io_seproxyhal_touch_stark_unsafe_sign_ok(__attribute__((unused)) - const bagl_element_t *e) { - cx_ecfp_private_key_t privateKey; - uint8_t privateKeyData[INT256_LENGTH]; - uint8_t signature[72]; - unsigned int info = 0; - uint32_t tx = 0; - io_seproxyhal_io_heartbeat(); - starkDerivePrivateKey(tmpCtx.transactionContext.bip32.path, - tmpCtx.transactionContext.bip32.length, - privateKeyData); - io_seproxyhal_io_heartbeat(); - cx_ecfp_init_private_key(CX_CURVE_Stark256, privateKeyData, 32, &privateKey); - cx_ecdsa_sign(&privateKey, - CX_RND_RFC6979 | CX_LAST, - CX_SHA256, - dataContext.starkContext.w2, - sizeof(dataContext.starkContext.w2), - signature, - sizeof(signature), - &info); - G_io_apdu_buffer[0] = 0; - format_signature_out(signature); - tx = 65; - G_io_apdu_buffer[tx++] = 0x90; - G_io_apdu_buffer[tx++] = 0x00; - reset_app_context(); - // Send back the response, do not restart the event loop - io_exchange(CHANNEL_APDU | IO_RETURN_AFTER_TX, tx); - // Display back the original UX - ui_idle(); - return 0; // do not redraw the widget -} - -#endif // HAVE_STARKWARE diff --git a/src_nbgl/network_icons.c b/src_nbgl/network_icons.c new file mode 100644 index 000000000..8f7a4532e --- /dev/null +++ b/src_nbgl/network_icons.c @@ -0,0 +1,20 @@ +#include "os_utils.h" +#include "os_pic.h" +#include "net_icons.gen.h" + +/** + * Get the network icon from a given chain ID + * + * Loops onto the generated \ref g_network_icons array until a chain ID matches. + * + * @param[in] chain_id network's chain ID + * @return the network icon if found, \ref NULL otherwise + */ +const nbgl_icon_details_t *get_network_icon_from_chain_id(const uint64_t *chain_id) { + for (size_t i = 0; i < ARRAYLEN(g_network_icons); ++i) { + if ((uint64_t) PIC(g_network_icons[i].chain_id) == *chain_id) { + return PIC(g_network_icons[i].icon); + } + } + return NULL; +} diff --git a/src_nbgl/network_icons.h b/src_nbgl/network_icons.h new file mode 100644 index 000000000..0a85afebf --- /dev/null +++ b/src_nbgl/network_icons.h @@ -0,0 +1,9 @@ +#ifndef NETWORK_ICONS_H_ +#define NETWORK_ICONS_H_ + +#include +#include "nbgl_types.h" + +const nbgl_icon_details_t *get_network_icon_from_chain_id(const uint64_t *chain_id); + +#endif // NETWORK_ICONS_H_ diff --git a/src_nbgl/ui_approve_tx.c b/src_nbgl/ui_approve_tx.c index a6253c35d..7e2f59d39 100644 --- a/src_nbgl/ui_approve_tx.c +++ b/src_nbgl/ui_approve_tx.c @@ -3,10 +3,12 @@ #include "shared_context.h" #include "ui_callbacks.h" #include "ui_nbgl.h" -#include "ethUtils.h" #include "ui_signing.h" #include "plugins.h" #include "domain_name.h" +#include "caller_api.h" +#include "network_icons.h" +#include "network.h" #define TEXT_TX "transaction" // 1 more than actually displayed on screen, because of calculations in StaticReview @@ -190,7 +192,12 @@ static const nbgl_icon_details_t *get_tx_icon(void) { } } } else { - icon = get_app_icon(false); + uint64_t chain_id = get_tx_chain_id(); + if (chain_id == chainConfig->chainId) { + icon = get_app_icon(false); + } else { + icon = get_network_icon_from_chain_id(&chain_id); + } } return icon; } diff --git a/src_nbgl/ui_get_public_key.c b/src_nbgl/ui_get_public_key.c index 5966737ea..b3c495342 100644 --- a/src_nbgl/ui_get_public_key.c +++ b/src_nbgl/ui_get_public_key.c @@ -2,27 +2,57 @@ #include "shared_context.h" #include "ui_callbacks.h" #include "ui_nbgl.h" +#include "network.h" +#include "network_icons.h" -static void reviewReject(void) { +static void cancel_send(void) { io_seproxyhal_touch_address_cancel(NULL); } -static void confirmTransation(void) { +static void confirm_send(void) { io_seproxyhal_touch_address_ok(NULL); } -static void reviewChoice(bool confirm) { +static void confirm_addr(void) { + // display a status page and go back to main + nbgl_useCaseStatus("ADDRESS\nVERIFIED", true, confirm_send); +} + +static void reject_addr(void) { + nbgl_useCaseStatus("Address verification\ncancelled", false, cancel_send); +} + +static void review_choice(bool confirm) { if (confirm) { - // display a status page and go back to main - nbgl_useCaseStatus("ADDRESS\nVERIFIED", true, confirmTransation); + confirm_addr(); } else { - nbgl_useCaseStatus("Address verification\ncancelled", false, reviewReject); + reject_addr(); } } -static void buildScreen(void) { - nbgl_useCaseAddressConfirmation(strings.common.fullAddress, reviewChoice); +static void display_addr(void) { + nbgl_useCaseAddressConfirmation(strings.common.fullAddress, review_choice); +} + +void ui_display_public_key(const uint64_t *chain_id) { + const nbgl_icon_details_t *icon; + + // - if a chain_id is given and it's - known, we specify its network name + // - unknown, we don't specify anything + // - if no chain_id is given we specify the APPNAME (legacy behaviour) + strlcpy(g_stax_shared_buffer, "Verify ", sizeof(g_stax_shared_buffer)); + if (chain_id != NULL) { + if (chain_is_ethereum_compatible(chain_id)) { + strlcat(g_stax_shared_buffer, + get_network_name_from_chain_id(chain_id), + sizeof(g_stax_shared_buffer)); + strlcat(g_stax_shared_buffer, "\n", sizeof(g_stax_shared_buffer)); + } + icon = get_network_icon_from_chain_id(chain_id); + } else { + strlcat(g_stax_shared_buffer, APPNAME "\n", sizeof(g_stax_shared_buffer)); + icon = get_app_icon(false); + } + strlcat(g_stax_shared_buffer, "address", sizeof(g_stax_shared_buffer)); + nbgl_useCaseReviewStart(icon, g_stax_shared_buffer, NULL, "Cancel", display_addr, reject_addr); } -void ui_display_public_key(void) { - buildScreen(); -} \ No newline at end of file diff --git a/src_nbgl/ui_get_stark_public_key.c b/src_nbgl/ui_get_stark_public_key.c deleted file mode 100644 index ce5778750..000000000 --- a/src_nbgl/ui_get_stark_public_key.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include "shared_context.h" -#include "ui_callbacks.h" -#include "ui_nbgl.h" - -static void reviewReject(void) { - io_seproxyhal_touch_address_cancel(NULL); -} - -static void confirmTransation(void) { - io_seproxyhal_touch_stark_pubkey_ok(NULL); -} - -static void reviewChoice(bool confirm) { - if (confirm) { - // display a status page and go back to main - nbgl_useCaseStatus("ADDRESS\nVERIFIED", true, confirmTransation); - } else { - nbgl_useCaseStatus("Address verification\ncancelled", false, reviewReject); - } -} - -static void buildScreen(void) { - nbgl_useCaseAddressConfirmation(strings.tmp.tmp, reviewChoice); -} - -void ui_display_stark_public(void) { - buildScreen(); -} \ No newline at end of file diff --git a/src_nbgl/ui_idle.c b/src_nbgl/ui_idle.c index faa47ca99..56f559ea8 100644 --- a/src_nbgl/ui_idle.c +++ b/src_nbgl/ui_idle.c @@ -3,6 +3,7 @@ #include "ui_nbgl.h" #include "nbgl_use_case.h" #include "glyphs.h" +#include "caller_api.h" #include "network.h" char g_stax_shared_buffer[SHARED_BUFFER_SIZE] = {0}; diff --git a/src_nbgl/ui_sign_712.c b/src_nbgl/ui_sign_712.c index 4d9aae7a3..ad4f07f92 100644 --- a/src_nbgl/ui_sign_712.c +++ b/src_nbgl/ui_sign_712.c @@ -30,7 +30,12 @@ static bool display_review_page(uint8_t page, nbgl_pageContent_t *content) { strings.tmp.tmp, SCREEN_WIDTH - (2 * BORDER_MARGIN), NB_MAX_LINES_IN_REVIEW, +#if (API_LEVEL == 0 || API_LEVEL >= 14) + &len, + false); +#else &len); +#endif strings.tmp.tmp[len] = '\0'; pair.item = strings.tmp.tmp2; diff --git a/src_nbgl/ui_sign_712_v0.c b/src_nbgl/ui_sign_712_v0.c index ec38eeaf7..0681009bc 100644 --- a/src_nbgl/ui_sign_712_v0.c +++ b/src_nbgl/ui_sign_712_v0.c @@ -2,7 +2,6 @@ #include "ui_nbgl.h" #include "common_712.h" #include "network.h" -#include "ethUtils.h" #include "ui_message_signing.h" #include "ui_signing.h" diff --git a/src_nbgl/ui_sign_message.c b/src_nbgl/ui_sign_message.c index 6d85f80e8..a85d98b90 100644 --- a/src_nbgl/ui_sign_message.c +++ b/src_nbgl/ui_sign_message.c @@ -47,7 +47,12 @@ static bool display_message(nbgl_pageContent_t *content) { (char *) g_stax_shared_buffer, SCREEN_WIDTH - (2 * BORDER_MARGIN), NB_MAX_LINES_IN_REVIEW, +#if (API_LEVEL == 0 || API_LEVEL >= 14) + &len, + false); +#else &len); +#endif stringsTmpTmpIdx = len - eip191MessageIdx; eip191MessageIdx = len; diff --git a/src_nbgl/ui_stark_limit_order.c b/src_nbgl/ui_stark_limit_order.c deleted file mode 100644 index 89cfdbf83..000000000 --- a/src_nbgl/ui_stark_limit_order.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "common_ui.h" -#include "ui_signing.h" -#include "ui_nbgl.h" -#include "ui_callbacks.h" -#include "nbgl_use_case.h" -#include "network.h" - -#ifdef HAVE_STARKWARE - -static nbgl_layoutTagValue_t pairs[3]; - -static void reviewReject(void) { - io_seproxyhal_touch_tx_cancel(NULL); -} - -static void confirmTransation(void) { - io_seproxyhal_touch_stark_ok(NULL); -} - -static void reviewChoice(bool confirm) { - if (confirm) { - confirmTransation(); - } else { - reviewReject(); - } -} - -static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) { - if (page == 0) { - pairs[0].item = "Sell"; - pairs[0].value = strings.common.fullAmount; - pairs[1].item = "Buy"; - pairs[1].value = strings.common.maxFee; - pairs[2].item = "Token Account"; - pairs[2].value = strings.common.fullAddress; - - content->type = TAG_VALUE_LIST; - content->tagValueList.nbPairs = 3; - content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs; - } else if (page == 1) { - content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(false); - content->infoLongPress.text = "Review stark limit order"; - content->infoLongPress.longPressText = SIGN_BUTTON; - } else { - return false; - } - // valid page so return true - return true; -} - -static void reviewContinue(void) { - nbgl_useCaseRegularReview(0, 2, REJECT_BUTTON, NULL, displayTransactionPage, reviewChoice); -} - -static void buildFirstPage(void) { - nbgl_useCaseReviewStart(get_app_icon(false), - "Review stark limit order", - NULL, - REJECT_BUTTON, - reviewContinue, - reviewReject); -} - -void ui_stark_limit_order(void) { - buildFirstPage(); -} - -#endif diff --git a/src_nbgl/ui_stark_transfer.c b/src_nbgl/ui_stark_transfer.c deleted file mode 100644 index d7decfbca..000000000 --- a/src_nbgl/ui_stark_transfer.c +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include "shared_context.h" -#include "ui_callbacks.h" -#include "ui_nbgl.h" -#include "ui_signing.h" -#include "starkDisplayUtils.h" -#include "ethUtils.h" -#include "network.h" - -#ifdef HAVE_STARKWARE - -static nbgl_layoutTagValue_t pairs[3]; -static char condAddressBuffer[43]; -struct stark_transfer_context { - bool selfTransfer; - bool conditional; -}; - -static struct stark_transfer_context context; - -static void reviewReject(void) { - io_seproxyhal_touch_tx_cancel(NULL); -} - -static void confirmTransation(void) { - io_seproxyhal_touch_stark_ok(NULL); -} - -static void reviewChoice(bool confirm) { - if (confirm) { - confirmTransation(); - } else { - reviewReject(); - } -} - -static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) { - uint8_t count = 0; - if (page == 0) { - pairs[count].item = "Amount"; - pairs[count].value = tmpContent.tmp; - count++; - - if (context.selfTransfer == false && context.conditional == false) { - pairs[count].item = "Master Account"; - pairs[count].value = strings.tmp.tmp; - count++; - } - if (context.conditional) { - stark_sign_display_master_account(); - pairs[count].item = "Master Account"; - pairs[count].value = strings.tmp.tmp; - count++; - } - - pairs[count].item = "Token Account"; - pairs[count].value = strings.tmp.tmp2; - count++; - - content->type = TAG_VALUE_LIST; - content->tagValueList.nbPairs = count; - content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs; - - return true; - } - if (page == 1) { - if (context.conditional) { - getEthDisplayableAddress(dataContext.starkContext.conditionAddress, - condAddressBuffer, - sizeof(condAddressBuffer), - &global_sha3, - chainConfig->chainId); - pairs[0].item = "Cond. Address"; - pairs[0].value = condAddressBuffer; - - stark_sign_display_condition_fact(); - pairs[1].item = "Cond. Address"; - pairs[1].value = strings.tmp.tmp; - - content->type = TAG_VALUE_LIST; - content->tagValueList.nbPairs = 2; - content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs; - - return true; - } else { - page++; - } - } - if (page == 2) { - content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(false); - content->infoLongPress.text = "Review transaction"; - content->infoLongPress.longPressText = SIGN_BUTTON; - return true; - } - - return false; -} - -static void reviewContinue(void) { - nbgl_useCaseRegularReview(0, - context.conditional ? 3 : 2, - REJECT_BUTTON, - NULL, - displayTransactionPage, - reviewChoice); -} - -void ui_stark_transfer(bool selfTransfer, bool conditional) { - context.selfTransfer = selfTransfer; - context.conditional = conditional; - char *subTitle; - if (conditional) { - if (selfTransfer) { - subTitle = (char *) "Conditional Self Transfer"; - } else { - subTitle = (char *) "Conditional Transfer"; - } - } else { - if (selfTransfer) { - subTitle = (char *) "Self Transfer"; - } else { - subTitle = (char *) "Transfer"; - } - } - nbgl_useCaseReviewStart(get_app_icon(false), - "Review stark\ntransaction", - subTitle, - REJECT_BUTTON, - reviewContinue, - reviewReject); -} - -#endif // #ifdef HAVE_STARKWARE diff --git a/src_nbgl/ui_stark_unsafe_sign.c b/src_nbgl/ui_stark_unsafe_sign.c deleted file mode 100644 index 45a8556db..000000000 --- a/src_nbgl/ui_stark_unsafe_sign.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "common_ui.h" -#include "ui_signing.h" -#include "ui_nbgl.h" -#include "ui_callbacks.h" -#include "nbgl_use_case.h" -#include "network.h" - -#ifdef HAVE_STARKWARE - -static nbgl_layoutTagValue_t pairs[2]; -static char from_account[64]; -static char message_hash[64]; - -static void reviewReject(void) { - io_seproxyhal_touch_tx_cancel(NULL); -} - -static void confirmTransation(void) { - io_seproxyhal_touch_stark_unsafe_sign_ok(NULL); -} - -static void reviewChoice(bool confirm) { - if (confirm) { - confirmTransation(); - } else { - reviewReject(); - } -} - -static bool displayTransactionPage(uint8_t page, nbgl_pageContent_t *content) { - snprintf(from_account, sizeof(from_account), "0x%.*H", 32, dataContext.starkContext.w1); - snprintf(message_hash, sizeof(message_hash), "0x%.*H", 32, dataContext.starkContext.w2); - - if (page == 0) { - pairs[0].item = "From Account"; - pairs[0].value = from_account; - pairs[1].item = "Hash"; - pairs[1].value = message_hash; - content->type = TAG_VALUE_LIST; - content->tagValueList.nbPairs = 2; - content->tagValueList.pairs = (nbgl_layoutTagValue_t *) pairs; - } else if (page == 1) { - content->type = INFO_LONG_PRESS, content->infoLongPress.icon = get_app_icon(false); - content->infoLongPress.text = "Unsafe Stark Sign"; - content->infoLongPress.longPressText = SIGN_BUTTON; - } else { - return false; - } - // valid page so return true - return true; -} - -static void reviewContinue(void) { - nbgl_useCaseRegularReview(0, 2, REJECT_BUTTON, NULL, displayTransactionPage, reviewChoice); -} - -static void buildFirstPage(void) { - nbgl_useCaseReviewStart(get_app_icon(false), - "Unsafe Stark Sign", - NULL, - REJECT_BUTTON, - reviewContinue, - reviewReject); -} - -void ui_stark_unsafe_sign(void) { - buildFirstPage(); -} - -#endif // HAVE_STARKWARE diff --git a/src_plugin_sdk/CHANGELOG.md b/src_plugin_sdk/CHANGELOG.md new file mode 100644 index 000000000..90ead8d91 --- /dev/null +++ b/src_plugin_sdk/CHANGELOG.md @@ -0,0 +1,68 @@ +# Ethereum Plugin SDK changelog + +| Icon | Impact | +|----------------------|-------------------------------| +| :rotating_light: | Breaks build | +| :warning: | Breaks compatibility with app | + +## [latest](/) - 2024/02/07 + +### Removed + +* UI disabler + +## [2250549](/../../commit/2250549) - 2024/02/02 + +### Changed + +* The SDK source code has been split into multiple smaller files + +## [3b7e7ad](/../../commit/3b7e7ad) - 2023/12/07 + +### Fixed + +* standard\_plugin build ([this PR on the SDK](https://github.com/LedgerHQ/ledger-secure-sdk/pull/473) had broken it) +* Broken variant auto-setting in the standard\_plugin Makefile +* Missing null-check on parameters received by the plugins + +### Changed + +* utils renamed to plugin\_utils to prevent filename conflicts in plugins + +## [4d8e044](/../../commit/4d8e044) - 2023/11/09 + +### Added + +* standard\_plugin Makefile so plugins can use it & have a really small Makefile +with only the relevant information +* Comments in the plugin interface header file + +## [1fe4085](/../../commit/1fe4085) - 2023/10/19 + +### Changed + +* Now only uses *\_no\_throw* functions, SDK functions now return a boolean +(keeps the guidelines enforcer happy) + +### Added + +* *main* & *dispatch\_call* functions are now part of the SDK and don't need to +be implemented by each plugin :rotating_light: + +## [b9777e7](/../../commit/b9777e7) - 2023/05/16 + +### Added + +* Stax support with information passed from plugin to app-ethereum (with caller app struct) + +## [a4b971f](/../../commit/a4b971f) - 2023/01/24 + +### Changed + +* Removed end space in tickers :warning: + +## [81eb658](/../../commit/81eb658) - 2022/11/17 + +### Added + +* *U2BE\_from\_parameter* & *U4BE\_from\_parameter* safe functions diff --git a/src_plugin_sdk/LICENSE b/src_plugin_sdk/LICENSE new file mode 100644 index 000000000..8dada3eda --- /dev/null +++ b/src_plugin_sdk/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/src_plugin_sdk/README.md b/src_plugin_sdk/README.md new file mode 100644 index 000000000..a5c308d36 --- /dev/null +++ b/src_plugin_sdk/README.md @@ -0,0 +1,18 @@ +# ethereum-plugin-sdk + +This repository is meant to be linked as submodule and used in external plugins working with [app-ethereum](https://github.com/LedgerHQ/app-ethereum). +It is composed of a few headers containing definitions about app-ethereum's internal transaction parsing state and some structures to communicate via shared memory. + +## Updating this SDK + +This SDK is updated at (app-ethereum) build time every time one of app-ethereum internals structures of interest are modified. +If this SDK gets updated, it is possible that all plugins must be recompiled (and eventually updated to work again with the update) with this new SDK. +Be careful, and weight your choices. + +## Manual build + +If for some reasons you want to rebuild this SDK manually from [app-ethereum](https://github.com/LedgerHQ/app-ethereum) (reminder: it is rebuild automatically when building app-ethereum itself): + +```shell +$> ./tools/build_sdk.sh +``` diff --git a/src_plugin_sdk/src/eth_internals.h b/src_plugin_sdk/src/eth_internals.h new file mode 100644 index 000000000..60087eabc --- /dev/null +++ b/src_plugin_sdk/src/eth_internals.h @@ -0,0 +1,21 @@ +/******************************************************************************* + * Ledger Ethereum App + * (c) 2016-2019 Ledger + * + * 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 + +// Empty file, introduced to not break compatibility following plugin-sdk structure rework +#warning "Deprecated file, the sdk sources have been rationalized in several dedicated files." diff --git a/src_plugin_sdk/src/main.c b/src_plugin_sdk/src/main.c new file mode 100644 index 000000000..bd5b56c10 --- /dev/null +++ b/src_plugin_sdk/src/main.c @@ -0,0 +1,129 @@ +/***************************************************************************** + * Ledger Plugin SDK + * (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 "eth_plugin_interface.h" +#include "lib_standard_app/swap_lib_calls.h" // RUN_APPLICATION + +// Functions implemented by the plugin +void handle_init_contract(ethPluginInitContract_t *parameters); +void handle_provide_parameter(ethPluginProvideParameter_t *parameters); +void handle_finalize(ethPluginFinalize_t *parameters); +void handle_provide_token(ethPluginProvideInfo_t *parameters); +void handle_query_contract_id(ethQueryContractID_t *parameters); +void handle_query_contract_ui(ethQueryContractUI_t *parameters); + +// Calls the ethereum app. +static void call_app_ethereum() { + unsigned int libcall_params[5]; + libcall_params[0] = (unsigned int) "Ethereum"; + libcall_params[1] = 0x100; + libcall_params[2] = RUN_APPLICATION; + libcall_params[3] = (unsigned int) NULL; +#ifdef HAVE_NBGL + caller_app_t capp; + const char name[] = APPNAME; + nbgl_icon_details_t icon_details; + uint8_t bitmap[sizeof(ICONBITMAP)]; + + memcpy(&icon_details, &ICONGLYPH, sizeof(ICONGLYPH)); + memcpy(&bitmap, &ICONBITMAP, sizeof(bitmap)); + icon_details.bitmap = (const uint8_t *) bitmap; + capp.name = (const char *) name; + capp.icon = &icon_details; + libcall_params[4] = (unsigned int) &capp; +#else + libcall_params[4] = (unsigned int) NULL; +#endif + os_lib_call((unsigned int *) &libcall_params); +} + +// Function to dispatch calls from the ethereum app. +static void dispatch_call(int message, void *parameters) { + if (parameters != NULL) { + switch (message) { + case ETH_PLUGIN_INIT_CONTRACT: + handle_init_contract(parameters); + break; + case ETH_PLUGIN_PROVIDE_PARAMETER: + handle_provide_parameter(parameters); + break; + case ETH_PLUGIN_FINALIZE: + handle_finalize(parameters); + break; + case ETH_PLUGIN_PROVIDE_INFO: + handle_provide_token(parameters); + break; + case ETH_PLUGIN_QUERY_CONTRACT_ID: + handle_query_contract_id(parameters); + break; + case ETH_PLUGIN_QUERY_CONTRACT_UI: + handle_query_contract_ui(parameters); + break; + default: + PRINTF("Unhandled message %d\n", message); + break; + } + } else { + PRINTF("Received null parameters\n"); + } +} + +// Low-level main for plugins. +__attribute__((section(".boot"))) int main(int arg0) { + // Exit critical section + __asm volatile("cpsie i"); + + os_boot(); + + BEGIN_TRY { + TRY { + // Check if plugin is called from the dashboard. + if (!arg0) { + // Called from dashboard, launch Ethereum app + call_app_ethereum(); + + // Will not get reached. + __builtin_unreachable(); + + os_sched_exit(-1); + + } else { + // Not called from dashboard: called from the ethereum app! + const unsigned int *args = (unsigned int *) arg0; + + // If `ETH_PLUGIN_CHECK_PRESENCE` is set, this means the caller is just trying to + // know whether this app exists or not. We can skip `paraswap_plugin_call`. + if (args[0] != ETH_PLUGIN_CHECK_PRESENCE) { + dispatch_call(args[0], (void *) args[1]); + } + } + + // Call `os_lib_end`, go back to the ethereum app. + os_lib_end(); + + // Will not get reached. + __builtin_unreachable(); + } + CATCH_OTHER(e) { + PRINTF("Exiting following exception: %d\n", e); + } + FINALLY { + os_lib_end(); + } + } + END_TRY; +} diff --git a/src_plugin_sdk/standard_plugin.mk b/src_plugin_sdk/standard_plugin.mk new file mode 100644 index 000000000..f52c1327e --- /dev/null +++ b/src_plugin_sdk/standard_plugin.mk @@ -0,0 +1,59 @@ +# **************************************************************************** +# Ledger Ethereum Plugin SDK +# (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. +# **************************************************************************** + +ifeq ($(BOLOS_SDK),) +$(error Environment variable BOLOS_SDK is not set) +endif + +include $(BOLOS_SDK)/Makefile.defines + +APPVERSION ?= "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)" + +# Application source files +APP_SOURCE_PATH += src ethereum-plugin-sdk + +# Application icons following guidelines: +# https://developers.ledger.com/docs/embedded-app/design-requirements/#device-icon +NORMAL_NAME ?= $(shell echo -n "$(APPNAME)" | tr " ." "_" | tr "[:upper:]" "[:lower:]") +ICON_NANOS = icons/nanos_app_$(NORMAL_NAME).gif +ICON_NANOX = icons/nanox_app_$(NORMAL_NAME).gif +ICON_NANOSP = $(ICON_NANOX) +ICON_STAX = icons/stax_app_$(NORMAL_NAME).gif + +ifeq ($(TARGET_NAME),TARGET_STAX) + DEFINES += ICONGLYPH=C_stax_$(NORMAL_NAME)_64px + DEFINES += ICONBITMAP=C_stax_$(NORMAL_NAME)_64px_bitmap +endif + +CURVE_APP_LOAD_PARAMS = secp256k1 + +PATH_APP_LOAD_PARAMS ?= "44'/60'" + +VARIANT_PARAM = COIN +VARIANT_VALUES ?= $(NORMAL_NAME) + +HAVE_APPLICATION_FLAG_LIBRARY = 1 + +DISABLE_STANDARD_APP_FILES = 1 +DISABLE_STANDARD_SNPRINTF = 1 +DISABLE_STANDARD_USB = 1 +DISABLE_STANDARD_WEBUSB = 1 +DISABLE_STANDARD_BAGL_UX_FLOW = 1 +DISABLE_DEBUG_LEDGER_ASSERT = 1 +DISABLE_DEBUG_THROW = 1 + +include $(BOLOS_SDK)/Makefile.standard_app diff --git a/src_plugins/erc1155/erc1155_plugin.c b/src_plugins/erc1155/erc1155_plugin.c index 4c530daaf..b81aa8d5c 100644 --- a/src_plugins/erc1155/erc1155_plugin.c +++ b/src_plugins/erc1155/erc1155_plugin.c @@ -2,8 +2,8 @@ #include #include "erc1155_plugin.h" +#include "plugin_utils.h" #include "eth_plugin_internal.h" -#include "ethUtils.h" #include "eth_plugin_handler.h" static const uint8_t ERC1155_APPROVE_FOR_ALL_SELECTOR[SELECTOR_SIZE] = {0xa2, 0x2c, 0xb4, 0x65}; @@ -108,7 +108,12 @@ static void handle_query_contract_id(void *parameters) { switch (context->selectorIndex) { case SET_APPROVAL_FOR_ALL: +#ifdef HAVE_NBGL + strlcpy(msg->version, "manage", msg->versionLength); + strlcat(msg->name, " allowance", msg->nameLength); +#else strlcpy(msg->version, "Allowance", msg->versionLength); +#endif break; case SAFE_TRANSFER: strlcpy(msg->version, "Transfer", msg->versionLength); diff --git a/src_plugins/erc1155/erc1155_plugin.h b/src_plugins/erc1155/erc1155_plugin.h index eb174bdc8..a60dab69b 100644 --- a/src_plugins/erc1155/erc1155_plugin.h +++ b/src_plugins/erc1155/erc1155_plugin.h @@ -7,7 +7,7 @@ #include #include "ethUstream.h" #include "uint256.h" -#include "nft.h" +#include "asset_info.h" // Internal plugin for EIP 1155: https://eips.ethereum.org/EIPS/eip-1155 diff --git a/src_plugins/erc1155/erc1155_provide_parameters.c b/src_plugins/erc1155/erc1155_provide_parameters.c index 8b5e1cacd..454f9a233 100644 --- a/src_plugins/erc1155/erc1155_provide_parameters.c +++ b/src_plugins/erc1155/erc1155_provide_parameters.c @@ -2,9 +2,9 @@ #include #include "erc1155_plugin.h" +#include "plugin_utils.h" #include "eth_plugin_internal.h" -#include "utils.h" -#include "ethUtils.h" +#include "common_utils.h" static void handle_safe_transfer(ethPluginProvideParameter_t *msg, erc1155_context_t *context) { uint8_t new_value[INT256_LENGTH]; diff --git a/src_plugins/erc1155/erc1155_ui.c b/src_plugins/erc1155/erc1155_ui.c index 43067045f..a31dd966c 100644 --- a/src_plugins/erc1155/erc1155_ui.c +++ b/src_plugins/erc1155/erc1155_ui.c @@ -2,9 +2,9 @@ #include #include "erc1155_plugin.h" +#include "eth_plugin_internal.h" #include "eth_plugin_interface.h" -#include "ethUtils.h" -#include "utils.h" +#include "common_utils.h" static void set_approval_for_all_ui(ethQueryContractUI_t *msg, erc1155_context_t *context) { switch (msg->screenIndex) { @@ -14,11 +14,13 @@ static void set_approval_for_all_ui(ethQueryContractUI_t *msg, erc1155_context_t } else { strlcpy(msg->title, "Revoke", msg->titleLength); } - getEthDisplayableAddress(context->address, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(context->address, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 1: strlcpy(msg->title, "To Manage ALL", msg->titleLength); @@ -26,11 +28,13 @@ static void set_approval_for_all_ui(ethQueryContractUI_t *msg, erc1155_context_t break; case 2: strlcpy(msg->title, "NFT Address", msg->titleLength); - getEthDisplayableAddress(msg->item1->nft.contractAddress, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(msg->item1->nft.contractAddress, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; default: PRINTF("Unsupported screen index %d\n", msg->screenIndex); @@ -43,11 +47,13 @@ static void set_transfer_ui(ethQueryContractUI_t *msg, erc1155_context_t *contex switch (msg->screenIndex) { case 0: strlcpy(msg->title, "To", msg->titleLength); - getEthDisplayableAddress(context->address, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(context->address, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 1: strlcpy(msg->title, "Collection Name", msg->titleLength); @@ -55,22 +61,28 @@ static void set_transfer_ui(ethQueryContractUI_t *msg, erc1155_context_t *contex break; case 2: strlcpy(msg->title, "NFT Address", msg->titleLength); - getEthDisplayableAddress(msg->item1->nft.contractAddress, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(msg->item1->nft.contractAddress, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 3: strlcpy(msg->title, "NFT ID", msg->titleLength); - uint256_to_decimal(context->tokenId, - sizeof(context->tokenId), - msg->msg, - msg->msgLength); + if (!uint256_to_decimal(context->tokenId, + sizeof(context->tokenId), + msg->msg, + msg->msgLength)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 4: strlcpy(msg->title, "Quantity", msg->titleLength); - tostring256(&context->value, 10, msg->msg, msg->msgLength); + if (!tostring256(&context->value, 10, msg->msg, msg->msgLength)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; default: PRINTF("Unsupported screen index %d\n", msg->screenIndex); @@ -85,11 +97,13 @@ static void set_batch_transfer_ui(ethQueryContractUI_t *msg, erc1155_context_t * switch (msg->screenIndex) { case 0: strlcpy(msg->title, "To", msg->titleLength); - getEthDisplayableAddress(context->address, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(context->address, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 1: strlcpy(msg->title, "Collection Name", msg->titleLength); @@ -97,15 +111,20 @@ static void set_batch_transfer_ui(ethQueryContractUI_t *msg, erc1155_context_t * break; case 2: strlcpy(msg->title, "NFT Address", msg->titleLength); - getEthDisplayableAddress(msg->item1->nft.contractAddress, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(msg->item1->nft.contractAddress, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 3: strlcpy(msg->title, "Total Quantity", msg->titleLength); - tostring256(&context->value, 10, &quantity_str[0], sizeof(quantity_str)); + if (!tostring256(&context->value, 10, &quantity_str[0], sizeof(quantity_str))) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + break; + } snprintf(msg->msg, msg->msgLength, "%s from %d NFT IDs", diff --git a/src_plugins/erc20/erc20_plugin.c b/src_plugins/erc20/erc20_plugin.c index 220e05f9d..e5b1ba008 100644 --- a/src_plugins/erc20/erc20_plugin.c +++ b/src_plugins/erc20/erc20_plugin.c @@ -2,9 +2,9 @@ #include "eth_plugin_internal.h" #include "eth_plugin_handler.h" #include "shared_context.h" -#include "ethUtils.h" +#include "plugin_utils.h" #include "ethUstream.h" -#include "utils.h" +#include "common_utils.h" typedef enum { ERC20_TRANSFER = 0, ERC20_APPROVE } erc20Selector_t; @@ -73,23 +73,6 @@ bool check_contract(erc20_parameters_t *context) { return false; } -bool erc20_plugin_available_check() { -#ifdef HAVE_STARKWARE - if (quantumSet) { - switch (dataContext.tokenContext.quantumType) { - case STARK_QUANTUM_LEGACY: - case STARK_QUANTUM_ETH: - case STARK_QUANTUM_ERC20: - case STARK_QUANTUM_MINTABLE_ERC20: - return true; - default: - return false; - } - } -#endif - return true; -} - void erc20_plugin_call(int message, void *parameters) { switch (message) { case ETH_PLUGIN_INIT_CONTRACT: { @@ -201,12 +184,14 @@ void erc20_plugin_call(int message, void *parameters) { strlcpy(msg->msg, "Unlimited ", msg->msgLength); strlcat(msg->msg, context->ticker, msg->msgLength); } else { - amountToString(context->amount, - sizeof(context->amount), - context->decimals, - context->ticker, - msg->msg, - 100); + if (!amountToString(context->amount, + sizeof(context->amount), + context->decimals, + context->ticker, + msg->msg, + 100)) { + THROW(EXCEPTION_OVERFLOW); + } } msg->result = ETH_PLUGIN_RESULT_OK; break; @@ -216,11 +201,13 @@ void erc20_plugin_call(int message, void *parameters) { strlcpy(msg->msg, context->contract_name, msg->msgLength); } else { strlcpy(msg->title, "Address", msg->titleLength); - getEthDisplayableAddress(context->destinationAddress, - msg->msg, - msg->msgLength, - msg->pluginSharedRW->sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(context->destinationAddress, + msg->msg, + msg->msgLength, + msg->pluginSharedRW->sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } } msg->result = ETH_PLUGIN_RESULT_OK; diff --git a/src_plugins/erc721/erc721_plugin.c b/src_plugins/erc721/erc721_plugin.c index 12a0a92ec..bfe12cd9d 100644 --- a/src_plugins/erc721/erc721_plugin.c +++ b/src_plugins/erc721/erc721_plugin.c @@ -1,10 +1,10 @@ #ifdef HAVE_NFT_SUPPORT #include +#include "plugin_utils.h" #include "erc721_plugin.h" #include "eth_plugin_internal.h" #include "eth_plugin_interface.h" -#include "ethUtils.h" #include "eth_plugin_handler.h" static const uint8_t ERC721_APPROVE_SELECTOR[SELECTOR_SIZE] = {0x09, 0x5e, 0xa7, 0xb3}; @@ -116,7 +116,12 @@ static void handle_query_contract_id(void *parameters) { switch (context->selectorIndex) { case SET_APPROVAL_FOR_ALL: case APPROVE: +#ifdef HAVE_NBGL + strlcpy(msg->version, "manage", msg->versionLength); + strlcat(msg->name, " allowance", msg->nameLength); +#else strlcpy(msg->version, "Allowance", msg->versionLength); +#endif break; case SAFE_TRANSFER: case SAFE_TRANSFER_DATA: diff --git a/src_plugins/erc721/erc721_plugin.h b/src_plugins/erc721/erc721_plugin.h index 62870fae5..685c5e9d0 100644 --- a/src_plugins/erc721/erc721_plugin.h +++ b/src_plugins/erc721/erc721_plugin.h @@ -6,7 +6,7 @@ #include #include #include "ethUstream.h" -#include "nft.h" +#include "asset_info.h" // Internal plugin for EIP 721: https://eips.ethereum.org/EIPS/eip-721 diff --git a/src_plugins/erc721/erc721_provide_parameters.c b/src_plugins/erc721/erc721_provide_parameters.c index ac5b8701d..18a19cb6e 100644 --- a/src_plugins/erc721/erc721_provide_parameters.c +++ b/src_plugins/erc721/erc721_provide_parameters.c @@ -1,6 +1,7 @@ #ifdef HAVE_NFT_SUPPORT #include "erc721_plugin.h" +#include "plugin_utils.h" #include "eth_plugin_internal.h" static void handle_approve(ethPluginProvideParameter_t *msg, erc721_context_t *context) { diff --git a/src_plugins/erc721/erc721_ui.c b/src_plugins/erc721/erc721_ui.c index 8fc4c599e..e9480874a 100644 --- a/src_plugins/erc721/erc721_ui.c +++ b/src_plugins/erc721/erc721_ui.c @@ -2,19 +2,21 @@ #include #include "erc721_plugin.h" +#include "eth_plugin_internal.h" #include "eth_plugin_interface.h" -#include "ethUtils.h" -#include "utils.h" +#include "common_utils.h" static void set_approval_ui(ethQueryContractUI_t *msg, erc721_context_t *context) { switch (msg->screenIndex) { case 0: strlcpy(msg->title, "Allow", msg->titleLength); - getEthDisplayableAddress(context->address, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(context->address, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 1: strlcpy(msg->title, "To Manage Your", msg->titleLength); @@ -22,18 +24,22 @@ static void set_approval_ui(ethQueryContractUI_t *msg, erc721_context_t *context break; case 2: strlcpy(msg->title, "NFT Address", msg->titleLength); - getEthDisplayableAddress(msg->item1->nft.contractAddress, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(msg->item1->nft.contractAddress, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 3: strlcpy(msg->title, "NFT ID", msg->titleLength); - uint256_to_decimal(context->tokenId, - sizeof(context->tokenId), - msg->msg, - msg->msgLength); + if (!uint256_to_decimal(context->tokenId, + sizeof(context->tokenId), + msg->msg, + msg->msgLength)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; default: PRINTF("Unsupported screen index %d\n", msg->screenIndex); @@ -50,11 +56,13 @@ static void set_approval_for_all_ui(ethQueryContractUI_t *msg, erc721_context_t } else { strlcpy(msg->title, "Revoke", msg->titleLength); } - getEthDisplayableAddress(context->address, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(context->address, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 1: strlcpy(msg->title, "To Manage ALL", msg->titleLength); @@ -62,11 +70,13 @@ static void set_approval_for_all_ui(ethQueryContractUI_t *msg, erc721_context_t break; case 2: strlcpy(msg->title, "NFT Address", msg->titleLength); - getEthDisplayableAddress(msg->item1->nft.contractAddress, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(msg->item1->nft.contractAddress, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; default: PRINTF("Unsupported screen index %d\n", msg->screenIndex); @@ -79,11 +89,13 @@ static void set_transfer_ui(ethQueryContractUI_t *msg, erc721_context_t *context switch (msg->screenIndex) { case 0: strlcpy(msg->title, "To", msg->titleLength); - getEthDisplayableAddress(context->address, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(context->address, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 1: strlcpy(msg->title, "Collection Name", msg->titleLength); @@ -91,18 +103,22 @@ static void set_transfer_ui(ethQueryContractUI_t *msg, erc721_context_t *context break; case 2: strlcpy(msg->title, "NFT Address", msg->titleLength); - getEthDisplayableAddress(msg->item1->nft.contractAddress, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress(msg->item1->nft.contractAddress, + msg->msg, + msg->msgLength, + &global_sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; case 3: strlcpy(msg->title, "NFT ID", msg->titleLength); - uint256_to_decimal(context->tokenId, - sizeof(context->tokenId), - msg->msg, - msg->msgLength); + if (!uint256_to_decimal(context->tokenId, + sizeof(context->tokenId), + msg->msg, + msg->msgLength)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + } break; default: PRINTF("Unsupported screen index %d\n", msg->screenIndex); diff --git a/src_plugins/eth2/eth2_plugin.c b/src_plugins/eth2/eth2_plugin.c index c93c82ec6..588199ea9 100644 --- a/src_plugins/eth2/eth2_plugin.c +++ b/src_plugins/eth2/eth2_plugin.c @@ -4,8 +4,7 @@ #include "eth_plugin_internal.h" #include "eth_plugin_handler.h" #include "shared_context.h" -#include "ethUtils.h" -#include "utils.h" +#include "common_utils.h" void getEth2PublicKey(uint32_t *bip32Path, uint8_t bip32PathLength, uint8_t *out); @@ -117,11 +116,14 @@ void eth2_plugin_call(int message, void *parameters) { // Use a temporary buffer to store the string representation. char tmp[ETH2_DEPOSIT_PUBKEY_LENGTH]; - getEthDisplayableAddress((uint8_t *) context->deposit_address, - tmp, - sizeof(tmp), - msg->pluginSharedRW->sha3, - chainConfig->chainId); + if (!getEthDisplayableAddress((uint8_t *) context->deposit_address, + tmp, + sizeof(tmp), + msg->pluginSharedRW->sha3, + chainConfig->chainId)) { + msg->result = ETH_PLUGIN_RESULT_ERROR; + return; + } // Copy back the string to the global variable. strlcpy(context->deposit_address, tmp, ETH2_DEPOSIT_PUBKEY_LENGTH); @@ -200,12 +202,14 @@ void eth2_plugin_call(int message, void *parameters) { uint8_t decimals = WEI_TO_ETHER; char *ticker = chainConfig->coinName; strlcpy(msg->title, "Amount", msg->titleLength); - amountToString(tmpContent.txContent.value.value, - tmpContent.txContent.value.length, - decimals, - ticker, - msg->msg, - 100); + if (!amountToString(tmpContent.txContent.value.value, + tmpContent.txContent.value.length, + decimals, + ticker, + msg->msg, + 100)) { + THROW(EXCEPTION_OVERFLOW); + } msg->result = ETH_PLUGIN_RESULT_OK; } break; case 1: { // Deposit pubkey screen diff --git a/src_plugins/starkware/starkware_plugin.c b/src_plugins/starkware/starkware_plugin.c deleted file mode 100644 index 634ea4e53..000000000 --- a/src_plugins/starkware/starkware_plugin.c +++ /dev/null @@ -1,929 +0,0 @@ -#include -#include "os_io_seproxyhal.h" -#include "eth_plugin_interface.h" -#include "shared_context.h" // TODO : rewrite as independant code -#include "eth_plugin_internal.h" // TODO : rewrite as independant code -#include "stark_utils.h" -#include "utils.h" -#include "ethUtils.h" - -#ifdef HAVE_STARKWARE - -typedef enum { - - STARKWARE_REGISTER = 0, - STARKWARE_DEPOSIT_TOKEN, - STARKWARE_DEPOSIT_ETH, - STARKWARE_DEPOSIT_CANCEL, - STARKWARE_DEPOSIT_RECLAIM, - STARKWARE_WITHDRAW, - STARKWARE_FULL_WITHDRAW, - STARKWARE_FREEZE, - STARKWARE_ESCAPE, - STARKWARE_VERIFY_ESCAPE, - STARKWARE_WITHDRAW_TO, - STARKWARE_DEPOSIT_NFT, - STARKWARE_DEPOSIT_NFT_RECLAIM, - STARKWARE_WITHDRAW_AND_MINT, - STARKWARE_WITHDRAW_NFT, - STARKWARE_WITHDRAW_NFT_TO, - STARKWARE_REGISTER_AND_DEPOSIT_TOKEN, - STARKWARE_REGISTER_AND_DEPOSIT_ETH, - STARKWARE_PROXY_DEPOSIT_TOKEN, - STARKWARE_PROXY_DEPOSIT_ETH, -} starkwareSelector_t; - -#ifndef HAVE_TOKENS_EXTRA_LIST - -static const uint8_t DEVERSIFI_CONTRACT[] = { - 0x02, - - 0x5d, 0x22, 0x04, 0x5d, 0xac, 0xea, 0xb0, 0x3b, 0x15, 0x80, - 0x31, 0xec, 0xb7, 0xd9, 0xd0, 0x6f, 0xad, 0x24, 0x60, 0x9b, - - 0x7d, 0xe1, 0xf0, 0x42, 0x04, 0xef, 0x29, 0x22, 0x9d, 0x84, - 0xe7, 0xc0, 0xc2, 0xd1, 0x21, 0x6c, 0x28, 0x64, 0x5a, 0x15}; - -#else - -static const uint8_t DEVERSIFI_CONTRACT[] = { - 0x02, 0xe7, 0x3a, 0x39, 0x4a, 0xde, 0x4d, 0x94, 0xa0, 0x73, 0x50, 0x2d, 0xa8, 0x70, - 0x3e, 0xa2, 0x34, 0x90, 0xdc, 0x7b, 0x6a, 0x69, 0xC6, 0x39, 0x2E, 0xb0, 0x2a, 0x28, - 0x82, 0x31, 0x41, 0x34, 0xc9, 0x8D, 0xDC, 0xBF, 0x73, 0xB7, 0xAd, 0xBa, 0xb1}; - -#endif - -// register : address (20), stark key (32), drop param 3 -// Registration -// Contract Name -// From ETH address -// Master account -// deposit token : stark key (32), verify assetType (32), vaultId (4), quantized Amount (32) -// Deposit -// Contract Name -// Master Account -// Token Account -// Amount -// deposit : stark key (32), verify assetType (32), vaultId (4) -// Flow similar to deposit -// deposit cancel, deposit reclaim : stark key (32), assetType (reclaim) / assetId (cancel) (32) -// ignored, vaultId(4) full withdrawal, freeze : stark key (32), vaultId (4) Cancel Deposit | -// Reclaim Deposit | Full Withdrawal | Freeze Contract Name Master Account Token Account -// withdrawal : stark key (32), verify assetType (32) -// Withdrawal -// Contract Name -// Master Account -// To Eth Address -// Token Symbol -// withdrawal to : stark key (32), verify assetType (32), address (20) -// Withdrawal To -// Contract Name -// Master Account -// To Eth Address -// Token Symbol -// escape : stark key (32), vaultId (4), verify assetType (32), quantized Amount (32) -// Escape -// Contract Name -// Amount -// Master Account -// Token Account -// verify escape : escapeProof (ignore) -// Verify Escape -// Contract Name -// deposit NFT : stark key (32), verify assetType (32), vault id (4), token id (32) -// Deposit -// Contract Name -// Master Account -// Token Account -// NFT Contract -// Token ID -// deposit NFT reclaim : stark key (32), verify assetType (32), vault id (4), token id (32) -// Reclaim Deposit -// Contract Name -// Master Account -// Token Account -// NFT Contract -// Token ID -// withdraw and mint : stark key (32), verify assetType (32), mintable blob (ignored variable) -// Withdrawal -// Contract Name -// Master Account -// Asset Contract -// withdraw NFT : stark key (32), verify assetType (32), token id (32) -// Withdrawal -// Contract Name -// Master Account -// To Eth Address -// NFT Contract -// Token ID -// withdraw NFT To : stark key (32), verify assetType (32), token id (32), address (20) -// Withdrawal To -// Contract Name -// Master Account -// To Eth Address -// NFT Contract -// Token ID -// register and deposit token : stark key (32), variable signature, verify assetType (32), vault Id -// (4), quantized amount (32), token address (20), quantum (32) Register and deposit Contract Name -// From ETH address -// Master account -// Token Account -// Amount -// register and deposit : stark key (32), variable signature, verify assetType (32), vault Id (4) -// flow similar to register and deposit -// deposit token proxy : stark key (32), verify assetType (32), vault Id (4), quantized Amount (32), -// token address (20), quantum (32) flow similar to deposit deposit proxy : stark key (32), verify -// assetType (32), vault Id (4) flow similar to deposit - -static const uint8_t STARKWARE_EXPECTED_DATA_SIZE[] = {0, - 4 + 32 + 32 + 32 + 32, - 4 + 32 + 32 + 32, - 4 + 32 + 32 + 32, - 4 + 32 + 32 + 32, - 4 + 32 + 32, - 4 + 32 + 32, - 4 + 32 + 32, - 4 + 32 + 32 + 32 + 32, - 0, - 4 + 32 + 32 + 32, - 4 + 32 + 32 + 32 + 32, - 4 + 32 + 32 + 32 + 32, - 0, - 4 + 32 + 32 + 32, - 4 + 32 + 32 + 32 + 32, - 0, - 0, - 4 + 32 + 32 + 32 + 32 + 32 + 32, - 4 + 32 + 32 + 32}; - -static const uint8_t STARKWARE_NUM_SCREENS[] = {4 - 1, 5 - 1, 5 - 1, 4 - 1, 4 - 1, 5 - 1, 4 - 1, - 4 - 1, 5 - 1, 2 - 1, 5 - 1, 6 - 1, 6 - 1, 4 - 1, - 6 - 1, 6 - 1, 6 - 1, 6 - 1, 5 - 1, 5 - 1}; - -typedef struct starkware_parameters_t { - uint8_t vaultId[4]; - uint8_t selectorIndex; - uint8_t starkKey[32]; - uint8_t amount[32]; - uint8_t validToken; - -} starkware_parameters_t; - -#define STARK_KEY_LENGTH (2 + length * 2 + 1) -#define VAULT_ID_LENGTH 10 - -bool is_deversify_contract(const uint8_t *address) { - uint32_t offset = 0; - uint8_t i; - - for (i = 0; i < DEVERSIFI_CONTRACT[0]; i++) { - if (memcmp(address, DEVERSIFI_CONTRACT + offset + 1, 20) == 0) { - return true; - } - offset += 20; - } - return false; -} - -// TODO : rewrite as independant code -bool starkware_verify_asset_id(uint8_t *tmp32, const uint8_t *tokenId, bool assetTypeOnly) { - if (quantumSet) { - cx_sha3_t sha3; - tokenDefinition_t *currentToken = NULL; - if (dataContext.tokenContext.quantumIndex != MAX_ITEMS) { - currentToken = - &tmpCtx.transactionContext.extraInfo[dataContext.tokenContext.quantumIndex].token; - } - cx_keccak_init(&sha3, 256); - compute_token_id(&sha3, - (currentToken != NULL ? currentToken->address : NULL), - dataContext.tokenContext.quantumType, - dataContext.tokenContext.quantum, - dataContext.tokenContext.mintingBlob, - assetTypeOnly, - tmp32); - if (memcmp(tokenId, tmp32, 32) != 0) { - PRINTF("Token ID not matching - computed %.*H\n", 32, tmp32); - PRINTF("Current quantum %.*H\n", 32, dataContext.tokenContext.quantum); - PRINTF("Requested %.*H\n", 32, tokenId); - return false; - } - } else { - PRINTF("Quantum not set\n"); - return false; - } - return true; -} - -bool starkware_verify_token(const uint8_t *token) { - if (quantumSet) { - if (dataContext.tokenContext.quantumIndex != MAX_ITEMS) { - tokenDefinition_t *currentToken = - &tmpCtx.transactionContext.extraInfo[dataContext.tokenContext.quantumIndex].token; - if (memcmp(token + 32 - 20, currentToken->address, 20) != 0) { - PRINTF("Token not matching got %.*H\n", 20, token + 32 - 20); - PRINTF("Current token %.*H\n", 20, currentToken->address); - return false; - } - } else { - PRINTF("Quantum not set\n"); - return false; - } - } else { - PRINTF("Quantum not set\n"); - return false; - } - return true; -} - -bool starkware_verify_quantum(const uint8_t *quantum) { - if (quantumSet) { - if (dataContext.tokenContext.quantumIndex != MAX_ITEMS) { - if (memcmp(quantum, dataContext.tokenContext.quantum, 32) != 0) { - PRINTF("Quantum not matching got %.*H\n", 32, quantum); - PRINTF("Current quantum %.*H\n", 32, dataContext.tokenContext.quantum); - return false; - } - } else { - PRINTF("Quantum not set\n"); - return false; - } - } else { - PRINTF("Quantum not set\n"); - return false; - } - return true; -} - -bool starkware_verify_nft_token_id(const uint8_t *tokenId) { - if (!quantumSet) { - PRINTF("Quantum not set\n"); - return false; - } - switch (dataContext.tokenContext.quantumType) { - case STARK_QUANTUM_ERC721: - case STARK_QUANTUM_MINTABLE_ERC721: - break; - default: - PRINTF("Unexpected quantum type for NFT token id check %d\n", - dataContext.tokenContext.quantumType); - return false; - } - if (memcmp(dataContext.tokenContext.quantum, tokenId, 32) != 0) { - PRINTF("Token ID not matching - expected %.*H\n", 32, dataContext.tokenContext.quantum); - PRINTF("Current token ID %.*H\n", 32, tokenId); - return false; - } - return true; -} - -void starkware_print_vault_id(uint32_t vaultId, char *destination, size_t max_length) { - if (VAULT_ID_LENGTH > max_length) { - os_sched_exit(EXCEPTION_OVERFLOW); - } - snprintf(destination, max_length, "%d", vaultId); -} - -void starkware_print_stark_key(uint8_t *starkKey, - size_t length, - char *destination, - size_t max_length) { - if (STARK_KEY_LENGTH > max_length) { - os_sched_exit(EXCEPTION_OVERFLOW); - } - snprintf(destination, max_length, "0x%.*H", length, starkKey); -} - -// TODO : rewrite as independant code -void starkware_print_amount(uint8_t *amountData, - char *destination, - size_t destinationLength, - bool forEscape) { - uint256_t amount, amountPre, quantum; - uint8_t decimals; - char *ticker = chainConfig->coinName; - - if ((amountData == NULL) || - (forEscape && (dataContext.tokenContext.quantumIndex == MAX_ITEMS))) { - decimals = WEI_TO_ETHER; - if (!forEscape) { - convertUint256BE(tmpContent.txContent.value.value, - tmpContent.txContent.value.length, - &amount); - } else { - readu256BE(amountData, &amountPre); - } - } else { - tokenDefinition_t *token = - &tmpCtx.transactionContext.extraInfo[dataContext.tokenContext.quantumIndex].token; - decimals = token->decimals; - ticker = token->ticker; - readu256BE(amountData, &amountPre); - } - if (amountData != NULL) { - readu256BE(dataContext.tokenContext.quantum, &quantum); - mul256(&amountPre, &quantum, &amount); - } - tostring256(&amount, 10, (char *) (G_io_apdu_buffer + 100), 100); - strlcpy(destination, ticker, destinationLength); - strlcat(destination, " ", destinationLength); - adjustDecimals((char *) (G_io_apdu_buffer + 100), - strlen((char *) (G_io_apdu_buffer + 100)), - destination + strlen(ticker) + 1, - destinationLength - strlen(ticker) - 1, - decimals); -} - -// TODO : rewrite as independant code -void starkware_print_ticker(char *destination, size_t destinationLength) { - char *ticker = chainConfig->coinName; - - if (dataContext.tokenContext.quantumIndex != MAX_ITEMS) { - tokenDefinition_t *token = - &tmpCtx.transactionContext.extraInfo[dataContext.tokenContext.quantumIndex].token; - ticker = token->ticker; - } - strlcpy(destination, ticker, destinationLength); -} - -// TODO : rewrite as independant code -void starkware_print_asset_contract(char *destination, size_t destinationLength) { - // token has been validated to be present previously - if (dataContext.tokenContext.quantumIndex != MAX_ITEMS) { - tokenDefinition_t *token = - &tmpCtx.transactionContext.extraInfo[dataContext.tokenContext.quantumIndex].token; - getEthDisplayableAddress(token->address, - destination, - destinationLength, - &global_sha3, - chainConfig->chainId); - } else { - strlcpy(destination, "UNKNOWN", destinationLength); - } -} - -// TODO : rewrite as independant code -void starkware_get_source_address(char *destination) { - uint8_t privateKeyData[INT256_LENGTH]; - cx_ecfp_private_key_t privateKey; - cx_ecfp_public_key_t publicKey; - os_perso_derive_node_bip32(CX_CURVE_256K1, - tmpCtx.transactionContext.bip32.path, - tmpCtx.transactionContext.bip32.length, - privateKeyData, - NULL); - cx_ecfp_init_private_key(CX_CURVE_256K1, privateKeyData, 32, &privateKey); - io_seproxyhal_io_heartbeat(); - cx_ecfp_generate_pair(CX_CURVE_256K1, &publicKey, &privateKey, 1); - explicit_bzero(&privateKey, sizeof(privateKey)); - explicit_bzero(privateKeyData, sizeof(privateKeyData)); - io_seproxyhal_io_heartbeat(); - destination[0] = '0'; - destination[1] = 'x'; - getEthAddressStringFromKey(&publicKey, destination + 2, &global_sha3, chainConfig->chainId); - destination[42] = '\0'; -} - -void starkware_plugin_call(int message, void *parameters) { - switch (message) { - case ETH_PLUGIN_INIT_CONTRACT: { - uint8_t i; - ethPluginInitContract_t *msg = (ethPluginInitContract_t *) parameters; - starkware_parameters_t *context = (starkware_parameters_t *) msg->pluginContext; - PRINTF("starkware plugin init\n"); - for (i = 0; i < NUM_STARKWARE_SELECTORS; i++) { - if (memcmp((const void *) PIC(STARKWARE_SELECTORS[i]), - msg->selector, - SELECTOR_SIZE) == 0) { - context->selectorIndex = i; - break; - } - } - if (i == NUM_STARKWARE_SELECTORS) { - PRINTF("Unknown selector %.*H\n", SELECTOR_SIZE, msg->selector); - break; - } - if (STARKWARE_EXPECTED_DATA_SIZE[context->selectorIndex] != 0) { - if (msg->dataSize != STARKWARE_EXPECTED_DATA_SIZE[context->selectorIndex]) { - PRINTF("Unexpected data size for command %d expected %d got %d\n", - context->selectorIndex, - STARKWARE_EXPECTED_DATA_SIZE[context->selectorIndex], - msg->dataSize); - break; - } - } - context->validToken = true; - msg->result = ETH_PLUGIN_RESULT_OK; - } break; - - case ETH_PLUGIN_PROVIDE_PARAMETER: { - ethPluginProvideParameter_t *msg = (ethPluginProvideParameter_t *) parameters; - starkware_parameters_t *context = (starkware_parameters_t *) msg->pluginContext; - PRINTF("starkware plugin provide parameter %d %.*H\n", - msg->parameterOffset, - 32, - msg->parameter); - // Ignore for verify escape - if (context->selectorIndex == STARKWARE_VERIFY_ESCAPE) { - msg->result = ETH_PLUGIN_RESULT_OK; - break; - } - switch (msg->parameterOffset) { - case 4: - switch (context->selectorIndex) { - case STARKWARE_REGISTER: - memmove(context->amount, msg->parameter + 32 - 20, 20); - break; - - case STARKWARE_DEPOSIT_TOKEN: - case STARKWARE_DEPOSIT_ETH: - case STARKWARE_DEPOSIT_CANCEL: - case STARKWARE_DEPOSIT_RECLAIM: - case STARKWARE_WITHDRAW: - case STARKWARE_FULL_WITHDRAW: - case STARKWARE_FREEZE: - case STARKWARE_ESCAPE: - case STARKWARE_WITHDRAW_TO: - case STARKWARE_DEPOSIT_NFT: - case STARKWARE_DEPOSIT_NFT_RECLAIM: - case STARKWARE_WITHDRAW_AND_MINT: - case STARKWARE_WITHDRAW_NFT: - case STARKWARE_WITHDRAW_NFT_TO: - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - case STARKWARE_PROXY_DEPOSIT_TOKEN: - case STARKWARE_PROXY_DEPOSIT_ETH: - memmove(context->starkKey, msg->parameter, 32); - break; - - default: - break; - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - case 4 + 32: - switch (context->selectorIndex) { - case STARKWARE_REGISTER: - memmove(context->starkKey, msg->parameter, 32); - break; - - case STARKWARE_ESCAPE: - memmove(context->vaultId, msg->parameter + 32 - 4, 4); - break; - - case STARKWARE_DEPOSIT_CANCEL: - case STARKWARE_DEPOSIT_RECLAIM: - break; - - case STARKWARE_FULL_WITHDRAW: - case STARKWARE_FREEZE: - memmove(context->vaultId, msg->parameter + 32 - 4, 4); - break; - - case STARKWARE_DEPOSIT_ETH: - case STARKWARE_DEPOSIT_TOKEN: - case STARKWARE_WITHDRAW: - case STARKWARE_WITHDRAW_TO: - case STARKWARE_DEPOSIT_NFT: - case STARKWARE_DEPOSIT_NFT_RECLAIM: - case STARKWARE_WITHDRAW_AND_MINT: - case STARKWARE_WITHDRAW_NFT: - case STARKWARE_WITHDRAW_NFT_TO: - case STARKWARE_PROXY_DEPOSIT_TOKEN: - case STARKWARE_PROXY_DEPOSIT_ETH: - context->validToken = - starkware_verify_asset_id(context->amount, msg->parameter, true); - break; - - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - // drop variable byte array signature offset - break; - - default: - break; - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - case 4 + 32 + 32: - switch (context->selectorIndex) { - case STARKWARE_ESCAPE: - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - context->validToken = - starkware_verify_asset_id(context->amount, msg->parameter, true); - break; - - case STARKWARE_DEPOSIT_CANCEL: - case STARKWARE_DEPOSIT_RECLAIM: - case STARKWARE_DEPOSIT_ETH: - case STARKWARE_DEPOSIT_TOKEN: - case STARKWARE_DEPOSIT_NFT: - case STARKWARE_DEPOSIT_NFT_RECLAIM: - case STARKWARE_PROXY_DEPOSIT_TOKEN: - case STARKWARE_PROXY_DEPOSIT_ETH: - memmove(context->vaultId, msg->parameter + 32 - 4, 4); - break; - - case STARKWARE_WITHDRAW_TO: - memmove(context->amount, msg->parameter + 32 - 20, 20); - break; - - case STARKWARE_WITHDRAW_NFT: - case STARKWARE_WITHDRAW_NFT_TO: - context->validToken = starkware_verify_nft_token_id(msg->parameter); - break; - - default: - break; - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - case 4 + 32 + 32 + 32: - switch (context->selectorIndex) { - case STARKWARE_ESCAPE: - case STARKWARE_DEPOSIT_TOKEN: - case STARKWARE_PROXY_DEPOSIT_TOKEN: - memmove(context->amount, msg->parameter, 32); - break; - - case STARKWARE_WITHDRAW_NFT_TO: - memmove(context->amount, msg->parameter + 32 - 20, 20); - break; - - case STARKWARE_DEPOSIT_NFT: - case STARKWARE_DEPOSIT_NFT_RECLAIM: - context->validToken = starkware_verify_nft_token_id(msg->parameter); - break; - - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - memmove(context->vaultId, msg->parameter + 32 - 4, 4); - break; - - default: - break; - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - case 4 + 32 + 32 + 32 + 32: - switch (context->selectorIndex) { - switch (context->selectorIndex) { - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - memmove(context->amount, msg->parameter, 32); - break; - - case STARKWARE_PROXY_DEPOSIT_TOKEN: - context->validToken = starkware_verify_token(msg->parameter); - break; - - default: - break; - } - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - case 4 + 32 + 32 + 32 + 32 + 32: - switch (context->selectorIndex) { - switch (context->selectorIndex) { - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - context->validToken = starkware_verify_token(msg->parameter); - break; - - case STARKWARE_PROXY_DEPOSIT_TOKEN: - context->validToken = starkware_verify_quantum(msg->parameter); - break; - - default: - break; - } - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - case 4 + 32 + 32 + 32 + 32 + 32 + 32: - switch (context->selectorIndex) { - switch (context->selectorIndex) { - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - context->validToken = starkware_verify_quantum(msg->parameter); - break; - - default: - break; - } - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - default: - switch (context->selectorIndex) { - case STARKWARE_REGISTER: - case STARKWARE_VERIFY_ESCAPE: - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - default: - PRINTF("Unhandled parameter offset\n"); - break; - } - } - } break; - - case ETH_PLUGIN_FINALIZE: { - ethPluginFinalize_t *msg = (ethPluginFinalize_t *) parameters; - starkware_parameters_t *context = (starkware_parameters_t *) msg->pluginContext; - PRINTF("starkware plugin finalize\n"); - if (!context->validToken) { - msg->result = ETH_PLUGIN_RESULT_FALLBACK; - } else { - msg->uiType = ETH_UI_TYPE_GENERIC; - msg->numScreens = STARKWARE_NUM_SCREENS[context->selectorIndex]; - msg->result = ETH_PLUGIN_RESULT_OK; - } - } break; - - case ETH_PLUGIN_QUERY_CONTRACT_ID: { - ethQueryContractID_t *msg = (ethQueryContractID_t *) parameters; - starkware_parameters_t *context = (starkware_parameters_t *) msg->pluginContext; - PRINTF("starkware query contract id\n"); - switch (context->selectorIndex) { - case STARKWARE_REGISTER: - strlcpy(msg->name, "Register", msg->nameLength); - break; - case STARKWARE_DEPOSIT_TOKEN: - case STARKWARE_DEPOSIT_ETH: - case STARKWARE_DEPOSIT_NFT: - case STARKWARE_PROXY_DEPOSIT_TOKEN: - case STARKWARE_PROXY_DEPOSIT_ETH: - strlcpy(msg->name, "Deposit", msg->nameLength); - break; - case STARKWARE_DEPOSIT_CANCEL: - strlcpy(msg->name, "Cancel Deposit", msg->nameLength); - break; - case STARKWARE_DEPOSIT_RECLAIM: - case STARKWARE_DEPOSIT_NFT_RECLAIM: - strlcpy(msg->name, "Reclaim Deposit", msg->nameLength); - break; - case STARKWARE_WITHDRAW: - case STARKWARE_WITHDRAW_NFT: - case STARKWARE_WITHDRAW_AND_MINT: - strlcpy(msg->name, "Withdrawal", msg->nameLength); - break; - case STARKWARE_FULL_WITHDRAW: - strlcpy(msg->name, "Full Withdrawal", msg->nameLength); - break; - case STARKWARE_FREEZE: - strlcpy(msg->name, "Freeze", msg->nameLength); - break; - case STARKWARE_ESCAPE: - strlcpy(msg->name, "Escape", msg->nameLength); - break; - case STARKWARE_VERIFY_ESCAPE: - strlcpy(msg->name, "Verify Escape", msg->nameLength); - break; - case STARKWARE_WITHDRAW_TO: - case STARKWARE_WITHDRAW_NFT_TO: - strlcpy(msg->name, "Withdrawal To", msg->nameLength); - break; - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - strlcpy(msg->name, "Register&Deposit", msg->nameLength); - break; - - default: - break; - } - strlcpy( - msg->version, - is_deversify_contract(tmpContent.txContent.destination) ? "DeversiFi" : "Starkware", - msg->versionLength); - msg->result = ETH_PLUGIN_RESULT_OK; - } break; - - case ETH_PLUGIN_QUERY_CONTRACT_UI: { - ethQueryContractUI_t *msg = (ethQueryContractUI_t *) parameters; - starkware_parameters_t *context = (starkware_parameters_t *) msg->pluginContext; - switch (msg->screenIndex) { - case 0: - strlcpy(msg->title, "Contract Name", msg->titleLength); - if (is_deversify_contract(tmpContent.txContent.destination)) { - strlcpy(msg->msg, "DeversiFi", msg->msgLength); - } else { - getEthDisplayableAddress(tmpContent.txContent.destination, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - case 1: - switch (context->selectorIndex) { - case STARKWARE_REGISTER: - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - strlcpy(msg->title, "From ETH Address", msg->titleLength); - getEthDisplayableAddress(context->amount, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); - break; - case STARKWARE_ESCAPE: - strlcpy(msg->title, "Amount", msg->titleLength); - starkware_print_amount(context->amount, msg->msg, msg->msgLength, true); - break; - case STARKWARE_DEPOSIT_TOKEN: - case STARKWARE_DEPOSIT_ETH: - case STARKWARE_PROXY_DEPOSIT_TOKEN: - case STARKWARE_PROXY_DEPOSIT_ETH: - case STARKWARE_DEPOSIT_CANCEL: - case STARKWARE_DEPOSIT_RECLAIM: - case STARKWARE_WITHDRAW: - case STARKWARE_FULL_WITHDRAW: - case STARKWARE_FREEZE: - case STARKWARE_VERIFY_ESCAPE: - case STARKWARE_WITHDRAW_TO: - case STARKWARE_DEPOSIT_NFT: - case STARKWARE_DEPOSIT_NFT_RECLAIM: - case STARKWARE_WITHDRAW_AND_MINT: - case STARKWARE_WITHDRAW_NFT: - case STARKWARE_WITHDRAW_NFT_TO: - strlcpy(msg->title, "Master Account", msg->titleLength); - starkware_print_stark_key(context->starkKey, - sizeof(context->starkKey), - msg->msg, - msg->msgLength); - break; - default: - PRINTF("Unexpected screen %d for %d\n", - msg->screenIndex, - context->selectorIndex); - break; - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - case 2: - switch (context->selectorIndex) { - case STARKWARE_REGISTER: - case STARKWARE_ESCAPE: - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - strlcpy(msg->title, "Master Account", msg->titleLength); - starkware_print_stark_key(context->starkKey, - sizeof(context->starkKey), - msg->msg, - msg->msgLength); - break; - - case STARKWARE_DEPOSIT_TOKEN: - case STARKWARE_DEPOSIT_ETH: - case STARKWARE_PROXY_DEPOSIT_TOKEN: - case STARKWARE_PROXY_DEPOSIT_ETH: - case STARKWARE_DEPOSIT_CANCEL: - case STARKWARE_DEPOSIT_RECLAIM: - case STARKWARE_FULL_WITHDRAW: - case STARKWARE_FREEZE: - case STARKWARE_DEPOSIT_NFT: - case STARKWARE_DEPOSIT_NFT_RECLAIM: - strlcpy(msg->title, "Token Account", msg->titleLength); - starkware_print_vault_id(U4BE(context->vaultId, 0), - msg->msg, - msg->msgLength); - break; - case STARKWARE_WITHDRAW: - case STARKWARE_WITHDRAW_NFT: - strlcpy(msg->title, "To ETH Address", msg->titleLength); - starkware_get_source_address(msg->msg); - break; - case STARKWARE_WITHDRAW_TO: - case STARKWARE_WITHDRAW_NFT_TO: - strlcpy(msg->title, "To ETH Address", msg->titleLength); - getEthDisplayableAddress(context->amount, - msg->msg, - msg->msgLength, - &global_sha3, - chainConfig->chainId); - break; - case STARKWARE_WITHDRAW_AND_MINT: - strlcpy(msg->title, "Asset Contract", msg->titleLength); - starkware_print_asset_contract(msg->msg, msg->msgLength); - break; - - default: - PRINTF("Unexpected screen %d for %d\n", - msg->screenIndex, - context->selectorIndex); - break; - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - case 3: - switch (context->selectorIndex) { - case STARKWARE_ESCAPE: - strlcpy(msg->title, "Token Account", msg->titleLength); - starkware_print_vault_id(U4BE(context->vaultId, 0), - msg->msg, - msg->msgLength); - break; - case STARKWARE_DEPOSIT_TOKEN: - case STARKWARE_DEPOSIT_ETH: - case STARKWARE_PROXY_DEPOSIT_TOKEN: - case STARKWARE_PROXY_DEPOSIT_ETH: - strlcpy(msg->title, "Amount", msg->titleLength); - starkware_print_amount( - (((context->selectorIndex == STARKWARE_DEPOSIT_ETH) || - (context->selectorIndex == STARKWARE_PROXY_DEPOSIT_ETH)) - ? NULL - : context->amount), - msg->msg, - msg->msgLength, - false); - break; - case STARKWARE_WITHDRAW: - case STARKWARE_WITHDRAW_TO: - strlcpy(msg->title, "Token Symbol", msg->titleLength); - starkware_print_ticker(msg->msg, msg->msgLength); - break; - - case STARKWARE_WITHDRAW_NFT: - case STARKWARE_WITHDRAW_NFT_TO: - case STARKWARE_DEPOSIT_NFT: - case STARKWARE_DEPOSIT_NFT_RECLAIM: - strlcpy(msg->title, "NFT Contract", msg->titleLength); - starkware_print_asset_contract(msg->msg, msg->msgLength); - break; - - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - strlcpy(msg->title, "Token Account", msg->titleLength); - starkware_print_vault_id(U4BE(context->vaultId, 0), - msg->msg, - msg->msgLength); - break; - - default: - PRINTF("Unexpected screen %d for %d\n", - msg->screenIndex, - context->selectorIndex); - break; - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - case 4: - switch (context->selectorIndex) { - case STARKWARE_WITHDRAW_NFT: - case STARKWARE_WITHDRAW_NFT_TO: - case STARKWARE_DEPOSIT_NFT: - case STARKWARE_DEPOSIT_NFT_RECLAIM: - strlcpy(msg->title, "TokenID", msg->titleLength); - starkware_print_stark_key(dataContext.tokenContext.quantum, - sizeof(dataContext.tokenContext.quantum), - msg->msg, - msg->msgLength); - break; - - case STARKWARE_REGISTER_AND_DEPOSIT_TOKEN: - case STARKWARE_REGISTER_AND_DEPOSIT_ETH: - strlcpy(msg->title, "Amount", msg->titleLength); - starkware_print_amount( - ((context->selectorIndex == STARKWARE_REGISTER_AND_DEPOSIT_ETH) - ? NULL - : context->amount), - msg->msg, - msg->msgLength, - false); - break; - - default: - PRINTF("Unexpected screen %d for %d\n", - msg->screenIndex, - context->selectorIndex); - break; - } - msg->result = ETH_PLUGIN_RESULT_OK; - break; - - default: - PRINTF("Unexpected screen %d for %d\n", - msg->screenIndex, - context->selectorIndex); - break; - } - } break; - - default: - PRINTF("Unhandled message %d\n", message); - } -} - -#endif diff --git a/tests/ragger/abis/erc1155.json b/tests/ragger/abis/erc1155.json new file mode 100644 index 000000000..6f8e6ab25 --- /dev/null +++ b/tests/ragger/abis/erc1155.json @@ -0,0 +1,276 @@ +[ + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "_owner", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "_operator", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "bool", + "name" : "_approved", + "type" : "bool" + } + ], + "name" : "ApprovalForAll", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "_operator", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "_from", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256[]", + "name" : "_ids", + "type" : "uint256[]" + }, + { + "indexed" : false, + "internalType" : "uint256[]", + "name" : "_values", + "type" : "uint256[]" + } + ], + "name" : "TransferBatch", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "_operator", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "_from", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "_id", + "type" : "uint256" + }, + { + "indexed" : false, + "internalType" : "uint256", + "name" : "_value", + "type" : "uint256" + } + ], + "name" : "TransferSingle", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : false, + "internalType" : "string", + "name" : "_value", + "type" : "string" + }, + { + "indexed" : true, + "internalType" : "uint256", + "name" : "_id", + "type" : "uint256" + } + ], + "name" : "URI", + "type" : "event" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_owner", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "_id", + "type" : "uint256" + } + ], + "name" : "balanceOf", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address[]", + "name" : "_owners", + "type" : "address[]" + }, + { + "internalType" : "uint256[]", + "name" : "_ids", + "type" : "uint256[]" + } + ], + "name" : "balanceOfBatch", + "outputs" : [ + { + "internalType" : "uint256[]", + "name" : "", + "type" : "uint256[]" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_owner", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "_operator", + "type" : "address" + } + ], + "name" : "isApprovedForAll", + "outputs" : [ + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_from", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "internalType" : "uint256[]", + "name" : "_ids", + "type" : "uint256[]" + }, + { + "internalType" : "uint256[]", + "name" : "_values", + "type" : "uint256[]" + }, + { + "internalType" : "bytes", + "name" : "_data", + "type" : "bytes" + } + ], + "name" : "safeBatchTransferFrom", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_from", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "_id", + "type" : "uint256" + }, + { + "internalType" : "uint256", + "name" : "_value", + "type" : "uint256" + }, + { + "internalType" : "bytes", + "name" : "_data", + "type" : "bytes" + } + ], + "name" : "safeTransferFrom", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_operator", + "type" : "address" + }, + { + "internalType" : "bool", + "name" : "_approved", + "type" : "bool" + } + ], + "name" : "setApprovalForAll", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + } +] diff --git a/tests/ragger/abis/erc20.json b/tests/ragger/abis/erc20.json new file mode 100644 index 000000000..301b94656 --- /dev/null +++ b/tests/ragger/abis/erc20.json @@ -0,0 +1,135 @@ +[ + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_owner", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "_spender", + "type" : "address" + } + ], + "name" : "allowance", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "remaining", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_spender", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "_value", + "type" : "uint256" + } + ], + "name" : "approve", + "outputs" : [ + { + "internalType" : "bool", + "name" : "success", + "type" : "bool" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_owner", + "type" : "address" + } + ], + "name" : "balanceOf", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "balance", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [], + "name" : "totalSupply", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "_value", + "type" : "uint256" + } + ], + "name" : "transfer", + "outputs" : [ + { + "internalType" : "bool", + "name" : "success", + "type" : "bool" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_from", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "_value", + "type" : "uint256" + } + ], + "name" : "transferFrom", + "outputs" : [ + { + "internalType" : "bool", + "name" : "success", + "type" : "bool" + } + ], + "stateMutability" : "nonpayable", + "type" : "function" + } +] diff --git a/tests/ragger/abis/erc721.json b/tests/ragger/abis/erc721.json new file mode 100644 index 000000000..b6f583563 --- /dev/null +++ b/tests/ragger/abis/erc721.json @@ -0,0 +1,268 @@ +[ + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "_owner", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "_approved", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "uint256", + "name" : "_tokenId", + "type" : "uint256" + } + ], + "name" : "Approval", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "_owner", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "_operator", + "type" : "address" + }, + { + "indexed" : false, + "internalType" : "bool", + "name" : "_approved", + "type" : "bool" + } + ], + "name" : "ApprovalForAll", + "type" : "event" + }, + { + "anonymous" : false, + "inputs" : [ + { + "indexed" : true, + "internalType" : "address", + "name" : "_from", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "indexed" : true, + "internalType" : "uint256", + "name" : "_tokenId", + "type" : "uint256" + } + ], + "name" : "Transfer", + "type" : "event" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_approved", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "_tokenId", + "type" : "uint256" + } + ], + "name" : "approve", + "outputs" : [], + "stateMutability" : "payable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_owner", + "type" : "address" + } + ], + "name" : "balanceOf", + "outputs" : [ + { + "internalType" : "uint256", + "name" : "", + "type" : "uint256" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "uint256", + "name" : "_tokenId", + "type" : "uint256" + } + ], + "name" : "getApproved", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_owner", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "_operator", + "type" : "address" + } + ], + "name" : "isApprovedForAll", + "outputs" : [ + { + "internalType" : "bool", + "name" : "", + "type" : "bool" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "uint256", + "name" : "_tokenId", + "type" : "uint256" + } + ], + "name" : "ownerOf", + "outputs" : [ + { + "internalType" : "address", + "name" : "", + "type" : "address" + } + ], + "stateMutability" : "view", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_from", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "_tokenId", + "type" : "uint256" + } + ], + "name" : "safeTransferFrom", + "outputs" : [], + "stateMutability" : "payable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_from", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "_tokenId", + "type" : "uint256" + }, + { + "internalType" : "bytes", + "name" : "data", + "type" : "bytes" + } + ], + "name" : "safeTransferFrom", + "outputs" : [], + "stateMutability" : "payable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_operator", + "type" : "address" + }, + { + "internalType" : "bool", + "name" : "_approved", + "type" : "bool" + } + ], + "name" : "setApprovalForAll", + "outputs" : [], + "stateMutability" : "nonpayable", + "type" : "function" + }, + { + "inputs" : [ + { + "internalType" : "address", + "name" : "_from", + "type" : "address" + }, + { + "internalType" : "address", + "name" : "_to", + "type" : "address" + }, + { + "internalType" : "uint256", + "name" : "_tokenId", + "type" : "uint256" + } + ], + "name" : "transferFrom", + "outputs" : [], + "stateMutability" : "payable", + "type" : "function" + } +] diff --git a/tests/ragger/app/client.py b/tests/ragger/app/client.py deleted file mode 100644 index 616670c0a..000000000 --- a/tests/ragger/app/client.py +++ /dev/null @@ -1,143 +0,0 @@ -from enum import IntEnum, auto -from typing import Optional -from ragger.backend import BackendInterface -from ragger.utils import RAPDU -from .command_builder import CommandBuilder -from .eip712 import EIP712FieldType -from .tlv import format_tlv -from pathlib import Path -import keychain -import rlp - - -ROOT_SCREENSHOT_PATH = Path(__file__).parent.parent -WEI_IN_ETH = 1e+18 - - -class StatusWord(IntEnum): - OK = 0x9000 - ERROR_NO_INFO = 0x6a00 - INVALID_DATA = 0x6a80 - INSUFFICIENT_MEMORY = 0x6a84 - INVALID_INS = 0x6d00 - INVALID_P1_P2 = 0x6b00 - CONDITION_NOT_SATISFIED = 0x6985 - REF_DATA_NOT_FOUND = 0x6a88 - -class DOMAIN_NAME_TAG(IntEnum): - STRUCTURE_TYPE = 0x01 - STRUCTURE_VERSION = 0x02 - CHALLENGE = 0x12 - SIGNER_KEY_ID = 0x13 - SIGNER_ALGO = 0x14 - SIGNATURE = 0x15 - DOMAIN_NAME = 0x20 - COIN_TYPE = 0x21 - ADDRESS = 0x22 - - -class EthAppClient: - def __init__(self, client: BackendInterface): - self._client = client - self._cmd_builder = CommandBuilder() - - def _send(self, payload: bytearray): - return self._client.exchange_async_raw(payload) - - def response(self) -> RAPDU: - return self._client._last_async_response - - def eip712_send_struct_def_struct_name(self, name: str): - return self._send(self._cmd_builder.eip712_send_struct_def_struct_name(name)) - - def eip712_send_struct_def_struct_field(self, - field_type: EIP712FieldType, - type_name: str, - type_size: int, - array_levels: [], - key_name: str): - return self._send(self._cmd_builder.eip712_send_struct_def_struct_field( - field_type, - type_name, - type_size, - array_levels, - key_name)) - - def eip712_send_struct_impl_root_struct(self, name: str): - return self._send(self._cmd_builder.eip712_send_struct_impl_root_struct(name)) - - def eip712_send_struct_impl_array(self, size: int): - return self._send(self._cmd_builder.eip712_send_struct_impl_array(size)) - - def eip712_send_struct_impl_struct_field(self, raw_value: bytes): - chunks = self._cmd_builder.eip712_send_struct_impl_struct_field(raw_value) - for chunk in chunks[:-1]: - with self._send(chunk): - pass - return self._send(chunks[-1]) - - def eip712_sign_new(self, bip32_path: str, verbose: bool): - return self._send(self._cmd_builder.eip712_sign_new(bip32_path)) - - def eip712_sign_legacy(self, - bip32_path: str, - domain_hash: bytes, - message_hash: bytes): - return self._send(self._cmd_builder.eip712_sign_legacy(bip32_path, - domain_hash, - message_hash)) - - def eip712_filtering_activate(self): - return self._send(self._cmd_builder.eip712_filtering_activate()) - - def eip712_filtering_message_info(self, name: str, filters_count: int, sig: bytes): - return self._send(self._cmd_builder.eip712_filtering_message_info(name, filters_count, sig)) - - def eip712_filtering_show_field(self, name: str, sig: bytes): - return self._send(self._cmd_builder.eip712_filtering_show_field(name, sig)) - - def send_fund(self, - bip32_path: str, - nonce: int, - gas_price: int, - gas_limit: int, - to: bytes, - amount: float, - chain_id: int): - data = list() - data.append(nonce) - data.append(gas_price) - data.append(gas_limit) - data.append(to) - data.append(int(amount * WEI_IN_ETH)) - data.append(bytes()) - data.append(chain_id) - data.append(bytes()) - data.append(bytes()) - - chunks = self._cmd_builder.sign(bip32_path, rlp.encode(data)) - for chunk in chunks[:-1]: - with self._send(chunk): - pass - return self._send(chunks[-1]) - - def get_challenge(self): - return self._send(self._cmd_builder.get_challenge()) - - def provide_domain_name(self, challenge: int, name: str, addr: bytes): - payload = format_tlv(DOMAIN_NAME_TAG.STRUCTURE_TYPE, 3) # TrustedDomainName - payload += format_tlv(DOMAIN_NAME_TAG.STRUCTURE_VERSION, 1) - payload += format_tlv(DOMAIN_NAME_TAG.SIGNER_KEY_ID, 0) # test key - payload += format_tlv(DOMAIN_NAME_TAG.SIGNER_ALGO, 1) # secp256k1 - payload += format_tlv(DOMAIN_NAME_TAG.CHALLENGE, challenge) - payload += format_tlv(DOMAIN_NAME_TAG.COIN_TYPE, 0x3c) # ETH in slip-44 - payload += format_tlv(DOMAIN_NAME_TAG.DOMAIN_NAME, name) - payload += format_tlv(DOMAIN_NAME_TAG.ADDRESS, addr) - payload += format_tlv(DOMAIN_NAME_TAG.SIGNATURE, - keychain.sign_data(keychain.Key.DOMAIN_NAME, payload)) - - chunks = self._cmd_builder.provide_domain_name(payload) - for chunk in chunks[:-1]: - with self._send(chunk): - pass - return self._send(chunks[-1]) diff --git a/tests/ragger/app/response_parser.py b/tests/ragger/app/response_parser.py deleted file mode 100644 index 5e73df498..000000000 --- a/tests/ragger/app/response_parser.py +++ /dev/null @@ -1,14 +0,0 @@ -def signature(data: bytes) -> tuple[bytes, bytes, bytes]: - assert len(data) == (1 + 32 + 32) - - v = data[0:1] - data = data[1:] - r = data[0:32] - data = data[32:] - s = data[0:32] - - return v, r, s - -def challenge(data: bytes) -> int: - assert len(data) == 4 - return int.from_bytes(data, "big") diff --git a/tests/ragger/client b/tests/ragger/client new file mode 120000 index 000000000..96cd109b0 --- /dev/null +++ b/tests/ragger/client @@ -0,0 +1 @@ +../../client \ No newline at end of file diff --git a/tests/ragger/constants.py b/tests/ragger/constants.py new file mode 100644 index 000000000..0f375a71f --- /dev/null +++ b/tests/ragger/constants.py @@ -0,0 +1,5 @@ +from pathlib import Path +import os + +ROOT_SNAPSHOT_PATH = Path(__file__).parent +ABIS_FOLDER = "%s/abis" % (os.path.dirname(__file__)) diff --git a/tests/ragger/eip712/input_files/00-simple_mail-data.json b/tests/ragger/eip712_input_files/00-simple_mail-data.json similarity index 100% rename from tests/ragger/eip712/input_files/00-simple_mail-data.json rename to tests/ragger/eip712_input_files/00-simple_mail-data.json diff --git a/tests/ragger/eip712/input_files/00-simple_mail-filter.json b/tests/ragger/eip712_input_files/00-simple_mail-filter.json similarity index 100% rename from tests/ragger/eip712/input_files/00-simple_mail-filter.json rename to tests/ragger/eip712_input_files/00-simple_mail-filter.json diff --git a/tests/ragger/eip712/input_files/00-simple_mail.ini b/tests/ragger/eip712_input_files/00-simple_mail.ini similarity index 100% rename from tests/ragger/eip712/input_files/00-simple_mail.ini rename to tests/ragger/eip712_input_files/00-simple_mail.ini diff --git a/tests/ragger/eip712/input_files/01-addresses_array_mail-data.json b/tests/ragger/eip712_input_files/01-addresses_array_mail-data.json similarity index 100% rename from tests/ragger/eip712/input_files/01-addresses_array_mail-data.json rename to tests/ragger/eip712_input_files/01-addresses_array_mail-data.json diff --git a/tests/ragger/eip712/input_files/01-addresses_array_mail.ini b/tests/ragger/eip712_input_files/01-addresses_array_mail.ini similarity index 100% rename from tests/ragger/eip712/input_files/01-addresses_array_mail.ini rename to tests/ragger/eip712_input_files/01-addresses_array_mail.ini diff --git a/tests/ragger/eip712/input_files/02-recipients_array_mail-data.json b/tests/ragger/eip712_input_files/02-recipients_array_mail-data.json similarity index 100% rename from tests/ragger/eip712/input_files/02-recipients_array_mail-data.json rename to tests/ragger/eip712_input_files/02-recipients_array_mail-data.json diff --git a/tests/ragger/eip712/input_files/02-recipients_array_mail.ini b/tests/ragger/eip712_input_files/02-recipients_array_mail.ini similarity index 100% rename from tests/ragger/eip712/input_files/02-recipients_array_mail.ini rename to tests/ragger/eip712_input_files/02-recipients_array_mail.ini diff --git a/tests/ragger/eip712/input_files/03-long_string-data.json b/tests/ragger/eip712_input_files/03-long_string-data.json similarity index 100% rename from tests/ragger/eip712/input_files/03-long_string-data.json rename to tests/ragger/eip712_input_files/03-long_string-data.json diff --git a/tests/ragger/eip712/input_files/03-long_string.ini b/tests/ragger/eip712_input_files/03-long_string.ini similarity index 100% rename from tests/ragger/eip712/input_files/03-long_string.ini rename to tests/ragger/eip712_input_files/03-long_string.ini diff --git a/tests/ragger/eip712/input_files/04-long_bytes-data.json b/tests/ragger/eip712_input_files/04-long_bytes-data.json similarity index 100% rename from tests/ragger/eip712/input_files/04-long_bytes-data.json rename to tests/ragger/eip712_input_files/04-long_bytes-data.json diff --git a/tests/ragger/eip712/input_files/04-long_bytes.ini b/tests/ragger/eip712_input_files/04-long_bytes.ini similarity index 100% rename from tests/ragger/eip712/input_files/04-long_bytes.ini rename to tests/ragger/eip712_input_files/04-long_bytes.ini diff --git a/tests/ragger/eip712/input_files/05-signed_ints-data.json b/tests/ragger/eip712_input_files/05-signed_ints-data.json similarity index 100% rename from tests/ragger/eip712/input_files/05-signed_ints-data.json rename to tests/ragger/eip712_input_files/05-signed_ints-data.json diff --git a/tests/ragger/eip712/input_files/05-signed_ints.ini b/tests/ragger/eip712_input_files/05-signed_ints.ini similarity index 100% rename from tests/ragger/eip712/input_files/05-signed_ints.ini rename to tests/ragger/eip712_input_files/05-signed_ints.ini diff --git a/tests/ragger/eip712/input_files/06-boolean-data.json b/tests/ragger/eip712_input_files/06-boolean-data.json similarity index 100% rename from tests/ragger/eip712/input_files/06-boolean-data.json rename to tests/ragger/eip712_input_files/06-boolean-data.json diff --git a/tests/ragger/eip712/input_files/06-boolean.ini b/tests/ragger/eip712_input_files/06-boolean.ini similarity index 100% rename from tests/ragger/eip712/input_files/06-boolean.ini rename to tests/ragger/eip712_input_files/06-boolean.ini diff --git a/tests/ragger/eip712/input_files/07-fixed_bytes-data.json b/tests/ragger/eip712_input_files/07-fixed_bytes-data.json similarity index 100% rename from tests/ragger/eip712/input_files/07-fixed_bytes-data.json rename to tests/ragger/eip712_input_files/07-fixed_bytes-data.json diff --git a/tests/ragger/eip712/input_files/07-fixed_bytes.ini b/tests/ragger/eip712_input_files/07-fixed_bytes.ini similarity index 100% rename from tests/ragger/eip712/input_files/07-fixed_bytes.ini rename to tests/ragger/eip712_input_files/07-fixed_bytes.ini diff --git a/tests/ragger/eip712/input_files/08-opensea-data.json b/tests/ragger/eip712_input_files/08-opensea-data.json similarity index 100% rename from tests/ragger/eip712/input_files/08-opensea-data.json rename to tests/ragger/eip712_input_files/08-opensea-data.json diff --git a/tests/ragger/eip712/input_files/08-opensea-filter.json b/tests/ragger/eip712_input_files/08-opensea-filter.json similarity index 100% rename from tests/ragger/eip712/input_files/08-opensea-filter.json rename to tests/ragger/eip712_input_files/08-opensea-filter.json diff --git a/tests/ragger/eip712/input_files/08-opensea.ini b/tests/ragger/eip712_input_files/08-opensea.ini similarity index 100% rename from tests/ragger/eip712/input_files/08-opensea.ini rename to tests/ragger/eip712_input_files/08-opensea.ini diff --git a/tests/ragger/eip712/input_files/09-rarible-data.json b/tests/ragger/eip712_input_files/09-rarible-data.json similarity index 100% rename from tests/ragger/eip712/input_files/09-rarible-data.json rename to tests/ragger/eip712_input_files/09-rarible-data.json diff --git a/tests/ragger/eip712/input_files/09-rarible.ini b/tests/ragger/eip712_input_files/09-rarible.ini similarity index 100% rename from tests/ragger/eip712/input_files/09-rarible.ini rename to tests/ragger/eip712_input_files/09-rarible.ini diff --git a/tests/ragger/eip712/input_files/10-multidimensional_arrays-data.json b/tests/ragger/eip712_input_files/10-multidimensional_arrays-data.json similarity index 100% rename from tests/ragger/eip712/input_files/10-multidimensional_arrays-data.json rename to tests/ragger/eip712_input_files/10-multidimensional_arrays-data.json diff --git a/tests/ragger/eip712/input_files/10-multidimensional_arrays.ini b/tests/ragger/eip712_input_files/10-multidimensional_arrays.ini similarity index 100% rename from tests/ragger/eip712/input_files/10-multidimensional_arrays.ini rename to tests/ragger/eip712_input_files/10-multidimensional_arrays.ini diff --git a/tests/ragger/eip712/input_files/11-complex_structs-data.json b/tests/ragger/eip712_input_files/11-complex_structs-data.json similarity index 100% rename from tests/ragger/eip712/input_files/11-complex_structs-data.json rename to tests/ragger/eip712_input_files/11-complex_structs-data.json diff --git a/tests/ragger/eip712/input_files/11-complex_structs-filter.json b/tests/ragger/eip712_input_files/11-complex_structs-filter.json similarity index 100% rename from tests/ragger/eip712/input_files/11-complex_structs-filter.json rename to tests/ragger/eip712_input_files/11-complex_structs-filter.json diff --git a/tests/ragger/eip712/input_files/11-complex_structs.ini b/tests/ragger/eip712_input_files/11-complex_structs.ini similarity index 100% rename from tests/ragger/eip712/input_files/11-complex_structs.ini rename to tests/ragger/eip712_input_files/11-complex_structs.ini diff --git a/tests/ragger/eip712/input_files/12-sign_in-data.json b/tests/ragger/eip712_input_files/12-sign_in-data.json similarity index 100% rename from tests/ragger/eip712/input_files/12-sign_in-data.json rename to tests/ragger/eip712_input_files/12-sign_in-data.json diff --git a/tests/ragger/eip712/input_files/12-sign_in-filter.json b/tests/ragger/eip712_input_files/12-sign_in-filter.json similarity index 100% rename from tests/ragger/eip712/input_files/12-sign_in-filter.json rename to tests/ragger/eip712_input_files/12-sign_in-filter.json diff --git a/tests/ragger/eip712/input_files/12-sign_in.ini b/tests/ragger/eip712_input_files/12-sign_in.ini similarity index 100% rename from tests/ragger/eip712/input_files/12-sign_in.ini rename to tests/ragger/eip712_input_files/12-sign_in.ini diff --git a/tests/ragger/eip712/input_files/13-empty_arrays-data.json b/tests/ragger/eip712_input_files/13-empty_arrays-data.json similarity index 100% rename from tests/ragger/eip712/input_files/13-empty_arrays-data.json rename to tests/ragger/eip712_input_files/13-empty_arrays-data.json diff --git a/tests/ragger/eip712/input_files/13-empty_arrays.ini b/tests/ragger/eip712_input_files/13-empty_arrays.ini similarity index 100% rename from tests/ragger/eip712/input_files/13-empty_arrays.ini rename to tests/ragger/eip712_input_files/13-empty_arrays.ini diff --git a/tests/ragger/eip712_input_files/address_substitution.json b/tests/ragger/eip712_input_files/address_substitution.json new file mode 100644 index 000000000..3cff494e8 --- /dev/null +++ b/tests/ragger/eip712_input_files/address_substitution.json @@ -0,0 +1,29 @@ +{ + "domain": { + "chainId": 1, + "name": "Token test", + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", + "version": "1" + }, + "message": { + "from": "0xaAaAaAaaAaAaAaaAaAAAAAAAAaaaAaAaAaaAaaAa", + "to": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", + "amount": "117", + "token": "0x6B175474E89094C44Da98b954EedeAC495271d0F" + }, + "primaryType": "Transfer", + "types": { + "EIP712Domain": [ + { "name": "name", "type": "string" }, + { "name": "version", "type": "string" }, + { "name": "chainId", "type": "uint256" }, + { "name": "verifyingContract", "type": "address" } + ], + "Transfer": [ + { "name": "from", "type": "address" }, + { "name": "to", "type": "address" }, + { "name": "amount", "type": "uint256" }, + { "name": "token", "type": "address" } + ] + } +} diff --git a/tests/ragger/requirements.txt b/tests/ragger/requirements.txt index 34213d69f..1149a7528 100644 --- a/tests/ragger/requirements.txt +++ b/tests/ragger/requirements.txt @@ -1,4 +1,3 @@ -ragger[speculos] pytest ecdsa -simple-rlp +./client/ diff --git a/tests/ragger/snapshots/nanos/blind-signed_approval/00000.png b/tests/ragger/snapshots/nanos/blind-signed_approval/00000.png new file mode 100644 index 000000000..c2420afe1 Binary files /dev/null and b/tests/ragger/snapshots/nanos/blind-signed_approval/00000.png differ diff --git a/tests/ragger/snapshots/nanos/blind-signed_approval/00001.png b/tests/ragger/snapshots/nanos/blind-signed_approval/00001.png new file mode 100644 index 000000000..b31e45596 Binary files /dev/null and b/tests/ragger/snapshots/nanos/blind-signed_approval/00001.png differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00016.png b/tests/ragger/snapshots/nanos/blind-signed_approval/00002.png similarity index 100% rename from tests/zemu/snapshots/nanos_starkware_usdt_deposit/00016.png rename to tests/ragger/snapshots/nanos/blind-signed_approval/00002.png diff --git a/tests/ragger/snapshots/nanos/get_pk_1/00000.png b/tests/ragger/snapshots/nanos/get_pk_1/00000.png new file mode 100644 index 000000000..63778c416 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_1/00000.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_1/00001.png b/tests/ragger/snapshots/nanos/get_pk_1/00001.png new file mode 100644 index 000000000..7c0b047e7 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_1/00001.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_1/00002.png b/tests/ragger/snapshots/nanos/get_pk_1/00002.png new file mode 100644 index 000000000..94d88887f Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_1/00002.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_1/00003.png b/tests/ragger/snapshots/nanos/get_pk_1/00003.png new file mode 100644 index 000000000..1fbf36d3b Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_1/00003.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_1/00004.png b/tests/ragger/snapshots/nanos/get_pk_1/00004.png new file mode 100644 index 000000000..66c411c2e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_1/00004.png differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00012.png b/tests/ragger/snapshots/nanos/get_pk_1/00005.png similarity index 100% rename from tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00012.png rename to tests/ragger/snapshots/nanos/get_pk_1/00005.png diff --git a/tests/ragger/snapshots/nanos/get_pk_137/00000.png b/tests/ragger/snapshots/nanos/get_pk_137/00000.png new file mode 100644 index 000000000..63778c416 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_137/00000.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_137/00001.png b/tests/ragger/snapshots/nanos/get_pk_137/00001.png new file mode 100644 index 000000000..7c0b047e7 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_137/00001.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_137/00002.png b/tests/ragger/snapshots/nanos/get_pk_137/00002.png new file mode 100644 index 000000000..94d88887f Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_137/00002.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_137/00003.png b/tests/ragger/snapshots/nanos/get_pk_137/00003.png new file mode 100644 index 000000000..1fbf36d3b Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_137/00003.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_137/00004.png b/tests/ragger/snapshots/nanos/get_pk_137/00004.png new file mode 100644 index 000000000..66c411c2e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_137/00004.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_137/00005.png b/tests/ragger/snapshots/nanos/get_pk_137/00005.png new file mode 100644 index 000000000..ce795f34e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_137/00005.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_2/00000.png b/tests/ragger/snapshots/nanos/get_pk_2/00000.png new file mode 100644 index 000000000..63778c416 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_2/00000.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_2/00001.png b/tests/ragger/snapshots/nanos/get_pk_2/00001.png new file mode 100644 index 000000000..7c0b047e7 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_2/00001.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_2/00002.png b/tests/ragger/snapshots/nanos/get_pk_2/00002.png new file mode 100644 index 000000000..94d88887f Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_2/00002.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_2/00003.png b/tests/ragger/snapshots/nanos/get_pk_2/00003.png new file mode 100644 index 000000000..1fbf36d3b Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_2/00003.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_2/00004.png b/tests/ragger/snapshots/nanos/get_pk_2/00004.png new file mode 100644 index 000000000..66c411c2e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_2/00004.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_2/00005.png b/tests/ragger/snapshots/nanos/get_pk_2/00005.png new file mode 100644 index 000000000..ce795f34e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_2/00005.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_5/00000.png b/tests/ragger/snapshots/nanos/get_pk_5/00000.png new file mode 100644 index 000000000..63778c416 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_5/00000.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_5/00001.png b/tests/ragger/snapshots/nanos/get_pk_5/00001.png new file mode 100644 index 000000000..7c0b047e7 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_5/00001.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_5/00002.png b/tests/ragger/snapshots/nanos/get_pk_5/00002.png new file mode 100644 index 000000000..94d88887f Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_5/00002.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_5/00003.png b/tests/ragger/snapshots/nanos/get_pk_5/00003.png new file mode 100644 index 000000000..1fbf36d3b Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_5/00003.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_5/00004.png b/tests/ragger/snapshots/nanos/get_pk_5/00004.png new file mode 100644 index 000000000..66c411c2e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_5/00004.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_5/00005.png b/tests/ragger/snapshots/nanos/get_pk_5/00005.png new file mode 100644 index 000000000..ce795f34e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_5/00005.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_None/00000.png b/tests/ragger/snapshots/nanos/get_pk_None/00000.png new file mode 100644 index 000000000..63778c416 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_None/00000.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_None/00001.png b/tests/ragger/snapshots/nanos/get_pk_None/00001.png new file mode 100644 index 000000000..7c0b047e7 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_None/00001.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_None/00002.png b/tests/ragger/snapshots/nanos/get_pk_None/00002.png new file mode 100644 index 000000000..94d88887f Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_None/00002.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_None/00003.png b/tests/ragger/snapshots/nanos/get_pk_None/00003.png new file mode 100644 index 000000000..1fbf36d3b Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_None/00003.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_None/00004.png b/tests/ragger/snapshots/nanos/get_pk_None/00004.png new file mode 100644 index 000000000..66c411c2e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_None/00004.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_None/00005.png b/tests/ragger/snapshots/nanos/get_pk_None/00005.png new file mode 100644 index 000000000..ce795f34e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_None/00005.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_rejected/00000.png b/tests/ragger/snapshots/nanos/get_pk_rejected/00000.png new file mode 100644 index 000000000..63778c416 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_rejected/00000.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_rejected/00001.png b/tests/ragger/snapshots/nanos/get_pk_rejected/00001.png new file mode 100644 index 000000000..7c0b047e7 Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_rejected/00001.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_rejected/00002.png b/tests/ragger/snapshots/nanos/get_pk_rejected/00002.png new file mode 100644 index 000000000..94d88887f Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_rejected/00002.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_rejected/00003.png b/tests/ragger/snapshots/nanos/get_pk_rejected/00003.png new file mode 100644 index 000000000..1fbf36d3b Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_rejected/00003.png differ diff --git a/tests/ragger/snapshots/nanos/get_pk_rejected/00004.png b/tests/ragger/snapshots/nanos/get_pk_rejected/00004.png new file mode 100644 index 000000000..66c411c2e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_rejected/00004.png differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00014.png b/tests/ragger/snapshots/nanos/get_pk_rejected/00005.png similarity index 100% rename from tests/zemu/snapshots/nanos_starkware_usdt_deposit/00014.png rename to tests/ragger/snapshots/nanos/get_pk_rejected/00005.png diff --git a/tests/ragger/snapshots/nanos/get_pk_rejected/00006.png b/tests/ragger/snapshots/nanos/get_pk_rejected/00006.png new file mode 100644 index 000000000..ce795f34e Binary files /dev/null and b/tests/ragger/snapshots/nanos/get_pk_rejected/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/blind-signed_approval/00000.png b/tests/ragger/snapshots/nanosp/blind-signed_approval/00000.png new file mode 100644 index 000000000..11ea8a56b Binary files /dev/null and b/tests/ragger/snapshots/nanosp/blind-signed_approval/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/blind-signed_approval/00001.png b/tests/ragger/snapshots/nanosp/blind-signed_approval/00001.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/blind-signed_approval/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00004.png b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00004.png index 70c1b9a68..1bcb78761 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00004.png and b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00006.png b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00006.png index a58590b98..657887225 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00006.png and b/tests/ragger/snapshots/nanosp/domain_name_non_mainnet/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00001.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00001.png index f9840e3ab..23d61ed89 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00001.png and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00004.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00004.png index 70c1b9a68..c2a8d9070 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00004.png and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00006.png b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00006.png index a58590b98..657887225 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00006.png and b/tests/ragger/snapshots/nanosp/domain_name_unknown_chain/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00003.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00003.png index 70c1b9a68..1bcb78761 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00003.png and b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00005.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00005.png index a58590b98..657887225 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00005.png and b/tests/ragger/snapshots/nanosp/domain_name_verbose_False/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00004.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00004.png index 70c1b9a68..1bcb78761 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00004.png and b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00006.png b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00006.png index a58590b98..657887225 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00006.png and b/tests/ragger/snapshots/nanosp/domain_name_verbose_True/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00003.png b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00003.png index 70c1b9a68..1bcb78761 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00003.png and b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00005.png b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00005.png index a58590b98..657887225 100644 Binary files a/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00005.png and b/tests/ragger/snapshots/nanosp/domain_name_wrong_addr/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution/00000.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00000.png new file mode 100644 index 000000000..b546f65af Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution/00001.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00001.png new file mode 100644 index 000000000..5ea6164a8 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution/00002.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00002.png new file mode 100644 index 000000000..e9adb7c1d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution/00003.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00003.png new file mode 100644 index 000000000..13f8255b9 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution/00004.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00004.png new file mode 100644 index 000000000..6983285c2 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution/00005.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00005.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution/00006.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00006.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00000.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00000.png new file mode 100644 index 000000000..b546f65af Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00001.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00001.png new file mode 100644 index 000000000..7f1fe8adc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00002.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00002.png new file mode 100644 index 000000000..71834ce43 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00003.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00003.png new file mode 100644 index 000000000..25bfb0686 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00004.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00004.png new file mode 100644 index 000000000..a4619ff2c Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00005.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00005.png new file mode 100644 index 000000000..bb49e6dab Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00006.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00006.png new file mode 100644 index 000000000..b9d7e1524 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00007.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00007.png new file mode 100644 index 000000000..2191773cc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00008.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00008.png new file mode 100644 index 000000000..394eff681 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00009.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00009.png new file mode 100644 index 000000000..139d26557 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00010.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00010.png new file mode 100644 index 000000000..aa7c74d61 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00010.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00011.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00011.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00011.png differ diff --git a/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00012.png b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00012.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/eip712_address_substitution_verbose/00012.png differ diff --git a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00000.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00000.png similarity index 100% rename from tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00000.png rename to tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00000.png diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00001.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00001.png new file mode 100644 index 000000000..ba1dfa0e3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00002.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00003.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00003.png new file mode 100644 index 000000000..950fd72aa Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00004.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00004.png new file mode 100644 index 000000000..5906d1967 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00005.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00005.png new file mode 100644 index 000000000..1a9d80bd0 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00006.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00006.png differ diff --git a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00005.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00007.png similarity index 100% rename from tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00005.png rename to tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00007.png diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00008.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_1/00008.png differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00000.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00000.png similarity index 100% rename from tests/zemu/snapshots/nanox_starkware_usdt_deposit/00000.png rename to tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00000.png diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00001.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00001.png new file mode 100644 index 000000000..ba1dfa0e3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00002.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00003.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00003.png new file mode 100644 index 000000000..402128bbd Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00004.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00004.png new file mode 100644 index 000000000..6e50574d2 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00005.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00005.png new file mode 100644 index 000000000..1a9d80bd0 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00006.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00006.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00007.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00007.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00007.png differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00009.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00008.png similarity index 100% rename from tests/zemu/snapshots/nanox_starkware_usdt_deposit/00009.png rename to tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00008.png diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00009.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_137/00009.png differ diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00000.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00000.png similarity index 100% rename from tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00000.png rename to tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00000.png diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00001.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00001.png new file mode 100644 index 000000000..ba1dfa0e3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00002.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00003.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00003.png new file mode 100644 index 000000000..402128bbd Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00004.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00004.png new file mode 100644 index 000000000..417f99b10 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00005.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00005.png new file mode 100644 index 000000000..1a9d80bd0 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00006.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00006.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00007.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00007.png differ diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00005.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00008.png similarity index 100% rename from tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00005.png rename to tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00008.png diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00009.png b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeBatchTransferFrom_5/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00000.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00001.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00002.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00003.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00003.png new file mode 100644 index 000000000..950fd72aa Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00004.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00004.png new file mode 100644 index 000000000..5906d1967 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00005.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00006.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00006.png new file mode 100644 index 000000000..55ce94fdd Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00007.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00008.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00009.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00009.png new file mode 100644 index 000000000..e90cd9db3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00010.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00010.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1-rejected/00010.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00000.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00001.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00002.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00003.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00003.png new file mode 100644 index 000000000..950fd72aa Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00004.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00004.png new file mode 100644 index 000000000..5906d1967 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00005.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00006.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00006.png new file mode 100644 index 000000000..55ce94fdd Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00007.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00008.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00009.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_1/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00000.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00001.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00002.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00003.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00003.png new file mode 100644 index 000000000..402128bbd Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00004.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00004.png new file mode 100644 index 000000000..6e50574d2 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00005.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00006.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00006.png new file mode 100644 index 000000000..55ce94fdd Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00007.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00007.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00008.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00008.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00009.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00009.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00010.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00010.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_137/00010.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00000.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00001.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00002.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00003.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00003.png new file mode 100644 index 000000000..402128bbd Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00004.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00004.png new file mode 100644 index 000000000..417f99b10 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00005.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00006.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00006.png new file mode 100644 index 000000000..55ce94fdd Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00007.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00007.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00008.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00008.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00009.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00009.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00010.png b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00010.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_safeTransferFrom_5/00010.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00000.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00001.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00002.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00003.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00003.png new file mode 100644 index 000000000..c5b41a354 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00004.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00004.png new file mode 100644 index 000000000..5906d1967 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00005.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00005.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00006.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00006.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00007.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00007.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_1/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00000.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00001.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00002.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00003.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00003.png new file mode 100644 index 000000000..e3e9c918d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00004.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00004.png new file mode 100644 index 000000000..6e50574d2 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00005.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00005.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00006.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00006.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00007.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00008.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_137/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00000.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00001.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00002.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00003.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00003.png new file mode 100644 index 000000000..e3e9c918d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00004.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00004.png new file mode 100644 index 000000000..417f99b10 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00005.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00005.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00006.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00007.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00008.png b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc1155_setApprovalForAll_5/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_1/00000.png b/tests/ragger/snapshots/nanosp/erc721_approve_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_1/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_1/00001.png b/tests/ragger/snapshots/nanosp/erc721_approve_1/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_1/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_1/00002.png b/tests/ragger/snapshots/nanosp/erc721_approve_1/00002.png new file mode 100644 index 000000000..ef84a421e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_1/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_1/00003.png b/tests/ragger/snapshots/nanosp/erc721_approve_1/00003.png new file mode 100644 index 000000000..02c6fc77c Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_1/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_1/00004.png b/tests/ragger/snapshots/nanosp/erc721_approve_1/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_1/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_1/00005.png b/tests/ragger/snapshots/nanosp/erc721_approve_1/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_1/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_1/00006.png b/tests/ragger/snapshots/nanosp/erc721_approve_1/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_1/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_1/00007.png b/tests/ragger/snapshots/nanosp/erc721_approve_1/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_1/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_1/00008.png b/tests/ragger/snapshots/nanosp/erc721_approve_1/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_1/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00000.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00001.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00002.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00002.png new file mode 100644 index 000000000..ef84a421e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00003.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00003.png new file mode 100644 index 000000000..4ef9c7d27 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00004.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00004.png new file mode 100644 index 000000000..5ec458c27 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00005.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00006.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00006.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00007.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00007.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00008.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_137/00009.png b/tests/ragger/snapshots/nanosp/erc721_approve_137/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_137/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00000.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00001.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00002.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00002.png new file mode 100644 index 000000000..ef84a421e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00003.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00003.png new file mode 100644 index 000000000..994363ff0 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00004.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00004.png new file mode 100644 index 000000000..694eda507 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00005.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00006.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00006.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00007.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00008.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_approve_5/00009.png b/tests/ragger/snapshots/nanosp/erc721_approve_5/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_approve_5/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00000.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00001.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00002.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00003.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00003.png new file mode 100644 index 000000000..b1d7a7b57 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00004.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00005.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00006.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00007.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00008.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00008.png new file mode 100644 index 000000000..e90cd9db3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00009.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1-rejected/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00000.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00001.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00002.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00003.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00003.png new file mode 100644 index 000000000..b1d7a7b57 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00004.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00005.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00006.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00007.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00008.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_1/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00000.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00001.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00002.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00003.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00003.png new file mode 100644 index 000000000..74c9ac0e7 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00004.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00004.png new file mode 100644 index 000000000..5ec458c27 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00005.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00006.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00006.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00007.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00007.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00008.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00009.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_137/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00000.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00001.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00002.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00003.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00003.png new file mode 100644 index 000000000..3d7d224d3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00004.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00004.png new file mode 100644 index 000000000..694eda507 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00005.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00006.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00006.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00007.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00008.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00009.png b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_safeTransferFrom_5/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00000.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00001.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00002.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00003.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00003.png new file mode 100644 index 000000000..d22cc8c57 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00004.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00005.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00005.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00006.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00006.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00007.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00007.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_1/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00000.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00001.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00002.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00003.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00003.png new file mode 100644 index 000000000..b5fdf8b83 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00004.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00004.png new file mode 100644 index 000000000..5ec458c27 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00005.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00005.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00006.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00006.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00007.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00008.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_137/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00000.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00001.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00002.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00003.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00003.png new file mode 100644 index 000000000..63ae03f4f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00004.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00004.png new file mode 100644 index 000000000..694eda507 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00005.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00005.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00006.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00007.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00008.png b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_setApprovalForAll_5/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00000.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00001.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00002.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00003.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00003.png new file mode 100644 index 000000000..b1d7a7b57 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00004.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00005.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00006.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00007.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00008.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_1/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00000.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00001.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00002.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00003.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00003.png new file mode 100644 index 000000000..74c9ac0e7 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00004.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00004.png new file mode 100644 index 000000000..5ec458c27 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00005.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00006.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00006.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00007.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00007.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00008.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00009.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_137/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00000.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00001.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00002.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00003.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00003.png new file mode 100644 index 000000000..3d7d224d3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00004.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00004.png new file mode 100644 index 000000000..694eda507 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00005.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00006.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00006.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00006.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00007.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00007.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00008.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00008.png differ diff --git a/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00009.png b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/erc721_transferFrom_5/00009.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_1/00000.png b/tests/ragger/snapshots/nanosp/get_pk_1/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_1/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_1/00001.png b/tests/ragger/snapshots/nanosp/get_pk_1/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_1/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_1/00002.png b/tests/ragger/snapshots/nanosp/get_pk_1/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_1/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_1/00003.png b/tests/ragger/snapshots/nanosp/get_pk_1/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_1/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_137/00000.png b/tests/ragger/snapshots/nanosp/get_pk_137/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_137/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_137/00001.png b/tests/ragger/snapshots/nanosp/get_pk_137/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_137/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_137/00002.png b/tests/ragger/snapshots/nanosp/get_pk_137/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_137/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_137/00003.png b/tests/ragger/snapshots/nanosp/get_pk_137/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_137/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_2/00000.png b/tests/ragger/snapshots/nanosp/get_pk_2/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_2/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_2/00001.png b/tests/ragger/snapshots/nanosp/get_pk_2/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_2/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_2/00002.png b/tests/ragger/snapshots/nanosp/get_pk_2/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_2/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_2/00003.png b/tests/ragger/snapshots/nanosp/get_pk_2/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_2/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_5/00000.png b/tests/ragger/snapshots/nanosp/get_pk_5/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_5/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_5/00001.png b/tests/ragger/snapshots/nanosp/get_pk_5/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_5/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_5/00002.png b/tests/ragger/snapshots/nanosp/get_pk_5/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_5/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_5/00003.png b/tests/ragger/snapshots/nanosp/get_pk_5/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_5/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_None/00000.png b/tests/ragger/snapshots/nanosp/get_pk_None/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_None/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_None/00001.png b/tests/ragger/snapshots/nanosp/get_pk_None/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_None/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_None/00002.png b/tests/ragger/snapshots/nanosp/get_pk_None/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_None/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_None/00003.png b/tests/ragger/snapshots/nanosp/get_pk_None/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_None/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_rejected/00000.png b/tests/ragger/snapshots/nanosp/get_pk_rejected/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_rejected/00000.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_rejected/00001.png b/tests/ragger/snapshots/nanosp/get_pk_rejected/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_rejected/00001.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_rejected/00002.png b/tests/ragger/snapshots/nanosp/get_pk_rejected/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_rejected/00002.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_rejected/00003.png b/tests/ragger/snapshots/nanosp/get_pk_rejected/00003.png new file mode 100644 index 000000000..e90cd9db3 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_rejected/00003.png differ diff --git a/tests/ragger/snapshots/nanosp/get_pk_rejected/00004.png b/tests/ragger/snapshots/nanosp/get_pk_rejected/00004.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanosp/get_pk_rejected/00004.png differ diff --git a/tests/ragger/snapshots/nanox/blind-signed_approval/00000.png b/tests/ragger/snapshots/nanox/blind-signed_approval/00000.png new file mode 100644 index 000000000..11ea8a56b Binary files /dev/null and b/tests/ragger/snapshots/nanox/blind-signed_approval/00000.png differ diff --git a/tests/ragger/snapshots/nanox/blind-signed_approval/00001.png b/tests/ragger/snapshots/nanox/blind-signed_approval/00001.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/blind-signed_approval/00001.png differ diff --git a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00001.png b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00001.png index f9840e3ab..23d61ed89 100644 Binary files a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00001.png and b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00001.png differ diff --git a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00004.png b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00004.png index 1bcb78761..c2a8d9070 100644 Binary files a/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00004.png and b/tests/ragger/snapshots/nanox/domain_name_unknown_chain/00004.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution/00000.png b/tests/ragger/snapshots/nanox/eip712_address_substitution/00000.png new file mode 100644 index 000000000..b546f65af Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution/00000.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution/00001.png b/tests/ragger/snapshots/nanox/eip712_address_substitution/00001.png new file mode 100644 index 000000000..5ea6164a8 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution/00001.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution/00002.png b/tests/ragger/snapshots/nanox/eip712_address_substitution/00002.png new file mode 100644 index 000000000..e9adb7c1d Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution/00002.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution/00003.png b/tests/ragger/snapshots/nanox/eip712_address_substitution/00003.png new file mode 100644 index 000000000..13f8255b9 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution/00003.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution/00004.png b/tests/ragger/snapshots/nanox/eip712_address_substitution/00004.png new file mode 100644 index 000000000..6983285c2 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution/00004.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution/00005.png b/tests/ragger/snapshots/nanox/eip712_address_substitution/00005.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution/00005.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution/00006.png b/tests/ragger/snapshots/nanox/eip712_address_substitution/00006.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution/00006.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00000.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00000.png new file mode 100644 index 000000000..b546f65af Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00000.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00001.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00001.png new file mode 100644 index 000000000..7f1fe8adc Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00001.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00002.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00002.png new file mode 100644 index 000000000..71834ce43 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00002.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00003.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00003.png new file mode 100644 index 000000000..25bfb0686 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00003.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00004.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00004.png new file mode 100644 index 000000000..a4619ff2c Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00004.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00005.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00005.png new file mode 100644 index 000000000..bb49e6dab Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00005.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00006.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00006.png new file mode 100644 index 000000000..b9d7e1524 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00006.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00007.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00007.png new file mode 100644 index 000000000..2191773cc Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00007.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00008.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00008.png new file mode 100644 index 000000000..394eff681 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00008.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00009.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00009.png new file mode 100644 index 000000000..139d26557 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00009.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00010.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00010.png new file mode 100644 index 000000000..aa7c74d61 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00010.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00011.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00011.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00011.png differ diff --git a/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00012.png b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00012.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/eip712_address_substitution_verbose/00012.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00000.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00001.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00001.png new file mode 100644 index 000000000..ba1dfa0e3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00002.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00003.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00003.png new file mode 100644 index 000000000..950fd72aa Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00004.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00004.png new file mode 100644 index 000000000..5906d1967 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00005.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00005.png new file mode 100644 index 000000000..1a9d80bd0 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00006.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00007.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00008.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_1/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00000.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00001.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00001.png new file mode 100644 index 000000000..ba1dfa0e3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00002.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00003.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00003.png new file mode 100644 index 000000000..402128bbd Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00004.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00004.png new file mode 100644 index 000000000..6e50574d2 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00005.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00005.png new file mode 100644 index 000000000..1a9d80bd0 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00006.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00006.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00007.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00007.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00008.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00009.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_137/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00000.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00001.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00001.png new file mode 100644 index 000000000..ba1dfa0e3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00002.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00003.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00003.png new file mode 100644 index 000000000..402128bbd Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00004.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00004.png new file mode 100644 index 000000000..417f99b10 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00005.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00005.png new file mode 100644 index 000000000..1a9d80bd0 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00006.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00006.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00007.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00008.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00009.png b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeBatchTransferFrom_5/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00000.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00001.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00002.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00003.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00003.png new file mode 100644 index 000000000..950fd72aa Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00004.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00004.png new file mode 100644 index 000000000..5906d1967 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00005.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00006.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00006.png new file mode 100644 index 000000000..55ce94fdd Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00007.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00008.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00009.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00009.png new file mode 100644 index 000000000..e90cd9db3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00010.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00010.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1-rejected/00010.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00000.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00001.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00002.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00003.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00003.png new file mode 100644 index 000000000..950fd72aa Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00004.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00004.png new file mode 100644 index 000000000..5906d1967 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00005.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00006.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00006.png new file mode 100644 index 000000000..55ce94fdd Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00007.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00008.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00009.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_1/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00000.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00001.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00002.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00003.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00003.png new file mode 100644 index 000000000..402128bbd Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00004.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00004.png new file mode 100644 index 000000000..6e50574d2 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00005.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00006.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00006.png new file mode 100644 index 000000000..55ce94fdd Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00007.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00007.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00008.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00008.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00009.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00009.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00010.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00010.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_137/00010.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00000.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00001.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00002.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00003.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00003.png new file mode 100644 index 000000000..402128bbd Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00004.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00004.png new file mode 100644 index 000000000..417f99b10 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00005.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00006.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00006.png new file mode 100644 index 000000000..55ce94fdd Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00007.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00007.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00008.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00008.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00009.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00009.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00010.png b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00010.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_safeTransferFrom_5/00010.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00000.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00001.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00002.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00003.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00003.png new file mode 100644 index 000000000..c5b41a354 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00004.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00004.png new file mode 100644 index 000000000..5906d1967 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00005.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00005.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00006.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00006.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00007.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00007.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_1/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00000.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00001.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00002.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00003.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00003.png new file mode 100644 index 000000000..e3e9c918d Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00004.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00004.png new file mode 100644 index 000000000..6e50574d2 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00005.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00005.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00006.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00006.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00007.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00008.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_137/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00000.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00001.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00002.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00003.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00003.png new file mode 100644 index 000000000..e3e9c918d Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00004.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00004.png new file mode 100644 index 000000000..417f99b10 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00005.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00005.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00006.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00007.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00008.png b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc1155_setApprovalForAll_5/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_1/00000.png b/tests/ragger/snapshots/nanox/erc721_approve_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_1/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_1/00001.png b/tests/ragger/snapshots/nanox/erc721_approve_1/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_1/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_1/00002.png b/tests/ragger/snapshots/nanox/erc721_approve_1/00002.png new file mode 100644 index 000000000..ef84a421e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_1/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_1/00003.png b/tests/ragger/snapshots/nanox/erc721_approve_1/00003.png new file mode 100644 index 000000000..02c6fc77c Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_1/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_1/00004.png b/tests/ragger/snapshots/nanox/erc721_approve_1/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_1/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_1/00005.png b/tests/ragger/snapshots/nanox/erc721_approve_1/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_1/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_1/00006.png b/tests/ragger/snapshots/nanox/erc721_approve_1/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_1/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_1/00007.png b/tests/ragger/snapshots/nanox/erc721_approve_1/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_1/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_1/00008.png b/tests/ragger/snapshots/nanox/erc721_approve_1/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_1/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00000.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00001.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00002.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00002.png new file mode 100644 index 000000000..ef84a421e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00003.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00003.png new file mode 100644 index 000000000..4ef9c7d27 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00004.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00004.png new file mode 100644 index 000000000..5ec458c27 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00005.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00006.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00006.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00007.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00007.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00008.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_137/00009.png b/tests/ragger/snapshots/nanox/erc721_approve_137/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_137/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00000.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00001.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00002.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00002.png new file mode 100644 index 000000000..ef84a421e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00003.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00003.png new file mode 100644 index 000000000..994363ff0 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00004.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00004.png new file mode 100644 index 000000000..694eda507 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00005.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00006.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00006.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00007.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00008.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_approve_5/00009.png b/tests/ragger/snapshots/nanox/erc721_approve_5/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_approve_5/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00000.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00001.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00002.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00003.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00003.png new file mode 100644 index 000000000..b1d7a7b57 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00004.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00005.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00006.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00007.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00008.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00008.png new file mode 100644 index 000000000..e90cd9db3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00009.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1-rejected/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00000.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00001.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00002.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00003.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00003.png new file mode 100644 index 000000000..b1d7a7b57 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00004.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00005.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00006.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00007.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00008.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_1/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00000.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00001.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00002.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00003.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00003.png new file mode 100644 index 000000000..74c9ac0e7 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00004.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00004.png new file mode 100644 index 000000000..5ec458c27 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00005.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00006.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00006.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00007.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00007.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00008.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00009.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_137/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00000.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00001.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00002.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00003.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00003.png new file mode 100644 index 000000000..3d7d224d3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00004.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00004.png new file mode 100644 index 000000000..694eda507 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00005.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00006.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00006.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00007.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00008.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00009.png b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_safeTransferFrom_5/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00000.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00001.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00002.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00003.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00003.png new file mode 100644 index 000000000..d22cc8c57 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00004.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00005.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00005.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00006.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00006.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00007.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00007.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_1/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00000.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00001.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00002.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00003.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00003.png new file mode 100644 index 000000000..b5fdf8b83 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00004.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00004.png new file mode 100644 index 000000000..5ec458c27 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00005.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00005.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00006.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00006.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00007.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00008.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_137/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00000.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00001.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00001.png new file mode 100644 index 000000000..5a35ae4bf Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00002.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00002.png new file mode 100644 index 000000000..4524ac5c7 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00003.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00003.png new file mode 100644 index 000000000..63ae03f4f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00004.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00004.png new file mode 100644 index 000000000..694eda507 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00005.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00005.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00006.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00007.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00008.png b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_setApprovalForAll_5/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00000.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00001.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00002.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00003.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00003.png new file mode 100644 index 000000000..b1d7a7b57 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00004.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00004.png new file mode 100644 index 000000000..185581ea3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00005.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00006.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00006.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00007.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00007.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00008.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00008.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_1/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00000.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00001.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00002.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00003.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00003.png new file mode 100644 index 000000000..74c9ac0e7 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00004.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00004.png new file mode 100644 index 000000000..5ec458c27 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00005.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00006.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00006.png new file mode 100644 index 000000000..66ebda506 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00007.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00007.png new file mode 100644 index 000000000..73d6bb75d Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00008.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00009.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_137/00009.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00000.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00000.png new file mode 100644 index 000000000..487ea10fc Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00001.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00001.png new file mode 100644 index 000000000..2b0fd141f Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00002.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00002.png new file mode 100644 index 000000000..79e2760ee Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00003.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00003.png new file mode 100644 index 000000000..3d7d224d3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00004.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00004.png new file mode 100644 index 000000000..694eda507 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00005.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00005.png new file mode 100644 index 000000000..b0804b03e Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00006.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00006.png new file mode 100644 index 000000000..93112b3ab Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00006.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00007.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00007.png new file mode 100644 index 000000000..1bcb78761 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00007.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00008.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00008.png new file mode 100644 index 000000000..570ce28d5 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00008.png differ diff --git a/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00009.png b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00009.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/erc721_transferFrom_5/00009.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_1/00000.png b/tests/ragger/snapshots/nanox/get_pk_1/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_1/00000.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_1/00001.png b/tests/ragger/snapshots/nanox/get_pk_1/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_1/00001.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_1/00002.png b/tests/ragger/snapshots/nanox/get_pk_1/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_1/00002.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_1/00003.png b/tests/ragger/snapshots/nanox/get_pk_1/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_1/00003.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_137/00000.png b/tests/ragger/snapshots/nanox/get_pk_137/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_137/00000.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_137/00001.png b/tests/ragger/snapshots/nanox/get_pk_137/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_137/00001.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_137/00002.png b/tests/ragger/snapshots/nanox/get_pk_137/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_137/00002.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_137/00003.png b/tests/ragger/snapshots/nanox/get_pk_137/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_137/00003.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_2/00000.png b/tests/ragger/snapshots/nanox/get_pk_2/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_2/00000.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_2/00001.png b/tests/ragger/snapshots/nanox/get_pk_2/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_2/00001.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_2/00002.png b/tests/ragger/snapshots/nanox/get_pk_2/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_2/00002.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_2/00003.png b/tests/ragger/snapshots/nanox/get_pk_2/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_2/00003.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_5/00000.png b/tests/ragger/snapshots/nanox/get_pk_5/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_5/00000.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_5/00001.png b/tests/ragger/snapshots/nanox/get_pk_5/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_5/00001.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_5/00002.png b/tests/ragger/snapshots/nanox/get_pk_5/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_5/00002.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_5/00003.png b/tests/ragger/snapshots/nanox/get_pk_5/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_5/00003.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_None/00000.png b/tests/ragger/snapshots/nanox/get_pk_None/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_None/00000.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_None/00001.png b/tests/ragger/snapshots/nanox/get_pk_None/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_None/00001.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_None/00002.png b/tests/ragger/snapshots/nanox/get_pk_None/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_None/00002.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_None/00003.png b/tests/ragger/snapshots/nanox/get_pk_None/00003.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_None/00003.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_rejected/00000.png b/tests/ragger/snapshots/nanox/get_pk_rejected/00000.png new file mode 100644 index 000000000..a487005a8 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_rejected/00000.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_rejected/00001.png b/tests/ragger/snapshots/nanox/get_pk_rejected/00001.png new file mode 100644 index 000000000..da2878f8d Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_rejected/00001.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_rejected/00002.png b/tests/ragger/snapshots/nanox/get_pk_rejected/00002.png new file mode 100644 index 000000000..53ae65195 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_rejected/00002.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_rejected/00003.png b/tests/ragger/snapshots/nanox/get_pk_rejected/00003.png new file mode 100644 index 000000000..e90cd9db3 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_rejected/00003.png differ diff --git a/tests/ragger/snapshots/nanox/get_pk_rejected/00004.png b/tests/ragger/snapshots/nanox/get_pk_rejected/00004.png new file mode 100644 index 000000000..657887225 Binary files /dev/null and b/tests/ragger/snapshots/nanox/get_pk_rejected/00004.png differ diff --git a/tests/ragger/snapshots/stax/blind-signed_approval/00000.png b/tests/ragger/snapshots/stax/blind-signed_approval/00000.png new file mode 100644 index 000000000..7c13332b6 Binary files /dev/null and b/tests/ragger/snapshots/stax/blind-signed_approval/00000.png differ diff --git a/tests/ragger/snapshots/stax/blind-signed_approval/00001.png b/tests/ragger/snapshots/stax/blind-signed_approval/00001.png new file mode 100644 index 000000000..b1ff1b3ab Binary files /dev/null and b/tests/ragger/snapshots/stax/blind-signed_approval/00001.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00000.png b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00000.png index 795ca0c2a..0108042c1 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00000.png and b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00000.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00001.png b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00001.png index 661ea68ef..9c677e29b 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00001.png and b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00001.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00002.png b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00002.png index 7f634cc4a..5bc6ddc96 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00002.png and b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00002.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00003.png b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00003.png index 7a05bf7b3..a21279c8a 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_non_mainnet/00003.png and b/tests/ragger/snapshots/stax/domain_name_non_mainnet/00003.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00000.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00000.png index 795ca0c2a..74fa840cc 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00000.png and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00000.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00001.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00001.png index 252785952..5962c92ea 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00001.png and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00001.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00002.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00002.png index 592a8aca7..285801cfe 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00002.png and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00002.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00003.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00003.png index 299779759..aed7d3335 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00003.png and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00003.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00004.png b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00004.png index 7a05bf7b3..a21279c8a 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_unknown_chain/00004.png and b/tests/ragger/snapshots/stax/domain_name_unknown_chain/00004.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_False/00000.png b/tests/ragger/snapshots/stax/domain_name_verbose_False/00000.png index 795ca0c2a..f992e718a 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_verbose_False/00000.png and b/tests/ragger/snapshots/stax/domain_name_verbose_False/00000.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_False/00001.png b/tests/ragger/snapshots/stax/domain_name_verbose_False/00001.png index 5e0c0a941..b12e252d4 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_verbose_False/00001.png and b/tests/ragger/snapshots/stax/domain_name_verbose_False/00001.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_False/00002.png b/tests/ragger/snapshots/stax/domain_name_verbose_False/00002.png index 7f634cc4a..bc1ca9382 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_verbose_False/00002.png and b/tests/ragger/snapshots/stax/domain_name_verbose_False/00002.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_False/00003.png b/tests/ragger/snapshots/stax/domain_name_verbose_False/00003.png index 7a05bf7b3..a21279c8a 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_verbose_False/00003.png and b/tests/ragger/snapshots/stax/domain_name_verbose_False/00003.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00000.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00000.png index 795ca0c2a..f992e718a 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_verbose_True/00000.png and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00000.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00001.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00001.png index ad8f07755..03184921c 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_verbose_True/00001.png and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00001.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00002.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00002.png index e64dacc0f..d4429dd58 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_verbose_True/00002.png and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00002.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00003.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00003.png index 299779759..687a019ce 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_verbose_True/00003.png and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00003.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_verbose_True/00004.png b/tests/ragger/snapshots/stax/domain_name_verbose_True/00004.png index 7a05bf7b3..a21279c8a 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_verbose_True/00004.png and b/tests/ragger/snapshots/stax/domain_name_verbose_True/00004.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00000.png b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00000.png index 795ca0c2a..f992e718a 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00000.png and b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00000.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00001.png b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00001.png index 3e505d39d..4fdbc6255 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00001.png and b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00001.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00002.png b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00002.png index 7f634cc4a..bc1ca9382 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00002.png and b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00002.png differ diff --git a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00003.png b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00003.png index 7a05bf7b3..a21279c8a 100644 Binary files a/tests/ragger/snapshots/stax/domain_name_wrong_addr/00003.png and b/tests/ragger/snapshots/stax/domain_name_wrong_addr/00003.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution/00000.png b/tests/ragger/snapshots/stax/eip712_address_substitution/00000.png new file mode 100644 index 000000000..7c64769b1 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution/00000.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution/00001.png b/tests/ragger/snapshots/stax/eip712_address_substitution/00001.png new file mode 100644 index 000000000..7437b4fca Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution/00001.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution/00002.png b/tests/ragger/snapshots/stax/eip712_address_substitution/00002.png new file mode 100644 index 000000000..7d3100bcc Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution/00002.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution/00003.png b/tests/ragger/snapshots/stax/eip712_address_substitution/00003.png new file mode 100644 index 000000000..404c49553 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution/00003.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution/00004.png b/tests/ragger/snapshots/stax/eip712_address_substitution/00004.png new file mode 100644 index 000000000..987479c5e Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution/00004.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution/00005.png b/tests/ragger/snapshots/stax/eip712_address_substitution/00005.png new file mode 100644 index 000000000..726c927de Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution/00005.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution/00006.png b/tests/ragger/snapshots/stax/eip712_address_substitution/00006.png new file mode 100644 index 000000000..1c2d6cd43 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution/00006.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00000.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00000.png new file mode 100644 index 000000000..7c64769b1 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00000.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00001.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00001.png new file mode 100644 index 000000000..eb09cbfbf Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00001.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00002.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00002.png new file mode 100644 index 000000000..ebd81164b Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00002.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00003.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00003.png new file mode 100644 index 000000000..539bd78ea Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00003.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00004.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00004.png new file mode 100644 index 000000000..249ca4f62 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00004.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00005.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00005.png new file mode 100644 index 000000000..c9f59eb18 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00005.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00006.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00006.png new file mode 100644 index 000000000..8da1fa8c0 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00006.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00007.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00007.png new file mode 100644 index 000000000..26ca67961 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00007.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00008.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00008.png new file mode 100644 index 000000000..dee5c6cd2 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00008.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00009.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00009.png new file mode 100644 index 000000000..fa8a88e3c Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00009.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00010.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00010.png new file mode 100644 index 000000000..606a1edc8 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00010.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00011.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00011.png new file mode 100644 index 000000000..726c927de Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00011.png differ diff --git a/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00012.png b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00012.png new file mode 100644 index 000000000..1c2d6cd43 Binary files /dev/null and b/tests/ragger/snapshots/stax/eip712_address_substitution_verbose/00012.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00000.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00000.png new file mode 100644 index 000000000..a052cf5b7 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00001.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00001.png new file mode 100644 index 000000000..fff290d24 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00002.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00002.png new file mode 100644 index 000000000..8a12928a1 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00003.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00003.png new file mode 100644 index 000000000..3add68c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00004.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00000.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00000.png new file mode 100644 index 000000000..793dc7ce8 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00001.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00001.png new file mode 100644 index 000000000..ac999f455 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00002.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00002.png new file mode 100644 index 000000000..ebba918e0 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00003.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00003.png new file mode 100644 index 000000000..97b18b86b Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00004.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00004.png new file mode 100644 index 000000000..f1745c661 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00005.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00000.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00000.png new file mode 100644 index 000000000..2f11ba6e6 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00001.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00001.png new file mode 100644 index 000000000..ac999f455 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00002.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00002.png new file mode 100644 index 000000000..013c76cfb Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00003.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00003.png new file mode 100644 index 000000000..637827a11 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00004.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00004.png new file mode 100644 index 000000000..1ebf85c49 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00005.png b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeBatchTransferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00000.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00000.png new file mode 100644 index 000000000..4db1d2e9f Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00001.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00001.png new file mode 100644 index 000000000..8e0349ca1 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00002.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00002.png new file mode 100644 index 000000000..eb3fbaffe Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00003.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00003.png new file mode 100644 index 000000000..637827a11 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00004.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00004.png new file mode 100644 index 000000000..2e4e974b4 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00005.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00005.png new file mode 100644 index 000000000..9d261148b Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00006.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00006.png new file mode 100644 index 000000000..cebc8bede Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1-rejected/00006.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00000.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00000.png new file mode 100644 index 000000000..4db1d2e9f Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00001.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00001.png new file mode 100644 index 000000000..8e0349ca1 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00002.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00002.png new file mode 100644 index 000000000..eb3fbaffe Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00003.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00003.png new file mode 100644 index 000000000..637827a11 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00004.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00004.png new file mode 100644 index 000000000..2e4e974b4 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00005.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_1/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00000.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00000.png new file mode 100644 index 000000000..84aef9b75 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00001.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00001.png new file mode 100644 index 000000000..ac999f455 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00002.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00002.png new file mode 100644 index 000000000..c735e5bdf Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00003.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00003.png new file mode 100644 index 000000000..31f149012 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00004.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00004.png new file mode 100644 index 000000000..82b2b6782 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00005.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00000.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00000.png new file mode 100644 index 000000000..b4c13a184 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00001.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00001.png new file mode 100644 index 000000000..ac999f455 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00002.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00002.png new file mode 100644 index 000000000..f8ef32816 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00003.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00003.png new file mode 100644 index 000000000..902eabaf0 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00004.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00004.png new file mode 100644 index 000000000..61c857633 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00005.png b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_safeTransferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00000.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00000.png new file mode 100644 index 000000000..3507984ef Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00001.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00001.png new file mode 100644 index 000000000..d77ef275e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00002.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00002.png new file mode 100644 index 000000000..079bac224 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00003.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00003.png new file mode 100644 index 000000000..4ea90064d Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00004.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_1/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00000.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00000.png new file mode 100644 index 000000000..ea3b0441c Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00001.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00001.png new file mode 100644 index 000000000..783fdcab3 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00002.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00002.png new file mode 100644 index 000000000..2889b8092 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00003.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00003.png new file mode 100644 index 000000000..5aa28c72c Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00004.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_137/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00000.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00000.png new file mode 100644 index 000000000..7a48edd5e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00001.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00001.png new file mode 100644 index 000000000..783fdcab3 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00002.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00002.png new file mode 100644 index 000000000..50a0880d9 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00003.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00003.png new file mode 100644 index 000000000..c51949c59 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00004.png b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc1155_setApprovalForAll_5/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_1/00000.png b/tests/ragger/snapshots/stax/erc721_approve_1/00000.png new file mode 100644 index 000000000..3507984ef Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_1/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_1/00001.png b/tests/ragger/snapshots/stax/erc721_approve_1/00001.png new file mode 100644 index 000000000..a479dee56 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_1/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_1/00002.png b/tests/ragger/snapshots/stax/erc721_approve_1/00002.png new file mode 100644 index 000000000..ec7ce097e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_1/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_1/00003.png b/tests/ragger/snapshots/stax/erc721_approve_1/00003.png new file mode 100644 index 000000000..4ea90064d Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_1/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_1/00004.png b/tests/ragger/snapshots/stax/erc721_approve_1/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_1/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_137/00000.png b/tests/ragger/snapshots/stax/erc721_approve_137/00000.png new file mode 100644 index 000000000..ea3b0441c Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_137/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_137/00001.png b/tests/ragger/snapshots/stax/erc721_approve_137/00001.png new file mode 100644 index 000000000..8a1c95371 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_137/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_137/00002.png b/tests/ragger/snapshots/stax/erc721_approve_137/00002.png new file mode 100644 index 000000000..4e99e6786 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_137/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_137/00003.png b/tests/ragger/snapshots/stax/erc721_approve_137/00003.png new file mode 100644 index 000000000..97b18b86b Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_137/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_137/00004.png b/tests/ragger/snapshots/stax/erc721_approve_137/00004.png new file mode 100644 index 000000000..1fc04a35a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_137/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_137/00005.png b/tests/ragger/snapshots/stax/erc721_approve_137/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_137/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_5/00000.png b/tests/ragger/snapshots/stax/erc721_approve_5/00000.png new file mode 100644 index 000000000..7a48edd5e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_5/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_5/00001.png b/tests/ragger/snapshots/stax/erc721_approve_5/00001.png new file mode 100644 index 000000000..675b1ae48 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_5/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_5/00002.png b/tests/ragger/snapshots/stax/erc721_approve_5/00002.png new file mode 100644 index 000000000..186b27cd4 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_5/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_5/00003.png b/tests/ragger/snapshots/stax/erc721_approve_5/00003.png new file mode 100644 index 000000000..637827a11 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_5/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_5/00004.png b/tests/ragger/snapshots/stax/erc721_approve_5/00004.png new file mode 100644 index 000000000..107ce91bf Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_5/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_approve_5/00005.png b/tests/ragger/snapshots/stax/erc721_approve_5/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_approve_5/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00000.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00000.png new file mode 100644 index 000000000..4db1d2e9f Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00001.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00001.png new file mode 100644 index 000000000..9488ed1c8 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00002.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00002.png new file mode 100644 index 000000000..ec7ce097e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00003.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00003.png new file mode 100644 index 000000000..b73cefa5e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00004.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00004.png new file mode 100644 index 000000000..9d261148b Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00005.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00005.png new file mode 100644 index 000000000..cebc8bede Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1-rejected/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00000.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00000.png new file mode 100644 index 000000000..4db1d2e9f Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00001.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00001.png new file mode 100644 index 000000000..9488ed1c8 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00002.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00002.png new file mode 100644 index 000000000..ec7ce097e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00003.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00003.png new file mode 100644 index 000000000..b73cefa5e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00004.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00000.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00000.png new file mode 100644 index 000000000..84aef9b75 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00001.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00001.png new file mode 100644 index 000000000..4d9ac34bd Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00002.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00002.png new file mode 100644 index 000000000..4e99e6786 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00003.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00003.png new file mode 100644 index 000000000..97b18b86b Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00004.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00004.png new file mode 100644 index 000000000..82b2b6782 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00005.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00000.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00000.png new file mode 100644 index 000000000..b4c13a184 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00001.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00001.png new file mode 100644 index 000000000..759bdc47b Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00002.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00002.png new file mode 100644 index 000000000..186b27cd4 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00003.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00003.png new file mode 100644 index 000000000..637827a11 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00004.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00004.png new file mode 100644 index 000000000..61c857633 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00005.png b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_safeTransferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00000.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00000.png new file mode 100644 index 000000000..3507984ef Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00001.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00001.png new file mode 100644 index 000000000..d64e222d5 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00002.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00002.png new file mode 100644 index 000000000..7de0c0e9b Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00003.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00003.png new file mode 100644 index 000000000..4ea90064d Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00004.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_1/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00000.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00000.png new file mode 100644 index 000000000..ea3b0441c Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00001.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00001.png new file mode 100644 index 000000000..36791d885 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00002.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00002.png new file mode 100644 index 000000000..7479cde7d Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00003.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00003.png new file mode 100644 index 000000000..5aa28c72c Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00004.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_137/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00000.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00000.png new file mode 100644 index 000000000..7a48edd5e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00001.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00001.png new file mode 100644 index 000000000..49d18f1b7 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00002.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00002.png new file mode 100644 index 000000000..acad067d0 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00003.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00003.png new file mode 100644 index 000000000..c51949c59 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00004.png b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_setApprovalForAll_5/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_1/00000.png b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00000.png new file mode 100644 index 000000000..4db1d2e9f Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_1/00001.png b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00001.png new file mode 100644 index 000000000..9488ed1c8 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_1/00002.png b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00002.png new file mode 100644 index 000000000..ec7ce097e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_1/00003.png b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00003.png new file mode 100644 index 000000000..b73cefa5e Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_1/00004.png b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00004.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_1/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_137/00000.png b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00000.png new file mode 100644 index 000000000..84aef9b75 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_137/00001.png b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00001.png new file mode 100644 index 000000000..4d9ac34bd Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_137/00002.png b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00002.png new file mode 100644 index 000000000..4e99e6786 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_137/00003.png b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00003.png new file mode 100644 index 000000000..97b18b86b Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_137/00004.png b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00004.png new file mode 100644 index 000000000..82b2b6782 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_137/00005.png b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_137/00005.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_5/00000.png b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00000.png new file mode 100644 index 000000000..b4c13a184 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00000.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_5/00001.png b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00001.png new file mode 100644 index 000000000..759bdc47b Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00001.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_5/00002.png b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00002.png new file mode 100644 index 000000000..186b27cd4 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00002.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_5/00003.png b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00003.png new file mode 100644 index 000000000..637827a11 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00003.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_5/00004.png b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00004.png new file mode 100644 index 000000000..61c857633 Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00004.png differ diff --git a/tests/ragger/snapshots/stax/erc721_transferFrom_5/00005.png b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00005.png new file mode 100644 index 000000000..a21279c8a Binary files /dev/null and b/tests/ragger/snapshots/stax/erc721_transferFrom_5/00005.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_1/00000.png b/tests/ragger/snapshots/stax/get_pk_1/00000.png new file mode 100644 index 000000000..759339003 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_1/00000.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_1/00001.png b/tests/ragger/snapshots/stax/get_pk_1/00001.png new file mode 100644 index 000000000..16af88b19 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_1/00001.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_1/00002.png b/tests/ragger/snapshots/stax/get_pk_1/00002.png new file mode 100644 index 000000000..13499fcc9 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_1/00002.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_137/00000.png b/tests/ragger/snapshots/stax/get_pk_137/00000.png new file mode 100644 index 000000000..9e93052a4 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_137/00000.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_137/00001.png b/tests/ragger/snapshots/stax/get_pk_137/00001.png new file mode 100644 index 000000000..16af88b19 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_137/00001.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_137/00002.png b/tests/ragger/snapshots/stax/get_pk_137/00002.png new file mode 100644 index 000000000..13499fcc9 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_137/00002.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_137/00003.png b/tests/ragger/snapshots/stax/get_pk_137/00003.png new file mode 100644 index 000000000..b1ff1b3ab Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_137/00003.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_2/00000.png b/tests/ragger/snapshots/stax/get_pk_2/00000.png new file mode 100644 index 000000000..123dc8cc1 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_2/00000.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_2/00001.png b/tests/ragger/snapshots/stax/get_pk_2/00001.png new file mode 100644 index 000000000..16af88b19 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_2/00001.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_2/00002.png b/tests/ragger/snapshots/stax/get_pk_2/00002.png new file mode 100644 index 000000000..13499fcc9 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_2/00002.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_2/00003.png b/tests/ragger/snapshots/stax/get_pk_2/00003.png new file mode 100644 index 000000000..b1ff1b3ab Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_2/00003.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_5/00000.png b/tests/ragger/snapshots/stax/get_pk_5/00000.png new file mode 100644 index 000000000..2400ed1a1 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_5/00000.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_5/00001.png b/tests/ragger/snapshots/stax/get_pk_5/00001.png new file mode 100644 index 000000000..16af88b19 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_5/00001.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_5/00002.png b/tests/ragger/snapshots/stax/get_pk_5/00002.png new file mode 100644 index 000000000..13499fcc9 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_5/00002.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_5/00003.png b/tests/ragger/snapshots/stax/get_pk_5/00003.png new file mode 100644 index 000000000..b1ff1b3ab Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_5/00003.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_None/00000.png b/tests/ragger/snapshots/stax/get_pk_None/00000.png new file mode 100644 index 000000000..759339003 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_None/00000.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_None/00001.png b/tests/ragger/snapshots/stax/get_pk_None/00001.png new file mode 100644 index 000000000..16af88b19 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_None/00001.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_None/00002.png b/tests/ragger/snapshots/stax/get_pk_None/00002.png new file mode 100644 index 000000000..13499fcc9 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_None/00002.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_rejected/00000.png b/tests/ragger/snapshots/stax/get_pk_rejected/00000.png new file mode 100644 index 000000000..759339003 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_rejected/00000.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_rejected/00001.png b/tests/ragger/snapshots/stax/get_pk_rejected/00001.png new file mode 100644 index 000000000..16af88b19 Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_rejected/00001.png differ diff --git a/tests/ragger/snapshots/stax/get_pk_rejected/00002.png b/tests/ragger/snapshots/stax/get_pk_rejected/00002.png new file mode 100644 index 000000000..b0eba3f0c Binary files /dev/null and b/tests/ragger/snapshots/stax/get_pk_rejected/00002.png differ diff --git a/tests/ragger/test_blind_sign.py b/tests/ragger/test_blind_sign.py new file mode 100644 index 000000000..a4ed7679c --- /dev/null +++ b/tests/ragger/test_blind_sign.py @@ -0,0 +1,55 @@ +import json +from ragger.backend import BackendInterface +from ragger.firmware import Firmware +from ragger.navigator import Navigator, NavInsID +from ragger.error import ExceptionRAPDU +from ledger_app_clients.ethereum.client import EthAppClient +from web3 import Web3 +from constants import ROOT_SNAPSHOT_PATH, ABIS_FOLDER + + +# Token approval, would require loading the "internal plugin" & +# providing the token metadata from the CAL +def test_blind_sign(firmware: Firmware, + backend: BackendInterface, + navigator: Navigator): + app_client = EthAppClient(backend) + + with open("%s/erc20.json" % (ABIS_FOLDER)) as file: + contract = Web3().eth.contract( + abi=json.load(file), + address=None + ) + data = contract.encodeABI("approve", [ + # Uniswap Protocol: Permit2 + bytes.fromhex("000000000022d473030f116ddee9f6b43ac78ba3"), + Web3.to_wei("2", "ether") + ]) + tx_params = { + "nonce": 235, + "maxFeePerGas": Web3.to_wei(100, "gwei"), + "maxPriorityFeePerGas": Web3.to_wei(10, "gwei"), + "gas": 44001, + # Maker: Dai Stablecoin + "to": bytes.fromhex("6b175474e89094c44da98b954eedeac495271d0f"), + "data": data, + "chainId": 1 + } + try: + with app_client.sign("m/44'/60'/0'/0/0", tx_params): + pass + except ExceptionRAPDU: + pass + else: + assert False + + moves = list() + if firmware.device.startswith("nano"): + if firmware.device == "nanos": + moves += [NavInsID.RIGHT_CLICK] + moves += [NavInsID.BOTH_CLICK] + else: + moves += [NavInsID.USE_CASE_CHOICE_CONFIRM] + navigator.navigate_and_compare(ROOT_SNAPSHOT_PATH, + "blind-signed_approval", + moves) diff --git a/tests/ragger/test_domain_name.py b/tests/ragger/test_domain_name.py index f137610db..71eea7bdb 100644 --- a/tests/ragger/test_domain_name.py +++ b/tests/ragger/test_domain_name.py @@ -1,12 +1,16 @@ import pytest -from ragger.error import ExceptionRAPDU -from ragger.firmware import Firmware from ragger.backend import BackendInterface +from ragger.firmware import Firmware +from ragger.error import ExceptionRAPDU from ragger.navigator import Navigator, NavInsID -from app.client import EthAppClient, StatusWord, ROOT_SCREENSHOT_PATH -from app.settings import SettingID, settings_toggle -import app.response_parser as ResponseParser -import struct +from constants import ROOT_SNAPSHOT_PATH + +import ledger_app_clients.ethereum.response_parser as ResponseParser +from ledger_app_clients.ethereum.client import EthAppClient, StatusWord +from ledger_app_clients.ethereum.settings import SettingID, settings_toggle + +from web3 import Web3 + # Values used across all tests CHAIN_ID = 1 @@ -16,14 +20,16 @@ ALGO_ID = 1 BIP32_PATH = "m/44'/60'/0'/0/0" NONCE = 21 -GAS_PRICE = 13000000000 +GAS_PRICE = 13 GAS_LIMIT = 21000 AMOUNT = 1.22 + @pytest.fixture(params=[False, True]) def verbose(request) -> bool: return request.param + def common(app_client: EthAppClient) -> int: if app_client._client.firmware.device == "nanos": pytest.skip("Not supported on LNS") @@ -46,25 +52,27 @@ def test_send_fund(firmware: Firmware, with app_client.provide_domain_name(challenge, NAME, ADDR): pass - with app_client.send_fund(BIP32_PATH, - NONCE, - GAS_PRICE, - GAS_LIMIT, - ADDR, - AMOUNT, - CHAIN_ID): + with app_client.sign(BIP32_PATH, + { + "nonce": NONCE, + "gasPrice": Web3.to_wei(GAS_PRICE, "gwei"), + "gas": GAS_LIMIT, + "to": ADDR, + "value": Web3.to_wei(AMOUNT, "ether"), + "chainId": CHAIN_ID + }): moves = list() if firmware.device.startswith("nano"): - moves += [ NavInsID.RIGHT_CLICK ] * 4 + moves += [NavInsID.RIGHT_CLICK] * 4 if verbose: - moves += [ NavInsID.RIGHT_CLICK ] - moves += [ NavInsID.BOTH_CLICK ] + moves += [NavInsID.RIGHT_CLICK] + moves += [NavInsID.BOTH_CLICK] else: - moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 2 + moves += [NavInsID.USE_CASE_REVIEW_TAP] * 2 if verbose: - moves += [ NavInsID.USE_CASE_REVIEW_TAP ] - moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ] - navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + moves += [NavInsID.USE_CASE_REVIEW_TAP] + moves += [NavInsID.USE_CASE_REVIEW_CONFIRM] + navigator.navigate_and_compare(ROOT_SNAPSHOT_PATH, "domain_name_verbose_" + str(verbose), moves) @@ -73,7 +81,6 @@ def test_send_fund_wrong_challenge(firmware: Firmware, backend: BackendInterface, navigator: Navigator): app_client = EthAppClient(backend) - caught = False challenge = common(app_client) try: @@ -82,7 +89,7 @@ def test_send_fund_wrong_challenge(firmware: Firmware, except ExceptionRAPDU as e: assert e.status == StatusWord.INVALID_DATA else: - assert False # An exception should have been raised + assert False # An exception should have been raised def test_send_fund_wrong_addr(firmware: Firmware, @@ -98,21 +105,23 @@ def test_send_fund_wrong_addr(firmware: Firmware, addr = bytearray(ADDR) addr.reverse() - with app_client.send_fund(BIP32_PATH, - NONCE, - GAS_PRICE, - GAS_LIMIT, - addr, - AMOUNT, - CHAIN_ID): + with app_client.sign(BIP32_PATH, + { + "nonce": NONCE, + "gasPrice": Web3.to_wei(GAS_PRICE, "gwei"), + "gas": GAS_LIMIT, + "to": bytes(addr), + "value": Web3.to_wei(AMOUNT, "ether"), + "chainId": CHAIN_ID + }): moves = list() if firmware.device.startswith("nano"): - moves += [ NavInsID.RIGHT_CLICK ] * 4 - moves += [ NavInsID.BOTH_CLICK ] + moves += [NavInsID.RIGHT_CLICK] * 4 + moves += [NavInsID.BOTH_CLICK] else: - moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 2 - moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ] - navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + moves += [NavInsID.USE_CASE_REVIEW_TAP] * 2 + moves += [NavInsID.USE_CASE_REVIEW_CONFIRM] + navigator.navigate_and_compare(ROOT_SNAPSHOT_PATH, "domain_name_wrong_addr", moves) @@ -127,21 +136,23 @@ def test_send_fund_non_mainnet(firmware: Firmware, with app_client.provide_domain_name(challenge, NAME, ADDR): pass - with app_client.send_fund(BIP32_PATH, - NONCE, - GAS_PRICE, - GAS_LIMIT, - ADDR, - AMOUNT, - 5): + with app_client.sign(BIP32_PATH, + { + "nonce": NONCE, + "gasPrice": Web3.to_wei(GAS_PRICE, "gwei"), + "gas": GAS_LIMIT, + "to": ADDR, + "value": Web3.to_wei(AMOUNT, "ether"), + "chainId": 5 + }): moves = list() if firmware.device.startswith("nano"): - moves += [ NavInsID.RIGHT_CLICK ] * 5 - moves += [ NavInsID.BOTH_CLICK ] + moves += [NavInsID.RIGHT_CLICK] * 5 + moves += [NavInsID.BOTH_CLICK] else: - moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 2 - moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ] - navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + moves += [NavInsID.USE_CASE_REVIEW_TAP] * 2 + moves += [NavInsID.USE_CASE_REVIEW_CONFIRM] + navigator.navigate_and_compare(ROOT_SNAPSHOT_PATH, "domain_name_non_mainnet", moves) @@ -156,21 +167,23 @@ def test_send_fund_unknown_chain(firmware: Firmware, with app_client.provide_domain_name(challenge, NAME, ADDR): pass - with app_client.send_fund(BIP32_PATH, - NONCE, - GAS_PRICE, - GAS_LIMIT, - ADDR, - AMOUNT, - 9): + with app_client.sign(BIP32_PATH, + { + "nonce": NONCE, + "gasPrice": Web3.to_wei(GAS_PRICE, "gwei"), + "gas": GAS_LIMIT, + "to": ADDR, + "value": Web3.to_wei(AMOUNT, "ether"), + "chainId": 9 + }): moves = list() if firmware.device.startswith("nano"): - moves += [ NavInsID.RIGHT_CLICK ] * 5 - moves += [ NavInsID.BOTH_CLICK ] + moves += [NavInsID.RIGHT_CLICK] * 5 + moves += [NavInsID.BOTH_CLICK] else: - moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 3 - moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ] - navigator.navigate_and_compare(ROOT_SCREENSHOT_PATH, + moves += [NavInsID.USE_CASE_REVIEW_TAP] * 3 + moves += [NavInsID.USE_CASE_REVIEW_CONFIRM] + navigator.navigate_and_compare(ROOT_SNAPSHOT_PATH, "domain_name_unknown_chain", moves) @@ -187,7 +200,7 @@ def test_send_fund_domain_too_long(firmware: Firmware, except ExceptionRAPDU as e: assert e.status == StatusWord.INVALID_DATA else: - assert False # An exception should have been raised + assert False # An exception should have been raised def test_send_fund_domain_invalid_character(firmware: Firmware, @@ -202,7 +215,7 @@ def test_send_fund_domain_invalid_character(firmware: Firmware, except ExceptionRAPDU as e: assert e.status == StatusWord.INVALID_DATA else: - assert False # An exception should have been raised + assert False # An exception should have been raised def test_send_fund_uppercase(firmware: Firmware, @@ -217,7 +230,7 @@ def test_send_fund_uppercase(firmware: Firmware, except ExceptionRAPDU as e: assert e.status == StatusWord.INVALID_DATA else: - assert False # An exception should have been raised + assert False # An exception should have been raised def test_send_fund_domain_non_ens(firmware: Firmware, @@ -232,4 +245,4 @@ def test_send_fund_domain_non_ens(firmware: Firmware, except ExceptionRAPDU as e: assert e.status == StatusWord.INVALID_DATA else: - assert False # An exception should have been raised + assert False # An exception should have been raised diff --git a/tests/ragger/test_eip712.py b/tests/ragger/test_eip712.py index 6ff0bc7b3..b4551885e 100644 --- a/tests/ragger/test_eip712.py +++ b/tests/ragger/test_eip712.py @@ -1,37 +1,58 @@ -import pytest -import os import fnmatch -from typing import List -from ragger.firmware import Firmware -from ragger.backend import BackendInterface -from ragger.navigator import Navigator, NavInsID -from app.client import EthAppClient -from app.settings import SettingID, settings_toggle -from eip712 import InputData -from pathlib import Path +import os +import pytest +import time from configparser import ConfigParser -import app.response_parser as ResponseParser from functools import partial -import time +from pathlib import Path +from ragger.backend import BackendInterface +from ragger.firmware import Firmware +from ragger.navigator import Navigator, NavInsID +import json +from typing import Optional +from constants import ROOT_SNAPSHOT_PATH + +import ledger_app_clients.ethereum.response_parser as ResponseParser +from ledger_app_clients.ethereum.client import EthAppClient +from ledger_app_clients.ethereum.eip712 import InputData +from ledger_app_clients.ethereum.settings import SettingID, settings_toggle + + +class SnapshotsConfig: + test_name: str + idx: int + + def __init__(self, test_name: str, idx: int = 0): + self.test_name = test_name + self.idx = idx + BIP32_PATH = "m/44'/60'/0'/0/0" +snaps_config: Optional[SnapshotsConfig] = None + + +def eip712_json_path() -> str: + return "%s/eip712_input_files" % (os.path.dirname(__file__)) -def input_files() -> List[str]: +def input_files() -> list[str]: files = [] - for file in os.scandir("%s/eip712/input_files" % (os.path.dirname(__file__))): + for file in os.scandir(eip712_json_path()): if fnmatch.fnmatch(file, "*-data.json"): files.append(file.path) return sorted(files) + @pytest.fixture(params=input_files()) def input_file(request) -> str: return Path(request.param) + @pytest.fixture(params=[True, False]) def verbose(request) -> bool: return request.param + @pytest.fixture(params=[False, True]) def filtering(request) -> bool: return request.param @@ -47,16 +68,16 @@ def test_eip712_legacy(firmware: Firmware, bytes.fromhex('eb4221181ff3f1a83ea7313993ca9218496e424604ba9492bb4052c03d5c3df8')): moves = list() if firmware.device.startswith("nano"): - moves += [ NavInsID.RIGHT_CLICK ] + moves += [NavInsID.RIGHT_CLICK] if firmware.device == "nanos": screens_per_hash = 4 else: screens_per_hash = 2 - moves += [ NavInsID.RIGHT_CLICK ] * screens_per_hash * 2 - moves += [ NavInsID.BOTH_CLICK ] + moves += [NavInsID.RIGHT_CLICK] * screens_per_hash * 2 + moves += [NavInsID.BOTH_CLICK] else: - moves += [ NavInsID.USE_CASE_REVIEW_TAP ] * 2 - moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ] + moves += [NavInsID.USE_CASE_REVIEW_TAP] * 2 + moves += [NavInsID.USE_CASE_REVIEW_CONFIRM] navigator.navigate(moves) v, r, s = ResponseParser.signature(app_client.response().data) @@ -69,10 +90,55 @@ def test_eip712_legacy(firmware: Firmware, def autonext(fw: Firmware, nav: Navigator): moves = list() if fw.device.startswith("nano"): - moves = [ NavInsID.RIGHT_CLICK ] + moves = [NavInsID.RIGHT_CLICK] else: - moves = [ NavInsID.USE_CASE_REVIEW_TAP ] - nav.navigate(moves, screen_change_before_first_instruction=False, screen_change_after_last_instruction=False) + moves = [NavInsID.USE_CASE_REVIEW_TAP] + if snaps_config is not None: + nav.navigate_and_compare(ROOT_SNAPSHOT_PATH, + snaps_config.test_name, + moves, + screen_change_before_first_instruction=False, + screen_change_after_last_instruction=False, + snap_start_idx=snaps_config.idx) + snaps_config.idx += 1 + else: + nav.navigate(moves, + screen_change_before_first_instruction=False, + screen_change_after_last_instruction=False) + + +def eip712_new_common(fw: Firmware, + nav: Navigator, + app_client: EthAppClient, + json_data: dict, + filters: Optional[dict], + verbose: bool): + assert InputData.process_data(app_client, + json_data, + filters, + partial(autonext, fw, nav)) + with app_client.eip712_sign_new(BIP32_PATH): + moves = list() + if fw.device.startswith("nano"): + # need to skip the message hash + if not verbose and filters is None: + moves = [NavInsID.RIGHT_CLICK] * 2 + moves += [NavInsID.BOTH_CLICK] + else: + time.sleep(1.5) + # need to skip the message hash + if not verbose and filters is None: + moves += [NavInsID.USE_CASE_REVIEW_TAP] + moves += [NavInsID.USE_CASE_REVIEW_CONFIRM] + if snaps_config is not None: + nav.navigate_and_compare(ROOT_SNAPSHOT_PATH, + snaps_config.test_name, + moves, + snap_start_idx=snaps_config.idx) + snaps_config.idx += 1 + else: + nav.navigate(moves) + return ResponseParser.signature(app_client.response().data) def test_eip712_new(firmware: Firmware, @@ -87,10 +153,14 @@ def test_eip712_new(firmware: Firmware, else: test_path = "%s/%s" % (input_file.parent, "-".join(input_file.stem.split("-")[:-1])) conf_file = "%s.ini" % (test_path) - filter_file = None + filters = None if filtering: - filter_file = "%s-filter.json" % (test_path) + try: + with open("%s-filter.json" % (test_path)) as f: + filters = json.load(f) + except (IOError, json.decoder.JSONDecodeError) as e: + pytest.skip("Filter file error: %s" % (e.strerror)) config = ConfigParser() config.read(conf_file) @@ -101,34 +171,73 @@ def test_eip712_new(firmware: Firmware, assert "r" in config["signature"] assert "s" in config["signature"] - if not filtering or Path(filter_file).is_file(): + if verbose: + settings_toggle(firmware, navigator, [SettingID.VERBOSE_EIP712]) + + with open(input_file) as file: + v, r, s = eip712_new_common(firmware, + navigator, + app_client, + json.load(file), + filters, + verbose) + + assert v == bytes.fromhex(config["signature"]["v"]) + assert r == bytes.fromhex(config["signature"]["r"]) + assert s == bytes.fromhex(config["signature"]["s"]) + + +def test_eip712_address_substitution(firmware: Firmware, + backend: BackendInterface, + navigator: Navigator, + verbose: bool): + global snaps_config + + app_client = EthAppClient(backend) + if firmware.device == "nanos": + pytest.skip("Not supported on LNS") + else: + test_name = "eip712_address_substitution" + if verbose: + test_name += "_verbose" + snaps_config = SnapshotsConfig(test_name) + with open("%s/address_substitution.json" % (eip712_json_path())) as file: + data = json.load(file) + + with app_client.provide_token_metadata("DAI", + bytes.fromhex(data["message"]["token"][2:]), + 18, + 1): + pass + + with app_client.get_challenge(): + pass + challenge = ResponseParser.challenge(app_client.response().data) + with app_client.provide_domain_name(challenge, + "vitalik.eth", + bytes.fromhex(data["message"]["to"][2:])): + pass + if verbose: settings_toggle(firmware, navigator, [SettingID.VERBOSE_EIP712]) - - assert InputData.process_file(app_client, - input_file, - filter_file, - partial(autonext, firmware, navigator)) == True - with app_client.eip712_sign_new(BIP32_PATH, verbose): - time.sleep(0.5) # tight on timing, needed by the CI otherwise might fail sometimes - moves = list() - if firmware.device.startswith("nano"): - if not verbose and not filtering: # need to skip the message hash - moves = [ NavInsID.RIGHT_CLICK ] * 2 - moves += [ NavInsID.BOTH_CLICK ] - else: - if not verbose and not filtering: # need to skip the message hash - moves += [ NavInsID.USE_CASE_REVIEW_TAP ] - moves += [ NavInsID.USE_CASE_REVIEW_CONFIRM ] - navigator.navigate(moves) - v, r, s = ResponseParser.signature(app_client.response().data) - #print("[signature]") - #print("v = %s" % (v.hex())) - #print("r = %s" % (r.hex())) - #print("s = %s" % (s.hex())) - - assert v == bytes.fromhex(config["signature"]["v"]) - assert r == bytes.fromhex(config["signature"]["r"]) - assert s == bytes.fromhex(config["signature"]["s"]) - else: - pytest.skip("No filter file found") + filters = None + else: + filters = { + "name": "Token test", + "fields": { + "amount": "Amount", + "token": "Token", + "to": "To", + } + } + + v, r, s = eip712_new_common(firmware, + navigator, + app_client, + data, + filters, + verbose) + + assert v == bytes.fromhex("1b") + assert r == bytes.fromhex("d4a0e058251cdc3845aaa5eb8409d8a189ac668db7c55a64eb3121b0db7fd8c0") + assert s == bytes.fromhex("3221800e4f45272c6fa8fafda5e94c848d1a4b90c442aa62afa8e8d6a9af0f00") diff --git a/tests/ragger/test_get_address.py b/tests/ragger/test_get_address.py new file mode 100644 index 000000000..60cf4bb41 --- /dev/null +++ b/tests/ragger/test_get_address.py @@ -0,0 +1,82 @@ +import pytest +from typing import Optional +from ragger.error import ExceptionRAPDU +from ragger.firmware import Firmware +from ragger.backend import BackendInterface +from ragger.navigator import Navigator, NavInsID +from ledger_app_clients.ethereum.client import EthAppClient, StatusWord +import ledger_app_clients.ethereum.response_parser as ResponseParser +from ragger.bip import calculate_public_key_and_chaincode, CurveChoice +from constants import ROOT_SNAPSHOT_PATH + + +@pytest.fixture(params=[True, False]) +def with_chaincode(request) -> bool: + return request.param + + +@pytest.fixture(params=[None, 1, 2, 5, 137]) +def chain(request) -> Optional[int]: + return request.param + + +def get_moves(firmware: Firmware, + navigator: BackendInterface, + chain: Optional[int] = None, + reject: bool = False): + moves = list() + + if firmware.is_nano: + moves += [NavInsID.RIGHT_CLICK] + if firmware.device == "nanos": + moves += [NavInsID.RIGHT_CLICK] * 3 + else: + moves += [NavInsID.RIGHT_CLICK] + if reject: + moves += [NavInsID.RIGHT_CLICK] + moves += [NavInsID.BOTH_CLICK] + else: + moves += [NavInsID.USE_CASE_REVIEW_TAP] + if chain is not None and chain > 1: + moves += [NavInsID.USE_CASE_ADDRESS_CONFIRMATION_TAP] + if reject: + moves += [NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CANCEL] + else: + moves += [NavInsID.USE_CASE_ADDRESS_CONFIRMATION_CONFIRM] + + return moves + + +def test_get_pk_rejected(firmware: Firmware, + backend: BackendInterface, + navigator: Navigator): + app_client = EthAppClient(backend) + + try: + with app_client.get_public_addr(): + navigator.navigate_and_compare(ROOT_SNAPSHOT_PATH, + "get_pk_rejected", + get_moves(firmware, navigator, reject=True)) + except ExceptionRAPDU as e: + assert e.status == StatusWord.CONDITION_NOT_SATISFIED + else: + assert False # An exception should have been raised + + +def test_get_pk(firmware: Firmware, + backend: BackendInterface, + navigator: Navigator, + with_chaincode: bool, + chain: Optional[int]): + app_client = EthAppClient(backend) + + with app_client.get_public_addr(chaincode=with_chaincode, chain_id=chain): + navigator.navigate_and_compare(ROOT_SNAPSHOT_PATH, + "get_pk_%s" % (chain), + get_moves(firmware, navigator, chain=chain)) + pk, addr, chaincode = ResponseParser.pk_addr(app_client.response().data, with_chaincode) + ref_pk, ref_chaincode = calculate_public_key_and_chaincode(curve=CurveChoice.Secp256k1, + path="m/44'/60'/0'/0/0") + assert pk.hex() == ref_pk + if with_chaincode: + assert chaincode.hex() == ref_chaincode diff --git a/tests/ragger/test_nft.py b/tests/ragger/test_nft.py new file mode 100644 index 000000000..fd3987122 --- /dev/null +++ b/tests/ragger/test_nft.py @@ -0,0 +1,364 @@ +import pytest +from typing import Optional, Any +from pathlib import Path +from typing import Callable +from ragger.error import ExceptionRAPDU +from ragger.firmware import Firmware +from ragger.backend import BackendInterface +from ragger.navigator import Navigator, NavInsID +from ledger_app_clients.ethereum.client import EthAppClient, StatusWord +import ledger_app_clients.ethereum.response_parser as ResponseParser +from ledger_app_clients.ethereum.utils import get_selector_from_data, recover_transaction +from web3 import Web3 +import json +from constants import ROOT_SNAPSHOT_PATH, ABIS_FOLDER + + +BIP32_PATH = "m/44'/60'/0'/0/0" +NONCE = 21 +GAS_PRICE = 13 +GAS_LIMIT = 21000 +FROM = bytes.fromhex("1122334455667788990011223344556677889900") +TO = bytes.fromhex("0099887766554433221100998877665544332211") +NFTS = [(1, 3), (5, 2), (7, 4)] # tuples of (token_id, amount) +DATA = "Some data".encode() +DEVICE_ADDR: Optional[bytes] = None + + +class NFTCollection: + addr: bytes + name: str + chain_id: int + + def __init__(self, addr: bytes, name: str, chain_id: int, contract): + self.addr = addr + self.name = name + self.chain_id = chain_id + self.contract = contract + + +class Action: + fn_name: str + fn_args: list[Any] + nav_fn: Callable + + def __init__(self, fn_name: str, fn_args: list[Any], nav_fn: Callable): + self.fn_name = fn_name + self.fn_args = fn_args + self.nav_fn = nav_fn + + +def common_nav_nft(is_nano: bool, + nano_steps: int, + stax_steps: int, + reject: bool) -> list[NavInsID]: + moves = list() + if is_nano: + moves += [NavInsID.RIGHT_CLICK] * nano_steps + if reject: + moves += [NavInsID.RIGHT_CLICK] + moves += [NavInsID.BOTH_CLICK] + else: + moves += [NavInsID.USE_CASE_REVIEW_TAP] * stax_steps + if reject: + moves += [ + NavInsID.USE_CASE_REVIEW_REJECT, + NavInsID.USE_CASE_CHOICE_CONFIRM + ] + else: + moves += [NavInsID.USE_CASE_REVIEW_CONFIRM] + return moves + + +def snapshot_test_name(nft_type: str, fn: str, chain_id: int, reject: bool) -> str: + name = "%s_%s_%s" % (nft_type, fn, str(chain_id)) + if reject: + name += "-rejected" + return name + + +def common_test_nft(fw: Firmware, + back: BackendInterface, + nav: Navigator, + collec: NFTCollection, + action: Action, + reject: bool, + plugin_name: str): + global DEVICE_ADDR + app_client = EthAppClient(back) + + if app_client._client.firmware.name == "nanos": + pytest.skip("Not supported on LNS") + + if DEVICE_ADDR is None: # to only have to request it once + with app_client.get_public_addr(display=False): + pass + _, DEVICE_ADDR, _ = ResponseParser.pk_addr(app_client.response().data) + + data = collec.contract.encodeABI(action.fn_name, action.fn_args) + with app_client.set_plugin(plugin_name, + collec.addr, + get_selector_from_data(data), + collec.chain_id): + pass + with app_client.provide_nft_metadata(collec.name, collec.addr, collec.chain_id): + pass + tx_params = { + "nonce": NONCE, + "gasPrice": Web3.to_wei(GAS_PRICE, "gwei"), + "gas": GAS_LIMIT, + "to": collec.addr, + "value": 0, + "chainId": collec.chain_id, + "data": data, + } + with app_client.sign(BIP32_PATH, tx_params): + nav.navigate_and_compare(ROOT_SNAPSHOT_PATH, + snapshot_test_name(plugin_name.lower(), + action.fn_name, + collec.chain_id, + reject), + action.nav_fn(fw.is_nano, + collec.chain_id, + reject)) + # verify signature + vrs = ResponseParser.signature(app_client.response().data) + addr = recover_transaction(tx_params, vrs) + assert addr == DEVICE_ADDR + + +def common_test_nft_reject(test_fn: Callable, + fw: Firmware, + back: BackendInterface, + nav: Navigator, + collec: NFTCollection, + action: Action): + try: + test_fn(fw, back, nav, collec, action, True) + except ExceptionRAPDU as e: + assert e.status == StatusWord.CONDITION_NOT_SATISFIED + else: + assert False # An exception should have been raised + +# ERC-721 + + +ERC721_PLUGIN = "ERC721" + +with open("%s/erc721.json" % (ABIS_FOLDER)) as file: + contract_erc721 = Web3().eth.contract( + abi=json.load(file), + address=bytes(20) + ) + +# ui nav functions + +def nav_erc721_transfer_from(is_nano: bool, + chain_id: int, + reject: bool) -> list[NavInsID]: + nano_steps = 7 + stax_steps = 3 + if chain_id != 1: + nano_steps += 1 + stax_steps += 1 + return common_nav_nft(is_nano, nano_steps, stax_steps, reject) + + +def nav_erc721_approve(is_nano: bool, + chain_id: int, + reject: bool) -> list[NavInsID]: + nano_steps = 7 + stax_steps = 3 + if chain_id != 1: + nano_steps += 1 + stax_steps += 1 + return common_nav_nft(is_nano, nano_steps, stax_steps, reject) + + +def nav_erc721_set_approval_for_all(is_nano: bool, + chain_id: int, + reject: bool) -> list[NavInsID]: + nano_steps = 6 + if chain_id != 1: + nano_steps += 1 + return common_nav_nft(is_nano, nano_steps, 3, reject) + + +collecs_721 = [ + NFTCollection(bytes.fromhex("bc4ca0eda7647a8ab7c2061c2e118a18a936f13d"), + "Bored Ape Yacht Club", + 1, + contract_erc721), + NFTCollection(bytes.fromhex("670fd103b1a08628e9557cd66b87ded841115190"), + "y00ts", + 137, + contract_erc721), + NFTCollection(bytes.fromhex("2909cf13e458a576cdd9aab6bd6617051a92dacf"), + "goerlirocks", + 5, + contract_erc721), +] +actions_721 = [ + Action("safeTransferFrom", + [FROM, TO, NFTS[0][0], DATA], + nav_erc721_transfer_from), + Action("safeTransferFrom", + [FROM, TO, NFTS[0][0]], + nav_erc721_transfer_from), + Action("transferFrom", + [FROM, TO, NFTS[0][0]], + nav_erc721_transfer_from), + Action("approve", + [TO, NFTS[0][0]], + nav_erc721_approve), + Action("setApprovalForAll", + [TO, False], + nav_erc721_set_approval_for_all), +] + + +@pytest.fixture(params=collecs_721) +def collec_721(request) -> NFTCollection: + return request.param + + +@pytest.fixture(params=actions_721) +def action_721(request) -> Action: + return request.param + + +def test_erc721(firmware: Firmware, + backend: BackendInterface, + navigator: Navigator, + collec_721: NFTCollection, + action_721: Action, + reject: bool = False): + common_test_nft(firmware, + backend, + navigator, + collec_721, + action_721, + reject, + ERC721_PLUGIN) + + +def test_erc721_reject(firmware: Firmware, + backend: BackendInterface, + navigator: Navigator): + common_test_nft_reject(test_erc721, + firmware, + backend, + navigator, + collecs_721[0], + actions_721[0]) + + +# ERC-1155 + +ERC1155_PLUGIN = "ERC1155" + +with open("%s/erc1155.json" % (ABIS_FOLDER)) as file: + contract_erc1155 = Web3().eth.contract( + abi=json.load(file), + address=bytes(20) + ) + + +# ui nav functions + +def nav_erc1155_safe_transfer_from(is_nano: bool, + chain_id: int, + reject: bool) -> list: + nano_steps = 8 + if chain_id != 1: + nano_steps += 1 + return common_nav_nft(is_nano, nano_steps, 4, reject) + + +def nav_erc1155_safe_batch_transfer_from(is_nano: bool, + chain_id: int, + reject: bool) -> list: + nano_steps = 7 + stax_steps = 3 + if chain_id != 1: + nano_steps += 1 + stax_steps += 1 + return common_nav_nft(is_nano, nano_steps, stax_steps, reject) + + +def nav_erc1155_set_approval_for_all(is_nano: bool, + chain_id: int, + reject: bool) -> list: + nano_steps = 6 + if chain_id != 1: + nano_steps += 1 + return common_nav_nft(is_nano, nano_steps, 3, reject) + + +collecs_1155 = [ + NFTCollection(bytes.fromhex("495f947276749ce646f68ac8c248420045cb7b5e"), + "OpenSea Shared Storefront", + 1, + contract_erc1155), + NFTCollection(bytes.fromhex("2953399124f0cbb46d2cbacd8a89cf0599974963"), + "OpenSea Collections", + 137, + contract_erc1155), + NFTCollection(bytes.fromhex("f4910c763ed4e47a585e2d34baa9a4b611ae448c"), + "OpenSea Collections", + 5, + contract_erc1155), +] +actions_1155 = [ + Action("safeTransferFrom", + [FROM, TO, NFTS[0][0], NFTS[0][1], DATA], + nav_erc1155_safe_transfer_from), + Action("safeBatchTransferFrom", + [ + FROM, + TO, + list(map(lambda nft: nft[0], NFTS)), + list(map(lambda nft: nft[1], NFTS)), + DATA + ], + nav_erc1155_safe_batch_transfer_from), + Action("setApprovalForAll", + [TO, False], + nav_erc1155_set_approval_for_all), +] + + +@pytest.fixture(params=collecs_1155) +def collec_1155(request) -> bool: + return request.param + + +@pytest.fixture(params=actions_1155) +def action_1155(request) -> Action: + return request.param + + +def test_erc1155(firmware: Firmware, + backend: BackendInterface, + navigator: Navigator, + collec_1155: NFTCollection, + action_1155: Action, + reject: bool = False): + common_test_nft(firmware, + backend, + navigator, + collec_1155, + action_1155, + reject, + ERC1155_PLUGIN) + + +def test_erc1155_reject(firmware: Firmware, + backend: BackendInterface, + navigator: Navigator): + common_test_nft_reject(test_erc1155, + firmware, + backend, + navigator, + collecs_1155[0], + actions_1155[0]) diff --git a/tests/ragger/test_sign.py b/tests/ragger/test_sign.py new file mode 100644 index 000000000..401be19a0 --- /dev/null +++ b/tests/ragger/test_sign.py @@ -0,0 +1,67 @@ +from ragger.backend import BackendInterface +from ragger.firmware import Firmware +from ragger.navigator import Navigator, NavInsID +from ledger_app_clients.ethereum.client import EthAppClient +import ledger_app_clients.ethereum.response_parser as ResponseParser +from ledger_app_clients.ethereum.utils import recover_transaction +from web3 import Web3 + + +# Values used across all tests +CHAIN_ID = 1 +ADDR = bytes.fromhex("0011223344556677889900112233445566778899") +BIP32_PATH = "m/44'/60'/0'/0/0" +NONCE = 21 +GAS_PRICE = 13 +GAS_LIMIT = 21000 +AMOUNT = 1.22 + + +def common(fw: Firmware, + back: BackendInterface, + nav: Navigator, + tx_params: dict): + app_client = EthAppClient(back) + + with app_client.get_public_addr(display=False): + pass + _, DEVICE_ADDR, _ = ResponseParser.pk_addr(app_client.response().data) + + with app_client.sign(BIP32_PATH, tx_params): + if fw.device.startswith("nano"): + next_action = NavInsID.RIGHT_CLICK + confirm_action = NavInsID.BOTH_CLICK + end_text = "Accept" + else: + next_action = NavInsID.USE_CASE_REVIEW_TAP + confirm_action = NavInsID.USE_CASE_REVIEW_CONFIRM + end_text = "Sign" + nav.navigate_until_text(next_action, [confirm_action], end_text) + + # verify signature + vrs = ResponseParser.signature(app_client.response().data) + addr = recover_transaction(tx_params, vrs) + assert addr == DEVICE_ADDR + + +def test_legacy(firmware: Firmware, backend: BackendInterface, navigator: Navigator): + common(firmware, backend, navigator, { + "nonce": NONCE, + "gasPrice": Web3.to_wei(GAS_PRICE, "gwei"), + "gas": GAS_LIMIT, + "to": ADDR, + "value": Web3.to_wei(AMOUNT, "ether"), + "chainId": CHAIN_ID + }) + + +def test_1559(firmware: Firmware, backend: BackendInterface, navigator: Navigator): + common(firmware, backend, navigator, { + "nonce": NONCE, + "maxFeePerGas": Web3.to_wei(145, "gwei"), + "maxPriorityFeePerGas": Web3.to_wei(1.5, "gwei"), + "gas": GAS_LIMIT, + "to": ADDR, + "value": Web3.to_wei(AMOUNT, "ether"), + "chainId": CHAIN_ID + }) diff --git a/tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00003.png b/tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00003.png index 1a7a3f353..a1e3cc0f7 100644 Binary files a/tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00003.png and b/tests/speculos/screenshots/eip1559/nanox/sign_eip_1559/00003.png differ diff --git a/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00004.png b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00004.png index f1733ce44..1039cd005 100644 Binary files a/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00004.png and b/tests/speculos/screenshots/eip2930/nanox/sign_eip_2930/00004.png differ diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00005.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00005.png index c9da92b60..e7ffedd90 100644 Binary files a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00005.png and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg/00005.png differ diff --git a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00005.png b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00005.png index c9da92b60..e7ffedd90 100644 Binary files a/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00005.png and b/tests/speculos/screenshots/eip712/nanox/sign_eip_712_hashed_msg_reject/00005.png differ diff --git a/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00006.png b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00006.png index 690bb3d26..fb49360e7 100644 Binary files a/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00006.png and b/tests/speculos/screenshots/erc1155/nanox/test_transfer_batch_erc1155/00006.png differ diff --git a/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00008.png b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00008.png index cd509d990..432e634e3 100644 Binary files a/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00008.png and b/tests/speculos/screenshots/erc1155/nanox/transfer_erc1155/00008.png differ diff --git a/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00006.png b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00006.png index 6ce12bac1..10b862ede 100644 Binary files a/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00006.png and b/tests/speculos/screenshots/erc721/nanox/transfer_erc721/00006.png differ diff --git a/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00003.png b/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00003.png index c9222461c..e90cd9db3 100644 Binary files a/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00003.png and b/tests/speculos/screenshots/pubkey/nanox/reject_get_public_key/00003.png differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00000.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00000.png deleted file mode 100644 index 8d84cc70f..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00000.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00001.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00001.png deleted file mode 100644 index 7ebda4f3a..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00001.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00002.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00002.png deleted file mode 100644 index c2af54e96..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00002.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00003.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00003.png deleted file mode 100644 index a54fefd4c..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00003.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00004.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00004.png deleted file mode 100644 index 8656b8175..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00004.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00005.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00005.png deleted file mode 100644 index fd3155c0d..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00005.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00006.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00006.png deleted file mode 100644 index c63f25f8d..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00006.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00007.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00007.png deleted file mode 100644 index f0a7d0e1a..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00007.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00008.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00008.png deleted file mode 100644 index c84d3ec3e..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00008.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00009.png b/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00009.png deleted file mode 100644 index 1c9156c31..000000000 Binary files a/tests/speculos/screenshots/sign/nanos/dai_coin_type_on_network_5234/00009.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00001.png b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00001.png index 990173650..b4d7befa3 100644 Binary files a/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00001.png and b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00001.png differ diff --git a/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00005.png b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00005.png index 70c1b9a68..1bcb78761 100644 Binary files a/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00005.png and b/tests/speculos/screenshots/sign/nanox/blind_and_nonce_display/00005.png differ diff --git a/tests/speculos/screenshots/sign/nanox/blind_simple/00001.png b/tests/speculos/screenshots/sign/nanox/blind_simple/00001.png index 990173650..b4d7befa3 100644 Binary files a/tests/speculos/screenshots/sign/nanox/blind_simple/00001.png and b/tests/speculos/screenshots/sign/nanox/blind_simple/00001.png differ diff --git a/tests/speculos/screenshots/sign/nanox/blind_simple/00004.png b/tests/speculos/screenshots/sign/nanox/blind_simple/00004.png index 70c1b9a68..1bcb78761 100644 Binary files a/tests/speculos/screenshots/sign/nanox/blind_simple/00004.png and b/tests/speculos/screenshots/sign/nanox/blind_simple/00004.png differ diff --git a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00001.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00001.png deleted file mode 100644 index 0976a317a..000000000 Binary files a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00001.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00002.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00002.png deleted file mode 100644 index 0f18eeec9..000000000 Binary files a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00002.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00003.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00003.png deleted file mode 100644 index 7037eb59e..000000000 Binary files a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00003.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00004.png b/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00004.png deleted file mode 100644 index 70c1b9a68..000000000 Binary files a/tests/speculos/screenshots/sign/nanox/dai_coin_type_on_network_5234/00004.png and /dev/null differ diff --git a/tests/speculos/screenshots/sign/nanox/limit_nonce/00003.png b/tests/speculos/screenshots/sign/nanox/limit_nonce/00003.png index 3edd720b3..50135b20b 100644 Binary files a/tests/speculos/screenshots/sign/nanox/limit_nonce/00003.png and b/tests/speculos/screenshots/sign/nanox/limit_nonce/00003.png differ diff --git a/tests/speculos/screenshots/sign/nanox/nonce_display/00004.png b/tests/speculos/screenshots/sign/nanox/nonce_display/00004.png index 70c1b9a68..1bcb78761 100644 Binary files a/tests/speculos/screenshots/sign/nanox/nonce_display/00004.png and b/tests/speculos/screenshots/sign/nanox/nonce_display/00004.png differ diff --git a/tests/speculos/screenshots/sign/nanox/reject/00003.png b/tests/speculos/screenshots/sign/nanox/reject/00003.png index 70c1b9a68..1bcb78761 100644 Binary files a/tests/speculos/screenshots/sign/nanox/reject/00003.png and b/tests/speculos/screenshots/sign/nanox/reject/00003.png differ diff --git a/tests/speculos/screenshots/sign/nanox/reject/00005.png b/tests/speculos/screenshots/sign/nanox/reject/00005.png index c9222461c..e90cd9db3 100644 Binary files a/tests/speculos/screenshots/sign/nanox/reject/00005.png and b/tests/speculos/screenshots/sign/nanox/reject/00005.png differ diff --git a/tests/speculos/screenshots/sign/nanox/simple/00003.png b/tests/speculos/screenshots/sign/nanox/simple/00003.png index 70c1b9a68..1bcb78761 100644 Binary files a/tests/speculos/screenshots/sign/nanox/simple/00003.png and b/tests/speculos/screenshots/sign/nanox/simple/00003.png differ diff --git a/tests/speculos/test_configuration_cmd.py b/tests/speculos/test_configuration_cmd.py index 8027b2cf8..c27915612 100644 --- a/tests/speculos/test_configuration_cmd.py +++ b/tests/speculos/test_configuration_cmd.py @@ -1,10 +1,3 @@ def test_configuration(cmd): - if cmd.model == "nanos": - assert cmd.get_configuration() == (14, 1, 10, 3) - - if cmd.model == "nanox": - assert cmd.get_configuration() == (14, 1, 10, 3) - - if cmd.model == "nanosp": - assert cmd.get_configuration() == (14, 1, 10, 3) + assert cmd.get_configuration() == (2, 1, 10, 4) diff --git a/tests/speculos/test_sign_cmd.py b/tests/speculos/test_sign_cmd.py index 588e7aa06..90879acd3 100644 --- a/tests/speculos/test_sign_cmd.py +++ b/tests/speculos/test_sign_cmd.py @@ -83,90 +83,6 @@ def test_sign_simple(cmd): assert v == 0x26 # 38 assert r.hex() == "6f389d15320f0501383526ed03de917c14212716f09a262dbc98431086a5db49" assert s.hex() == "0dc994b7b97230bb35fdf6fec2f4d8ff4cfb8bfeb2a652c364c738ff033c05dd" - - -def test_sign_dai_coin_type_on_network_5234(cmd): - result: list = [] - - # DAI coin type - bip32_path="44'/700'/1'/0/0" - - transaction = Transaction( - txType=0xEB, - nonce=0, - gasPrice=0x0306dc4200, - gasLimit=0x5208, - to="0x5a321744667052affa8386ed49e00ef223cbffc3", - value=0x6f9c9e7bf61818, - chainID=5243, - ) - - with cmd.simple_sign_tx(bip32_path=bip32_path, transaction=transaction, result=result) as ex: - sleep(0.5) - - if cmd.model == "nanos": - # Review transaction - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00000.png") - cmd.client.press_and_release('right') - - # Amount 1/3, 2/3, 3/3 - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00001.png") - cmd.client.press_and_release('right') - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00002.png") - cmd.client.press_and_release('right') - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00003.png") - cmd.client.press_and_release('right') - - # Address 1/3, 2/3, 3/3 - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00004.png") - cmd.client.press_and_release('right') - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00005.png") - cmd.client.press_and_release('right') - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00006.png") - cmd.client.press_and_release('right') - - # Network 5243 - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00007.png") - cmd.client.press_and_release('right') - - # Max Fees - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00008.png") - cmd.client.press_and_release('right') - - # Accept and send - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00009.png") - cmd.client.press_and_release('both') - - if cmd.model == "nanox" or cmd.model == "nanosp": - # Review transaction - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00000.png") - cmd.client.press_and_release('right') - - # Amount - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00001.png") - cmd.client.press_and_release('right') - - # Address - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00002.png") - cmd.client.press_and_release('right') - - # Network 5243 - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00003.png") - cmd.client.press_and_release('right') - - # Max Fees - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00004.png") - cmd.client.press_and_release('right') - - # Accept and send - compare_screenshot(cmd, f"screenshots/sign/{PATH_IMG[cmd.model]}/dai_coin_type_on_network_5234/00005.png") - cmd.client.press_and_release('both') - - v, r, s = result - - assert v == 0x1A # 26 - assert r.hex() == "7ebfa5d5cac1e16bb1f1a8c67706b5c6019c0f198df6bb44e742a9de72330961" - assert s.hex() == "537419d8d1443d38ea87943c110789decb43b8f4fea8fae256fe842f669da634" def test_sign_reject(cmd): diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00000.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00000.png deleted file mode 100644 index 8d84cc70f..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00000.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00001.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00001.png deleted file mode 100644 index 049c0d847..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00001.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00002.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00002.png deleted file mode 100644 index e90234003..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00002.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00003.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00003.png deleted file mode 100644 index ed560d59c..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00003.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00004.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00004.png deleted file mode 100644 index 8aa353695..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00004.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00005.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00005.png deleted file mode 100644 index 200f905b0..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00005.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00006.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00006.png deleted file mode 100644 index f10841629..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00006.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00007.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00007.png deleted file mode 100644 index 6577660f6..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00007.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00008.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00008.png deleted file mode 100644 index 2e6aeb852..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00008.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00009.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00009.png deleted file mode 100644 index d242dc575..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00009.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00010.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00010.png deleted file mode 100644 index a62ca78e2..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00010.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00011.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00011.png deleted file mode 100644 index 6c0730332..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00011.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00012.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00012.png deleted file mode 100644 index 3b16ec02c..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00012.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00013.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00013.png deleted file mode 100644 index 1c9156c31..000000000 Binary files a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00013.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00015.png b/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00015.png deleted file mode 120000 index 79f379fcb..000000000 --- a/tests/zemu/snapshots/nanos_starkware_usdt_deposit/00015.png +++ /dev/null @@ -1 +0,0 @@ -00013.png \ No newline at end of file diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00001.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00001.png index 7ebda4f3a..73ac9f618 100644 Binary files a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00001.png and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00001.png differ diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00008.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00008.png index c84d3ec3e..fff41ba06 100644 Binary files a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00008.png and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00008.png differ diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00011.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00011.png deleted file mode 120000 index 489390ada..000000000 --- a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00011.png +++ /dev/null @@ -1 +0,0 @@ -00009.png \ No newline at end of file diff --git a/tests/zemu/snapshots/nanos_transfer_112233445566_network/00011.png b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00011.png new file mode 100644 index 000000000..1c9156c31 Binary files /dev/null and b/tests/zemu/snapshots/nanos_transfer_112233445566_network/00011.png differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00000.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00000.png deleted file mode 100644 index 8d84cc70f..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00000.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00001.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00001.png deleted file mode 100644 index 7ebda4f3a..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00001.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00002.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00002.png deleted file mode 100644 index c2af54e96..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00002.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00003.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00003.png deleted file mode 100644 index a54fefd4c..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00003.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00004.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00004.png deleted file mode 100644 index 8656b8175..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00004.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00005.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00005.png deleted file mode 100644 index fd3155c0d..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00005.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00006.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00006.png deleted file mode 100644 index c63f25f8d..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00006.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00007.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00007.png deleted file mode 100644 index e1d28613d..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00007.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00008.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00008.png deleted file mode 100644 index c84d3ec3e..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00008.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00009.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00009.png deleted file mode 100644 index 1c9156c31..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00009.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00010.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00010.png deleted file mode 100644 index 9c7e7049c..000000000 Binary files a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00010.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00011.png b/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00011.png deleted file mode 120000 index 489390ada..000000000 --- a/tests/zemu/snapshots/nanos_transfer_ethereum_5234_network/00011.png +++ /dev/null @@ -1 +0,0 @@ -00009.png \ No newline at end of file diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00001.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00001.png deleted file mode 100644 index e8ec78b3d..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00001.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00002.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00002.png deleted file mode 100644 index 6735a0784..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00002.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00003.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00003.png deleted file mode 100644 index 85f3a2b4c..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00003.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00004.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00004.png deleted file mode 100644 index e56268e93..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00004.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00005.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00005.png deleted file mode 100644 index d8befd4d0..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00005.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00006.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00006.png deleted file mode 100644 index 9fce3dc7d..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00006.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00007.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00007.png deleted file mode 100644 index 814adcc25..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00007.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00008.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00008.png deleted file mode 100644 index fcc883ef0..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00008.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00010.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00010.png deleted file mode 100644 index c9222461c..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00010.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00011.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00011.png deleted file mode 120000 index 489390ada..000000000 --- a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00011.png +++ /dev/null @@ -1 +0,0 @@ -00009.png \ No newline at end of file diff --git a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00012.png b/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00012.png deleted file mode 100644 index a58590b98..000000000 Binary files a/tests/zemu/snapshots/nanox_starkware_usdt_deposit/00012.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00001.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00001.png deleted file mode 100644 index 0976a317a..000000000 Binary files a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00001.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00002.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00002.png deleted file mode 100644 index 0f18eeec9..000000000 Binary files a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00002.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00003.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00003.png deleted file mode 100644 index 0423eb5fc..000000000 Binary files a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00003.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00004.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00004.png deleted file mode 100644 index 70c1b9a68..000000000 Binary files a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00004.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00006.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00006.png deleted file mode 100644 index c9222461c..000000000 Binary files a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00006.png and /dev/null differ diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00007.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00007.png deleted file mode 120000 index 7159a1242..000000000 --- a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00007.png +++ /dev/null @@ -1 +0,0 @@ -00005.png \ No newline at end of file diff --git a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00008.png b/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00008.png deleted file mode 100644 index a58590b98..000000000 Binary files a/tests/zemu/snapshots/nanox_transfer_ethereum_5234_network/00008.png and /dev/null differ diff --git a/tests/zemu/src/send.test.js b/tests/zemu/src/send.test.js index ad83a4cdd..1634974c2 100644 --- a/tests/zemu/src/send.test.js +++ b/tests/zemu/src/send.test.js @@ -36,25 +36,3 @@ nano_models.forEach(function(model) { await expect(tx).rejects.toEqual(new TransportStatusError(0x6807)); })); }); - -nano_models.forEach(function(model) { - test('[Nano ' + model.letter + '] Transfer Ether on network 5234 on Ethereum app', zemu(model, async (sim, eth) => { - - const tx = eth.signTransaction( - "44'/60'/1'/0/0", - 'ED44850306DC4200825208945A321744667052AFFA8386ED49E00EF223CBFFC3876F9C9E7BF61818808214728080', - ); - - await waitForAppScreen(sim); - let clicks; - if (model.letter === 'S') clicks = 10; - else clicks = 6; - await sim.navigateAndCompareSnapshots('.', model.name + '_transfer_ethereum_5234_network', [clicks, -1, 0]); - - await expect(tx).resolves.toEqual({ - "r": "07a7982dfd16360c96a03467877d0cf9c36f799deff4dace250cdb18e28a3b90", - "s": "773318a93da2e32c1cf308ddd6add1e8c0d285973e541520a05fb4dc720e4fb1", - "v": "2908", - }); - })); -}); diff --git a/tests/zemu/src/starkware.test.js b/tests/zemu/src/starkware.test.js deleted file mode 100644 index 91de9d05d..000000000 --- a/tests/zemu/src/starkware.test.js +++ /dev/null @@ -1,40 +0,0 @@ -import "core-js/stable"; -import "regenerator-runtime/runtime"; -import { waitForAppScreen, zemu, nano_models } from './test.fixture'; -import { byContractAddressAndChainId } from '@ledgerhq/hw-app-eth/erc20' -import { BigNumber } from "bignumber.js"; - -nano_models.forEach(function(model) { - test('[Nano ' + model.letter + '] Transfer Ether on Ethereum app', zemu(model, async (sim, eth) => { - - // Provide USDT token info to the app - const usdt_info = byContractAddressAndChainId("0xdac17f958d2ee523a2206206994597c13d831ec7", 1); - await eth.provideERC20TokenInformation(usdt_info); - - // Provide Stark quantum - const quantization = new BigNumber(1); - await eth.starkProvideQuantum_v2( - "0xdac17f958d2ee523a2206206994597c13d831ec7", - "erc20", - quantization, - null - ) - - const tx = eth.signTransaction( - "44'/60'/1'/0/0", - 'f8b5018a0472698b413b43200000825208940102030405060708090a0b0c0d0e0f1011121314872bd72a24874000b8842505c3d9010101010101010102020202020202020303030303030303040404040404040402ce625e94458d39dd0bf3b45a843544dd4a14b8169045a3a3d15aa564b936c500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000030d40808080', - ); - - await waitForAppScreen(sim); - let clicks; - if (model.letter === 'S') clicks = 14; - else clicks = 10; - await sim.navigateAndCompareSnapshots('.', model.name + '_starkware_usdt_deposit', [clicks, -1, 0]); - - await expect(tx).resolves.toEqual({ - "r": "14c368c0d32e399470d6113cf796c5f4cd70300766337d8b0ba71ecad21b3d52", - "s": "4207c027959e84fc2242a1f4fd955603f137ba28f67268ffc91fef5d65071b0a", - "v": "1c", - }); - })); -}); diff --git a/tools/build_sdk.py b/tools/build_sdk.py deleted file mode 100755 index 552bb25cf..000000000 --- a/tools/build_sdk.py +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/env python3 - -''' -This script extract a few specific definitions from app-ethereum that are -required to exchange information with ethereum external plugins. -It should always be launched from app-ethereum: - -python3 ethereum-plugin-sdk/build_sdk.py - -''' - -import os - - -def extract_from_headers(sources, nodes_to_extract): - cat_sources = [] - for source in sources: - with open(source, 'r') as f: - cat_sources += f.readlines() - - sdk_body = [] - for key, values in nodes_to_extract.items(): - for value in values: - node = [] - unclosed_curvy_brackets = False - unclosed_parantheses = False - for line in cat_sources: - if key in line and value in line: - node += [line] - unclosed_curvy_brackets = line.count('{') - line.count('}') - if unclosed_curvy_brackets == False: - break - elif (key == "fn" and value in line) or unclosed_parantheses: - node += [line] - unclosed_parantheses = line.find(")") == -1 - if unclosed_parantheses == False: - break - elif unclosed_curvy_brackets: - node += [line] - unclosed_curvy_brackets += line.count( - '{') - line.count('}') - if unclosed_curvy_brackets: - continue - else: - break - - sdk_body += [''.join(node)] - - return '\n'.join(sdk_body) - - -def extract_from_c_files(sources, nodes_to_extract): - cat_sources = [] - for source in sources: - with open(source, 'r') as f: - cat_sources += f.readlines() - - sdk_body = [] - for node_name in nodes_to_extract: - node = [] - copying = False - wait_curvy_bracket = True - for line in cat_sources: - if node_name in line: - copying = True - node += [line] - unclosed_curvy_brackets = line.count('{') - line.count('}') - elif copying: - node += [line] - unclosed_curvy_brackets += line.count('{') - line.count('}') - if wait_curvy_bracket: - wait_curvy_bracket = line.count('}') == 0 - if unclosed_curvy_brackets != 0 or wait_curvy_bracket: - continue - else: - break - - sdk_body += [''.join(node)] - - return '\n'.join(sdk_body) - - -def merge_headers(sources, nodes_to_extract): - includes = [ - '#include ', - '#include ', - '#include "os.h"', - '#include "cx.h"', - '#ifdef HAVE_NBGL', - '#include "nbgl_types.h"', - '#endif' - ] - - body = extract_from_headers(sources, nodes_to_extract) - - eth_internals_h = '\n\n'.join([ - "/* This file is auto-generated, don't edit it */", - "#pragma once", - '\n'.join(includes), - body - ]) - - with open("ethereum-plugin-sdk/include/eth_internals.h", 'w') as f: - f.write(eth_internals_h) - - -def copy_header(header_to_copy, merged_headers): - - merged_headers = [os.path.basename(path) for path in merged_headers] - - with open(header_to_copy, 'r') as f: - source = f.readlines() - - eth_plugin_interface_h = [ - "/* This file is auto-generated, don't edit it */\n"] - for line in source: - eth_plugin_interface_h += [line] - for header in merged_headers: - if header in line: - del eth_plugin_interface_h[-1] - break - - # add '#include "eth_internals.h"' - include_index = eth_plugin_interface_h.index('#include "cx.h"\n') - eth_plugin_interface_h.insert( - include_index+1, '#include "eth_internals.h"\n') - - # dump to file - with open("ethereum-plugin-sdk/include/eth_plugin_interface.h", 'w') as f: - f.writelines(eth_plugin_interface_h) - - -def merge_c_files(sources, nodes_to_extract): - includes = [ - '#include "eth_internals.h"' - ] - - body = extract_from_c_files(sources, nodes_to_extract) - - eth_internals_h = '\n\n'.join([ - "/* This file is auto-generated, don't edit it */", - '\n'.join(includes), - body - ]) - - with open("ethereum-plugin-sdk/include/eth_internals.c", 'w') as f: - f.write(eth_internals_h) - - -if __name__ == "__main__": - - # some nodes will be extracted from these headers and merged into a new one, copied to sdk - headers_to_merge = [ - "src/tokens.h", - "src/chainConfig.h", - "src/utils.h", - "src_common/ethUstream.h", - "src_common/ethUtils.h", - "src/shared_context.h", - "src/eth_plugin_internal.h", - "src/nft.h", - "src/swap_lib_calls.h" - ] - nodes_to_extract = { - "#define": ["MAX_TICKER_LEN", "ADDRESS_LENGTH", "INT256_LENGTH", "WEI_TO_ETHER", "SELECTOR_SIZE", "PARAMETER_LENGTH", "RUN_APPLICATION", "COLLECTION_NAME_MAX_LEN"], - "typedef enum": [], - "typedef struct": ["tokenDefinition_t", "txInt256_t", "txContent_t", "nftInfo_t", "caller_app_t"], - "typedef union": ["extraInfo_t"], - "__attribute__((no_instrument_function)) inline": ["int allzeroes"], - "const": ["HEXDIGITS"], - "fn": ["void getEthAddressStringFromBinary", "void getEthAddressFromKey", "void getEthDisplayableAddress", "bool adjustDecimals", "bool uint256_to_decimal", "void amountToString", "void u64_to_string", "void copy_address", "void copy_parameter", "bool U2BE_from_parameter", "bool U4BE_from_parameter"] - } - merge_headers(headers_to_merge, nodes_to_extract) - - # this header will be stripped from all #include related to previously merged headers, then copied to sdk - copy_header("src/eth_plugin_interface.h", headers_to_merge) - - # extract and merge function bodies - c_files_to_merge = [ - "src/utils.c", - "src_common/ethUtils.c", - "src/eth_plugin_internal.c" - ] - merge_c_files(c_files_to_merge, nodes_to_extract["fn"]) diff --git a/tools/build_sdk.sh b/tools/build_sdk.sh new file mode 100755 index 000000000..f4ec6a382 --- /dev/null +++ b/tools/build_sdk.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Clean the sdk +find ./ethereum-plugin-sdk/ -mindepth 1 -maxdepth 1 ! -name .git -exec rm -r {} \; + +# Copy exclusive files +cp -r src_plugin_sdk/* ./ethereum-plugin-sdk/ + +# Copy common sources +cp -r src_common/* ./ethereum-plugin-sdk/src/ diff --git a/tools/gen_networks.py b/tools/gen_networks.py new file mode 100755 index 000000000..7c91b17a0 --- /dev/null +++ b/tools/gen_networks.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 + +import os +import sys +import re +import argparse +from pathlib import Path + + +class Network: + chain_id: int + name: str + ticker: str + + def __init__(self, chain_id: int, name: str, ticker: str): + self.chain_id = chain_id + self.name = name + self.ticker = ticker + + +def get_network_glyph_name(net: Network) -> str: + return "stax_chain_%u_64px" % (net.chain_id) + + +def get_header() -> str: + return """\ +/* + * Generated by %s + */ + +""" % (sys.argv[0]) + + +def gen_icons_array_inc(networks: list[Network], path: str) -> bool: + with open(path + ".h", "w") as out: + print(get_header() + """\ +#ifndef NETWORK_ICONS_GENERATED_H_ +#define NETWORK_ICONS_GENERATED_H_ + +#include +#include "nbgl_types.h" + +typedef struct { + uint64_t chain_id; + const nbgl_icon_details_t *icon; +} network_icon_t; + +extern const network_icon_t g_network_icons[%u]; + +#endif // NETWORK_ICONS_GENERATED_H_ \ +""" % (len(networks)), file=out) + return True + + +def gen_icons_array_src(networks: list[Network], path: str) -> bool: + with open(path + ".c", "w") as out: + print(get_header() + """\ +#include "glyphs.h" +#include "%s.h" + +const network_icon_t g_network_icons[%u] = {\ +""" % (os.path.basename(path), len(networks)), file=out) + + for net in networks: + glyph_name = get_network_glyph_name(net) + glyph_file = "glyphs/%s.gif" % (glyph_name) + if os.path.isfile(glyph_file): + if os.path.islink(glyph_file): + glyph_name = Path(os.path.realpath(glyph_file)).stem + print(" "*4, end="", file=out) + print("{.chain_id = %u, .icon = &C_%s}, // %s" % (net.chain_id, + glyph_name, + net.name), + file=out) + + print("};", file=out) + return True + + +def gen_icons_array(networks: list[Network], path: str) -> bool: + path += "/net_icons.gen" + if not gen_icons_array_inc(networks, path) or \ + not gen_icons_array_src(networks, path): + return False + return True + + +def network_icon_exists(net: Network) -> bool: + return os.path.isfile("glyphs/%s.gif" % (get_network_glyph_name(net))) + + +def main(output_dir: str) -> bool: + networks: list[Network] = list() + + # get chain IDs and network names + expr = r"{\.chain_id = ([0-9]*), \.name = \"(.*)\", \.ticker = \"(.*)\"}," + with open("src/network.c") as f: + for line in f.readlines(): + line = line.strip() + if line.startswith("{") and line.endswith("},"): + m = re.search(expr, + line) + assert(m.lastindex == 3) + networks.append(Network(int(m.group(1)), + m.group(2), + m.group(3))) + + networks.sort(key=lambda x: x.chain_id) + + if not gen_icons_array(list(filter(network_icon_exists, networks)), + output_dir): + return False + return True + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("OUTPUT_DIR") + args = parser.parse_args() + assert os.path.isdir(args.OUTPUT_DIR) + quit(0 if main(args.OUTPUT_DIR) else 1)